1 /*-
2 * Copyright (c) 2012,2013 Kai Wang
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include "ld.h"
28 #include "ld_arch.h"
29 #include "ld_dynamic.h"
30 #include "ld_input.h"
31 #include "ld_output.h"
32 #include "ld_reloc.h"
33 #include "ld_symbols.h"
34 #include "ld_utils.h"
35 #include "i386.h"
36
37 ELFTC_VCSID("$Id: i386.c 3402 2016-02-13 15:35:06Z jkoshy $");
38
39 static void _create_plt_reloc(struct ld *ld, struct ld_symbol *lsb,
40 uint64_t offset);
41 static void _create_got_reloc(struct ld *ld, struct ld_symbol *lsb,
42 uint64_t type, uint64_t offset);
43 static void _create_copy_reloc(struct ld *ld, struct ld_symbol *lsb);
44 static void _create_dynamic_reloc(struct ld *ld, struct ld_input_section *is,
45 struct ld_symbol *lsb, uint64_t type, uint64_t offset);
46 static void _scan_reloc(struct ld *ld, struct ld_input_section *is,
47 struct ld_reloc_entry *lre);
48 static struct ld_input_section *_find_and_create_got_section(struct ld *ld,
49 int create);
50 static struct ld_input_section *_find_and_create_gotplt_section(struct ld *ld,
51 int create);
52 static struct ld_input_section *_find_and_create_plt_section(struct ld *ld,
53 int create);
54 static uint64_t _get_max_page_size(struct ld *ld);
55 static uint64_t _get_common_page_size(struct ld *ld);
56 static void _process_reloc(struct ld *ld, struct ld_input_section *is,
57 struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf);
58 static const char *_reloc2str(uint64_t r);
59 static void _reserve_got_entry(struct ld *ld, struct ld_symbol *lsb, int num);
60 static void _reserve_gotplt_entry(struct ld *ld, struct ld_symbol *lsb);
61 static void _reserve_plt_entry(struct ld *ld, struct ld_symbol *lsb);
62 static int _is_absolute_reloc(uint64_t r);
63 static int _is_relative_reloc(uint64_t r);
64 static void _warn_pic(struct ld *ld, struct ld_reloc_entry *lre);
65 static uint32_t _got_offset(struct ld *ld, struct ld_symbol *lsb);
66
67 static uint64_t
_get_max_page_size(struct ld * ld)68 _get_max_page_size(struct ld *ld)
69 {
70
71 (void) ld;
72 return (0x1000);
73 }
74
75 static uint64_t
_get_common_page_size(struct ld * ld)76 _get_common_page_size(struct ld *ld)
77 {
78
79 (void) ld;
80 return (0x1000);
81 }
82
83 static const char *
_reloc2str(uint64_t r)84 _reloc2str(uint64_t r)
85 {
86 static char s[32];
87
88 switch (r) {
89 case 0: return "R_386_NONE";
90 case 1: return "R_386_32";
91 case 2: return "R_386_PC32";
92 case 3: return "R_386_GOT32";
93 case 4: return "R_386_PLT32";
94 case 5: return "R_386_COPY";
95 case 6: return "R_386_GLOB_DAT";
96 case 7: return "R_386_JUMP_SLOT";
97 case 8: return "R_386_RELATIVE";
98 case 9: return "R_386_GOTOFF";
99 case 10: return "R_386_GOTPC";
100 case 14: return "R_386_TLS_TPOFF";
101 case 15: return "R_386_TLS_IE";
102 case 16: return "R_386_TLS_GOTI";
103 case 17: return "R_386_TLS_LE";
104 case 18: return "R_386_TLS_GD";
105 case 19: return "R_386_TLS_LDM";
106 case 24: return "R_386_TLS_GD_32";
107 case 25: return "R_386_TLS_GD_PUSH";
108 case 26: return "R_386_TLS_GD_CALL";
109 case 27: return "R_386_TLS_GD_POP";
110 case 28: return "R_386_TLS_LDM_32";
111 case 29: return "R_386_TLS_LDM_PUSH";
112 case 30: return "R_386_TLS_LDM_CALL";
113 case 31: return "R_386_TLS_LDM_POP";
114 case 32: return "R_386_TLS_LDO_32";
115 case 33: return "R_386_TLS_IE_32";
116 case 34: return "R_386_TLS_LE_32";
117 case 35: return "R_386_TLS_DTPMOD32";
118 case 36: return "R_386_TLS_DTPOFF32";
119 case 37: return "R_386_TLS_TPOFF32";
120
121 default:
122 snprintf(s, sizeof(s), "<unkown: %ju>", (uintmax_t) r);
123 return (s);
124 }
125 }
126
127 static int
_is_absolute_reloc(uint64_t r)128 _is_absolute_reloc(uint64_t r)
129 {
130
131 if (r == R_386_32)
132 return (1);
133
134 return (0);
135 }
136
137 static int
_is_relative_reloc(uint64_t r)138 _is_relative_reloc(uint64_t r)
139 {
140
141 if (r == R_386_RELATIVE)
142 return (1);
143
144 return (0);
145 }
146
147 static void
_warn_pic(struct ld * ld,struct ld_reloc_entry * lre)148 _warn_pic(struct ld *ld, struct ld_reloc_entry *lre)
149 {
150 struct ld_symbol *lsb;
151
152 lsb = lre->lre_sym;
153
154 if (lsb->lsb_bind != STB_LOCAL)
155 ld_warn(ld, "relocation %s against `%s' can not be used"
156 " by runtime linker; recompile with -fPIC",
157 _reloc2str(lre->lre_type), lsb->lsb_name);
158 else
159 ld_warn(ld, "relocation %s can not be used by runtime linker;"
160 " recompile with -fPIC", _reloc2str(lre->lre_type));
161 }
162
163 static struct ld_input_section *
_find_and_create_got_section(struct ld * ld,int create)164 _find_and_create_got_section(struct ld *ld, int create)
165 {
166 struct ld_input_section *is;
167
168 /* Check if the GOT section is already created. */
169 is = ld_input_find_internal_section(ld, ".got");
170 if (is != NULL)
171 return (is);
172
173 if (create) {
174 is = ld_input_add_internal_section(ld, ".got");
175 is->is_entsize = 4;
176 is->is_align = 4;
177 is->is_type = SHT_PROGBITS;
178 is->is_flags = SHF_ALLOC | SHF_WRITE;
179 }
180
181 return (is);
182 }
183
184 static struct ld_input_section *
_find_and_create_gotplt_section(struct ld * ld,int create)185 _find_and_create_gotplt_section(struct ld *ld, int create)
186 {
187 struct ld_input_section *is;
188
189 /* Check if the GOT (for PLT) section is already created. */
190 is = ld_input_find_internal_section(ld, ".got.plt");
191 if (is != NULL)
192 return (is);
193
194 if (create) {
195 is = ld_input_add_internal_section(ld, ".got.plt");
196 is->is_entsize = 4;
197 is->is_align = 4;
198 is->is_type = SHT_PROGBITS;
199 is->is_flags = SHF_ALLOC | SHF_WRITE;
200
201 /* Reserve space for the initial entries. */
202 (void) ld_input_reserve_ibuf(is, 3);
203
204 /* Create _GLOBAL_OFFSET_TABLE_ symbol. */
205 ld_symbols_add_internal(ld, "_GLOBAL_OFFSET_TABLE_", 0, 0,
206 is->is_index, STB_LOCAL, STT_OBJECT, STV_HIDDEN, is, NULL);
207 }
208
209 return (is);
210 }
211
212 static struct ld_input_section *
_find_and_create_plt_section(struct ld * ld,int create)213 _find_and_create_plt_section(struct ld *ld, int create)
214 {
215 struct ld_input_section *is;
216
217 /* Check if the PLT section is already created. */
218 is = ld_input_find_internal_section(ld, ".plt");
219 if (is != NULL)
220 return (is);
221
222 if (create) {
223 is = ld_input_add_internal_section(ld, ".plt");
224 is->is_entsize = 4;
225 is->is_align = 4;
226 is->is_type = SHT_PROGBITS;
227 is->is_flags = SHF_ALLOC | SHF_EXECINSTR;
228
229 /* Reserve space for the initial entry. */
230 (void) ld_input_reserve_ibuf(is, 1);
231 }
232
233 return (is);
234 }
235
236 static void
_reserve_got_entry(struct ld * ld,struct ld_symbol * lsb,int num)237 _reserve_got_entry(struct ld *ld, struct ld_symbol *lsb, int num)
238 {
239 struct ld_input_section *is;
240
241 is = _find_and_create_got_section(ld, 1);
242
243 /* Check if the entry already has a GOT entry. */
244 if (lsb->lsb_got)
245 return;
246
247 /* Reserve GOT entries. */
248 lsb->lsb_got_off = ld_input_reserve_ibuf(is, num);
249 lsb->lsb_got = 1;
250 }
251
252 static void
_reserve_gotplt_entry(struct ld * ld,struct ld_symbol * lsb)253 _reserve_gotplt_entry(struct ld *ld, struct ld_symbol *lsb)
254 {
255 struct ld_input_section *is;
256
257 is = _find_and_create_gotplt_section(ld, 1);
258
259 /* Reserve a GOT entry for PLT. */
260 (void) ld_input_reserve_ibuf(is, 1);
261
262 /*
263 * Record a R_386_JUMP_SLOT entry for this symbol. Note that
264 * we don't need to record the offset (relative to the GOT section)
265 * here, since the PLT relocations will be sorted later and we
266 * will generate GOT section according to the new order.
267 */
268 _create_plt_reloc(ld, lsb, 0);
269 }
270
271 static void
_reserve_plt_entry(struct ld * ld,struct ld_symbol * lsb)272 _reserve_plt_entry(struct ld *ld, struct ld_symbol *lsb)
273 {
274 struct ld_input_section *is;
275
276 is = _find_and_create_plt_section(ld, 1);
277
278 (void) ld_input_reserve_ibuf(is, 1);
279 lsb->lsb_plt = 1;
280 }
281
282 static void
_create_plt_reloc(struct ld * ld,struct ld_symbol * lsb,uint64_t offset)283 _create_plt_reloc(struct ld *ld, struct ld_symbol *lsb, uint64_t offset)
284 {
285
286 ld_reloc_create_entry(ld, ".rel.plt", NULL, R_386_JUMP_SLOT,
287 lsb, offset, 0);
288
289 lsb->lsb_dynrel = 1;
290 }
291
292 static void
_create_got_reloc(struct ld * ld,struct ld_symbol * lsb,uint64_t type,uint64_t offset)293 _create_got_reloc(struct ld *ld, struct ld_symbol *lsb, uint64_t type,
294 uint64_t offset)
295 {
296 struct ld_input_section *tis;
297
298 tis = _find_and_create_got_section(ld, 0);
299 assert(tis != NULL);
300
301 ld_reloc_create_entry(ld, ".rel.got", tis, type, lsb, offset, 0);
302
303 if (type != R_386_RELATIVE)
304 lsb->lsb_dynrel = 1;
305 }
306
307 static void
_create_copy_reloc(struct ld * ld,struct ld_symbol * lsb)308 _create_copy_reloc(struct ld *ld, struct ld_symbol *lsb)
309 {
310 struct ld_input_section *tis;
311
312 ld_dynamic_reserve_dynbss_entry(ld, lsb);
313
314 tis = ld_input_find_internal_section(ld, ".dynbss");
315 assert(tis != NULL);
316
317 ld_reloc_create_entry(ld, ".rel.bss", tis, R_386_COPY, lsb,
318 lsb->lsb_value, 0);
319
320 lsb->lsb_dynrel = 1;
321 }
322
323 static void
_create_dynamic_reloc(struct ld * ld,struct ld_input_section * is,struct ld_symbol * lsb,uint64_t type,uint64_t offset)324 _create_dynamic_reloc(struct ld *ld, struct ld_input_section *is,
325 struct ld_symbol *lsb, uint64_t type, uint64_t offset)
326 {
327
328 if (lsb->lsb_bind == STB_LOCAL) {
329 if (is->is_flags & SHF_WRITE)
330 ld_reloc_create_entry(ld, ".rel.data.rel.local",
331 is, type, lsb, offset, 0);
332 else
333 ld_reloc_create_entry(ld, ".rel.data.rel.ro.local",
334 is, type, lsb, offset, 0);
335 } else {
336 if (is->is_flags & SHF_WRITE)
337 ld_reloc_create_entry(ld, ".rel.data.rel",
338 is, type, lsb, offset, 0);
339 else
340 ld_reloc_create_entry(ld, ".rel.data.rel.ro",
341 is, type, lsb, offset, 0);
342 }
343
344 if (type != R_386_RELATIVE)
345 lsb->lsb_dynrel = 1;
346 }
347
348 static void
_scan_reloc(struct ld * ld,struct ld_input_section * is,struct ld_reloc_entry * lre)349 _scan_reloc(struct ld *ld, struct ld_input_section *is,
350 struct ld_reloc_entry *lre)
351 {
352 struct ld_symbol *lsb;
353
354 lsb = ld_symbols_ref(lre->lre_sym);
355
356 switch (lre->lre_type) {
357 case R_386_NONE:
358 break;
359
360 case R_386_32:
361 /*
362 * For a local symbol, if te linker output a PIE or DSO,
363 * we should generate a R_386_RELATIVE reloc for R_386_32.
364 */
365 if (lsb->lsb_bind == STB_LOCAL) {
366 if (ld->ld_pie || ld->ld_dso)
367 _create_dynamic_reloc(ld, is, lsb,
368 R_386_RELATIVE, lre->lre_offset);
369 break;
370 }
371
372 /*
373 * For a global symbol, we probably need to generate PLE entry
374 * and/ore a dynamic relocation.
375 *
376 * Note here, normally the compiler will generate a PC-relative
377 * relocation for function calls. However, if the code retrieve
378 * the address of a function and call it indirectly, assembler
379 * will generate absolute relocation instead. That's why we
380 * should check if we need to create a PLT entry here. Also, if
381 * we're going to create the PLT entry, we should also set the
382 * symbol value to the address of PLT entry just in case the
383 * function address is used to compare with other function
384 * addresses. (If PLT address is used, function will have
385 * unified address in the main executable and DSOs)
386 */
387 if (ld_reloc_require_plt(ld, lre)) {
388 if (!lsb->lsb_plt) {
389 _reserve_gotplt_entry(ld, lsb);
390 _reserve_plt_entry(ld, lsb);
391 }
392 /*
393 * Note here even if we have generated PLT for this
394 * function before, we still need to set this flag.
395 * It's possible that we first see the relative
396 * relocation then this absolute relocation, in
397 * other words, the same function can be called in
398 * different ways.
399 */
400 lsb->lsb_func_addr = 1;
401 }
402
403 if (ld_reloc_require_copy_reloc(ld, lre) &&
404 !lsb->lsb_copy_reloc)
405 _create_copy_reloc(ld, lsb);
406 else if (ld_reloc_require_dynamic_reloc(ld, lre)) {
407 /*
408 * Check if we can relax R_386_32 to
409 * R_386_RELATIVE instead.
410 */
411 if (ld_reloc_relative_relax(ld, lre))
412 _create_dynamic_reloc(ld, is, lsb,
413 R_386_RELATIVE, lre->lre_offset);
414 else
415 _create_dynamic_reloc(ld, is, lsb,
416 R_386_32, lre->lre_offset);
417 }
418
419 break;
420
421 case R_386_PLT32:
422 /*
423 * In some cases we don't really need to generate a PLT
424 * entry, then a R_386_PLT32 relocation can be relaxed
425 * to a R_386_PC32 relocation.
426 */
427 if (lsb->lsb_bind == STB_LOCAL ||
428 !ld_reloc_require_plt(ld, lre)) {
429 lre->lre_type = R_386_PC32;
430 break;
431 }
432
433 /*
434 * If linker outputs an normal executable and the symbol is
435 * defined but is not defined inside a DSO, we can generate
436 * a R_386_PC32 relocation instead.
437 */
438 if (ld->ld_exec && lsb->lsb_shndx != SHN_UNDEF &&
439 (lsb->lsb_input == NULL ||
440 lsb->lsb_input->li_type != LIT_DSO)) {
441 lre->lre_type = R_386_PC32;
442 break;
443 }
444
445 /* Create an PLT entry otherwise. */
446 if (!lsb->lsb_plt) {
447 _reserve_gotplt_entry(ld, lsb);
448 _reserve_plt_entry(ld, lsb);
449 }
450 break;
451
452 case R_386_PC32:
453 /*
454 * When R_386_PC32 apply to a global symbol, we should
455 * check if we need to generate PLT entry and/or a dynamic
456 * relocation.
457 */
458 if (lsb->lsb_bind != STB_LOCAL) {
459 if (ld_reloc_require_plt(ld, lre) && !lsb->lsb_plt) {
460 _reserve_gotplt_entry(ld, lsb);
461 _reserve_plt_entry(ld, lsb);
462 }
463
464 if (ld_reloc_require_copy_reloc(ld, lre) &&
465 !lsb->lsb_copy_reloc)
466 _create_copy_reloc(ld, lsb);
467 else if (ld_reloc_require_dynamic_reloc(ld, lre)) {
468 /*
469 * We can not generate dynamic relocation for
470 * these PC-relative relocation since they
471 * are probably not supported by the runtime
472 * linkers.
473 */
474 _warn_pic(ld, lre);
475 }
476 }
477 break;
478
479 case R_386_GOTOFF:
480 case R_386_GOTPC:
481 /*
482 * These relocation types use GOT address as a base address
483 * and instruct the linker to build a GOT.
484 */
485 (void) _find_and_create_got_section(ld, 1);
486 break;
487
488 case R_386_GOT32:
489 /*
490 * R_386_GOT32 relocation instructs the linker to build a
491 * GOT and generate a GOT entry.
492 */
493 if (!lsb->lsb_got) {
494 _reserve_got_entry(ld, lsb, 1);
495 /*
496 * TODO: For now we always create a R_386_GLOB_DAT
497 * relocation for a GOT entry. There are cases that
498 * the symbol's address is known at link time and
499 * the GOT entry value can be filled in by the program
500 * linker instead.
501 */
502 if (ld_reloc_require_glob_dat(ld, lre))
503 _create_got_reloc(ld, lsb, R_386_GLOB_DAT,
504 lsb->lsb_got_off);
505 else
506 _create_got_reloc(ld, lsb, R_386_RELATIVE,
507 lsb->lsb_got_off);
508 }
509
510 default:
511 ld_warn(ld, "can not handle relocation %ju",
512 lre->lre_type);
513 break;
514 }
515 }
516
517 static uint32_t
_got_offset(struct ld * ld,struct ld_symbol * lsb)518 _got_offset(struct ld *ld, struct ld_symbol *lsb)
519 {
520 struct ld_output_section *os;
521
522 assert(lsb->lsb_got);
523
524 if (ld->ld_got == NULL) {
525 ld->ld_got = _find_and_create_got_section(ld, 0);
526 assert(ld->ld_got != NULL);
527 }
528
529 os = ld->ld_got->is_output;
530
531 return (os->os_addr + ld->ld_got->is_reloff + lsb->lsb_got_off);
532 }
533
534 static void
_process_reloc(struct ld * ld,struct ld_input_section * is,struct ld_reloc_entry * lre,struct ld_symbol * lsb,uint8_t * buf)535 _process_reloc(struct ld *ld, struct ld_input_section *is,
536 struct ld_reloc_entry *lre, struct ld_symbol *lsb, uint8_t *buf)
537 {
538 struct ld_state *ls;
539 struct ld_output *lo;
540 uint32_t p, s, l, g, got;
541 int32_t a, v;
542
543 ls = &ld->ld_state;
544
545 lo = ld->ld_output;
546 assert(lo != NULL);
547
548 l = lsb->lsb_plt_off;
549 p = lre->lre_offset + is->is_output->os_addr + is->is_reloff;
550 got = ld->ld_got->is_output->os_addr;
551 s = (uint32_t) lsb->lsb_value;
552 READ_32(buf + lre->lre_offset, a);
553
554 switch (lre->lre_type) {
555 case R_386_NONE:
556 break;
557
558 case R_386_32:
559 v = s + a;
560 WRITE_32(buf + lre->lre_offset, v);
561 break;
562
563 case R_386_PC32:
564 if (lsb->lsb_plt)
565 v = l + a - p;
566 else
567 v = s + a - p;
568 WRITE_32(buf + lre->lre_offset, v);
569 break;
570
571 case R_386_PLT32:
572 if (!ls->ls_ignore_next_plt) {
573 v = l + a - p;
574 WRITE_32(buf + lre->lre_offset, v);
575 } else
576 ls->ls_ignore_next_plt = 0;
577 break;
578
579 case R_386_GOT32:
580 g = _got_offset(ld, lsb);
581 v = g + a;
582 WRITE_32(buf + lre->lre_offset, v);
583 break;
584
585 case R_386_GOTOFF:
586 v = s + a - got;
587 WRITE_32(buf + lre->lre_offset, v);
588 break;
589
590 case R_386_GOTPC:
591 v = got + a - p;
592 WRITE_32(buf + lre->lre_offset, v);
593 break;
594
595 default:
596 ld_fatal(ld, "Relocation %d not supported", lre->lre_type);
597 break;
598 }
599 }
600
601 void
i386_register(struct ld * ld)602 i386_register(struct ld *ld)
603 {
604 struct ld_arch *i386_arch;
605
606 if ((i386_arch = calloc(1, sizeof(*i386_arch))) == NULL)
607 ld_fatal_std(ld, "calloc");
608
609 snprintf(i386_arch->name, sizeof(i386_arch->name), "%s", "i386");
610
611 i386_arch->script = i386_script;
612 i386_arch->get_max_page_size = _get_max_page_size;
613 i386_arch->get_common_page_size = _get_common_page_size;
614 i386_arch->scan_reloc = _scan_reloc;
615 i386_arch->process_reloc = _process_reloc;
616 i386_arch->is_absolute_reloc = _is_absolute_reloc;
617 i386_arch->is_relative_reloc = _is_relative_reloc;
618 i386_arch->reloc_is_64bit = 0;
619 i386_arch->reloc_is_rela = 0;
620 i386_arch->reloc_entsize = sizeof(Elf32_Rel);
621
622 HASH_ADD_STR(ld->ld_arch_list, name, i386_arch);
623 }
624