Rev 2933 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2933 | Rev 2952 | ||
---|---|---|---|
1 | /* |
1 | /* |
2 | * Copyright (c) 2008 Jiri Svoboda |
2 | * Copyright (c) 2008 Jiri Svoboda |
3 | * All rights reserved. |
3 | * All rights reserved. |
4 | * |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
7 | * are met: |
8 | * |
8 | * |
9 | * - Redistributions of source code must retain the above copyright |
9 | * - Redistributions of source code must retain the above copyright |
10 | * notice, this list of conditions and the following disclaimer. |
10 | * notice, this list of conditions and the following disclaimer. |
11 | * - Redistributions in binary form must reproduce the above copyright |
11 | * - Redistributions in binary form must reproduce the above copyright |
12 | * notice, this list of conditions and the following disclaimer in the |
12 | * notice, this list of conditions and the following disclaimer in the |
13 | * documentation and/or other materials provided with the distribution. |
13 | * documentation and/or other materials provided with the distribution. |
14 | * - The name of the author may not be used to endorse or promote products |
14 | * - The name of the author may not be used to endorse or promote products |
15 | * derived from this software without specific prior written permission. |
15 | * derived from this software without specific prior written permission. |
16 | * |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | */ |
27 | */ |
28 | 28 | ||
29 | /** @addtogroup rtld rtld |
29 | /** @addtogroup rtld rtld |
30 | * @brief |
30 | * @brief |
31 | * @{ |
31 | * @{ |
32 | */ |
32 | */ |
33 | /** |
33 | /** |
34 | * @file |
34 | * @file |
35 | */ |
35 | */ |
36 | 36 | ||
- | 37 | void __main(void); |
|
- | 38 | void __io_init(void); |
|
- | 39 | void __exit(void); |
|
- | 40 | ||
37 | void _rtld_main(void); |
41 | void _rtld_main(void); |
38 | 42 | ||
39 | #define ELF32_R_SYM(i) ((i)>>8) |
43 | #define ELF32_R_SYM(i) ((i)>>8) |
40 | #define ELF32_R_TYPE(i) ((unsigned char)(i)) |
44 | #define ELF32_R_TYPE(i) ((unsigned char)(i)) |
41 | 45 | ||
42 | typedef struct { |
46 | typedef struct { |
43 | int d_tag; |
47 | int d_tag; |
44 | union { |
48 | union { |
45 | unsigned d_val; |
49 | unsigned d_val; |
46 | unsigned *d_ptr; |
50 | unsigned *d_ptr; |
47 | } d_un; |
51 | } d_un; |
48 | } elf32_dyn; |
52 | } elf32_dyn; |
49 | 53 | ||
50 | typedef struct { |
54 | typedef struct { |
51 | unsigned r_offset; |
55 | unsigned r_offset; |
52 | unsigned r_info; |
56 | unsigned r_info; |
53 | } elf32_rel; |
57 | } elf32_rel; |
54 | 58 | ||
55 | typedef struct { |
59 | typedef struct { |
56 | unsigned st_name; |
60 | unsigned st_name; |
57 | unsigned st_value; |
61 | unsigned st_value; |
58 | unsigned st_size; |
62 | unsigned st_size; |
59 | unsigned char st_info; |
63 | unsigned char st_info; |
60 | unsigned char st_other; |
64 | unsigned char st_other; |
61 | unsigned short st_shndx; |
65 | unsigned short st_shndx; |
62 | } elf32_sym; |
66 | } elf32_sym; |
63 | 67 | ||
64 | static void kputint(unsigned i) |
68 | static void kputint(unsigned i) |
65 | { |
69 | { |
66 | unsigned dummy; |
70 | unsigned dummy; |
67 | asm volatile ( |
71 | asm volatile ( |
68 | "movl $30, %%eax;" |
72 | "movl $30, %%eax;" |
69 | "int $0x30" |
73 | "int $0x30" |
70 | : "=d" (dummy) /* output - %edx clobbered */ |
74 | : "=d" (dummy) /* output - %edx clobbered */ |
71 | : "d" (i) /* input */ |
75 | : "d" (i) /* input */ |
72 | : "%eax","%ecx" /* all scratch registers clobbered */ |
76 | : "%eax","%ecx" /* all scratch registers clobbered */ |
73 | ); |
77 | ); |
74 | } |
78 | } |
75 | 79 | ||
76 | void __bootstrap(void) |
80 | void __bootstrap(void) |
77 | { |
81 | { |
78 | unsigned bias; |
82 | unsigned bias; |
79 | unsigned *got; |
83 | unsigned *got; |
80 | elf32_dyn *dynamic; |
84 | elf32_dyn *dynamic; |
81 | unsigned *dptr; |
85 | unsigned *dptr; |
82 | unsigned dval; |
86 | unsigned dval; |
83 | int i; |
87 | int i; |
84 | 88 | ||
85 | unsigned rel_entries; |
89 | unsigned rel_entries; |
86 | unsigned r_offset; |
90 | unsigned r_offset; |
87 | unsigned r_info; |
91 | unsigned r_info; |
88 | unsigned rel_type; |
92 | unsigned rel_type; |
89 | unsigned sym_idx; |
93 | unsigned sym_idx; |
90 | unsigned sym_addr; |
94 | unsigned sym_addr; |
91 | 95 | ||
92 | elf32_sym *sym_table; |
96 | elf32_sym *sym_table; |
93 | elf32_rel *rel_table; |
97 | elf32_rel *rel_table; |
- | 98 | elf32_rel *jmp_rel_table; |
|
- | 99 | elf32_rel *jmp_rel_entries; |
|
94 | 100 | ||
95 | asm volatile ( |
101 | asm volatile ( |
96 | "movl $30, %eax;" |
102 | "movl $30, %eax;" |
97 | "int $0x30" |
103 | "int $0x30" |
98 | ); |
104 | ); |
99 | 105 | ||
100 | /* Copied from libc/arch/ia32/entry.s */ |
106 | /* Copied from libc/arch/ia32/entry.s */ |
101 | /*asm volatile ( |
107 | /*asm volatile ( |
102 | "mov %ss, %ax;" |
108 | "mov %ss, %ax;" |
103 | "mov %ax, %ds;" |
109 | "mov %ax, %ds;" |
104 | "mov %ax, %es;" |
110 | "mov %ax, %es;" |
105 | "mov %ax, %fs;" |
111 | "mov %ax, %fs;" |
106 | );*/ |
112 | );*/ |
107 | 113 | ||
108 | 114 | ||
109 | asm volatile ( |
115 | asm volatile ( |
110 | /* Calculate the bias into %0 */ |
116 | /* Calculate the bias into %0 */ |
- | 117 | /* Generates "fake" R_386_RELATIVE run-time relocation */ |
|
111 | " call .L0;" |
118 | " call .L0;" |
112 | ".L0: pop %0;" |
119 | ".L0: pop %0;" |
113 | " subl $.L0, %0;" |
120 | " subl $.L0, %0;" |
114 | 121 | ||
115 | /* Calculate run-time address of _DYNAMIC into %1 */ |
122 | /* Calculate run-time address of _DYNAMIC into %1 */ |
- | 123 | /* Generates "fake" R_386_RELATIVE run-time relocation */ |
|
116 | " movl $_DYNAMIC, %1;" /* Again, at link time 0-based VMA gets in */ |
124 | " movl $_DYNAMIC, %1;" /* Again, at link time 0-based VMA gets in */ |
117 | " addl %0, %1;" /* Add bias to compute run-time address */ |
125 | " addl %0, %1;" /* Add bias to compute run-time address */ |
118 | 126 | ||
119 | : "=r" (bias), "=r" (dynamic) |
127 | : "=r" (bias), "=r" (dynamic) |
120 | ); |
128 | ); |
121 | 129 | ||
122 | kputint(bias); |
130 | kputint(bias); |
123 | kputint((unsigned)dynamic); |
131 | kputint((unsigned)dynamic); |
124 | 132 | ||
125 | /* parse DYNAMIC */ |
133 | /* parse DYNAMIC */ |
126 | got = 0; |
134 | got = 0; |
127 | sym_table = 0; |
135 | sym_table = 0; |
128 | rel_table = 0; |
136 | rel_table = 0; |
129 | rel_entries = 0; |
137 | rel_entries = 0; |
- | 138 | jmp_rel_table = 0; |
|
- | 139 | jmp_rel_entries = 0; |
|
130 | 140 | ||
131 | i = 0; |
141 | i = 0; |
132 | while (dynamic[i].d_tag != 0) { |
142 | while (dynamic[i].d_tag != 0) { |
133 | dptr = (unsigned *)(dynamic[i].d_un.d_val + bias); |
143 | dptr = (unsigned *)(dynamic[i].d_un.d_val + bias); |
134 | dval = dynamic[i].d_un.d_val; |
144 | dval = dynamic[i].d_un.d_val; |
135 | 145 | ||
136 | switch (dynamic[i].d_tag) { |
146 | switch (dynamic[i].d_tag) { |
- | 147 | case 2/* DT_PLTRELSZ */: jmp_rel_entries = dval/8; break; |
|
- | 148 | case 23/* DT_JMPREL */: jmp_rel_table = dptr; break; |
|
137 | case 3 /* DT_PLTGOT */: |
149 | case 3 /* DT_PLTGOT */: |
138 | /* GOT address */ |
150 | /* GOT address */ |
139 | got = dptr; break; |
151 | got = dptr; break; |
140 | case 6 /* DT_SYMTAB */ : sym_table = dptr; break; |
152 | case 6 /* DT_SYMTAB */ : sym_table = dptr; break; |
141 | case 17 /* DT_REL */ : rel_table = dptr; break; |
153 | case 17 /* DT_REL */ : rel_table = dptr; break; |
142 | case 18 /* DT_RELSZ */ : rel_entries = dval / 8; break; |
154 | case 18 /* DT_RELSZ */ : rel_entries = dval / 8; break; |
143 | default: break; |
155 | default: break; |
144 | } |
156 | } |
145 | 157 | ||
146 | ++i; |
158 | ++i; |
147 | } |
159 | } |
148 | 160 | ||
149 | kputint(1); |
161 | kputint(1); |
150 | kputint((unsigned)sym_table); |
162 | kputint((unsigned)sym_table); |
151 | kputint((unsigned)rel_table); |
163 | kputint((unsigned)rel_table); |
152 | kputint((unsigned)rel_entries); |
164 | kputint((unsigned)rel_entries); |
153 | 165 | ||
154 | /* Now relocate all our dynsyms */ |
166 | /* Now relocate all our dynsyms */ |
155 | kputint(-1); |
167 | kputint(-1); |
156 | 168 | ||
157 | for (i=0; i<rel_entries; i++) { |
169 | for (i=0; i<rel_entries; i++) { |
158 | kputint(i); |
170 | kputint(i); |
159 | r_offset = rel_table[i].r_offset; |
171 | r_offset = rel_table[i].r_offset; |
160 | r_info = rel_table[i].r_info; |
172 | r_info = rel_table[i].r_info; |
161 | 173 | ||
162 | rel_type = ELF32_R_TYPE(r_info); |
174 | rel_type = ELF32_R_TYPE(r_info); |
163 | 175 | ||
164 | kputint(rel_type); |
176 | kputint(rel_type); |
165 | kputint(r_offset); |
177 | kputint(r_offset); |
166 | 178 | ||
- | 179 | switch (rel_type) { |
|
- | 180 | case 6: /* R_386_GLOB_DAT */ |
|
- | 181 | case 7: /* R_386_JUMP_SLOT */ |
|
- | 182 | kputint(16); |
|
- | 183 | sym_idx = ELF32_R_SYM(r_info); |
|
- | 184 | ||
- | 185 | sym_addr = sym_table[sym_idx].st_value + bias; |
|
- | 186 | kputint(sym_idx); |
|
- | 187 | kputint(sym_addr); |
|
- | 188 | ||
- | 189 | *(unsigned *)(r_offset+bias) = sym_addr; |
|
- | 190 | break; |
|
- | 191 | ||
- | 192 | case 1: /* R_386_32 */ |
|
- | 193 | kputint(16); |
|
- | 194 | sym_idx = ELF32_R_SYM(r_info); |
|
- | 195 | ||
- | 196 | sym_addr = sym_table[sym_idx].st_value + bias; |
|
- | 197 | kputint(sym_idx); |
|
- | 198 | kputint(sym_addr); |
|
- | 199 | ||
- | 200 | *(unsigned *)(r_offset+bias) += sym_addr; |
|
- | 201 | break; |
|
- | 202 | ||
- | 203 | case 8: /* R_386_RELATIVE */ |
|
- | 204 | kputint(16); |
|
- | 205 | *(unsigned *)(r_offset+bias) += bias; |
|
- | 206 | break; |
|
- | 207 | } |
|
- | 208 | } |
|
- | 209 | ||
- | 210 | kputint(-1); |
|
- | 211 | ||
- | 212 | for (i=0; i<jmp_rel_entries; i++) { |
|
- | 213 | kputint(i); |
|
- | 214 | r_offset = jmp_rel_table[i].r_offset; |
|
- | 215 | r_info = jmp_rel_table[i].r_info; |
|
- | 216 | ||
- | 217 | rel_type = ELF32_R_TYPE(r_info); |
|
- | 218 | ||
- | 219 | kputint(rel_type); |
|
- | 220 | kputint(r_offset); |
|
- | 221 | ||
- | 222 | switch (rel_type) { |
|
- | 223 | case 6: /* R_386_GLOB_DAT */ |
|
167 | if (rel_type == 7 /* R_386_JUMP_SLOT */) { |
224 | case 7: /* R_386_JUMP_SLOT */ |
168 | kputint(16); |
225 | kputint(16); |
169 | sym_idx = ELF32_R_SYM(r_info); |
226 | sym_idx = ELF32_R_SYM(r_info); |
170 | 227 | ||
171 | sym_addr = sym_table[sym_idx].st_value + bias; |
228 | sym_addr = sym_table[sym_idx].st_value + bias; |
172 | kputint(sym_idx); |
229 | kputint(sym_idx); |
173 | kputint(sym_addr); |
230 | kputint(sym_addr); |
174 | 231 | ||
175 | *(unsigned *)(r_offset+bias) = sym_addr; |
232 | *(unsigned *)(r_offset+bias) = sym_addr; |
- | 233 | break; |
|
- | 234 | ||
- | 235 | case 1: /* R_386_32 */ |
|
- | 236 | kputint(16); |
|
- | 237 | sym_idx = ELF32_R_SYM(r_info); |
|
- | 238 | ||
- | 239 | sym_addr = sym_table[sym_idx].st_value + bias; |
|
- | 240 | kputint(sym_idx); |
|
- | 241 | kputint(sym_addr); |
|
- | 242 | ||
- | 243 | *(unsigned *)(r_offset+bias) += sym_addr; |
|
- | 244 | break; |
|
- | 245 | ||
- | 246 | case 8: /* R_386_RELATIVE */ |
|
- | 247 | kputint(16); |
|
- | 248 | *(unsigned *)(r_offset+bias) += bias; |
|
- | 249 | break; |
|
176 | } |
250 | } |
177 | } |
251 | } |
178 | 252 | ||
179 | kputint(-1); |
253 | kputint(-1); |
180 | 254 | ||
- | 255 | /* Init libc and run rtld main */ |
|
181 | kputint(32); |
256 | __main(); |
182 | 257 | ||
- | 258 | kputint(33); |
|
- | 259 | __io_init(); |
|
- | 260 | kputint(34); |
|
183 | _rtld_main(); |
261 | _rtld_main(); |
- | 262 | kputint(35); |
|
- | 263 | __exit(); |
|
- | 264 | ||
- | 265 | kputint(36); |
|
184 | 266 | ||
185 | asm ( |
267 | asm ( |
186 | "movl $250, %%eax;" |
268 | "movl $250, %%eax;" |
187 | "int $0x30" |
269 | "int $0x30" |
188 | : /* output */ |
270 | : /* output */ |
189 | : /* input */ |
271 | : /* input */ |
190 | : "%eax","%ecx","%edx" /* all scratch registers clobbered */ |
272 | : "%eax","%ecx","%edx" /* all scratch registers clobbered */ |
191 | ); |
273 | ); |
192 | } |
274 | } |
193 | 275 | ||
194 | /** @} |
276 | /** @} |
195 | */ |
277 | */ |
196 | 278 |