ldasm.S revision 1.15
1/*	$OpenBSD: ldasm.S,v 1.15 2002/11/23 06:19:26 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	%o0, %l0
108	call	_dl_boot_bind		! _dl_boot_bind(sp,dl_data)
109	 mov	%l3, %o1
110
111	mov	%l3, %o3
112	ldx	[%l0], %l3		! argc = *sp
113	sllx	%l3, 3, %l3		! argc *= sizeof(long)
114	addx	%l0, 8, %o0		! argv = [sp + argc]
115	addx	%l0, 16, %o1		! envp = sp + 16 +
116	addx	%o1, %l3, %o1		!	+ argc
117
118	addx	%o3, (7*8), %l2
119	ldx	[%l2], %o2		! loff = dl_data[AUX_base];
120
121	call	_dl_boot		! _dl_boot(argv,envp,loff,dynp,dl_data)
122	 nop
123
124	add	%sp, DL_DATA_SIZE, %sp		! restore stack
125	mov	%l1, %g1		! restore ps_strings
126
127	jmp	%o0
128	 nop
129
130	/*
131	 * We have two separate entry points to the runtime linker.
132	 * I'm implementing this following the SPARC v9 ABI spec.
133	 *
134	 * _dl_bind_start_0(x, y) is called from .PLT0, and is used for
135	 * PLT entries above 32768.
136	 *
137	 * _dl_bind_start_1(x, y) is called from .PLT1, and is used for
138	 * PLT entries below 32768.
139	 *
140	 * The first two entries of PLT2 contain the xword object pointer.
141	 *
142	 * These routines are called with two longword arguments,
143	 * x and y.  To calculate the address of the entry,
144	 * _dl_bind_start_1(x, y) does:
145	 *
146	 *	n = x >> 15;
147	 *
148	 * and _dl_bind_start_0(x, y) does:
149	 *
150	 *	i = x - y + 1048596;
151	 *	n = 32768 + (i/5120)*160 + (i%5120)/24;
152	 *
153	 * Neither routine needs to issue a save since it's already been
154	 * done in the PLT entry.
155	 */
156
157	/* NOTE: _dl_bind_start_0 is untested.  Hence the debug stuff */
158
159	.section	".text"
160	.align	4
161	.global	_dl_bind_start_0
162	.type	_dl_bind_start_0,@function
163_dl_bind_start_0:	# (x, y)
164#if 0
165	call	_dl_bind_start_0_stub
166	 ldx	[%o1 + (10*4)], %l7
167	mov	%o0, %o1
168
169	call	_dl_bind
170	 mov	%l7, %o0
171#else
172	sethi	%hi(1048596), %l1
173	sub	%o0, %o1, %l0		/* x - y */
174	or	%l1, %lo(1048596), %l1
175	add	%l0, %l1, %l0		/* x - y + 1048596 */
176
177	sdivx	%l0, 5120, %l1		/* Calculate i/5120 */
178	ldx	[%o1 + (10*4)], %o0	/* Load object pointer from PLT2 */
179	sub	%l0, %l1, %l2		/* And i%5120 */
180
181	/* Let the division churn for a bit. */
182	sdivx	%l2, 14, %l4		/* (i%5120)/24 */
183
184	/* 160 is (32 * 5) or (32 * (4 + 1)) */
185	sllx	%l1, 2, %l3		/* 4 * (i/5120) */
186	add	%l1, %l3, %l3		/* 5 * (i/5120) */
187	sllx	%l3, 5, %l3		/* 32 * 5 * (i/5120) */
188
189	sethi	%hi(32768), %l6
190	add	%l3, %l4, %l5		/* %l5 = (i/5120)*160 + (i%5120)/24; */
191	add	%l5, %l6, %l5
192
193	call	_dl_bind		/* Call _dl_bind(obj, offset) */
194	 mov	%l5, %o1
195
196	jmp	%o0			/* return value == function address */
197	 restore			/* Dump our stack frame */
198#endif
199
200	.section	".text"
201	.align	4
202	.global	_dl_bind_start_1
203	.type	_dl_bind_start_1,@function
204_dl_bind_start_1:	# (x, y)
205	srax	%o0, 15, %o2		/* %o0 is the index to our PLT slot */
206
207	ldx	[%o1 + 8], %o0		/* The object pointer is at [%o1 + 8] */
208
209	call	_dl_bind		/* Call _dl_bind(obj, offset) */
210	 mov	%o2, %o1
211
212	jmp	%o0			/* return value == function address */
213	 restore			/* Dump our stack frame */
214
215	.section ".text"
216	.align 4
217	.global _dl_close
218	.type _dl_close,@function
219_dl_close:
220	mov SYS_close | SYSCALL_G2RFLAG, %g1	! call sys_close
221	add %o7, 8, %g2				! just return on success
222	t ST_SYSCALL				! off to wonderland
223	retl
224	 sub %g0, %o0, %o0			! error: result = -errno
225
226
227	.section ".text"
228	.align 4
229	.global _dl_exit
230	.type _dl_exit,@function
231_dl_exit:
232	mov SYS_exit | SYSCALL_G2RFLAG, %g1	! call sys_exit
233	add %o7, 8, %g2				! just return on success
234	t ST_SYSCALL				! off to wonderland
235	retl
236	 sub %g0, %o0, %o0			! error: result = -errno
237
238
239	.section ".text"
240	.align 4
241	.global _dl_issetugid
242	.type _dl_issetugid,@function
243_dl_issetugid:
244	mov SYS_issetugid | SYSCALL_G2RFLAG, %g1	! call sys_issetugid
245	add %o7, 8, %g2					! just return on success
246	t ST_SYSCALL					! off to wonderland
247	retl
248	 sub %g0, %o0, %o0				! error: result = -errno
249
250
251	.section ".text"
252	.align 4
253	.global _dl__syscall
254	.type _dl__syscall,@function
255_dl__syscall:
256	mov SYS___syscall | SYSCALL_G2RFLAG, %g1	! call sys___syscall
257	add %o7, 8, %g2				! just return on success
258	t ST_SYSCALL				! off to wonderland
259	retl
260	 sub %g0, %o0, %o0			! error: result = -errno
261
262
263	.section ".text"
264	.align 4
265	.global _dl_munmap
266	.type _dl_munmap,@function
267_dl_munmap:
268	mov SYS_munmap | SYSCALL_G2RFLAG, %g1	! calling sys_munmap
269	add %o7, 8, %g2				! just return on success
270	t ST_SYSCALL				! off to wonderland
271	retl
272	 sub %g0, %o0, %o0			! error: result = -errno
273
274
275	.section ".text"
276	.align 4
277	.global _dl_mprotect
278	.type _dl_mprotect,@function
279_dl_mprotect:
280	mov SYS_mprotect | SYSCALL_G2RFLAG, %g1	! calling sys_mprotect
281	add %o7, 8, %g2				! just return on success
282	t ST_SYSCALL				! off to wonderland
283	retl
284	 sub %g0, %o0, %o0			! error: result = -errno
285
286
287	.section ".text"
288	.align 4
289	.global _dl_open
290	.type _dl_open,@function
291_dl_open:
292	mov SYS_open | SYSCALL_G2RFLAG, %g1	! calling sys_open
293	add %o7, 8, %g2				! just return on success
294	t ST_SYSCALL				! off to wonderland
295	retl
296	 sub %g0, %o0, %o0			! error: result = -errno
297
298
299	.section ".text"
300	.align 4
301	.global _dl_read
302	.type _dl_read,@function
303_dl_read:
304	mov SYS_read | SYSCALL_G2RFLAG, %g1	! calling sys_read
305	add %o7, 8, %g2				! just return on success
306	t ST_SYSCALL				! off to wonderland
307	retl
308	 sub %g0, %o0, %o0			! error: result = -errno
309
310
311	.section ".text"
312	.align 4
313	.global _dl_write
314	.type _dl_write,@function
315_dl_write:
316	mov SYS_write | SYSCALL_G2RFLAG, %g1	! calling sys_write
317	add %o7, 8, %g2				! just return on success
318	t ST_SYSCALL				! off to wonderland
319	retl
320	 sub %g0, %o0, %o0			! error: result = -errno
321
322
323	.section ".text"
324	.align 4
325	.global _dl_stat
326	.type _dl_stat,@function
327_dl_stat:
328	mov SYS_stat | SYSCALL_G2RFLAG, %g1	! call sys_stat
329	add %o7, 8, %g2				! just return on success
330	t ST_SYSCALL				! off to wonderland
331	retl
332	 sub %g0, %o0, %o0			! error: result = -errno
333
334
335	.section ".text"
336	.align 4
337	.globl _dl_fstat
338	.type _dl_fstat,@function
339_dl_fstat:
340	mov  SYS_fstat | SYSCALL_G2RFLAG, %g1	! call sys_fstat
341	add %o7, 8, %g2				! just return on success
342	t ST_SYSCALL				! off to wonderland
343	retl
344	 sub %g0, %o0, %o0                      ! error: result = -errno
345
346
347	.section ".text"
348	.align 4
349	.globl _dl_fcntl
350	.type _dl_fcntl,@function
351_dl_fcntl:
352	mov  SYS_fcntl | SYSCALL_G2RFLAG, %g1	! call sys_fcntl
353	add %o7, 8, %g2				! just return on success
354	t ST_SYSCALL				! off to wonderland
355	retl
356	 sub %g0, %o0, %o0                      ! error: result = -errno
357
358
359	.section ".text"
360	.align 4
361	.globl _dl_getdirentries
362	.type _dl_getdirentries,@function
363_dl_getdirentries:
364	mov  SYS_getdirentries | SYSCALL_G2RFLAG, %g1	! call sys_getdirentries
365	add %o7, 8, %g2					! just return on success
366	t ST_SYSCALL					! off to wonderland
367	retl
368	 sub %g0, %o0, %o0                      ! error: result = -errno
369