1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
/*-
* Copyright 1996-1998 John D. Polstra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
.text
.align 4
.globl .rtld_start
.type .rtld_start,@function
.rtld_start:
xorq %rbp,%rbp # Clear frame pointer for good form
subq $24,%rsp # A place to store exit procedure addr
movq %rdi,%r12
movq %rsp,%rsi # save address of exit proc
movq %rsp,%rdx # construct address of obj_main
addq $8,%rdx
call _rtld # Call rtld(sp); returns entry point
popq %rsi # Get exit procedure address
movq %r12,%rdi # *ap
/*
* At this point, %rax contains the entry point of the main program, and
* %rdx contains a pointer to a termination function that should be
* registered with atexit(). (crt1.o registers it.)
*/
.globl .rtld_goto_main
.rtld_goto_main: # This symbol exists just to make debugging easier.
jmp *%rax # Enter main program
/*
* Binder entry point. Control is transferred to here by code in the PLT.
* On entry, there are two arguments on the stack. In ascending address
* order, they are (1) "obj", a pointer to the calling object's Obj_Entry,
* and (2) "reloff", the byte offset of the appropriate relocation entry
* in the PLT relocation table.
*
* We are careful to preserve all registers, even the caller-save
* registers. That is because this code may be invoked by low-level
* assembly-language code that is not ABI-compliant.
*
* Stack map:
* reloff 0x60
* obj 0x58
* spare 0x50
* rflags 0x48
* rax 0x40
* rdx 0x38
* rcx 0x30
* rsi 0x28
* rdi 0x20
* r8 0x18
* r9 0x10
* r10 0x8
* r11 0x0
*/
.align 4
.globl _rtld_bind_start
.type _rtld_bind_start,@function
_rtld_bind_start:
.cfi_startproc
.cfi_adjust_cfa_offset 16
subq $8,%rsp
.cfi_adjust_cfa_offset 8
pushfq # Save rflags
.cfi_adjust_cfa_offset 8
pushq %rax # Save %rax
.cfi_adjust_cfa_offset 8
.cfi_offset %rax,-32
pushq %rdx # Save %rdx
.cfi_adjust_cfa_offset 8
.cfi_offset %rdx,-40
pushq %rcx # Save %rcx
.cfi_adjust_cfa_offset 8
.cfi_offset %rcx,-48
pushq %rsi # Save %rsi
.cfi_adjust_cfa_offset 8
.cfi_offset %rsi,-56
pushq %rdi # Save %rdi
.cfi_adjust_cfa_offset 8
.cfi_offset %rdi,-64
pushq %r8 # Save %r8
.cfi_adjust_cfa_offset 8
.cfi_offset %r8,-72
pushq %r9 # Save %r9
.cfi_adjust_cfa_offset 8
.cfi_offset %r9,-80
pushq %r10 # Save %r10
.cfi_adjust_cfa_offset 8
.cfi_offset %r10,-88
pushq %r11 # Save %r11
.cfi_adjust_cfa_offset 8
.cfi_offset %r11,-96
movq 0x58(%rsp),%rdi # Fetch obj argument
movq 0x60(%rsp),%rsi # Fetch reloff argument
leaq (%rsi,%rsi,2),%rsi # multiply by 3
leaq (,%rsi,8),%rsi # now 8, for 24 (sizeof Elf_Rela)
call _rtld_bind # Transfer control to the binder
/* Now %rax contains the entry point of the function being called. */
movq %rax,0x60(%rsp) # Store target over reloff argument
popq %r11 # Restore %r11
.cfi_adjust_cfa_offset -8
.cfi_restore %r11
popq %r10 # Restore %r10
.cfi_adjust_cfa_offset -8
.cfi_restore %r10
popq %r9 # Restore %r9
.cfi_adjust_cfa_offset -8
.cfi_restore %r9
popq %r8 # Restore %r8
.cfi_adjust_cfa_offset -8
.cfi_restore %r8
popq %rdi # Restore %rdi
.cfi_adjust_cfa_offset -8
.cfi_restore %rdi
popq %rsi # Restore %rsi
.cfi_adjust_cfa_offset -8
.cfi_restore %rsi
popq %rcx # Restore %rcx
.cfi_adjust_cfa_offset -8
.cfi_restore %rcx
popq %rdx # Restore %rdx
.cfi_adjust_cfa_offset -8
.cfi_restore %rdx
popq %rax # Restore %rax
.cfi_adjust_cfa_offset -8
.cfi_restore %rax
popfq # Restore rflags
.cfi_adjust_cfa_offset -8
leaq 16(%rsp),%rsp # Discard spare, obj, do not change rflags
ret # "Return" to target address
.cfi_endproc
.size _rtld_bind_start, . - _rtld_bind_start
.align 4
.globl rtld_dynamic_addr
.type rtld_dynamic_addr,@function
rtld_dynamic_addr:
.cfi_startproc
.weak _DYNAMIC
.hidden _DYNAMIC
lea _DYNAMIC(%rip),%rax
ret
.cfi_endproc
.size rtld_dynamic_addr, . - rtld_dynamic_addr
.section .note.GNU-stack,"",%progbits
|