4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1988 AT&T
27 * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
30 #pragma ident "%Z%%M% %I% %E% SMI"
34 #include <sys/types.h>
54 * On entry the 'glue code' has already done the following:
61 * so - -4(%ebp) contains the dyndata ptr
63 * 0x0 uintptr_t reflmp
64 * 0x4 uintptr_t deflmp
66 * 0xc ulont_t sb_flags
67 * 0x10 Elf32_Sym symdef.st_name
68 * 0x14 symdef.st_value
71 * 0x1d symdef.st_other
72 * 0x1e symdef.st_shndx
74 #define REFLMP_OFF 0x0
75 #define DEFLMP_OFF 0x4
76 #define SYMNDX_OFF 0x8
77 #define SBFLAGS_OFF 0xc
78 #define SYMDEF_OFF 0x10
79 #define SYMDEF_VALUE_OFF 0x14
82 .type elf_plt_trace,@function
85 subl $
84,%esp
/ create some local storage
90 call
.L1 / initialize %ebx to GOT
93 addl $_GLOBAL_OFFSET_TABLE_+
[.-.L1], %ebx
95 * Local stack space storage is allocated as follows:
97 * -4(%ebp) store dyndata ptr
98 * -8(%ebp) store call destination
99 * -84(%ebp) space for gregset
100 * -88(%ebp) prev stack size
101 * -92(%ebp) entering %eax
102 * -96(%ebp) entering %ebx
103 * -100(%ebp) entering %edi
104 * -104(%ebp) entering %esi
106 movl
-4(%ebp
), %eax
/ %eax
= dyndata
107 testb $LA_SYMB_NOPLTENTER
, 0xc(%eax
) / <link.h
>
109 movl SYMDEF_VALUE_OFF
(%eax
), %edi
110 movl
%edi
, -8(%ebp
) / save destination address
115 * save all registers into gregset_t
118 movl
%edi
, -84(%ebp
) / %esp
120 movl
%edi
, -80(%ebp
) / %ebp
122 * trapno, err, eip, cs, efl, uesp, ss
125 lea SBFLAGS_OFF
(%edi
), %eax
126 pushl
%eax
/ arg5
(&sb_flags
)
128 pushl
%eax
/ arg4
(regset
)
129 pushl SYMNDX_OFF
(%edi
) / arg3
(symndx
)
130 lea SYMDEF_OFF
(%edi
), %eax
131 pushl
%eax
/ arg2
(&sym
)
132 pushl DEFLMP_OFF
(%edi
) / arg1
(dlmp
)
133 pushl REFLMP_OFF
(%edi
) / arg0
(rlmp
)
134 call audit_pltenter@PLT
135 addl $
24, %esp
/ cleanup stack
136 movl
%eax
, -8(%ebp
) / save calling address
140 * If *no* la_pltexit() routines exist
141 * we do not need to keep the stack frame
142 * before we call the actual routine. Instead we
143 * jump to it and remove our stack from the stack
146 movl audit_flags@GOT
(%ebx
), %eax
148 andl $AF_PLTEXIT
, %eax
/ value of audit.h
:AF_PLTEXIT
152 * Has the *nopltexit* flag been set for this entry point
154 testb $LA_SYMB_NOPLTEXIT
, 12(%edi
)
159 * No PLTEXIT processing required.
163 movl
-8(%ebp
), %eax
/ eax
== calling destination
164 movl
%eax
, 0(%ebp
) / store destination at top
167 popl
%edi
/ clean up stack
170 subl $
4, %ebp
/ adjust
%ebp for
'ret'
172 * At this point, after a little doctoring, we should
173 * have the following on the stack:
177 * 0(%esp): Previous %ebp
179 * So - we pop the previous %ebp, and then
180 * ret to our final destination.
184 ret
/ jmp to final destination
185 / and clean up stack
:)
190 * In order to call the destination procedure and then return
191 * to audit_pltexit() for post analysis we must first grow
192 * our stack frame and then duplicate the original callers
193 * stack state. This duplicates all of the arguements
194 * that were to be passed to the destination procedure.
197 addl $
8, %edi
/ %edi
= src
199 subl
%edi
, %edx
/ %edx
== prev frame sz
201 * If audit_argcnt > 0 then we limit the number of
202 * arguements that will be duplicated to audit_argcnt.
204 * If (prev_stack_size > (audit_argcnt * 4))
205 * prev_stack_size = audit_argcnt * 4;
207 movl audit_argcnt@GOT
(%ebx
),%eax
208 movl
(%eax
), %eax
/ %eax
= audit_argcnt
211 lea
(,%eax
,4), %eax
/ %eax
= %eax
* 4
216 * Grow the stack and duplicate the arguements of the
220 subl
%edx
, %esp
/ grow the stack
221 movl
%edx
, -88(%ebp
) / -88(%ebp
) == prev frame sz
222 movl
%esp
, %ecx
/ %ecx
= dest
223 addl
%ecx
, %edx
/ %edx
== tail of dest
225 cmpl %edx
, %ecx
/ while
(base+size
>= src+
+) {
228 movl
%esi
,(%ecx
) / *dest
= *src
229 addl $
4, %edi
/ src+
+
230 addl $
4, %ecx
/ dest+
+
234 * The above stack is now an exact duplicate of
235 * the stack of the original calling procedure.
238 movl
-92(%ebp
), %eax
/ restore
%eax
239 movl
-96(%ebp
), %ebx
/ restore
%ebx
240 movl
-104(%ebp
), %esi
/ restore
%esi
243 call
*%edi
/ call dest_proc
()
245 addl
-88(%ebp
), %esp
/ cleanup dupped stack
248 pushl SYMNDX_OFF
(%edi
) / arg4
(symndx
)
249 lea SYMDEF_OFF
(%edi
), %ecx
250 pushl
%ecx
/ arg3
(symp
)
251 pushl DEFLMP_OFF
(%edi
) / arg2
(dlmp
)
252 pushl REFLMP_OFF
(%edi
) / arg1
(rlmp
)
253 pushl
%eax
/ arg0
(retval
)
254 call audit_pltexit@PLT
255 addl $
20, %esp
/ cleanup stack
258 * Clean up after ourselves and return to the
259 * original calling procedure.
262 popl
%edi
/ clean up stack
266 ret
/ return to caller
267 .size elf_plt_trace, .-elf_plt_trace
271 * We got here because a call to a function resolved to a procedure
272 * linkage table entry. That entry did a JMPL to the first PLT entry, which
273 * in turn did a call to elf_rtbndr.
275 * the code sequence that got us here was:
278 * jmp *name1@GOT(%ebx)
282 * 1st PLT entry (PLT0):
290 extern unsigned long elf_bndr
(Rt_map
*, unsigned long
, caddr_t
);
293 elf_rtbndr
(Rt_map
* lmp
, unsigned long reloc
, caddr_t pc
)
295 (void
) elf_bndr
(lmp
, reloc
, pc
);
302 _elf_rtbndr
= elf_rtbndr
/ Make dbx happy
303 .type elf_rtbndr,@function
312 pushl
12(%ebp
) / push pc
313 pushl
8(%ebp
) / push reloc
314 pushl
4(%ebp
) / push
*lmp
315 call elf_bndr@PLT
/ call the C binder code
316 addl $
12, %esp
/ pop args
317 movl
%eax
, 8(%ebp
) / store final destination
323 addl $
4,%esp
/ pop args
324 ret
/ invoke resolved function
325 .size elf_rtbndr, .-elf_rtbndr