1 // i386.cc -- i386 target support for gold.
11 #include "target-reloc.h"
12 #include "target-select.h"
19 // The i386 target class.
21 class Target_i386 : public Sized_target<32, false>
25 : Sized_target<32, false>(&i386_info)
28 // Scan the relocations to look for symbol adjustments.
30 scan_relocs(const General_options& options,
32 Sized_object<32, false>* object,
34 const unsigned char* prelocs,
36 size_t local_symbol_count,
37 const unsigned char* plocal_symbols,
38 Symbol** global_symbols);
40 // Relocate a section.
42 relocate_section(const Relocate_info<32, false>*,
44 const unsigned char* prelocs,
47 elfcpp::Elf_types<32>::Elf_Addr view_address,
51 // The class which scans relocations.
55 local(const General_options& options, Sized_object<32, false>* object,
56 const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
57 const elfcpp::Sym<32, false>& lsym);
60 global(const General_options& options, Sized_object<32, false>* object,
61 const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
65 // The class which implements relocation.
71 relocate(const Relocate_info<32, false>*, size_t relnum,
72 const elfcpp::Rel<32, false>&,
73 unsigned int r_type, Sized_symbol<32>*,
74 elfcpp::Elf_types<32>::Elf_Addr,
75 unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
79 // Do a TLS relocation.
81 relocate_tls(const Relocate_info<32, false>*, size_t relnum,
82 const elfcpp::Rel<32, false>&,
83 unsigned int r_type, Sized_symbol<32>*,
84 elfcpp::Elf_types<32>::Elf_Addr,
85 unsigned char*, elfcpp::Elf_types<32>::Elf_Addr, off_t);
87 // Do a TLS Initial-Exec to Local-Exec transition.
89 tls_ie_to_le(const Relocate_info<32, false>*, size_t relnum,
90 Output_segment* tls_segment,
91 const elfcpp::Rel<32, false>&, unsigned int r_type,
92 elfcpp::Elf_types<32>::Elf_Addr value,
96 // Check the range for a TLS relocation.
98 check_range(const Relocate_info<32, false>*, size_t relnum,
99 const elfcpp::Rel<32, false>&, off_t, off_t);
101 // Check the validity of a TLS relocation. This is like assert.
103 check_tls(const Relocate_info<32, false>*, size_t relnum,
104 const elfcpp::Rel<32, false>&, bool);
107 // Adjust TLS relocation type based on the options and whether this
108 // is a local symbol.
110 optimize_tls_reloc(const General_options*, bool is_local, int r_type);
112 // Information about this specific target which we pass to the
113 // general Target structure.
114 static const Target::Target_info i386_info;
117 const Target::Target_info Target_i386::i386_info =
120 false, // is_big_endian
121 elfcpp::EM_386, // machine_code
122 false, // has_make_symbol
123 false, // has_resolve,
124 0x08048000, // text_segment_address,
125 0x1000, // abi_pagesize
126 0x1000 // common_pagesize
129 // Optimize the TLS relocation type based on what we know about the
130 // symbol. IS_LOCAL is true if this symbol can be resolved entirely
131 // locally--i.e., does not have to be in the dynamic symbol table.
134 Target_i386::optimize_tls_reloc(const General_options* options, bool is_local,
137 // If we are generating a shared library, then we can't do anything
139 if (options->is_shared())
144 case elfcpp::R_386_TLS_GD:
145 case elfcpp::R_386_TLS_GOTDESC:
146 case elfcpp::R_386_TLS_DESC_CALL:
147 // These are Global-Dynamic which permits fully general TLS
148 // access. Since we know that we are generating an executable,
149 // we can convert this to Initial-Exec. If we also know that
150 // this is a local symbol, we can further switch to Local-Exec.
152 return elfcpp::R_386_TLS_LE_32;
153 return elfcpp::R_386_TLS_IE_32;
155 case elfcpp::R_386_TLS_LDM:
156 // This is Local-Dynamic, which refers to a local symbol in the
157 // dynamic TLS block. Since we know that we generating an
158 // executable, we can switch to Local-Exec.
159 return elfcpp::R_386_TLS_LE_32;
161 case elfcpp::R_386_TLS_LDO_32:
162 // Another type of Local-Dynamic relocation.
163 return elfcpp::R_386_TLS_LE;
165 case elfcpp::R_386_TLS_IE:
166 case elfcpp::R_386_TLS_GOTIE:
167 case elfcpp::R_386_TLS_IE_32:
168 // These are Initial-Exec relocs which get the thread offset
169 // from the GOT. If we know that we are linking against the
170 // local symbol, we can switch to Local-Exec, which links the
171 // thread offset into the instruction.
173 return elfcpp::R_386_TLS_LE_32;
176 case elfcpp::R_386_TLS_LE:
177 case elfcpp::R_386_TLS_LE_32:
178 // When we already have Local-Exec, there is nothing further we
187 // Scan a relocation for a local symbol.
190 Target_i386::Scan::local(const General_options& options,
191 Sized_object<32, false>* object,
192 const elfcpp::Rel<32, false>&, unsigned int r_type,
193 const elfcpp::Sym<32, false>&)
197 case elfcpp::R_386_NONE:
198 case elfcpp::R_386_GNU_VTINHERIT:
199 case elfcpp::R_386_GNU_VTENTRY:
202 case elfcpp::R_386_32:
203 case elfcpp::R_386_16:
204 case elfcpp::R_386_8:
205 // FIXME: If we are generating a shared object we need to copy
206 // this relocation into the object.
209 case elfcpp::R_386_PC32:
210 case elfcpp::R_386_PC16:
211 case elfcpp::R_386_PC8:
214 case elfcpp::R_386_COPY:
215 case elfcpp::R_386_GLOB_DAT:
216 case elfcpp::R_386_JUMP_SLOT:
217 case elfcpp::R_386_RELATIVE:
218 case elfcpp::R_386_TLS_TPOFF:
219 case elfcpp::R_386_TLS_DTPMOD32:
220 case elfcpp::R_386_TLS_DTPOFF32:
221 case elfcpp::R_386_TLS_TPOFF32:
222 case elfcpp::R_386_TLS_DESC:
223 fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
224 program_name, object->name().c_str(), r_type);
228 case elfcpp::R_386_TLS_IE:
229 case elfcpp::R_386_TLS_GOTIE:
230 case elfcpp::R_386_TLS_LE:
231 case elfcpp::R_386_TLS_GD:
232 case elfcpp::R_386_TLS_LDM:
233 case elfcpp::R_386_TLS_LDO_32:
234 case elfcpp::R_386_TLS_IE_32:
235 case elfcpp::R_386_TLS_LE_32:
236 case elfcpp::R_386_TLS_GOTDESC:
237 case elfcpp::R_386_TLS_DESC_CALL:
238 r_type = Target_i386::optimize_tls_reloc(&options, true, r_type);
241 case elfcpp::R_386_TLS_LE:
242 case elfcpp::R_386_TLS_LE_32:
243 // FIXME: If generating a shared object, we need to copy
244 // this relocation into the object.
247 case elfcpp::R_386_TLS_IE:
248 case elfcpp::R_386_TLS_GOTIE:
249 case elfcpp::R_386_TLS_GD:
250 case elfcpp::R_386_TLS_LDM:
251 case elfcpp::R_386_TLS_LDO_32:
252 case elfcpp::R_386_TLS_IE_32:
253 case elfcpp::R_386_TLS_GOTDESC:
254 case elfcpp::R_386_TLS_DESC_CALL:
256 _("%s: %s: unsupported reloc %u against local symbol\n"),
257 program_name, object->name().c_str(), r_type);
262 case elfcpp::R_386_GOT32:
263 case elfcpp::R_386_PLT32:
264 case elfcpp::R_386_GOTOFF:
265 case elfcpp::R_386_GOTPC:
266 case elfcpp::R_386_32PLT:
267 case elfcpp::R_386_TLS_GD_32:
268 case elfcpp::R_386_TLS_GD_PUSH:
269 case elfcpp::R_386_TLS_GD_CALL:
270 case elfcpp::R_386_TLS_GD_POP:
271 case elfcpp::R_386_TLS_LDM_32:
272 case elfcpp::R_386_TLS_LDM_PUSH:
273 case elfcpp::R_386_TLS_LDM_CALL:
274 case elfcpp::R_386_TLS_LDM_POP:
275 case elfcpp::R_386_USED_BY_INTEL_200:
277 fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"),
278 program_name, object->name().c_str(), r_type);
283 // Scan a relocation for a global symbol.
286 Target_i386::Scan::global(const General_options& options,
287 Sized_object<32, false>* object,
288 const elfcpp::Rel<32, false>&, unsigned int r_type,
293 case elfcpp::R_386_NONE:
294 case elfcpp::R_386_GNU_VTINHERIT:
295 case elfcpp::R_386_GNU_VTENTRY:
298 case elfcpp::R_386_32:
299 case elfcpp::R_386_PC32:
300 case elfcpp::R_386_16:
301 case elfcpp::R_386_PC16:
302 case elfcpp::R_386_8:
303 case elfcpp::R_386_PC8:
304 // FIXME: If we are generating a shared object we may need to
305 // copy this relocation into the object. If this symbol is
306 // defined in a shared object, we may need to copy this
307 // relocation in order to avoid a COPY relocation.
310 case elfcpp::R_386_COPY:
311 case elfcpp::R_386_GLOB_DAT:
312 case elfcpp::R_386_JUMP_SLOT:
313 case elfcpp::R_386_RELATIVE:
314 case elfcpp::R_386_TLS_TPOFF:
315 case elfcpp::R_386_TLS_DTPMOD32:
316 case elfcpp::R_386_TLS_DTPOFF32:
317 case elfcpp::R_386_TLS_TPOFF32:
318 case elfcpp::R_386_TLS_DESC:
319 fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
320 program_name, object->name().c_str(), r_type);
324 case elfcpp::R_386_TLS_IE:
325 case elfcpp::R_386_TLS_GOTIE:
326 case elfcpp::R_386_TLS_LE:
327 case elfcpp::R_386_TLS_GD:
328 case elfcpp::R_386_TLS_LDM:
329 case elfcpp::R_386_TLS_LDO_32:
330 case elfcpp::R_386_TLS_IE_32:
331 case elfcpp::R_386_TLS_LE_32:
332 case elfcpp::R_386_TLS_GOTDESC:
333 case elfcpp::R_386_TLS_DESC_CALL:
334 r_type = Target_i386::optimize_tls_reloc(&options,
339 case elfcpp::R_386_TLS_LE:
340 case elfcpp::R_386_TLS_LE_32:
341 // FIXME: If generating a shared object, we need to copy
342 // this relocation into the object.
345 case elfcpp::R_386_TLS_IE:
346 case elfcpp::R_386_TLS_GOTIE:
347 case elfcpp::R_386_TLS_GD:
348 case elfcpp::R_386_TLS_LDM:
349 case elfcpp::R_386_TLS_LDO_32:
350 case elfcpp::R_386_TLS_IE_32:
351 case elfcpp::R_386_TLS_GOTDESC:
352 case elfcpp::R_386_TLS_DESC_CALL:
354 _("%s: %s: unsupported reloc %u against global symbol %s\n"),
355 program_name, object->name().c_str(), r_type, gsym->name());
360 case elfcpp::R_386_GOT32:
361 case elfcpp::R_386_PLT32:
362 case elfcpp::R_386_GOTOFF:
363 case elfcpp::R_386_GOTPC:
364 case elfcpp::R_386_32PLT:
365 case elfcpp::R_386_TLS_GD_32:
366 case elfcpp::R_386_TLS_GD_PUSH:
367 case elfcpp::R_386_TLS_GD_CALL:
368 case elfcpp::R_386_TLS_GD_POP:
369 case elfcpp::R_386_TLS_LDM_32:
370 case elfcpp::R_386_TLS_LDM_PUSH:
371 case elfcpp::R_386_TLS_LDM_CALL:
372 case elfcpp::R_386_TLS_LDM_POP:
373 case elfcpp::R_386_USED_BY_INTEL_200:
376 _("%s: %s: unsupported reloc %u against global symbol %s\n"),
377 program_name, object->name().c_str(), r_type, gsym->name());
382 // Scan relocations for a section.
385 Target_i386::scan_relocs(const General_options& options,
386 Symbol_table* symtab,
387 Sized_object<32, false>* object,
388 unsigned int sh_type,
389 const unsigned char* prelocs,
391 size_t local_symbol_count,
392 const unsigned char* plocal_symbols,
393 Symbol** global_symbols)
395 if (sh_type == elfcpp::SHT_RELA)
397 fprintf(stderr, _("%s: %s: unsupported RELA reloc section\n"),
398 program_name, object->name().c_str());
402 gold::scan_relocs<32, false, elfcpp::SHT_REL, Target_i386::Scan>(
413 // Perform a relocation.
416 Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
418 const elfcpp::Rel<32, false>& rel,
420 Sized_symbol<32>* gsym,
421 elfcpp::Elf_types<32>::Elf_Addr value,
423 elfcpp::Elf_types<32>::Elf_Addr address,
428 case elfcpp::R_386_NONE:
429 case elfcpp::R_386_GNU_VTINHERIT:
430 case elfcpp::R_386_GNU_VTENTRY:
433 case elfcpp::R_386_32:
434 Relocate_functions<32, false>::rel32(view, value);
437 case elfcpp::R_386_PC32:
438 Relocate_functions<32, false>::pcrel32(view, value, address);
441 case elfcpp::R_386_16:
442 Relocate_functions<32, false>::rel16(view, value);
445 case elfcpp::R_386_PC16:
446 Relocate_functions<32, false>::pcrel16(view, value, address);
449 case elfcpp::R_386_8:
450 Relocate_functions<32, false>::rel8(view, value);
453 case elfcpp::R_386_PC8:
454 Relocate_functions<32, false>::pcrel8(view, value, address);
457 case elfcpp::R_386_COPY:
458 case elfcpp::R_386_GLOB_DAT:
459 case elfcpp::R_386_JUMP_SLOT:
460 case elfcpp::R_386_RELATIVE:
461 case elfcpp::R_386_TLS_TPOFF:
462 case elfcpp::R_386_TLS_DTPMOD32:
463 case elfcpp::R_386_TLS_DTPOFF32:
464 case elfcpp::R_386_TLS_TPOFF32:
465 case elfcpp::R_386_TLS_DESC:
466 fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
468 relinfo->location(relnum, rel.get_r_offset()).c_str(),
473 case elfcpp::R_386_TLS_IE:
474 case elfcpp::R_386_TLS_GOTIE:
475 case elfcpp::R_386_TLS_LE:
476 case elfcpp::R_386_TLS_GD:
477 case elfcpp::R_386_TLS_LDM:
478 case elfcpp::R_386_TLS_LDO_32:
479 case elfcpp::R_386_TLS_IE_32:
480 case elfcpp::R_386_TLS_LE_32:
481 case elfcpp::R_386_TLS_GOTDESC:
482 case elfcpp::R_386_TLS_DESC_CALL:
483 Target_i386::Relocate::relocate_tls(relinfo, relnum, rel, r_type,
484 gsym, value, view, address,
488 case elfcpp::R_386_GOT32:
489 case elfcpp::R_386_PLT32:
490 case elfcpp::R_386_GOTOFF:
491 case elfcpp::R_386_GOTPC:
492 case elfcpp::R_386_32PLT:
493 case elfcpp::R_386_TLS_GD_32:
494 case elfcpp::R_386_TLS_GD_PUSH:
495 case elfcpp::R_386_TLS_GD_CALL:
496 case elfcpp::R_386_TLS_GD_POP:
497 case elfcpp::R_386_TLS_LDM_32:
498 case elfcpp::R_386_TLS_LDM_PUSH:
499 case elfcpp::R_386_TLS_LDM_CALL:
500 case elfcpp::R_386_TLS_LDM_POP:
501 case elfcpp::R_386_USED_BY_INTEL_200:
503 fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
505 relinfo->location(relnum, rel.get_r_offset()).c_str(),
512 // Perform a TLS relocation.
515 Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
517 const elfcpp::Rel<32, false>& rel,
519 Sized_symbol<32>* gsym,
520 elfcpp::Elf_types<32>::Elf_Addr value,
522 elfcpp::Elf_types<32>::Elf_Addr,
525 Output_segment* tls_segment = relinfo->layout->tls_segment();
526 if (tls_segment == NULL)
528 fprintf(stderr, _("%s: %s: TLS reloc but no TLS segment\n"),
530 relinfo->location(relnum, rel.get_r_offset()).c_str());
534 const bool is_local = gsym == NULL || !gsym->in_dynsym();
535 const unsigned int opt_r_type =
536 Target_i386::optimize_tls_reloc(relinfo->options, is_local, r_type);
539 case elfcpp::R_386_TLS_LE_32:
540 value = tls_segment->vaddr() + tls_segment->memsz() - value;
541 Relocate_functions<32, false>::rel32(view, value);
544 case elfcpp::R_386_TLS_LE:
545 value = value - (tls_segment->vaddr() + tls_segment->memsz());
546 Relocate_functions<32, false>::rel32(view, value);
549 case elfcpp::R_386_TLS_IE:
550 case elfcpp::R_386_TLS_GOTIE:
551 case elfcpp::R_386_TLS_IE_32:
552 if (opt_r_type == elfcpp::R_386_TLS_LE_32)
554 Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
555 rel, r_type, value, view,
559 fprintf(stderr, _("%s: %s: unsupported reloc type %u\n"),
561 relinfo->location(relnum, rel.get_r_offset()).c_str(),
566 case elfcpp::R_386_TLS_GD:
567 case elfcpp::R_386_TLS_LDM:
568 case elfcpp::R_386_TLS_LDO_32:
569 case elfcpp::R_386_TLS_GOTDESC:
570 case elfcpp::R_386_TLS_DESC_CALL:
571 fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
573 relinfo->location(relnum, rel.get_r_offset()).c_str(),
580 // Do a relocation in which we convert a TLS Initial-Exec to a
584 Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo,
586 Output_segment* tls_segment,
587 const elfcpp::Rel<32, false>& rel,
589 elfcpp::Elf_types<32>::Elf_Addr value,
593 // We have to actually change the instructions, which means that we
594 // need to examine the opcodes to figure out which instruction we
596 if (r_type == elfcpp::R_386_TLS_IE)
598 // movl %gs:XX,%eax ==> movl $YY,%eax
599 // movl %gs:XX,%reg ==> movl $YY,%reg
600 // addl %gs:XX,%reg ==> addl $YY,%reg
601 Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -1);
602 Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, 4);
604 unsigned char op1 = view[-1];
607 // movl XX,%eax ==> movl $YY,%eax
612 Target_i386::Relocate::check_range(relinfo, relnum, rel,
615 unsigned char op2 = view[-2];
618 // movl XX,%reg ==> movl $YY,%reg
619 Target_i386::Relocate::check_tls(relinfo, relnum, rel,
620 (op1 & 0xc7) == 0x05);
622 view[-1] = 0xc0 | ((op1 >> 3) & 7);
624 else if (op2 == 0x03)
626 // addl XX,%reg ==> addl $YY,%reg
627 Target_i386::Relocate::check_tls(relinfo, relnum, rel,
628 (op1 & 0xc7) == 0x05);
630 view[-1] = 0xc0 | ((op1 >> 3) & 7);
633 Target_i386::Relocate::check_tls(relinfo, relnum, rel, 0);
638 // subl %gs:XX(%reg1),%reg2 ==> subl $YY,%reg2
639 // movl %gs:XX(%reg1),%reg2 ==> movl $YY,%reg2
640 // addl %gs:XX(%reg1),%reg2 ==> addl $YY,$reg2
641 Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -2);
642 Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, 4);
644 unsigned char op1 = view[-1];
645 unsigned char op2 = view[-2];
646 Target_i386::Relocate::check_tls(relinfo, relnum, rel,
647 (op1 & 0xc0) == 0x80 && (op1 & 7) != 4);
650 // movl %gs:XX(%reg1),%reg2 ==> movl $YY,%reg2
652 view[-1] = 0xc0 | ((op1 >> 3) & 7);
654 else if (op2 == 0x2b)
656 // subl %gs:XX(%reg1),%reg2 ==> subl $YY,%reg2
658 view[-1] = 0xe8 | ((op1 >> 3) & 7);
660 else if (op2 == 0x03)
662 // addl %gs:XX(%reg1),%reg2 ==> addl $YY,$reg2
664 view[-1] = 0xc0 | ((op1 >> 3) & 7);
667 Target_i386::Relocate::check_tls(relinfo, relnum, rel, 0);
670 if (r_type == elfcpp::R_386_TLS_IE_32)
671 value = tls_segment->vaddr() + tls_segment->memsz() - value;
672 else // elfcpp::R_386_TLS_IE, elfcpp::R_386_TLS_GOTIE
673 value = value - (tls_segment->vaddr() + tls_segment->memsz());
675 Relocate_functions<32, false>::rel32(view, value);
678 // Check the range for a TLS relocation.
681 Target_i386::Relocate::check_range(const Relocate_info<32, false>* relinfo,
683 const elfcpp::Rel<32, false>& rel,
684 off_t view_size, off_t off)
686 off_t offset = rel.get_r_offset() + off;
687 if (offset < 0 || offset > view_size)
689 fprintf(stderr, _("%s: %s: TLS relocation out of range\n"),
691 relinfo->location(relnum, rel.get_r_offset()).c_str());
696 // Check the validity of a TLS relocation. This is like assert.
699 Target_i386::Relocate::check_tls(const Relocate_info<32, false>* relinfo,
701 const elfcpp::Rel<32, false>& rel,
707 _("%s: %s: TLS relocation against invalid instruction\n"),
709 relinfo->location(relnum, rel.get_r_offset()).c_str());
714 // Relocate section data.
717 Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
718 unsigned int sh_type,
719 const unsigned char* prelocs,
722 elfcpp::Elf_types<32>::Elf_Addr address,
725 assert(sh_type == elfcpp::SHT_REL);
727 gold::relocate_section<32, false, elfcpp::SHT_REL, Target_i386::Relocate>(
738 Target_i386 target_i386;
740 // The selector for i386 object files.
742 class Target_selector_i386 : public Target_selector
745 Target_selector_i386()
746 : Target_selector(elfcpp::EM_386, 32, false)
750 recognize(int machine, int osabi, int abiversion) const;
753 // Recognize an i386 object file when we already know that the machine
757 Target_selector_i386::recognize(int, int, int) const
762 Target_selector_i386 target_selector_i386;
764 } // End anonymous namespace.