xref: /titanic_50/usr/src/cmd/sgs/rtld/i386/boot_elf.s (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate/*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate/*
23*7c478bd9Sstevel@tonic-gate *	Copyright (c) 1988 AT&T
24*7c478bd9Sstevel@tonic-gate *	  All Rights Reserved
25*7c478bd9Sstevel@tonic-gate *
26*7c478bd9Sstevel@tonic-gate *
27*7c478bd9Sstevel@tonic-gate *	Copyright 2000-2002 Sun Microsystems, Inc.  All rights reserved.
28*7c478bd9Sstevel@tonic-gate *	Use is subject to license terms.
29*7c478bd9Sstevel@tonic-gate */
30*7c478bd9Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate
32*7c478bd9Sstevel@tonic-gate#if	defined(lint)
33*7c478bd9Sstevel@tonic-gate
34*7c478bd9Sstevel@tonic-gate#include	<sys/types.h>
35*7c478bd9Sstevel@tonic-gate#include	"_rtld.h"
36*7c478bd9Sstevel@tonic-gate#include	"_audit.h"
37*7c478bd9Sstevel@tonic-gate#include	"_elf.h"
38*7c478bd9Sstevel@tonic-gate
39*7c478bd9Sstevel@tonic-gate/* ARGSUSED0 */
40*7c478bd9Sstevel@tonic-gateint
41*7c478bd9Sstevel@tonic-gateelf_plt_trace()
42*7c478bd9Sstevel@tonic-gate{
43*7c478bd9Sstevel@tonic-gate	return (0);
44*7c478bd9Sstevel@tonic-gate}
45*7c478bd9Sstevel@tonic-gate#else
46*7c478bd9Sstevel@tonic-gate
47*7c478bd9Sstevel@tonic-gate#include	<link.h>
48*7c478bd9Sstevel@tonic-gate#include	"_audit.h"
49*7c478bd9Sstevel@tonic-gate
50*7c478bd9Sstevel@tonic-gate	.file	"boot_elf.s"
51*7c478bd9Sstevel@tonic-gate	.text
52*7c478bd9Sstevel@tonic-gate
53*7c478bd9Sstevel@tonic-gate/*
54*7c478bd9Sstevel@tonic-gate * On entry the 'glue code' has already  done the following:
55*7c478bd9Sstevel@tonic-gate *
56*7c478bd9Sstevel@tonic-gate *	pushl	%ebp
57*7c478bd9Sstevel@tonic-gate *	movl	%esp, %ebp
58*7c478bd9Sstevel@tonic-gate *	pushl	dyndata_ptr
59*7c478bd9Sstevel@tonic-gate *	jmp	elf_plt_trace
60*7c478bd9Sstevel@tonic-gate *
61*7c478bd9Sstevel@tonic-gate * so - -4(%ebp) contains the dyndata ptr
62*7c478bd9Sstevel@tonic-gate *
63*7c478bd9Sstevel@tonic-gate *	0x0	uintptr_t	reflmp
64*7c478bd9Sstevel@tonic-gate *	0x4	uintptr_t	deflmp
65*7c478bd9Sstevel@tonic-gate *	0x8	ulong_t		symndx
66*7c478bd9Sstevel@tonic-gate *	0xc	ulont_t		sb_flags
67*7c478bd9Sstevel@tonic-gate *	0x10	Elf32_Sym	symdef.st_name
68*7c478bd9Sstevel@tonic-gate *	0x14			symdef.st_value
69*7c478bd9Sstevel@tonic-gate *	0x18			symdef.st_size
70*7c478bd9Sstevel@tonic-gate *	0x1c			symdef.st_info
71*7c478bd9Sstevel@tonic-gate *	0x1d			symdef.st_other
72*7c478bd9Sstevel@tonic-gate *	0x1e			symdef.st_shndx
73*7c478bd9Sstevel@tonic-gate */
74*7c478bd9Sstevel@tonic-gate#define	REFLMP_OFF		0x0
75*7c478bd9Sstevel@tonic-gate#define	DEFLMP_OFF		0x4
76*7c478bd9Sstevel@tonic-gate#define	SYMNDX_OFF		0x8
77*7c478bd9Sstevel@tonic-gate#define	SBFLAGS_OFF		0xc
78*7c478bd9Sstevel@tonic-gate#define	SYMDEF_OFF		0x10
79*7c478bd9Sstevel@tonic-gate#define	SYMDEF_VALUE_OFF	0x14
80*7c478bd9Sstevel@tonic-gate
81*7c478bd9Sstevel@tonic-gate	.globl	elf_plt_trace
82*7c478bd9Sstevel@tonic-gate	.type	elf_plt_trace,@function
83*7c478bd9Sstevel@tonic-gate	.align 16
84*7c478bd9Sstevel@tonic-gateelf_plt_trace:
85*7c478bd9Sstevel@tonic-gate	subl	$84,%esp			/ create some local storage
86*7c478bd9Sstevel@tonic-gate	pushl	%eax
87*7c478bd9Sstevel@tonic-gate	pushl	%ebx
88*7c478bd9Sstevel@tonic-gate	pushl	%edi
89*7c478bd9Sstevel@tonic-gate	pushl	%esi
90*7c478bd9Sstevel@tonic-gate	call	.L1				/ initialize %ebx to GOT
91*7c478bd9Sstevel@tonic-gate.L1:
92*7c478bd9Sstevel@tonic-gate	popl	%ebx
93*7c478bd9Sstevel@tonic-gate	addl	$_GLOBAL_OFFSET_TABLE_+[.-.L1], %ebx
94*7c478bd9Sstevel@tonic-gate	/*
95*7c478bd9Sstevel@tonic-gate	 * Local stack space storage is allocated as follows:
96*7c478bd9Sstevel@tonic-gate	 *
97*7c478bd9Sstevel@tonic-gate	 *	-4(%ebp)	store dyndata ptr
98*7c478bd9Sstevel@tonic-gate	 *	-8(%ebp)	store call destination
99*7c478bd9Sstevel@tonic-gate	 *	-84(%ebp)	space for gregset
100*7c478bd9Sstevel@tonic-gate	 *	-88(%ebp)	prev stack size
101*7c478bd9Sstevel@tonic-gate	 *	-92(%ebp)	entering %eax
102*7c478bd9Sstevel@tonic-gate	 *	-96(%ebp)	entering %ebx
103*7c478bd9Sstevel@tonic-gate	 *	-100(%ebp)	entering %edi
104*7c478bd9Sstevel@tonic-gate	 *	-104(%ebp)	entering %esi
105*7c478bd9Sstevel@tonic-gate	 */
106*7c478bd9Sstevel@tonic-gate	movl	-4(%ebp), %eax			/ %eax = dyndata
107*7c478bd9Sstevel@tonic-gate	testb	$LA_SYMB_NOPLTENTER, 0xc(%eax)	/ <link.h>
108*7c478bd9Sstevel@tonic-gate	je	.start_pltenter
109*7c478bd9Sstevel@tonic-gate	movl	SYMDEF_VALUE_OFF(%eax), %edi
110*7c478bd9Sstevel@tonic-gate	movl	%edi, -8(%ebp)			/ save destination address
111*7c478bd9Sstevel@tonic-gate	jmp	.end_pltenter
112*7c478bd9Sstevel@tonic-gate
113*7c478bd9Sstevel@tonic-gate.start_pltenter:
114*7c478bd9Sstevel@tonic-gate	/*
115*7c478bd9Sstevel@tonic-gate	 * save all registers into gregset_t
116*7c478bd9Sstevel@tonic-gate	 */
117*7c478bd9Sstevel@tonic-gate	lea	4(%ebp), %edi
118*7c478bd9Sstevel@tonic-gate	movl	%edi, -84(%ebp)		/ %esp
119*7c478bd9Sstevel@tonic-gate	movl	0(%ebp), %edi
120*7c478bd9Sstevel@tonic-gate	movl	%edi, -80(%ebp)		/ %ebp
121*7c478bd9Sstevel@tonic-gate	/*
122*7c478bd9Sstevel@tonic-gate	 * trapno, err, eip, cs, efl, uesp, ss
123*7c478bd9Sstevel@tonic-gate	 */
124*7c478bd9Sstevel@tonic-gate	movl	-4(%ebp), %edi
125*7c478bd9Sstevel@tonic-gate	lea	SBFLAGS_OFF(%edi), %eax
126*7c478bd9Sstevel@tonic-gate	pushl	%eax				/ arg5 (&sb_flags)
127*7c478bd9Sstevel@tonic-gate	lea	-84(%ebp), %eax
128*7c478bd9Sstevel@tonic-gate	pushl	%eax				/ arg4 (regset)
129*7c478bd9Sstevel@tonic-gate	pushl	SYMNDX_OFF(%edi)		/ arg3 (symndx)
130*7c478bd9Sstevel@tonic-gate	lea	SYMDEF_OFF(%edi), %eax
131*7c478bd9Sstevel@tonic-gate	pushl	%eax				/ arg2 (&sym)
132*7c478bd9Sstevel@tonic-gate	pushl	DEFLMP_OFF(%edi)		/ arg1 (dlmp)
133*7c478bd9Sstevel@tonic-gate	pushl	REFLMP_OFF(%edi)		/ arg0 (rlmp)
134*7c478bd9Sstevel@tonic-gate	call	audit_pltenter@PLT
135*7c478bd9Sstevel@tonic-gate	addl	$24, %esp			/ cleanup stack
136*7c478bd9Sstevel@tonic-gate	movl	%eax, -8(%ebp)			/ save calling address
137*7c478bd9Sstevel@tonic-gate.end_pltenter:
138*7c478bd9Sstevel@tonic-gate
139*7c478bd9Sstevel@tonic-gate	/*
140*7c478bd9Sstevel@tonic-gate	 * If *no* la_pltexit() routines exist
141*7c478bd9Sstevel@tonic-gate	 * we do not need to keep the stack frame
142*7c478bd9Sstevel@tonic-gate	 * before we call the actual routine.  Instead we
143*7c478bd9Sstevel@tonic-gate	 * jump to it and remove our stack from the stack
144*7c478bd9Sstevel@tonic-gate	 * at the same time.
145*7c478bd9Sstevel@tonic-gate	 */
146*7c478bd9Sstevel@tonic-gate	movl	audit_flags@GOT(%ebx), %eax
147*7c478bd9Sstevel@tonic-gate	movl	(%eax), %eax
148*7c478bd9Sstevel@tonic-gate	andl	$AF_PLTEXIT, %eax		/ value of audit.h:AF_PLTEXIT
149*7c478bd9Sstevel@tonic-gate	cmpl	$0, %eax
150*7c478bd9Sstevel@tonic-gate	je	.bypass_pltexit
151*7c478bd9Sstevel@tonic-gate	/*
152*7c478bd9Sstevel@tonic-gate	 * Has the *nopltexit* flag been set for this entry point
153*7c478bd9Sstevel@tonic-gate	 */
154*7c478bd9Sstevel@tonic-gate	testb	$LA_SYMB_NOPLTEXIT, 12(%edi)
155*7c478bd9Sstevel@tonic-gate	je	.start_pltexit
156*7c478bd9Sstevel@tonic-gate
157*7c478bd9Sstevel@tonic-gate.bypass_pltexit:
158*7c478bd9Sstevel@tonic-gate	/*
159*7c478bd9Sstevel@tonic-gate	 * No PLTEXIT processing required.
160*7c478bd9Sstevel@tonic-gate	 */
161*7c478bd9Sstevel@tonic-gate	movl	0(%ebp), %eax
162*7c478bd9Sstevel@tonic-gate	movl	%eax, -4(%ebp)
163*7c478bd9Sstevel@tonic-gate	movl	-8(%ebp), %eax			/ eax == calling destination
164*7c478bd9Sstevel@tonic-gate	movl	%eax, 0(%ebp)			/ store destination at top
165*7c478bd9Sstevel@tonic-gate
166*7c478bd9Sstevel@tonic-gate	popl	%esi				/
167*7c478bd9Sstevel@tonic-gate	popl	%edi				/    clean up stack
168*7c478bd9Sstevel@tonic-gate	popl	%ebx				/
169*7c478bd9Sstevel@tonic-gate	popl	%eax				/
170*7c478bd9Sstevel@tonic-gate	subl	$4, %ebp			/ adjust %ebp for 'ret'
171*7c478bd9Sstevel@tonic-gate	/*
172*7c478bd9Sstevel@tonic-gate	 * At this point, after a little doctoring, we should
173*7c478bd9Sstevel@tonic-gate	 * have the following on the stack:
174*7c478bd9Sstevel@tonic-gate	 *
175*7c478bd9Sstevel@tonic-gate	 *	8(%esp):  ret addr
176*7c478bd9Sstevel@tonic-gate	 *	4(%esp):  dest_addr
177*7c478bd9Sstevel@tonic-gate	 *	0(%esp):  Previous %ebp
178*7c478bd9Sstevel@tonic-gate	 *
179*7c478bd9Sstevel@tonic-gate	 * So - we pop the previous %ebp, and then
180*7c478bd9Sstevel@tonic-gate	 * ret to our final destination.
181*7c478bd9Sstevel@tonic-gate	 */
182*7c478bd9Sstevel@tonic-gate	movl	%ebp, %esp			/
183*7c478bd9Sstevel@tonic-gate	popl	%ebp				/
184*7c478bd9Sstevel@tonic-gate	ret					/ jmp to final destination
185*7c478bd9Sstevel@tonic-gate						/ and clean up stack :)
186*7c478bd9Sstevel@tonic-gate
187*7c478bd9Sstevel@tonic-gate.start_pltexit:
188*7c478bd9Sstevel@tonic-gate
189*7c478bd9Sstevel@tonic-gate	/*
190*7c478bd9Sstevel@tonic-gate	 * In order to call the destination procedure and then return
191*7c478bd9Sstevel@tonic-gate	 * to audit_pltexit() for post analysis we must first grow
192*7c478bd9Sstevel@tonic-gate	 * our stack frame and then duplicate the original callers
193*7c478bd9Sstevel@tonic-gate	 * stack state.  This duplicates all of the arguements
194*7c478bd9Sstevel@tonic-gate	 * that were to be passed to the destination procedure.
195*7c478bd9Sstevel@tonic-gate	 */
196*7c478bd9Sstevel@tonic-gate	movl	%ebp, %edi			/
197*7c478bd9Sstevel@tonic-gate	addl	$8, %edi			/    %edi = src
198*7c478bd9Sstevel@tonic-gate	movl	(%ebp), %edx			/
199*7c478bd9Sstevel@tonic-gate	subl	%edi, %edx			/    %edx == prev frame sz
200*7c478bd9Sstevel@tonic-gate	/*
201*7c478bd9Sstevel@tonic-gate	 * If audit_argcnt > 0 then we limit the number of
202*7c478bd9Sstevel@tonic-gate	 * arguements that will be duplicated to audit_argcnt.
203*7c478bd9Sstevel@tonic-gate	 *
204*7c478bd9Sstevel@tonic-gate	 * If (prev_stack_size > (audit_argcnt * 4))
205*7c478bd9Sstevel@tonic-gate	 *	prev_stack_size = audit_argcnt * 4;
206*7c478bd9Sstevel@tonic-gate	 */
207*7c478bd9Sstevel@tonic-gate	movl	audit_argcnt@GOT(%ebx),%eax
208*7c478bd9Sstevel@tonic-gate	movl	(%eax), %eax			/    %eax = audit_argcnt
209*7c478bd9Sstevel@tonic-gate	cmpl	$0, %eax
210*7c478bd9Sstevel@tonic-gate	jle	.grow_stack
211*7c478bd9Sstevel@tonic-gate	lea	(,%eax,4), %eax			/    %eax = %eax * 4
212*7c478bd9Sstevel@tonic-gate	cmpl	%eax,%edx
213*7c478bd9Sstevel@tonic-gate	jle	.grow_stack
214*7c478bd9Sstevel@tonic-gate	movl	%eax, %edx
215*7c478bd9Sstevel@tonic-gate	/*
216*7c478bd9Sstevel@tonic-gate	 * Grow the stack and duplicate the arguements of the
217*7c478bd9Sstevel@tonic-gate	 * original caller.
218*7c478bd9Sstevel@tonic-gate	 */
219*7c478bd9Sstevel@tonic-gate.grow_stack:
220*7c478bd9Sstevel@tonic-gate	subl	%edx, %esp			/    grow the stack
221*7c478bd9Sstevel@tonic-gate	movl	%edx, -88(%ebp)			/    -88(%ebp) == prev frame sz
222*7c478bd9Sstevel@tonic-gate	movl	%esp, %ecx			/    %ecx = dest
223*7c478bd9Sstevel@tonic-gate	addl	%ecx, %edx			/    %edx == tail of dest
224*7c478bd9Sstevel@tonic-gate.while_base:
225*7c478bd9Sstevel@tonic-gate	cmpl	%edx, %ecx			/   while (base+size >= src++) {
226*7c478bd9Sstevel@tonic-gate	jge	.end_while				/
227*7c478bd9Sstevel@tonic-gate	movl	(%edi), %esi
228*7c478bd9Sstevel@tonic-gate	movl	%esi,(%ecx)			/        *dest = *src
229*7c478bd9Sstevel@tonic-gate	addl	$4, %edi			/	 src++
230*7c478bd9Sstevel@tonic-gate	addl	$4, %ecx			/        dest++
231*7c478bd9Sstevel@tonic-gate	jmp	.while_base			/    }
232*7c478bd9Sstevel@tonic-gate
233*7c478bd9Sstevel@tonic-gate	/*
234*7c478bd9Sstevel@tonic-gate	 * The above stack is now an exact duplicate of
235*7c478bd9Sstevel@tonic-gate	 * the stack of the original calling procedure.
236*7c478bd9Sstevel@tonic-gate	 */
237*7c478bd9Sstevel@tonic-gate.end_while:
238*7c478bd9Sstevel@tonic-gate	movl	-92(%ebp), %eax			/ restore %eax
239*7c478bd9Sstevel@tonic-gate	movl	-96(%ebp), %ebx			/ restore %ebx
240*7c478bd9Sstevel@tonic-gate	movl	-104(%ebp), %esi		/ restore %esi
241*7c478bd9Sstevel@tonic-gate
242*7c478bd9Sstevel@tonic-gate	movl	-8(%ebp), %edi
243*7c478bd9Sstevel@tonic-gate	call	*%edi				/ call dest_proc()
244*7c478bd9Sstevel@tonic-gate
245*7c478bd9Sstevel@tonic-gate	addl	-88(%ebp), %esp			/ cleanup dupped stack
246*7c478bd9Sstevel@tonic-gate
247*7c478bd9Sstevel@tonic-gate	movl	-4(%ebp), %edi
248*7c478bd9Sstevel@tonic-gate	pushl	SYMNDX_OFF(%edi)		/ arg4 (symndx)
249*7c478bd9Sstevel@tonic-gate	lea	SYMDEF_OFF(%edi), %ecx
250*7c478bd9Sstevel@tonic-gate	pushl	%ecx				/ arg3 (symp)
251*7c478bd9Sstevel@tonic-gate	pushl	DEFLMP_OFF(%edi)		/ arg2 (dlmp)
252*7c478bd9Sstevel@tonic-gate	pushl	REFLMP_OFF(%edi)		/ arg1 (rlmp)
253*7c478bd9Sstevel@tonic-gate	pushl	%eax				/ arg0 (retval)
254*7c478bd9Sstevel@tonic-gate	call	audit_pltexit@PLT
255*7c478bd9Sstevel@tonic-gate	addl	$20, %esp			/ cleanup stack
256*7c478bd9Sstevel@tonic-gate
257*7c478bd9Sstevel@tonic-gate	/*
258*7c478bd9Sstevel@tonic-gate	 * Clean up after ourselves and return to the
259*7c478bd9Sstevel@tonic-gate	 * original calling procedure.
260*7c478bd9Sstevel@tonic-gate	 */
261*7c478bd9Sstevel@tonic-gate	popl	%esi				/
262*7c478bd9Sstevel@tonic-gate	popl	%edi				/ clean up stack
263*7c478bd9Sstevel@tonic-gate	popl	%ebx				/
264*7c478bd9Sstevel@tonic-gate	movl	%ebp, %esp			/
265*7c478bd9Sstevel@tonic-gate	popl	%ebp				/
266*7c478bd9Sstevel@tonic-gate	ret					/ return to caller
267*7c478bd9Sstevel@tonic-gate	.size	elf_plt_trace, .-elf_plt_trace
268*7c478bd9Sstevel@tonic-gate#endif
269*7c478bd9Sstevel@tonic-gate
270*7c478bd9Sstevel@tonic-gate/*
271*7c478bd9Sstevel@tonic-gate * We got here because a call to a function resolved to a procedure
272*7c478bd9Sstevel@tonic-gate * linkage table entry.  That entry did a JMPL to the first PLT entry, which
273*7c478bd9Sstevel@tonic-gate * in turn did a call to elf_rtbndr.
274*7c478bd9Sstevel@tonic-gate *
275*7c478bd9Sstevel@tonic-gate * the code sequence that got us here was:
276*7c478bd9Sstevel@tonic-gate *
277*7c478bd9Sstevel@tonic-gate * PLT entry for foo:
278*7c478bd9Sstevel@tonic-gate *	jmp	*name1@GOT(%ebx)
279*7c478bd9Sstevel@tonic-gate *	pushl	$rel.plt.foo
280*7c478bd9Sstevel@tonic-gate *	jmp	PLT0
281*7c478bd9Sstevel@tonic-gate *
282*7c478bd9Sstevel@tonic-gate * 1st PLT entry (PLT0):
283*7c478bd9Sstevel@tonic-gate *	pushl	4(%ebx)
284*7c478bd9Sstevel@tonic-gate *	jmp	*8(%ebx)
285*7c478bd9Sstevel@tonic-gate *	nop; nop; nop;nop;
286*7c478bd9Sstevel@tonic-gate *
287*7c478bd9Sstevel@tonic-gate */
288*7c478bd9Sstevel@tonic-gate#if defined(lint)
289*7c478bd9Sstevel@tonic-gate
290*7c478bd9Sstevel@tonic-gateextern unsigned long	elf_bndr(Rt_map *, unsigned long, caddr_t);
291*7c478bd9Sstevel@tonic-gate
292*7c478bd9Sstevel@tonic-gatevoid
293*7c478bd9Sstevel@tonic-gateelf_rtbndr(Rt_map * lmp, unsigned long reloc, caddr_t pc)
294*7c478bd9Sstevel@tonic-gate{
295*7c478bd9Sstevel@tonic-gate	(void) elf_bndr(lmp, reloc, pc);
296*7c478bd9Sstevel@tonic-gate}
297*7c478bd9Sstevel@tonic-gate
298*7c478bd9Sstevel@tonic-gate#else
299*7c478bd9Sstevel@tonic-gate	.globl	elf_bndr
300*7c478bd9Sstevel@tonic-gate	.globl	elf_rtbndr
301*7c478bd9Sstevel@tonic-gate	.weak	_elf_rtbndr
302*7c478bd9Sstevel@tonic-gate	_elf_rtbndr = elf_rtbndr	/ Make dbx happy
303*7c478bd9Sstevel@tonic-gate	.type   elf_rtbndr,@function
304*7c478bd9Sstevel@tonic-gate	.align	4
305*7c478bd9Sstevel@tonic-gate
306*7c478bd9Sstevel@tonic-gateelf_rtbndr:
307*7c478bd9Sstevel@tonic-gate	pushl	%ebp
308*7c478bd9Sstevel@tonic-gate	movl	%esp, %ebp
309*7c478bd9Sstevel@tonic-gate	pushl	%eax
310*7c478bd9Sstevel@tonic-gate	pushl	%ecx
311*7c478bd9Sstevel@tonic-gate	pushl	%edx
312*7c478bd9Sstevel@tonic-gate	pushl	12(%ebp)		/ push pc
313*7c478bd9Sstevel@tonic-gate	pushl	8(%ebp)			/ push reloc
314*7c478bd9Sstevel@tonic-gate	pushl	4(%ebp)			/ push *lmp
315*7c478bd9Sstevel@tonic-gate	call	elf_bndr@PLT		/ call the C binder code
316*7c478bd9Sstevel@tonic-gate	addl	$12, %esp		/ pop args
317*7c478bd9Sstevel@tonic-gate	movl	%eax, 8(%ebp)		/ store final destination
318*7c478bd9Sstevel@tonic-gate	popl	%edx
319*7c478bd9Sstevel@tonic-gate	popl	%ecx
320*7c478bd9Sstevel@tonic-gate	popl	%eax
321*7c478bd9Sstevel@tonic-gate	movl	%ebp, %esp
322*7c478bd9Sstevel@tonic-gate	popl	%ebp
323*7c478bd9Sstevel@tonic-gate	addl	$4,%esp			/ pop args
324*7c478bd9Sstevel@tonic-gate	ret				/ invoke resolved function
325*7c478bd9Sstevel@tonic-gate	.size 	elf_rtbndr, .-elf_rtbndr
326*7c478bd9Sstevel@tonic-gate#endif
327