OSDN Git Service

Split Object into Dynobj and Relobj, incorporate elfcpp swapping changes.
[pf3gnuchains/pf3gnuchains3x.git] / gold / i386.cc
1 // i386.cc -- i386 target support for gold.
2
3 #include "gold.h"
4
5 #include <cstring>
6
7 #include "elfcpp.h"
8 #include "reloc.h"
9 #include "i386.h"
10 #include "object.h"
11 #include "symtab.h"
12 #include "layout.h"
13 #include "output.h"
14 #include "target.h"
15 #include "target-reloc.h"
16 #include "target-select.h"
17
18 namespace
19 {
20
21 using namespace gold;
22
23 // The i386 target class.
24
25 class Target_i386 : public Sized_target<32, false>
26 {
27  public:
28   Target_i386()
29     : Sized_target<32, false>(&i386_info),
30       got_(NULL)
31   { }
32
33   // Scan the relocations to look for symbol adjustments.
34   void
35   scan_relocs(const General_options& options,
36               Symbol_table* symtab,
37               Layout* layout,
38               Sized_relobj<32, false>* object,
39               unsigned int sh_type,
40               const unsigned char* prelocs,
41               size_t reloc_count,
42               size_t local_symbol_count,
43               const unsigned char* plocal_symbols,
44               Symbol** global_symbols);
45
46   // Relocate a section.
47   void
48   relocate_section(const Relocate_info<32, false>*,
49                    unsigned int sh_type,
50                    const unsigned char* prelocs,
51                    size_t reloc_count,
52                    unsigned char* view,
53                    elfcpp::Elf_types<32>::Elf_Addr view_address,
54                    off_t view_size);
55
56  private:
57   // The class which scans relocations.
58   struct Scan
59   {
60     inline void
61     local(const General_options& options, Symbol_table* symtab,
62           Layout* layout, Target_i386* target,
63           Sized_relobj<32, false>* object,
64           const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
65           const elfcpp::Sym<32, false>& lsym);
66
67     inline void
68     global(const General_options& options, Symbol_table* symtab,
69            Layout* layout, Target_i386* target,
70            Sized_relobj<32, false>* object,
71            const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
72            Symbol* gsym);
73   };
74
75   // The class which implements relocation.
76   class Relocate
77   {
78    public:
79     Relocate()
80       : skip_call_tls_get_addr_(false)
81     { }
82
83     ~Relocate()
84     {
85       if (this->skip_call_tls_get_addr_)
86         {
87           // FIXME: This needs to specify the location somehow.
88           fprintf(stderr, _("%s: missing expected TLS relocation\n"),
89                   program_name);
90           gold_exit(false);
91         }
92     }
93
94     // Do a relocation.  Return false if the caller should not issue
95     // any warnings about this relocation.
96     inline bool
97     relocate(const Relocate_info<32, false>*, Target_i386*, size_t relnum,
98              const elfcpp::Rel<32, false>&,
99              unsigned int r_type, Sized_symbol<32>*,
100              elfcpp::Elf_types<32>::Elf_Addr,
101              unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
102              off_t);
103
104    private:
105     // Do a TLS relocation.
106     inline void
107     relocate_tls(const Relocate_info<32, false>*, size_t relnum,
108                  const elfcpp::Rel<32, false>&,
109                  unsigned int r_type, Sized_symbol<32>*,
110                  elfcpp::Elf_types<32>::Elf_Addr,
111                  unsigned char*, elfcpp::Elf_types<32>::Elf_Addr, off_t);
112
113     // Do a TLS Initial-Exec to Local-Exec transition.
114     static inline void
115     tls_ie_to_le(const Relocate_info<32, false>*, size_t relnum,
116                  Output_segment* tls_segment,
117                  const elfcpp::Rel<32, false>&, unsigned int r_type,
118                  elfcpp::Elf_types<32>::Elf_Addr value,
119                  unsigned char* view,
120                  off_t view_size);
121
122     // Do a TLS Global-Dynamic to Local-Exec transition.
123     inline void
124     tls_gd_to_le(const Relocate_info<32, false>*, size_t relnum,
125                  Output_segment* tls_segment,
126                  const elfcpp::Rel<32, false>&, unsigned int r_type,
127                  elfcpp::Elf_types<32>::Elf_Addr value,
128                  unsigned char* view,
129                  off_t view_size);
130
131     // Check the range for a TLS relocation.
132     static inline void
133     check_range(const Relocate_info<32, false>*, size_t relnum,
134                 const elfcpp::Rel<32, false>&, off_t, off_t);
135
136     // Check the validity of a TLS relocation.  This is like assert.
137     static inline void
138     check_tls(const Relocate_info<32, false>*, size_t relnum,
139               const elfcpp::Rel<32, false>&, bool);
140
141     // This is set if we should skip the next reloc, which should be a
142     // PLT32 reloc against ___tls_get_addr.
143     bool skip_call_tls_get_addr_;
144   };
145
146   // Adjust TLS relocation type based on the options and whether this
147   // is a local symbol.
148   static unsigned int
149   optimize_tls_reloc(const General_options*, bool is_local, int r_type);
150
151   // Get the GOT section, creating it if necessary.
152   Output_section_got<32, false>*
153   got_section(Symbol_table*, Layout*);
154
155   // Information about this specific target which we pass to the
156   // general Target structure.
157   static const Target::Target_info i386_info;
158
159   // The GOT section.
160   Output_section_got<32, false>* got_;
161 };
162
163 const Target::Target_info Target_i386::i386_info =
164 {
165   32,                   // size
166   false,                // is_big_endian
167   elfcpp::EM_386,       // machine_code
168   false,                // has_make_symbol
169   false,                // has_resolve,
170   0x08048000,           // text_segment_address,
171   0x1000,               // abi_pagesize
172   0x1000                // common_pagesize
173 };
174
175 // Get the GOT section, creating it if necessary.
176
177 Output_section_got<32, false>*
178 Target_i386::got_section(Symbol_table* symtab, Layout* layout)
179 {
180   if (this->got_ == NULL)
181     {
182       this->got_ = new Output_section_got<32, false>();
183
184       assert(symtab != NULL && layout != NULL);
185       layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS,
186                                       elfcpp::SHF_ALLOC, this->got_);
187
188       // The first three entries are reserved.
189       this->got_->add_constant(0);
190       this->got_->add_constant(0);
191       this->got_->add_constant(0);
192
193       // Define _GLOBAL_OFFSET_TABLE_ at the start of the section.
194       symtab->define_in_output_data(this, "_GLOBAL_OFFSET_TABLE_", this->got_,
195                                     0, 0, elfcpp::STT_OBJECT,
196                                     elfcpp::STB_GLOBAL,
197                                     elfcpp::STV_HIDDEN, 0,
198                                     false, false);
199     }
200   return this->got_;
201 }
202
203 // Optimize the TLS relocation type based on what we know about the
204 // symbol.  IS_LOCAL is true if this symbol can be resolved entirely
205 // locally--i.e., does not have to be in the dynamic symbol table.
206
207 unsigned int
208 Target_i386::optimize_tls_reloc(const General_options* options, bool is_local,
209                                 int r_type)
210 {
211   // If we are generating a shared library, then we can't do anything
212   // in the linker.
213   if (options->is_shared())
214     return r_type;
215
216   switch (r_type)
217     {
218     case elfcpp::R_386_TLS_GD:
219     case elfcpp::R_386_TLS_GOTDESC:
220     case elfcpp::R_386_TLS_DESC_CALL:
221       // These are Global-Dynamic which permits fully general TLS
222       // access.  Since we know that we are generating an executable,
223       // we can convert this to Initial-Exec.  If we also know that
224       // this is a local symbol, we can further switch to Local-Exec.
225       if (is_local)
226         return elfcpp::R_386_TLS_LE_32;
227       return elfcpp::R_386_TLS_IE_32;
228
229     case elfcpp::R_386_TLS_LDM:
230       // This is Local-Dynamic, which refers to a local symbol in the
231       // dynamic TLS block.  Since we know that we generating an
232       // executable, we can switch to Local-Exec.
233       return elfcpp::R_386_TLS_LE_32;
234
235     case elfcpp::R_386_TLS_LDO_32:
236       // Another type of Local-Dynamic relocation.
237       return elfcpp::R_386_TLS_LE;
238
239     case elfcpp::R_386_TLS_IE:
240     case elfcpp::R_386_TLS_GOTIE:
241     case elfcpp::R_386_TLS_IE_32:
242       // These are Initial-Exec relocs which get the thread offset
243       // from the GOT.  If we know that we are linking against the
244       // local symbol, we can switch to Local-Exec, which links the
245       // thread offset into the instruction.
246       if (is_local)
247         return elfcpp::R_386_TLS_LE_32;
248       return r_type;
249         
250     case elfcpp::R_386_TLS_LE:
251     case elfcpp::R_386_TLS_LE_32:
252       // When we already have Local-Exec, there is nothing further we
253       // can do.
254       return r_type;
255
256     default:
257       abort();
258     }
259 }
260
261 // Scan a relocation for a local symbol.
262
263 inline void
264 Target_i386::Scan::local(const General_options& options,
265                          Symbol_table* symtab,
266                          Layout* layout,
267                          Target_i386* target,
268                          Sized_relobj<32, false>* object,
269                          const elfcpp::Rel<32, false>&, unsigned int r_type,
270                          const elfcpp::Sym<32, false>&)
271 {
272   switch (r_type)
273     {
274     case elfcpp::R_386_NONE:
275     case elfcpp::R_386_GNU_VTINHERIT:
276     case elfcpp::R_386_GNU_VTENTRY:
277       break;
278
279     case elfcpp::R_386_32:
280     case elfcpp::R_386_16:
281     case elfcpp::R_386_8:
282       // FIXME: If we are generating a shared object we need to copy
283       // this relocation into the object.
284       break;
285
286     case elfcpp::R_386_PC32:
287     case elfcpp::R_386_PC16:
288     case elfcpp::R_386_PC8:
289       break;
290
291     case elfcpp::R_386_GOTOFF:
292     case elfcpp::R_386_GOTPC:
293       // We need a GOT section.
294       target->got_section(symtab, layout);
295       break;
296
297     case elfcpp::R_386_COPY:
298     case elfcpp::R_386_GLOB_DAT:
299     case elfcpp::R_386_JUMP_SLOT:
300     case elfcpp::R_386_RELATIVE:
301     case elfcpp::R_386_TLS_TPOFF:
302     case elfcpp::R_386_TLS_DTPMOD32:
303     case elfcpp::R_386_TLS_DTPOFF32:
304     case elfcpp::R_386_TLS_TPOFF32:
305     case elfcpp::R_386_TLS_DESC:
306       fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
307               program_name, object->name().c_str(), r_type);
308       gold_exit(false);
309       break;
310
311     case elfcpp::R_386_TLS_IE:
312     case elfcpp::R_386_TLS_GOTIE:
313     case elfcpp::R_386_TLS_LE:
314     case elfcpp::R_386_TLS_GD:
315     case elfcpp::R_386_TLS_LDM:
316     case elfcpp::R_386_TLS_LDO_32:
317     case elfcpp::R_386_TLS_IE_32:
318     case elfcpp::R_386_TLS_LE_32:
319     case elfcpp::R_386_TLS_GOTDESC:
320     case elfcpp::R_386_TLS_DESC_CALL:
321       r_type = Target_i386::optimize_tls_reloc(&options, true, r_type);
322       switch (r_type)
323         {
324         case elfcpp::R_386_TLS_LE:
325         case elfcpp::R_386_TLS_LE_32:
326           // FIXME: If generating a shared object, we need to copy
327           // this relocation into the object.
328           break;
329
330         case elfcpp::R_386_TLS_IE:
331         case elfcpp::R_386_TLS_GOTIE:
332         case elfcpp::R_386_TLS_GD:
333         case elfcpp::R_386_TLS_LDM:
334         case elfcpp::R_386_TLS_LDO_32:
335         case elfcpp::R_386_TLS_IE_32:
336         case elfcpp::R_386_TLS_GOTDESC:
337         case elfcpp::R_386_TLS_DESC_CALL:
338           fprintf(stderr,
339                   _("%s: %s: unsupported reloc %u against local symbol\n"),
340                   program_name, object->name().c_str(), r_type);
341           break;
342         }
343       break;
344
345     case elfcpp::R_386_GOT32:
346     case elfcpp::R_386_PLT32:
347     case elfcpp::R_386_32PLT:
348     case elfcpp::R_386_TLS_GD_32:
349     case elfcpp::R_386_TLS_GD_PUSH:
350     case elfcpp::R_386_TLS_GD_CALL:
351     case elfcpp::R_386_TLS_GD_POP:
352     case elfcpp::R_386_TLS_LDM_32:
353     case elfcpp::R_386_TLS_LDM_PUSH:
354     case elfcpp::R_386_TLS_LDM_CALL:
355     case elfcpp::R_386_TLS_LDM_POP:
356     case elfcpp::R_386_USED_BY_INTEL_200:
357     default:
358       fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"),
359               program_name, object->name().c_str(), r_type);
360       break;
361     }
362 }
363
364 // Scan a relocation for a global symbol.
365
366 inline void
367 Target_i386::Scan::global(const General_options& options,
368                           Symbol_table* symtab,
369                           Layout* layout,
370                           Target_i386* target,
371                           Sized_relobj<32, false>* object,
372                           const elfcpp::Rel<32, false>&, unsigned int r_type,
373                           Symbol* gsym)
374 {
375   switch (r_type)
376     {
377     case elfcpp::R_386_NONE:
378     case elfcpp::R_386_GNU_VTINHERIT:
379     case elfcpp::R_386_GNU_VTENTRY: 
380       break;
381
382     case elfcpp::R_386_32:
383     case elfcpp::R_386_PC32:
384     case elfcpp::R_386_16:
385     case elfcpp::R_386_PC16:
386     case elfcpp::R_386_8:
387     case elfcpp::R_386_PC8:
388       // FIXME: If we are generating a shared object we may need to
389       // copy this relocation into the object.  If this symbol is
390       // defined in a shared object, we may need to copy this
391       // relocation in order to avoid a COPY relocation.
392       break;
393
394     case elfcpp::R_386_GOT32:
395       // The symbol requires a GOT entry.
396       if (!gsym->has_got_offset())
397         {
398           Output_section_got<32, false>* got = target->got_section(symtab,
399                                                                    layout);
400           const unsigned int got_offset = got->add_global(gsym);
401           gsym->set_got_offset(got_offset);
402
403           // If this symbol is not resolved locally, we need to add a
404           // dynamic relocation for it.
405           if (!gsym->is_resolved_locally())
406             abort();
407         }
408       break;
409
410     case elfcpp::R_386_PLT32:
411       // If the symbol is resolved locally, this is just a PC32 reloc.
412       if (gsym->is_resolved_locally())
413         break;
414       fprintf(stderr,
415               _("%s: %s: unsupported reloc %u against global symbol %s\n"),
416               program_name, object->name().c_str(), r_type, gsym->name());
417       break;
418
419     case elfcpp::R_386_GOTOFF:
420     case elfcpp::R_386_GOTPC:
421       // We need a GOT section.
422       target->got_section(symtab, layout);
423       break;
424
425     case elfcpp::R_386_COPY:
426     case elfcpp::R_386_GLOB_DAT:
427     case elfcpp::R_386_JUMP_SLOT:
428     case elfcpp::R_386_RELATIVE:
429     case elfcpp::R_386_TLS_TPOFF:
430     case elfcpp::R_386_TLS_DTPMOD32:
431     case elfcpp::R_386_TLS_DTPOFF32:
432     case elfcpp::R_386_TLS_TPOFF32:
433     case elfcpp::R_386_TLS_DESC:
434       fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
435               program_name, object->name().c_str(), r_type);
436       gold_exit(false);
437       break;
438
439     case elfcpp::R_386_TLS_IE:
440     case elfcpp::R_386_TLS_GOTIE:
441     case elfcpp::R_386_TLS_LE:
442     case elfcpp::R_386_TLS_GD:
443     case elfcpp::R_386_TLS_LDM:
444     case elfcpp::R_386_TLS_LDO_32:
445     case elfcpp::R_386_TLS_IE_32:
446     case elfcpp::R_386_TLS_LE_32:
447     case elfcpp::R_386_TLS_GOTDESC:
448     case elfcpp::R_386_TLS_DESC_CALL:
449       r_type = Target_i386::optimize_tls_reloc(&options,
450                                                gsym->is_resolved_locally(),
451                                                r_type);
452       switch (r_type)
453         {
454         case elfcpp::R_386_TLS_LE:
455         case elfcpp::R_386_TLS_LE_32:
456           // FIXME: If generating a shared object, we need to copy
457           // this relocation into the object.
458           break;
459
460         case elfcpp::R_386_TLS_IE:
461         case elfcpp::R_386_TLS_GOTIE:
462         case elfcpp::R_386_TLS_GD:
463         case elfcpp::R_386_TLS_LDM:
464         case elfcpp::R_386_TLS_LDO_32:
465         case elfcpp::R_386_TLS_IE_32:
466         case elfcpp::R_386_TLS_GOTDESC:
467         case elfcpp::R_386_TLS_DESC_CALL:
468           fprintf(stderr,
469                   _("%s: %s: unsupported reloc %u against global symbol %s\n"),
470                   program_name, object->name().c_str(), r_type, gsym->name());
471           break;
472         }
473       break;
474
475     case elfcpp::R_386_32PLT:
476     case elfcpp::R_386_TLS_GD_32:
477     case elfcpp::R_386_TLS_GD_PUSH:
478     case elfcpp::R_386_TLS_GD_CALL:
479     case elfcpp::R_386_TLS_GD_POP:
480     case elfcpp::R_386_TLS_LDM_32:
481     case elfcpp::R_386_TLS_LDM_PUSH:
482     case elfcpp::R_386_TLS_LDM_CALL:
483     case elfcpp::R_386_TLS_LDM_POP:
484     case elfcpp::R_386_USED_BY_INTEL_200:
485     default:
486       fprintf(stderr,
487               _("%s: %s: unsupported reloc %u against global symbol %s\n"),
488               program_name, object->name().c_str(), r_type, gsym->name());
489       break;
490     }
491 }
492
493 // Scan relocations for a section.
494
495 void
496 Target_i386::scan_relocs(const General_options& options,
497                          Symbol_table* symtab,
498                          Layout* layout,
499                          Sized_relobj<32, false>* object,
500                          unsigned int sh_type,
501                          const unsigned char* prelocs,
502                          size_t reloc_count,
503                          size_t local_symbol_count,
504                          const unsigned char* plocal_symbols,
505                          Symbol** global_symbols)
506 {
507   if (sh_type == elfcpp::SHT_RELA)
508     {
509       fprintf(stderr, _("%s: %s: unsupported RELA reloc section\n"),
510               program_name, object->name().c_str());
511       gold_exit(false);
512     }
513
514   gold::scan_relocs<32, false, Target_i386, elfcpp::SHT_REL,
515                     Target_i386::Scan>(
516     options,
517     symtab,
518     layout,
519     this,
520     object,
521     prelocs,
522     reloc_count,
523     local_symbol_count,
524     plocal_symbols,
525     global_symbols);
526 }
527
528 // Perform a relocation.
529
530 inline bool
531 Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
532                                 Target_i386* target,
533                                 size_t relnum,
534                                 const elfcpp::Rel<32, false>& rel,
535                                 unsigned int r_type,
536                                 Sized_symbol<32>* gsym,
537                                 elfcpp::Elf_types<32>::Elf_Addr value,
538                                 unsigned char* view,
539                                 elfcpp::Elf_types<32>::Elf_Addr address,
540                                 off_t view_size)
541 {
542   if (this->skip_call_tls_get_addr_)
543     {
544       if (r_type != elfcpp::R_386_PLT32
545           || gsym == NULL
546           || strcmp(gsym->name(), "___tls_get_addr") != 0)
547         {
548           fprintf(stderr, _("%s: %s: missing expected TLS relocation\n"),
549                   program_name,
550                   relinfo->location(relnum, rel.get_r_offset()).c_str());
551           gold_exit(false);
552         }
553
554       this->skip_call_tls_get_addr_ = false;
555
556       return false;
557     }
558
559   switch (r_type)
560     {
561     case elfcpp::R_386_NONE:
562     case elfcpp::R_386_GNU_VTINHERIT:
563     case elfcpp::R_386_GNU_VTENTRY:
564       break;
565
566     case elfcpp::R_386_32:
567       Relocate_functions<32, false>::rel32(view, value);
568       break;
569
570     case elfcpp::R_386_PC32:
571       Relocate_functions<32, false>::pcrel32(view, value, address);
572       break;
573
574     case elfcpp::R_386_16:
575       Relocate_functions<32, false>::rel16(view, value);
576       break;
577
578     case elfcpp::R_386_PC16:
579       Relocate_functions<32, false>::pcrel16(view, value, address);
580       break;
581
582     case elfcpp::R_386_8:
583       Relocate_functions<32, false>::rel8(view, value);
584       break;
585
586     case elfcpp::R_386_PC8:
587       Relocate_functions<32, false>::pcrel8(view, value, address);
588       break;
589
590     case elfcpp::R_386_PLT32:
591       if (gsym->is_resolved_locally())
592         Relocate_functions<32, false>::pcrel32(view, value, address);
593       else
594         fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
595                 program_name,
596                 relinfo->location(relnum, rel.get_r_offset()).c_str(),
597                 r_type);
598       break;
599
600     case elfcpp::R_386_GOT32:
601       // Local GOT offsets not yet supported.
602       assert(gsym);
603       assert(gsym->has_got_offset());
604       value = gsym->got_offset();
605       Relocate_functions<32, false>::rel32(view, value);
606       break;
607
608     case elfcpp::R_386_GOTOFF:
609       value -= target->got_section(NULL, NULL)->address();
610       Relocate_functions<32, false>::rel32(view, value);
611       break;
612
613     case elfcpp::R_386_GOTPC:
614       value = target->got_section(NULL, NULL)->address();
615       Relocate_functions<32, false>::pcrel32(view, value, address);
616       break;
617
618     case elfcpp::R_386_COPY:
619     case elfcpp::R_386_GLOB_DAT:
620     case elfcpp::R_386_JUMP_SLOT:
621     case elfcpp::R_386_RELATIVE:
622     case elfcpp::R_386_TLS_TPOFF:
623     case elfcpp::R_386_TLS_DTPMOD32:
624     case elfcpp::R_386_TLS_DTPOFF32:
625     case elfcpp::R_386_TLS_TPOFF32:
626     case elfcpp::R_386_TLS_DESC:
627       fprintf(stderr, _("%s: %s: unexpected reloc %u in object file\n"),
628               program_name,
629               relinfo->location(relnum, rel.get_r_offset()).c_str(),
630               r_type);
631       gold_exit(false);
632       break;
633
634     case elfcpp::R_386_TLS_IE:
635     case elfcpp::R_386_TLS_GOTIE:
636     case elfcpp::R_386_TLS_LE:
637     case elfcpp::R_386_TLS_GD:
638     case elfcpp::R_386_TLS_LDM:
639     case elfcpp::R_386_TLS_LDO_32:
640     case elfcpp::R_386_TLS_IE_32:
641     case elfcpp::R_386_TLS_LE_32:
642     case elfcpp::R_386_TLS_GOTDESC:
643     case elfcpp::R_386_TLS_DESC_CALL:
644       this->relocate_tls(relinfo, relnum, rel, r_type, gsym, value, view,
645                          address, view_size);
646       break;
647
648     case elfcpp::R_386_32PLT:
649     case elfcpp::R_386_TLS_GD_32:
650     case elfcpp::R_386_TLS_GD_PUSH:
651     case elfcpp::R_386_TLS_GD_CALL:
652     case elfcpp::R_386_TLS_GD_POP:
653     case elfcpp::R_386_TLS_LDM_32:
654     case elfcpp::R_386_TLS_LDM_PUSH:
655     case elfcpp::R_386_TLS_LDM_CALL:
656     case elfcpp::R_386_TLS_LDM_POP:
657     case elfcpp::R_386_USED_BY_INTEL_200:
658     default:
659       fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
660               program_name,
661               relinfo->location(relnum, rel.get_r_offset()).c_str(),
662               r_type);
663       // gold_exit(false);
664       break;
665     }
666
667   return true;
668 }
669
670 // Perform a TLS relocation.
671
672 inline void
673 Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
674                                     size_t relnum,
675                                     const elfcpp::Rel<32, false>& rel,
676                                     unsigned int r_type,
677                                     Sized_symbol<32>* gsym,
678                                     elfcpp::Elf_types<32>::Elf_Addr value,
679                                     unsigned char* view,
680                                     elfcpp::Elf_types<32>::Elf_Addr,
681                                     off_t view_size)
682 {
683   Output_segment* tls_segment = relinfo->layout->tls_segment();
684   if (tls_segment == NULL)
685     {
686       fprintf(stderr, _("%s: %s: TLS reloc but no TLS segment\n"),
687               program_name,
688               relinfo->location(relnum, rel.get_r_offset()).c_str());
689       gold_exit(false);
690     }
691
692   const bool is_local = gsym == NULL || gsym->is_resolved_locally();
693   const unsigned int opt_r_type =
694     Target_i386::optimize_tls_reloc(relinfo->options, is_local, r_type);
695   switch (r_type)
696     {
697     case elfcpp::R_386_TLS_LE_32:
698       value = tls_segment->vaddr() + tls_segment->memsz() - value;
699       Relocate_functions<32, false>::rel32(view, value);
700       break;
701
702     case elfcpp::R_386_TLS_LE:
703       value = value - (tls_segment->vaddr() + tls_segment->memsz());
704       Relocate_functions<32, false>::rel32(view, value);
705       break;
706
707     case elfcpp::R_386_TLS_IE:
708     case elfcpp::R_386_TLS_GOTIE:
709     case elfcpp::R_386_TLS_IE_32:
710       if (opt_r_type == elfcpp::R_386_TLS_LE_32)
711         {
712           Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
713                                               rel, r_type, value, view,
714                                               view_size);
715           break;
716         }
717       fprintf(stderr, _("%s: %s: unsupported reloc type %u\n"),
718               program_name,
719               relinfo->location(relnum, rel.get_r_offset()).c_str(),
720               r_type);
721       // gold_exit(false);
722       break;
723
724     case elfcpp::R_386_TLS_GD:
725       if (opt_r_type == elfcpp::R_386_TLS_LE_32)
726         {
727           this->tls_gd_to_le(relinfo, relnum, tls_segment,
728                              rel, r_type, value, view,
729                              view_size);
730           break;
731         }
732       fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
733               program_name,
734               relinfo->location(relnum, rel.get_r_offset()).c_str(),
735               r_type);
736       // gold_exit(false);
737       break;
738
739     case elfcpp::R_386_TLS_LDM:
740     case elfcpp::R_386_TLS_LDO_32:
741     case elfcpp::R_386_TLS_GOTDESC:
742     case elfcpp::R_386_TLS_DESC_CALL:
743       fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
744               program_name,
745               relinfo->location(relnum, rel.get_r_offset()).c_str(),
746               r_type);
747       // gold_exit(false);
748       break;
749     }
750 }
751
752 // Do a relocation in which we convert a TLS Initial-Exec to a
753 // Local-Exec.
754
755 inline void
756 Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo,
757                                     size_t relnum,
758                                     Output_segment* tls_segment,
759                                     const elfcpp::Rel<32, false>& rel,
760                                     unsigned int r_type,
761                                     elfcpp::Elf_types<32>::Elf_Addr value,
762                                     unsigned char* view,
763                                     off_t view_size)
764 {
765   // We have to actually change the instructions, which means that we
766   // need to examine the opcodes to figure out which instruction we
767   // are looking at.
768   if (r_type == elfcpp::R_386_TLS_IE)
769     {
770       // movl %gs:XX,%eax  ==>  movl $YY,%eax
771       // movl %gs:XX,%reg  ==>  movl $YY,%reg
772       // addl %gs:XX,%reg  ==>  addl $YY,%reg
773       Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -1);
774       Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, 4);
775
776       unsigned char op1 = view[-1];
777       if (op1 == 0xa1)
778         {
779           // movl XX,%eax  ==>  movl $YY,%eax
780           view[-1] = 0xb8;
781         }
782       else
783         {
784           Target_i386::Relocate::check_range(relinfo, relnum, rel,
785                                              view_size, -2);
786
787           unsigned char op2 = view[-2];
788           if (op2 == 0x8b)
789             {
790               // movl XX,%reg  ==>  movl $YY,%reg
791               Target_i386::Relocate::check_tls(relinfo, relnum, rel,
792                                                (op1 & 0xc7) == 0x05);
793               view[-2] = 0xc7;
794               view[-1] = 0xc0 | ((op1 >> 3) & 7);
795             }
796           else if (op2 == 0x03)
797             {
798               // addl XX,%reg  ==>  addl $YY,%reg
799               Target_i386::Relocate::check_tls(relinfo, relnum, rel,
800                                                (op1 & 0xc7) == 0x05);
801               view[-2] = 0x81;
802               view[-1] = 0xc0 | ((op1 >> 3) & 7);
803             }
804           else
805             Target_i386::Relocate::check_tls(relinfo, relnum, rel, 0);
806         }
807     }
808   else
809     {
810       // subl %gs:XX(%reg1),%reg2  ==>  subl $YY,%reg2
811       // movl %gs:XX(%reg1),%reg2  ==>  movl $YY,%reg2
812       // addl %gs:XX(%reg1),%reg2  ==>  addl $YY,$reg2
813       Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -2);
814       Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, 4);
815
816       unsigned char op1 = view[-1];
817       unsigned char op2 = view[-2];
818       Target_i386::Relocate::check_tls(relinfo, relnum, rel,
819                                        (op1 & 0xc0) == 0x80 && (op1 & 7) != 4);
820       if (op2 == 0x8b)
821         {
822           // movl %gs:XX(%reg1),%reg2  ==>  movl $YY,%reg2
823           view[-2] = 0xc7;
824           view[-1] = 0xc0 | ((op1 >> 3) & 7);
825         }
826       else if (op2 == 0x2b)
827         {
828           // subl %gs:XX(%reg1),%reg2  ==>  subl $YY,%reg2
829           view[-2] = 0x81;
830           view[-1] = 0xe8 | ((op1 >> 3) & 7);
831         }
832       else if (op2 == 0x03)
833         {
834           // addl %gs:XX(%reg1),%reg2  ==>  addl $YY,$reg2
835           view[-2] = 0x81;
836           view[-1] = 0xc0 | ((op1 >> 3) & 7);
837         }
838       else
839         Target_i386::Relocate::check_tls(relinfo, relnum, rel, 0);
840     }
841
842   value = tls_segment->vaddr() + tls_segment->memsz() - value;
843   if (r_type == elfcpp::R_386_TLS_IE || r_type == elfcpp::R_386_TLS_GOTIE)
844     value = - value;
845
846   Relocate_functions<32, false>::rel32(view, value);
847 }
848
849 // Do a relocation in which we convert a TLS Global-Dynamic to a
850 // Local-Exec.
851
852 inline void
853 Target_i386::Relocate::tls_gd_to_le(const Relocate_info<32, false>* relinfo,
854                                     size_t relnum,
855                                     Output_segment* tls_segment,
856                                     const elfcpp::Rel<32, false>& rel,
857                                     unsigned int,
858                                     elfcpp::Elf_types<32>::Elf_Addr value,
859                                     unsigned char* view,
860                                     off_t view_size)
861 {
862   // leal foo(,%reg,1),%eax; call ___tls_get_addr
863   //  ==> movl %gs,0,%eax; subl $foo@tpoff,%eax
864   // leal foo(%reg),%eax; call ___tls_get_addr
865   //  ==> movl %gs:0,%eax; subl $foo@tpoff,%eax
866
867   Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -2);
868   Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, 9);
869
870   unsigned char op1 = view[-1];
871   unsigned char op2 = view[-2];
872
873   Target_i386::Relocate::check_tls(relinfo, relnum, rel,
874                                    op2 == 0x8d || op2 == 0x04);
875   Target_i386::Relocate::check_tls(relinfo, relnum, rel,
876                                    view[4] == 0xe8);
877
878   int roff = 5;
879
880   if (op2 == 0x04)
881     {
882       Target_i386::Relocate::check_range(relinfo, relnum, rel, view_size, -3);
883       Target_i386::Relocate::check_tls(relinfo, relnum, rel,
884                                        view[-3] == 0x8d);
885       Target_i386::Relocate::check_tls(relinfo, relnum, rel,
886                                        ((op1 & 0xc7) == 0x05
887                                         && op1 != (4 << 3)));
888       memcpy(view - 3, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
889     }
890   else
891     {
892       Target_i386::Relocate::check_tls(relinfo, relnum, rel,
893                                        (op1 & 0xf8) == 0x80 && (op1 & 7) != 4);
894       if (rel.get_r_offset() + 9 < view_size && view[9] == 0x90)
895         {
896           // There is a trailing nop.  Use the size byte subl.
897           memcpy(view - 2, "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
898           roff = 6;
899         }
900       else
901         {
902           // Use the five byte subl.
903           memcpy(view - 2, "\x65\xa1\0\0\0\0\x2d\0\0\0", 11);
904         }
905     }
906
907   value = tls_segment->vaddr() + tls_segment->memsz() - value;
908   Relocate_functions<32, false>::rel32(view + roff, value);
909
910   // The next reloc should be a PLT32 reloc against __tls_get_addr.
911   // We can skip it.
912   this->skip_call_tls_get_addr_ = true;
913 }
914
915 // Check the range for a TLS relocation.
916
917 inline void
918 Target_i386::Relocate::check_range(const Relocate_info<32, false>* relinfo,
919                                    size_t relnum,
920                                    const elfcpp::Rel<32, false>& rel,
921                                    off_t view_size, off_t off)
922 {
923   off_t offset = rel.get_r_offset() + off;
924   if (offset < 0 || offset > view_size)
925     {
926       fprintf(stderr, _("%s: %s: TLS relocation out of range\n"),
927               program_name,
928               relinfo->location(relnum, rel.get_r_offset()).c_str());
929       gold_exit(false);
930     }
931 }
932
933 // Check the validity of a TLS relocation.  This is like assert.
934
935 inline void
936 Target_i386::Relocate::check_tls(const Relocate_info<32, false>* relinfo,
937                                  size_t relnum,
938                                  const elfcpp::Rel<32, false>& rel,
939                                  bool valid)
940 {
941   if (!valid)
942     {
943       fprintf(stderr,
944               _("%s: %s: TLS relocation against invalid instruction\n"),
945               program_name,
946               relinfo->location(relnum, rel.get_r_offset()).c_str());
947       gold_exit(false);
948     }
949 }
950
951 // Relocate section data.
952
953 void
954 Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
955                               unsigned int sh_type,
956                               const unsigned char* prelocs,
957                               size_t reloc_count,
958                               unsigned char* view,
959                               elfcpp::Elf_types<32>::Elf_Addr address,
960                               off_t view_size)
961 {
962   assert(sh_type == elfcpp::SHT_REL);
963
964   gold::relocate_section<32, false, Target_i386, elfcpp::SHT_REL,
965                          Target_i386::Relocate>(
966     relinfo,
967     this,
968     prelocs,
969     reloc_count,
970     view,
971     address,
972     view_size);
973 }
974
975 // The selector for i386 object files.
976
977 class Target_selector_i386 : public Target_selector
978 {
979 public:
980   Target_selector_i386()
981     : Target_selector(elfcpp::EM_386, 32, false)
982   { }
983
984   Target*
985   recognize(int machine, int osabi, int abiversion);
986
987  private:
988   Target_i386* target_;
989 };
990
991 // Recognize an i386 object file when we already know that the machine
992 // number is EM_386.
993
994 Target*
995 Target_selector_i386::recognize(int, int, int)
996 {
997   if (this->target_ == NULL)
998     this->target_ = new Target_i386();
999   return this->target_;
1000 }
1001
1002 Target_selector_i386 target_selector_i386;
1003
1004 } // End anonymous namespace.