ldasm.S revision 1.9
1/*	$OpenBSD: ldasm.S,v 1.9 2002/03/17 00:22:04 art 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, %o4
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	%o4, (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	 mov	0, %o3			! dynp = 0
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
217	.section ".text"
218	.align 4
219	.global _dl_close
220	.type _dl_close,@function
221_dl_close:
222	mov SYS_close | SYSCALL_G2RFLAG, %g1	! call sys_close
223	add %o7, 8, %g2				! just return on sucess
224	t ST_SYSCALL				! off to wonderland
225	retl
226	 sub %g0, %o0, %o0			! error: result = -errno
227
228
229	.section ".text"
230	.align 4
231	.global _dl_exit
232	.type _dl_exit,@function
233_dl_exit:
234	mov SYS_exit | SYSCALL_G2RFLAG, %g1	! call sys_exit
235	add %o7, 8, %g2				! just return on sucess
236	t ST_SYSCALL				! off to wonderland
237	retl
238	 sub %g0, %o0, %o0			! error: result = -errno
239
240
241	.section ".text"
242	.align 4
243	.global _dl_issetugid
244	.type _dl_issetugid,@function
245_dl_issetugid:
246	mov SYS_issetugid | SYSCALL_G2RFLAG, %g1
247	add %o7, 8, %g2
248	t ST_SYSCALL
249	retl
250	 sub %g0, %o0, %o0
251
252
253	.section ".text"
254	.align 4
255	.global _dl___syscall
256	.type _dl___syscall,@function
257_dl___syscall:
258	mov SYS___syscall | SYSCALL_G2RFLAG, %g1	! call sys_exit
259	add %o7, 8, %g2				! just return on sucess
260	t ST_SYSCALL				! off to wonderland
261	retl
262	 sub %g0, %o0, %o0			! error: result = -errno
263
264
265	.section ".text"
266	.align 4
267	.global _dl_munmap
268	.type _dl_munmap,@function
269_dl_munmap:
270	mov SYS_munmap | SYSCALL_G2RFLAG, %g1	! calling sys_mmap
271	add %o7, 8, %g2				! just return on sucess
272	t ST_SYSCALL				! off to wonderland
273	retl
274	 sub %g0, %o0, %o0			! error: result = -errno
275
276
277	.section ".text"
278	.align 4
279	.global _dl_mprotect
280	.type _dl_mprotect,@function
281_dl_mprotect:
282	mov SYS_mprotect | SYSCALL_G2RFLAG, %g1	! calling sys_mprotect
283	add %o7, 8, %g2				! just return on sucess
284	t ST_SYSCALL				! off to wonderland
285	retl
286	 sub %g0, %o0, %o0			! error: result = -errno
287
288
289	.section ".text"
290	.align 4
291	.global _dl_open
292	.type _dl_open,@function
293_dl_open:
294	mov SYS_open | SYSCALL_G2RFLAG, %g1	! calling sys_open
295	add %o7, 8, %g2				! just return on sucess
296	t ST_SYSCALL				! off to wonderland
297	retl
298	 sub %g0, %o0, %o0			! error: result = -errno
299
300
301	.section ".text"
302	.align 4
303	.global _dl_read
304	.type _dl_read,@function
305_dl_read:
306	mov SYS_read | SYSCALL_G2RFLAG, %g1	! calling sys_read
307	add %o7, 8, %g2				! just return on sucess
308	t ST_SYSCALL				! off to wonderland
309	retl
310	 sub %g0, %o0, %o0			! error: result = -errno
311
312
313	.section ".text"
314	.align 4
315	.global _dl_write
316	.type _dl_write,@function
317_dl_write:
318	mov SYS_write | SYSCALL_G2RFLAG, %g1	! calling sys_write
319	add %o7, 8, %g2				! just return on sucess
320	t ST_SYSCALL				! off to wonderland
321	retl
322	 sub %g0, %o0, %o0			! error: result = -errno
323
324
325	.section ".text"
326	.align 4
327	.global _dl_stat
328	.type _dl_stat,@function
329_dl_stat:
330	mov SYS_stat | SYSCALL_G2RFLAG, %g1	! call sys_stat
331	add %o7, 8, %g2				! just return on sucess
332	t ST_SYSCALL				! off to wonderland
333	retl
334	 sub %g0, %o0, %o0			! error: result = -errno
335