xref: /illumos-gate/usr/src/cmd/sgs/rtld/i386/boot_elf.S (revision 5d9d9091)
17c478bd9Sstevel@tonic-gate/*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate/*
237c478bd9Sstevel@tonic-gate *	Copyright (c) 1988 AT&T
247c478bd9Sstevel@tonic-gate *	  All Rights Reserved
257c478bd9Sstevel@tonic-gate *
267c478bd9Sstevel@tonic-gate *
277c478bd9Sstevel@tonic-gate *	Copyright 2000-2002 Sun Microsystems, Inc.  All rights reserved.
287c478bd9Sstevel@tonic-gate *	Use is subject to license terms.
297c478bd9Sstevel@tonic-gate */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate#if	defined(lint)
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate#include	<sys/types.h>
347c478bd9Sstevel@tonic-gate#include	"_rtld.h"
357c478bd9Sstevel@tonic-gate#include	"_audit.h"
367c478bd9Sstevel@tonic-gate#include	"_elf.h"
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate/* ARGSUSED0 */
397c478bd9Sstevel@tonic-gateint
407c478bd9Sstevel@tonic-gateelf_plt_trace()
417c478bd9Sstevel@tonic-gate{
427c478bd9Sstevel@tonic-gate	return (0);
437c478bd9Sstevel@tonic-gate}
447c478bd9Sstevel@tonic-gate#else
457c478bd9Sstevel@tonic-gate
467c478bd9Sstevel@tonic-gate#include	<link.h>
477c478bd9Sstevel@tonic-gate#include	"_audit.h"
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate	.file	"boot_elf.s"
507c478bd9Sstevel@tonic-gate	.text
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate/*
537c478bd9Sstevel@tonic-gate * On entry the 'glue code' has already  done the following:
547c478bd9Sstevel@tonic-gate *
557c478bd9Sstevel@tonic-gate *	pushl	%ebp
567c478bd9Sstevel@tonic-gate *	movl	%esp, %ebp
577c478bd9Sstevel@tonic-gate *	pushl	dyndata_ptr
587c478bd9Sstevel@tonic-gate *	jmp	elf_plt_trace
597c478bd9Sstevel@tonic-gate *
607c478bd9Sstevel@tonic-gate * so - -4(%ebp) contains the dyndata ptr
617c478bd9Sstevel@tonic-gate *
627c478bd9Sstevel@tonic-gate *	0x0	uintptr_t	reflmp
637c478bd9Sstevel@tonic-gate *	0x4	uintptr_t	deflmp
647c478bd9Sstevel@tonic-gate *	0x8	ulong_t		symndx
657c478bd9Sstevel@tonic-gate *	0xc	ulont_t		sb_flags
667c478bd9Sstevel@tonic-gate *	0x10	Elf32_Sym	symdef.st_name
677c478bd9Sstevel@tonic-gate *	0x14			symdef.st_value
687c478bd9Sstevel@tonic-gate *	0x18			symdef.st_size
697c478bd9Sstevel@tonic-gate *	0x1c			symdef.st_info
707c478bd9Sstevel@tonic-gate *	0x1d			symdef.st_other
717c478bd9Sstevel@tonic-gate *	0x1e			symdef.st_shndx
727c478bd9Sstevel@tonic-gate */
737c478bd9Sstevel@tonic-gate#define	REFLMP_OFF		0x0
747c478bd9Sstevel@tonic-gate#define	DEFLMP_OFF		0x4
757c478bd9Sstevel@tonic-gate#define	SYMNDX_OFF		0x8
767c478bd9Sstevel@tonic-gate#define	SBFLAGS_OFF		0xc
777c478bd9Sstevel@tonic-gate#define	SYMDEF_OFF		0x10
787c478bd9Sstevel@tonic-gate#define	SYMDEF_VALUE_OFF	0x14
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate	.globl	elf_plt_trace
817c478bd9Sstevel@tonic-gate	.type	elf_plt_trace,@function
827c478bd9Sstevel@tonic-gate	.align 16
837c478bd9Sstevel@tonic-gateelf_plt_trace:
847c478bd9Sstevel@tonic-gate	subl	$84,%esp			/ create some local storage
857c478bd9Sstevel@tonic-gate	pushl	%eax
867c478bd9Sstevel@tonic-gate	pushl	%ebx
877c478bd9Sstevel@tonic-gate	pushl	%edi
887c478bd9Sstevel@tonic-gate	pushl	%esi
897c478bd9Sstevel@tonic-gate	call	.L1				/ initialize %ebx to GOT
907c478bd9Sstevel@tonic-gate.L1:
917c478bd9Sstevel@tonic-gate	popl	%ebx
927c478bd9Sstevel@tonic-gate	addl	$_GLOBAL_OFFSET_TABLE_+[.-.L1], %ebx
937c478bd9Sstevel@tonic-gate	/*
947c478bd9Sstevel@tonic-gate	 * Local stack space storage is allocated as follows:
957c478bd9Sstevel@tonic-gate	 *
967c478bd9Sstevel@tonic-gate	 *	-4(%ebp)	store dyndata ptr
977c478bd9Sstevel@tonic-gate	 *	-8(%ebp)	store call destination
987c478bd9Sstevel@tonic-gate	 *	-84(%ebp)	space for gregset
997c478bd9Sstevel@tonic-gate	 *	-88(%ebp)	prev stack size
1007c478bd9Sstevel@tonic-gate	 *	-92(%ebp)	entering %eax
1017c478bd9Sstevel@tonic-gate	 *	-96(%ebp)	entering %ebx
1027c478bd9Sstevel@tonic-gate	 *	-100(%ebp)	entering %edi
1037c478bd9Sstevel@tonic-gate	 *	-104(%ebp)	entering %esi
1047c478bd9Sstevel@tonic-gate	 */
1057c478bd9Sstevel@tonic-gate	movl	-4(%ebp), %eax			/ %eax = dyndata
1067c478bd9Sstevel@tonic-gate	testb	$LA_SYMB_NOPLTENTER, 0xc(%eax)	/ <link.h>
1077c478bd9Sstevel@tonic-gate	je	.start_pltenter
1087c478bd9Sstevel@tonic-gate	movl	SYMDEF_VALUE_OFF(%eax), %edi
1097c478bd9Sstevel@tonic-gate	movl	%edi, -8(%ebp)			/ save destination address
1107c478bd9Sstevel@tonic-gate	jmp	.end_pltenter
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate.start_pltenter:
1137c478bd9Sstevel@tonic-gate	/*
1147c478bd9Sstevel@tonic-gate	 * save all registers into gregset_t
1157c478bd9Sstevel@tonic-gate	 */
1167c478bd9Sstevel@tonic-gate	lea	4(%ebp), %edi
1177c478bd9Sstevel@tonic-gate	movl	%edi, -84(%ebp)		/ %esp
1187c478bd9Sstevel@tonic-gate	movl	0(%ebp), %edi
1197c478bd9Sstevel@tonic-gate	movl	%edi, -80(%ebp)		/ %ebp
1207c478bd9Sstevel@tonic-gate	/*
1217c478bd9Sstevel@tonic-gate	 * trapno, err, eip, cs, efl, uesp, ss
1227c478bd9Sstevel@tonic-gate	 */
1237c478bd9Sstevel@tonic-gate	movl	-4(%ebp), %edi
1247c478bd9Sstevel@tonic-gate	lea	SBFLAGS_OFF(%edi), %eax
1257c478bd9Sstevel@tonic-gate	pushl	%eax				/ arg5 (&sb_flags)
1267c478bd9Sstevel@tonic-gate	lea	-84(%ebp), %eax
1277c478bd9Sstevel@tonic-gate	pushl	%eax				/ arg4 (regset)
1287c478bd9Sstevel@tonic-gate	pushl	SYMNDX_OFF(%edi)		/ arg3 (symndx)
1297c478bd9Sstevel@tonic-gate	lea	SYMDEF_OFF(%edi), %eax
1307c478bd9Sstevel@tonic-gate	pushl	%eax				/ arg2 (&sym)
1317c478bd9Sstevel@tonic-gate	pushl	DEFLMP_OFF(%edi)		/ arg1 (dlmp)
1327c478bd9Sstevel@tonic-gate	pushl	REFLMP_OFF(%edi)		/ arg0 (rlmp)
1337c478bd9Sstevel@tonic-gate	call	audit_pltenter@PLT
1347c478bd9Sstevel@tonic-gate	addl	$24, %esp			/ cleanup stack
1357c478bd9Sstevel@tonic-gate	movl	%eax, -8(%ebp)			/ save calling address
1367c478bd9Sstevel@tonic-gate.end_pltenter:
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate	/*
1397c478bd9Sstevel@tonic-gate	 * If *no* la_pltexit() routines exist
1407c478bd9Sstevel@tonic-gate	 * we do not need to keep the stack frame
1417c478bd9Sstevel@tonic-gate	 * before we call the actual routine.  Instead we
1427c478bd9Sstevel@tonic-gate	 * jump to it and remove our stack from the stack
1437c478bd9Sstevel@tonic-gate	 * at the same time.
1447c478bd9Sstevel@tonic-gate	 */
1457c478bd9Sstevel@tonic-gate	movl	audit_flags@GOT(%ebx), %eax
1467c478bd9Sstevel@tonic-gate	movl	(%eax), %eax
1477c478bd9Sstevel@tonic-gate	andl	$AF_PLTEXIT, %eax		/ value of audit.h:AF_PLTEXIT
1487c478bd9Sstevel@tonic-gate	cmpl	$0, %eax
1497c478bd9Sstevel@tonic-gate	je	.bypass_pltexit
1507c478bd9Sstevel@tonic-gate	/*
1517c478bd9Sstevel@tonic-gate	 * Has the *nopltexit* flag been set for this entry point
1527c478bd9Sstevel@tonic-gate	 */
1537c478bd9Sstevel@tonic-gate	testb	$LA_SYMB_NOPLTEXIT, 12(%edi)
1547c478bd9Sstevel@tonic-gate	je	.start_pltexit
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate.bypass_pltexit:
1577c478bd9Sstevel@tonic-gate	/*
1587c478bd9Sstevel@tonic-gate	 * No PLTEXIT processing required.
1597c478bd9Sstevel@tonic-gate	 */
1607c478bd9Sstevel@tonic-gate	movl	0(%ebp), %eax
1617c478bd9Sstevel@tonic-gate	movl	%eax, -4(%ebp)
1627c478bd9Sstevel@tonic-gate	movl	-8(%ebp), %eax			/ eax == calling destination
1637c478bd9Sstevel@tonic-gate	movl	%eax, 0(%ebp)			/ store destination at top
1647c478bd9Sstevel@tonic-gate
1657c478bd9Sstevel@tonic-gate	popl	%esi				/
1667c478bd9Sstevel@tonic-gate	popl	%edi				/    clean up stack
1677c478bd9Sstevel@tonic-gate	popl	%ebx				/
1687c478bd9Sstevel@tonic-gate	popl	%eax				/
1697c478bd9Sstevel@tonic-gate	subl	$4, %ebp			/ adjust %ebp for 'ret'
1707c478bd9Sstevel@tonic-gate	/*
1717c478bd9Sstevel@tonic-gate	 * At this point, after a little doctoring, we should
1727c478bd9Sstevel@tonic-gate	 * have the following on the stack:
1737c478bd9Sstevel@tonic-gate	 *
1747c478bd9Sstevel@tonic-gate	 *	8(%esp):  ret addr
1757c478bd9Sstevel@tonic-gate	 *	4(%esp):  dest_addr
1767c478bd9Sstevel@tonic-gate	 *	0(%esp):  Previous %ebp
1777c478bd9Sstevel@tonic-gate	 *
1787c478bd9Sstevel@tonic-gate	 * So - we pop the previous %ebp, and then
1797c478bd9Sstevel@tonic-gate	 * ret to our final destination.
1807c478bd9Sstevel@tonic-gate	 */
1817c478bd9Sstevel@tonic-gate	movl	%ebp, %esp			/
1827c478bd9Sstevel@tonic-gate	popl	%ebp				/
1837c478bd9Sstevel@tonic-gate	ret					/ jmp to final destination
1847c478bd9Sstevel@tonic-gate						/ and clean up stack :)
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate.start_pltexit:
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate	/*
1897c478bd9Sstevel@tonic-gate	 * In order to call the destination procedure and then return
1907c478bd9Sstevel@tonic-gate	 * to audit_pltexit() for post analysis we must first grow
1917c478bd9Sstevel@tonic-gate	 * our stack frame and then duplicate the original callers
1927c478bd9Sstevel@tonic-gate	 * stack state.  This duplicates all of the arguements
1937c478bd9Sstevel@tonic-gate	 * that were to be passed to the destination procedure.
1947c478bd9Sstevel@tonic-gate	 */
1957c478bd9Sstevel@tonic-gate	movl	%ebp, %edi			/
1967c478bd9Sstevel@tonic-gate	addl	$8, %edi			/    %edi = src
1977c478bd9Sstevel@tonic-gate	movl	(%ebp), %edx			/
1987c478bd9Sstevel@tonic-gate	subl	%edi, %edx			/    %edx == prev frame sz
1997c478bd9Sstevel@tonic-gate	/*
2007c478bd9Sstevel@tonic-gate	 * If audit_argcnt > 0 then we limit the number of
2017c478bd9Sstevel@tonic-gate	 * arguements that will be duplicated to audit_argcnt.
2027c478bd9Sstevel@tonic-gate	 *
2037c478bd9Sstevel@tonic-gate	 * If (prev_stack_size > (audit_argcnt * 4))
2047c478bd9Sstevel@tonic-gate	 *	prev_stack_size = audit_argcnt * 4;
2057c478bd9Sstevel@tonic-gate	 */
2067c478bd9Sstevel@tonic-gate	movl	audit_argcnt@GOT(%ebx),%eax
2077c478bd9Sstevel@tonic-gate	movl	(%eax), %eax			/    %eax = audit_argcnt
2087c478bd9Sstevel@tonic-gate	cmpl	$0, %eax
2097c478bd9Sstevel@tonic-gate	jle	.grow_stack
2107c478bd9Sstevel@tonic-gate	lea	(,%eax,4), %eax			/    %eax = %eax * 4
2117c478bd9Sstevel@tonic-gate	cmpl	%eax,%edx
2127c478bd9Sstevel@tonic-gate	jle	.grow_stack
2137c478bd9Sstevel@tonic-gate	movl	%eax, %edx
2147c478bd9Sstevel@tonic-gate	/*
2157c478bd9Sstevel@tonic-gate	 * Grow the stack and duplicate the arguements of the
2167c478bd9Sstevel@tonic-gate	 * original caller.
2177c478bd9Sstevel@tonic-gate	 */
2187c478bd9Sstevel@tonic-gate.grow_stack:
2192a8bcb4eSToomas Soome	subl	%edx, %esp			/    grow the stack
2207c478bd9Sstevel@tonic-gate	movl	%edx, -88(%ebp)			/    -88(%ebp) == prev frame sz
2217c478bd9Sstevel@tonic-gate	movl	%esp, %ecx			/    %ecx = dest
2227c478bd9Sstevel@tonic-gate	addl	%ecx, %edx			/    %edx == tail of dest
2237c478bd9Sstevel@tonic-gate.while_base:
2247c478bd9Sstevel@tonic-gate	cmpl	%edx, %ecx			/   while (base+size >= src++) {
2257c478bd9Sstevel@tonic-gate	jge	.end_while				/
2267c478bd9Sstevel@tonic-gate	movl	(%edi), %esi
2277c478bd9Sstevel@tonic-gate	movl	%esi,(%ecx)			/        *dest = *src
2287c478bd9Sstevel@tonic-gate	addl	$4, %edi			/	 src++
2297c478bd9Sstevel@tonic-gate	addl	$4, %ecx			/        dest++
2307c478bd9Sstevel@tonic-gate	jmp	.while_base			/    }
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate	/*
2337c478bd9Sstevel@tonic-gate	 * The above stack is now an exact duplicate of
2347c478bd9Sstevel@tonic-gate	 * the stack of the original calling procedure.
2357c478bd9Sstevel@tonic-gate	 */
2367c478bd9Sstevel@tonic-gate.end_while:
2377c478bd9Sstevel@tonic-gate	movl	-92(%ebp), %eax			/ restore %eax
2387c478bd9Sstevel@tonic-gate	movl	-96(%ebp), %ebx			/ restore %ebx
2397c478bd9Sstevel@tonic-gate	movl	-104(%ebp), %esi		/ restore %esi
2407c478bd9Sstevel@tonic-gate
2417c478bd9Sstevel@tonic-gate	movl	-8(%ebp), %edi
2427c478bd9Sstevel@tonic-gate	call	*%edi				/ call dest_proc()
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate	addl	-88(%ebp), %esp			/ cleanup dupped stack
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate	movl	-4(%ebp), %edi
2477c478bd9Sstevel@tonic-gate	pushl	SYMNDX_OFF(%edi)		/ arg4 (symndx)
2487c478bd9Sstevel@tonic-gate	lea	SYMDEF_OFF(%edi), %ecx
2497c478bd9Sstevel@tonic-gate	pushl	%ecx				/ arg3 (symp)
2507c478bd9Sstevel@tonic-gate	pushl	DEFLMP_OFF(%edi)		/ arg2 (dlmp)
2517c478bd9Sstevel@tonic-gate	pushl	REFLMP_OFF(%edi)		/ arg1 (rlmp)
2527c478bd9Sstevel@tonic-gate	pushl	%eax				/ arg0 (retval)
2537c478bd9Sstevel@tonic-gate	call	audit_pltexit@PLT
2547c478bd9Sstevel@tonic-gate	addl	$20, %esp			/ cleanup stack
2552a8bcb4eSToomas Soome
2567c478bd9Sstevel@tonic-gate	/*
2577c478bd9Sstevel@tonic-gate	 * Clean up after ourselves and return to the
2587c478bd9Sstevel@tonic-gate	 * original calling procedure.
2597c478bd9Sstevel@tonic-gate	 */
2607c478bd9Sstevel@tonic-gate	popl	%esi				/
2617c478bd9Sstevel@tonic-gate	popl	%edi				/ clean up stack
2627c478bd9Sstevel@tonic-gate	popl	%ebx				/
2637c478bd9Sstevel@tonic-gate	movl	%ebp, %esp			/
2647c478bd9Sstevel@tonic-gate	popl	%ebp				/
2657c478bd9Sstevel@tonic-gate	ret					/ return to caller
2667c478bd9Sstevel@tonic-gate	.size	elf_plt_trace, .-elf_plt_trace
2677c478bd9Sstevel@tonic-gate#endif
2687c478bd9Sstevel@tonic-gate
2697c478bd9Sstevel@tonic-gate/*
2707c478bd9Sstevel@tonic-gate * We got here because a call to a function resolved to a procedure
2717c478bd9Sstevel@tonic-gate * linkage table entry.  That entry did a JMPL to the first PLT entry, which
2727c478bd9Sstevel@tonic-gate * in turn did a call to elf_rtbndr.
2737c478bd9Sstevel@tonic-gate *
2747c478bd9Sstevel@tonic-gate * the code sequence that got us here was:
2757c478bd9Sstevel@tonic-gate *
2767c478bd9Sstevel@tonic-gate * PLT entry for foo:
2777c478bd9Sstevel@tonic-gate *	jmp	*name1@GOT(%ebx)
2787c478bd9Sstevel@tonic-gate *	pushl	$rel.plt.foo
2797c478bd9Sstevel@tonic-gate *	jmp	PLT0
2807c478bd9Sstevel@tonic-gate *
2817c478bd9Sstevel@tonic-gate * 1st PLT entry (PLT0):
2827c478bd9Sstevel@tonic-gate *	pushl	4(%ebx)
2837c478bd9Sstevel@tonic-gate *	jmp	*8(%ebx)
2847c478bd9Sstevel@tonic-gate *	nop; nop; nop;nop;
2857c478bd9Sstevel@tonic-gate *
2867c478bd9Sstevel@tonic-gate */
2877c478bd9Sstevel@tonic-gate#if defined(lint)
2887c478bd9Sstevel@tonic-gate
2897c478bd9Sstevel@tonic-gateextern unsigned long	elf_bndr(Rt_map *, unsigned long, caddr_t);
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gatevoid
2927c478bd9Sstevel@tonic-gateelf_rtbndr(Rt_map * lmp, unsigned long reloc, caddr_t pc)
2937c478bd9Sstevel@tonic-gate{
2947c478bd9Sstevel@tonic-gate	(void) elf_bndr(lmp, reloc, pc);
2957c478bd9Sstevel@tonic-gate}
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate#else
2987c478bd9Sstevel@tonic-gate	.globl	elf_bndr
2997c478bd9Sstevel@tonic-gate	.globl	elf_rtbndr
3007c478bd9Sstevel@tonic-gate	.weak	_elf_rtbndr
3017c478bd9Sstevel@tonic-gate	_elf_rtbndr = elf_rtbndr	/ Make dbx happy
3027c478bd9Sstevel@tonic-gate	.type   elf_rtbndr,@function
3037c478bd9Sstevel@tonic-gate	.align	4
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gateelf_rtbndr:
3067c478bd9Sstevel@tonic-gate	pushl	%ebp
3077c478bd9Sstevel@tonic-gate	movl	%esp, %ebp
3087c478bd9Sstevel@tonic-gate	pushl	%eax
3097c478bd9Sstevel@tonic-gate	pushl	%ecx
3107c478bd9Sstevel@tonic-gate	pushl	%edx
3117c478bd9Sstevel@tonic-gate	pushl	12(%ebp)		/ push pc
3127c478bd9Sstevel@tonic-gate	pushl	8(%ebp)			/ push reloc
3137c478bd9Sstevel@tonic-gate	pushl	4(%ebp)			/ push *lmp
3147c478bd9Sstevel@tonic-gate	call	elf_bndr@PLT		/ call the C binder code
3157c478bd9Sstevel@tonic-gate	addl	$12, %esp		/ pop args
3167c478bd9Sstevel@tonic-gate	movl	%eax, 8(%ebp)		/ store final destination
3177c478bd9Sstevel@tonic-gate	popl	%edx
3187c478bd9Sstevel@tonic-gate	popl	%ecx
3197c478bd9Sstevel@tonic-gate	popl	%eax
3207c478bd9Sstevel@tonic-gate	movl	%ebp, %esp
3217c478bd9Sstevel@tonic-gate	popl	%ebp
3227c478bd9Sstevel@tonic-gate	addl	$4,%esp			/ pop args
3237c478bd9Sstevel@tonic-gate	ret				/ invoke resolved function
3247c478bd9Sstevel@tonic-gate	.size 	elf_rtbndr, .-elf_rtbndr
3257c478bd9Sstevel@tonic-gate#endif
326