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