Framework for relocation scanning. Implement simple static TLS
[platform/upstream/binutils.git] / gold / i386.cc
1 // i386.cc -- i386 target support for gold.
2
3 #include "gold.h"
4 #include "elfcpp.h"
5 #include "reloc.h"
6 #include "i386.h"
7 #include "object.h"
8 #include "layout.h"
9 #include "output.h"
10 #include "target.h"
11 #include "target-reloc.h"
12 #include "target-select.h"
13
14 namespace
15 {
16
17 using namespace gold;
18
19 // The i386 target class.
20
21 class Target_i386 : public Sized_target<32, false>
22 {
23  public:
24   Target_i386()
25     : Sized_target<32, false>(&i386_info)
26   { }
27
28   // Scan the relocations to look for symbol adjustments.
29   void
30   scan_relocs(const General_options& options,
31               Symbol_table* symtab,
32               Sized_object<32, false>* object,
33               unsigned int sh_type,
34               const unsigned char* prelocs,
35               size_t reloc_count,
36               size_t local_symbol_count,
37               const unsigned char* plocal_symbols,
38               Symbol** global_symbols);
39
40   // Relocate a section.
41   void
42   relocate_section(const Relocate_info<32, false>*,
43                    unsigned int sh_type,
44                    const unsigned char* prelocs,
45                    size_t reloc_count,
46                    unsigned char* view,
47                    elfcpp::Elf_types<32>::Elf_Addr view_address,
48                    off_t view_size);
49
50  private:
51   // The class which scans relocations.
52   struct Scan
53   {
54     inline void
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);
58
59     inline void
60     global(const General_options& options, Sized_object<32, false>* object,
61            const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
62            Symbol* gsym);
63   };
64
65   // The class which implements relocation.
66   class Relocate
67   {
68    public:
69     // Do a relocation.
70     static inline void
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,
76              off_t);
77
78    private:
79     // Do a TLS relocation.
80     static inline void
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);
86
87     // Do a TLS Initial-Exec to Local-Exec transition.
88     static inline void
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,
93                  unsigned char* view,
94                  off_t view_size);
95
96     // Check the range for a TLS relocation.
97     static inline void
98     check_range(const Relocate_info<32, false>*, size_t relnum,
99                 const elfcpp::Rel<32, false>&, off_t, off_t);
100
101     // Check the validity of a TLS relocation.  This is like assert.
102     static inline void
103     check_tls(const Relocate_info<32, false>*, size_t relnum,
104               const elfcpp::Rel<32, false>&, bool);
105   };
106
107   // Adjust TLS relocation type based on the options and whether this
108   // is a local symbol.
109   static unsigned int
110   optimize_tls_reloc(const General_options*, bool is_local, int r_type);
111
112   // Information about this specific target which we pass to the
113   // general Target structure.
114   static const Target::Target_info i386_info;
115 };
116
117 const Target::Target_info Target_i386::i386_info =
118 {
119   32,                   // size
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
127 };
128
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.
132
133 unsigned int
134 Target_i386::optimize_tls_reloc(const General_options* options, bool is_local,
135                                 int r_type)
136 {
137   // If we are generating a shared library, then we can't do anything
138   // in the linker.
139   if (options->is_shared())
140     return r_type;
141
142   switch (r_type)
143     {
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.
151       if (is_local)
152         return elfcpp::R_386_TLS_LE_32;
153       return elfcpp::R_386_TLS_IE_32;
154
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;
160
161     case elfcpp::R_386_TLS_LDO_32:
162       // Another type of Local-Dynamic relocation.
163       return elfcpp::R_386_TLS_LE;
164
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.
172       if (is_local)
173         return elfcpp::R_386_TLS_LE_32;
174       return r_type;
175         
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
179       // can do.
180       return r_type;
181
182     default:
183       abort();
184     }
185 }
186
187 // Scan a relocation for a local symbol.
188
189 inline void
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>&)
194 {
195   switch (r_type)
196     {
197     case elfcpp::R_386_NONE:
198     case elfcpp::R_386_GNU_VTINHERIT:
199     case elfcpp::R_386_GNU_VTENTRY:
200       break;
201
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.
207       break;
208
209     case elfcpp::R_386_PC32:
210     case elfcpp::R_386_PC16:
211     case elfcpp::R_386_PC8:
212       break;
213
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);
225       gold_exit(false);
226       break;
227
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);
239       switch (r_type)
240         {
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.
245           break;
246
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:
255           fprintf(stderr,
256                   _("%s: %s: unsupported reloc %u against local symbol\n"),
257                   program_name, object->name().c_str(), r_type);
258           break;
259         }
260       break;
261
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:
276     default:
277       fprintf(stderr, _("%s: %s: unsupported reloc %u against local symbol\n"),
278               program_name, object->name().c_str(), r_type);
279       break;
280     }
281 }
282
283 // Scan a relocation for a global symbol.
284
285 inline void
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,
289                           Symbol* gsym)
290 {
291   switch (r_type)
292     {
293     case elfcpp::R_386_NONE:
294     case elfcpp::R_386_GNU_VTINHERIT:
295     case elfcpp::R_386_GNU_VTENTRY: 
296       break;
297
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.
308       break;
309
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);
321       gold_exit(false);
322       break;
323
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,
335                                                !gsym->in_dynsym(),
336                                                r_type);
337       switch (r_type)
338         {
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.
343           break;
344
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:
353           fprintf(stderr,
354                   _("%s: %s: unsupported reloc %u against global symbol %s\n"),
355                   program_name, object->name().c_str(), r_type, gsym->name());
356           break;
357         }
358       break;
359
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:
374     default:
375       fprintf(stderr,
376               _("%s: %s: unsupported reloc %u against global symbol %s\n"),
377               program_name, object->name().c_str(), r_type, gsym->name());
378       break;
379     }
380 }
381
382 // Scan relocations for a section.
383
384 void
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,
390                          size_t reloc_count,
391                          size_t local_symbol_count,
392                          const unsigned char* plocal_symbols,
393                          Symbol** global_symbols)
394 {
395   if (sh_type == elfcpp::SHT_RELA)
396     {
397       fprintf(stderr, _("%s: %s: unsupported RELA reloc section\n"),
398               program_name, object->name().c_str());
399       gold_exit(false);
400     }
401
402   gold::scan_relocs<32, false, elfcpp::SHT_REL, Target_i386::Scan>(
403     options,
404     symtab,
405     object,
406     prelocs,
407     reloc_count,
408     local_symbol_count,
409     plocal_symbols,
410     global_symbols);
411 }
412
413 // Perform a relocation.
414
415 inline void
416 Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
417                                 size_t relnum,
418                                 const elfcpp::Rel<32, false>& rel,
419                                 unsigned int r_type,
420                                 Sized_symbol<32>* gsym,
421                                 elfcpp::Elf_types<32>::Elf_Addr value,
422                                 unsigned char* view,
423                                 elfcpp::Elf_types<32>::Elf_Addr address,
424                                 off_t view_size)
425 {
426   switch (r_type)
427     {
428     case elfcpp::R_386_NONE:
429     case elfcpp::R_386_GNU_VTINHERIT:
430     case elfcpp::R_386_GNU_VTENTRY:
431       break;
432
433     case elfcpp::R_386_32:
434       Relocate_functions<32, false>::rel32(view, value);
435       break;
436
437     case elfcpp::R_386_PC32:
438       Relocate_functions<32, false>::pcrel32(view, value, address);
439       break;
440
441     case elfcpp::R_386_16:
442       Relocate_functions<32, false>::rel16(view, value);
443       break;
444
445     case elfcpp::R_386_PC16:
446       Relocate_functions<32, false>::pcrel16(view, value, address);
447       break;
448
449     case elfcpp::R_386_8:
450       Relocate_functions<32, false>::rel8(view, value);
451       break;
452
453     case elfcpp::R_386_PC8:
454       Relocate_functions<32, false>::pcrel8(view, value, address);
455       break;
456
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"),
467               program_name,
468               relinfo->location(relnum, rel.get_r_offset()).c_str(),
469               r_type);
470       gold_exit(false);
471       break;
472
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,
485                                           view_size);
486       break;
487
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:
502     default:
503       fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
504               program_name,
505               relinfo->location(relnum, rel.get_r_offset()).c_str(),
506               r_type);
507       // gold_exit(false);
508       break;
509     }
510 }
511
512 // Perform a TLS relocation.
513
514 inline void
515 Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
516                                     size_t relnum,
517                                     const elfcpp::Rel<32, false>& rel,
518                                     unsigned int r_type,
519                                     Sized_symbol<32>* gsym,
520                                     elfcpp::Elf_types<32>::Elf_Addr value,
521                                     unsigned char* view,
522                                     elfcpp::Elf_types<32>::Elf_Addr,
523                                     off_t view_size)
524 {
525   Output_segment* tls_segment = relinfo->layout->tls_segment();
526   if (tls_segment == NULL)
527     {
528       fprintf(stderr, _("%s: %s: TLS reloc but no TLS segment\n"),
529               program_name,
530               relinfo->location(relnum, rel.get_r_offset()).c_str());
531       gold_exit(false);
532     }
533
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);
537   switch (r_type)
538     {
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);
542       break;
543
544     case elfcpp::R_386_TLS_LE:
545       value = value - (tls_segment->vaddr() + tls_segment->memsz());
546       Relocate_functions<32, false>::rel32(view, value);
547       break;
548
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)
553         {
554           Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
555                                               rel, r_type, value, view,
556                                               view_size);
557           break;
558         }
559       fprintf(stderr, _("%s: %s: unsupported reloc type %u\n"),
560               program_name,
561               relinfo->location(relnum, rel.get_r_offset()).c_str(),
562               r_type);
563       // gold_exit(false);
564       break;
565
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"),
572               program_name,
573               relinfo->location(relnum, rel.get_r_offset()).c_str(),
574               r_type);
575       // gold_exit(false);
576       break;
577     }
578 }
579
580 // Do a relocation in which we convert a TLS Initial-Exec to a
581 // Local-Exec.
582
583 inline void
584 Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo,
585                                     size_t relnum,
586                                     Output_segment* tls_segment,
587                                     const elfcpp::Rel<32, false>& rel,
588                                     unsigned int r_type,
589                                     elfcpp::Elf_types<32>::Elf_Addr value,
590                                     unsigned char* view,
591                                     off_t view_size)
592 {
593   // We have to actually change the instructions, which means that we
594   // need to examine the opcodes to figure out which instruction we
595   // are looking at.
596   if (r_type == elfcpp::R_386_TLS_IE)
597     {
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);
603
604       unsigned char op1 = view[-1];
605       if (op1 == 0xa1)
606         {
607           // movl XX,%eax  ==>  movl $YY,%eax
608           view[-1] = 0xb8;
609         }
610       else
611         {
612           Target_i386::Relocate::check_range(relinfo, relnum, rel,
613                                              view_size, -2);
614
615           unsigned char op2 = view[-2];
616           if (op2 == 0x8b)
617             {
618               // movl XX,%reg  ==>  movl $YY,%reg
619               Target_i386::Relocate::check_tls(relinfo, relnum, rel,
620                                                (op1 & 0xc7) == 0x05);
621               view[-2] = 0xc7;
622               view[-1] = 0xc0 | ((op1 >> 3) & 7);
623             }
624           else if (op2 == 0x03)
625             {
626               // addl XX,%reg  ==>  addl $YY,%reg
627               Target_i386::Relocate::check_tls(relinfo, relnum, rel,
628                                                (op1 & 0xc7) == 0x05);
629               view[-2] = 0x81;
630               view[-1] = 0xc0 | ((op1 >> 3) & 7);
631             }
632           else
633             Target_i386::Relocate::check_tls(relinfo, relnum, rel, 0);
634         }
635     }
636   else
637     {
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);
643
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);
648       if (op2 == 0x8b)
649         {
650           // movl %gs:XX(%reg1),%reg2  ==>  movl $YY,%reg2
651           view[-2] = 0xc7;
652           view[-1] = 0xc0 | ((op1 >> 3) & 7);
653         }
654       else if (op2 == 0x2b)
655         {
656           // subl %gs:XX(%reg1),%reg2  ==>  subl $YY,%reg2
657           view[-2] = 0x81;
658           view[-1] = 0xe8 | ((op1 >> 3) & 7);
659         }
660       else if (op2 == 0x03)
661         {
662           // addl %gs:XX(%reg1),%reg2  ==>  addl $YY,$reg2
663           view[-2] = 0x81;
664           view[-1] = 0xc0 | ((op1 >> 3) & 7);
665         }
666       else
667         Target_i386::Relocate::check_tls(relinfo, relnum, rel, 0);
668     }
669
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());
674
675   Relocate_functions<32, false>::rel32(view, value);
676 }
677
678 // Check the range for a TLS relocation.
679
680 inline void
681 Target_i386::Relocate::check_range(const Relocate_info<32, false>* relinfo,
682                                    size_t relnum,
683                                    const elfcpp::Rel<32, false>& rel,
684                                    off_t view_size, off_t off)
685 {
686   off_t offset = rel.get_r_offset() + off;
687   if (offset < 0 || offset > view_size)
688     {
689       fprintf(stderr, _("%s: %s: TLS relocation out of range\n"),
690               program_name,
691               relinfo->location(relnum, rel.get_r_offset()).c_str());
692       gold_exit(false);
693     }
694 }
695
696 // Check the validity of a TLS relocation.  This is like assert.
697
698 inline void
699 Target_i386::Relocate::check_tls(const Relocate_info<32, false>* relinfo,
700                                  size_t relnum,
701                                  const elfcpp::Rel<32, false>& rel,
702                                  bool valid)
703 {
704   if (!valid)
705     {
706       fprintf(stderr,
707               _("%s: %s: TLS relocation against invalid instruction\n"),
708               program_name,
709               relinfo->location(relnum, rel.get_r_offset()).c_str());
710       gold_exit(false);
711     }
712 }
713
714 // Relocate section data.
715
716 void
717 Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
718                               unsigned int sh_type,
719                               const unsigned char* prelocs,
720                               size_t reloc_count,
721                               unsigned char* view,
722                               elfcpp::Elf_types<32>::Elf_Addr address,
723                               off_t view_size)
724 {
725   assert(sh_type == elfcpp::SHT_REL);
726
727   gold::relocate_section<32, false, elfcpp::SHT_REL, Target_i386::Relocate>(
728     relinfo,
729     prelocs,
730     reloc_count,
731     view,
732     address,
733     view_size);
734 }
735
736 // The i386 target.
737
738 Target_i386 target_i386;
739
740 // The selector for i386 object files.
741
742 class Target_selector_i386 : public Target_selector
743 {
744 public:
745   Target_selector_i386()
746     : Target_selector(elfcpp::EM_386, 32, false)
747   { }
748
749   Target*
750   recognize(int machine, int osabi, int abiversion) const;
751 };
752
753 // Recognize an i386 object file when we already know that the machine
754 // number is EM_386.
755
756 Target*
757 Target_selector_i386::recognize(int, int, int) const
758 {
759   return &target_i386;
760 }
761
762 Target_selector_i386 target_selector_i386;
763
764 } // End anonymous namespace.