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