ldasm.S revision 1.19
1/*	$OpenBSD: ldasm.S,v 1.19 2003/06/02 20:20:35 jason Exp $	*/
2/*	$NetBSD: rtld_start.S,v 1.5 2001/08/14 22:17:48 eeh Exp $	*/
3
4/*
5 * Copyright (c) 2001 Jason L. Wright (jason@thought.net)
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*-
31 * Copyright (c) 2000 Eduardo Horvath.
32 * Copyright (c) 1999 The NetBSD Foundation, Inc.
33 * All rights reserved.
34 *
35 * This code is derived from software contributed to The NetBSD Foundation
36 * by Christos Zoulas and Paul Kranenburg.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 *    notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 *    notice, this list of conditions and the following disclaimer in the
45 *    documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 *    must display the following acknowledgement:
48 *	This product includes software developed by the NetBSD
49 *	Foundation, Inc. and its contributors.
50 * 4. Neither the name of The NetBSD Foundation nor the names of its
51 *    contributors may be used to endorse or promote products derived
52 *    from this software without specific prior written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
55 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE.
65 */
66
67#include <sys/syscall.h>
68#include <machine/trap.h>
69#include <machine/asm.h>
70#define	_LOCORE
71#include <machine/frame.h>
72
73/*
74 * ELF:
75 *	On startup the stack should contain 16 extended word register save area,
76 *	followed by the arg count, etc.
77 *
78 * _rtld() expects the stack pointer to point to two longwords for argument
79 *	return followed by argc, etc.  We need to create a pointer to
80 *	&argc + 16 and pass that in.  The return args will be in those locations.
81 *
82 * NB:	We are violating the ELF spec by passing a pointer to the ps strings in
83 *	%g1 instead of a termination routine.
84 */
85
86/* Offset of ARGC from bottom of stack */
87#define	ARGC	(16*8)
88/* XXX - DL_DATA_SIZE should be (9*8), but I can't think right now. */
89#define DL_DATA_SIZE (16*8)
90
91	.section	".text"
92	.align	16
93	.global	_dl_start
94	.type	_dl_start,@function
95_dl_start:
96	sub	%g0, %g0, %fp		! clear frame
97	mov	%g1, %l1		! save ps_strings
98	sub	%sp, DL_DATA_SIZE, %sp	! make room for dl_data
99	add	%sp, BIAS + ARGC, %l3
100
101	add	%l3, DL_DATA_SIZE, %o0
102	mov	%o0, %l0
103	call	_dl_boot_bind		! _dl_boot_bind(sp,dl_data)
104	 mov	%l3, %o1
105
106	mov	%l3, %o3
107	ldx	[%l0], %l3		! argc = *sp
108	sllx	%l3, 3, %l3		! argc *= sizeof(long)
109	addx	%l0, 8, %o0		! argv = [sp + argc]
110	addx	%l0, 16, %o1		! envp = sp + 16 +
111	addx	%o1, %l3, %o1		!	+ argc
112
113	addx	%o3, (7*8), %l2
114	ldx	[%l2], %o2		! loff = dl_data[AUX_base];
115
116	call	_dl_boot		! _dl_boot(argv,envp,loff,dynp,dl_data)
117	 nop
118
119	add	%sp, DL_DATA_SIZE, %sp		! restore stack
120	mov	%l1, %g1		! restore ps_strings
121
122	jmp	%o0
123	 nop
124
125	/*
126	 * We have two separate entry points to the runtime linker.
127	 * I'm implementing this following the SPARC v9 ABI spec.
128	 *
129	 * _dl_bind_start_0(x, y) is called from .PLT0, and is used for
130	 * PLT entries above 32768.
131	 *
132	 * _dl_bind_start_1(x, y) is called from .PLT1, and is used for
133	 * PLT entries below 32768.
134	 *
135	 * The first two entries of PLT2 contain the xword object pointer.
136	 *
137	 * These routines are called with two longword arguments,
138	 * x and y.  To calculate the address of the entry,
139	 * _dl_bind_start_1(x, y) does:
140	 *
141	 *	n = x >> 15;
142	 *
143	 * and _dl_bind_start_0(x, y) does:
144	 *
145	 *	i = x - y + 1048596;
146	 *	n = 32768 + (i/5120)*160 + (i%5120)/24;
147	 *
148	 * Neither routine needs to issue a save since it's already been
149	 * done in the PLT entry.
150	 */
151
152	/* NOTE: _dl_bind_start_0 is untested.  Hence the debug stuff */
153
154	.section	".text"
155	.align	4
156	.global	_dl_bind_start_0
157	.type	_dl_bind_start_0,@function
158_dl_bind_start_0:	# (x, y)
159#if 0
160	call	_dl_bind_start_0_stub
161	 ldx	[%o1 + (10*4)], %l7
162	mov	%o0, %o1
163
164	call	_dl_bind
165	 mov	%l7, %o0
166#else
167	sethi	%hi(1048596), %l1
168	sub	%o0, %o1, %l0		/* x - y */
169	or	%l1, %lo(1048596), %l1
170	add	%l0, %l1, %l0		/* x - y + 1048596 */
171
172	sdivx	%l0, 5120, %l1		/* Calculate i/5120 */
173	ldx	[%o1 + (10*4)], %o0	/* Load object pointer from PLT2 */
174	sub	%l0, %l1, %l2		/* And i%5120 */
175
176	/* Let the division churn for a bit. */
177	sdivx	%l2, 14, %l4		/* (i%5120)/24 */
178
179	/* 160 is (32 * 5) or (32 * (4 + 1)) */
180	sllx	%l1, 2, %l3		/* 4 * (i/5120) */
181	add	%l1, %l3, %l3		/* 5 * (i/5120) */
182	sllx	%l3, 5, %l3		/* 32 * 5 * (i/5120) */
183
184	sethi	%hi(32768), %l6
185	add	%l3, %l4, %l5		/* %l5 = (i/5120)*160 + (i%5120)/24; */
186	add	%l5, %l6, %l5
187
188	call	_dl_bind		/* Call _dl_bind(obj, offset) */
189	 mov	%l5, %o1
190
191	jmp	%o0			/* return value == function address */
192	 restore			/* Dump our stack frame */
193#endif
194
195	.section	".text"
196	.align	4
197	.global	_dl_bind_start_1
198	.type	_dl_bind_start_1,@function
199_dl_bind_start_1:	# (x, y)
200	srax	%o0, 15, %o2		/* %o0 is the index to our PLT slot */
201
202	ldx	[%o1 + 8], %o0		/* The object pointer is at [%o1 + 8] */
203
204	call	_dl_bind		/* Call _dl_bind(obj, offset) */
205	 mov	%o2, %o1
206
207	jmp	%o0			/* return value == function address */
208	 restore			/* Dump our stack frame */
209
210	.section ".text"
211	.align 4
212	.global _dl_close
213	.type _dl_close,@function
214_dl_close:
215	mov SYS_close | SYSCALL_G2RFLAG, %g1	! call sys_close
216	add %o7, 8, %g2				! just return on success
217	t ST_SYSCALL				! off to wonderland
218	retl
219	 sub %g0, %o0, %o0			! error: result = -errno
220
221
222	.section ".text"
223	.align 4
224	.global _dl_exit
225	.type _dl_exit,@function
226_dl_exit:
227	mov SYS_exit | SYSCALL_G2RFLAG, %g1	! call sys_exit
228	add %o7, 8, %g2				! just return on success
229	t ST_SYSCALL				! off to wonderland
230	retl
231	 sub %g0, %o0, %o0			! error: result = -errno
232
233
234	.section ".text"
235	.align 4
236	.global _dl_issetugid
237	.type _dl_issetugid,@function
238_dl_issetugid:
239	mov SYS_issetugid | SYSCALL_G2RFLAG, %g1	! call sys_issetugid
240	add %o7, 8, %g2					! just return on success
241	t ST_SYSCALL					! off to wonderland
242	retl
243	 sub %g0, %o0, %o0				! error: result = -errno
244
245
246	.section ".text"
247	.align 4
248	.global _dl__syscall
249	.type _dl__syscall,@function
250_dl__syscall:
251	mov SYS___syscall | SYSCALL_G2RFLAG, %g1	! call sys___syscall
252	add %o7, 8, %g2				! just return on success
253	t ST_SYSCALL				! off to wonderland
254	retl
255	 sub %g0, %o0, %o0			! error: result = -errno
256
257
258	.section ".text"
259	.align 4
260	.global _dl_munmap
261	.type _dl_munmap,@function
262_dl_munmap:
263	mov SYS_munmap | SYSCALL_G2RFLAG, %g1	! calling sys_munmap
264	add %o7, 8, %g2				! just return on success
265	t ST_SYSCALL				! off to wonderland
266	retl
267	 sub %g0, %o0, %o0			! error: result = -errno
268
269
270	.section ".text"
271	.align 4
272	.global _dl_mprotect
273	.type _dl_mprotect,@function
274_dl_mprotect:
275	mov SYS_mprotect | SYSCALL_G2RFLAG, %g1	! calling sys_mprotect
276	add %o7, 8, %g2				! just return on success
277	t ST_SYSCALL				! off to wonderland
278	retl
279	 sub %g0, %o0, %o0			! error: result = -errno
280
281
282	.section ".text"
283	.align 4
284	.global _dl_open
285	.type _dl_open,@function
286_dl_open:
287	mov SYS_open | SYSCALL_G2RFLAG, %g1	! calling sys_open
288	add %o7, 8, %g2				! just return on success
289	t ST_SYSCALL				! off to wonderland
290	retl
291	 sub %g0, %o0, %o0			! error: result = -errno
292
293
294	.section ".text"
295	.align 4
296	.global _dl_read
297	.type _dl_read,@function
298_dl_read:
299	mov SYS_read | SYSCALL_G2RFLAG, %g1	! calling sys_read
300	add %o7, 8, %g2				! just return on success
301	t ST_SYSCALL				! off to wonderland
302	retl
303	 sub %g0, %o0, %o0			! error: result = -errno
304
305
306	.section ".text"
307	.align 4
308	.global _dl_write
309	.type _dl_write,@function
310_dl_write:
311	mov SYS_write | SYSCALL_G2RFLAG, %g1	! calling sys_write
312	add %o7, 8, %g2				! just return on success
313	t ST_SYSCALL				! off to wonderland
314	retl
315	 sub %g0, %o0, %o0			! error: result = -errno
316
317
318	.section ".text"
319	.align 4
320	.global _dl_stat
321	.type _dl_stat,@function
322_dl_stat:
323	mov SYS_stat | SYSCALL_G2RFLAG, %g1	! call sys_stat
324	add %o7, 8, %g2				! just return on success
325	t ST_SYSCALL				! off to wonderland
326	retl
327	 sub %g0, %o0, %o0			! error: result = -errno
328
329
330	.section ".text"
331	.align 4
332	.globl _dl_fstat
333	.type _dl_fstat,@function
334_dl_fstat:
335	mov  SYS_fstat | SYSCALL_G2RFLAG, %g1	! call sys_fstat
336	add %o7, 8, %g2				! just return on success
337	t ST_SYSCALL				! off to wonderland
338	retl
339	 sub %g0, %o0, %o0                      ! error: result = -errno
340
341
342	.section ".text"
343	.align 4
344	.globl _dl_fcntl
345	.type _dl_fcntl,@function
346_dl_fcntl:
347	mov  SYS_fcntl | SYSCALL_G2RFLAG, %g1	! call sys_fcntl
348	add %o7, 8, %g2				! just return on success
349	t ST_SYSCALL				! off to wonderland
350	retl
351	 sub %g0, %o0, %o0                      ! error: result = -errno
352
353
354	.section ".text"
355	.align 4
356	.globl _dl_getdirentries
357	.type _dl_getdirentries,@function
358_dl_getdirentries:
359	mov  SYS_getdirentries | SYSCALL_G2RFLAG, %g1	! call sys_getdirentries
360	add %o7, 8, %g2					! just return on success
361	t ST_SYSCALL					! off to wonderland
362	retl
363	 sub %g0, %o0, %o0                      ! error: result = -errno
364
365
366	/* _dl_sigprocmask does not support NULL new mask */
367	.section ".text"
368	.align 4
369	.globl _dl_sigprocmask
370	.type _dl_sigprocmask,@function
371_dl_sigprocmask:
372	ld	[%o1], %o1			! indirect for new mask
373	mov	SYS_sigprocmask, %g1		! call sys_sigprocmask
374	t ST_SYSCALL				! off to wonderland
375						! what about errors?
376	cmp	%o2, 0
377	bne,a	1f				! if oset != NULL
378	 st	%o0, [%o2]			!   *oset = oldmask
3791:
380	retl
381	 clr %o0
382
383
384	.section ".text"
385	.align 4
386	.globl _dl_sysctl
387	.type _dl_sysctl,@function
388_dl_sysctl:
389	mov  SYS___sysctl | SYSCALL_G2RFLAG, %g1	! call sys_getdirentries
390	add %o7, 8, %g2					! just return on success
391	t ST_SYSCALL					! off to wonderland
392	retl
393	 sub %g0, %o0, %o0                      ! error: result = -errno
394