* peXXigen.c: Updates for PE/COFF V8.0, and clarification
[deliverable/binutils-gdb.git] / gold / i386.cc
CommitLineData
14bfc3f5
ILT
1// i386.cc -- i386 target support for gold.
2
3#include "gold.h"
ead1e424
ILT
4
5#include <cstring>
6
14bfc3f5 7#include "elfcpp.h"
92e059d8 8#include "reloc.h"
61ba1cf9
ILT
9#include "i386.h"
10#include "object.h"
ead1e424 11#include "symtab.h"
92e059d8
ILT
12#include "layout.h"
13#include "output.h"
14bfc3f5 14#include "target.h"
61ba1cf9 15#include "target-reloc.h"
14bfc3f5
ILT
16#include "target-select.h"
17
18namespace
19{
20
21using namespace gold;
22
23// The i386 target class.
24
25class Target_i386 : public Sized_target<32, false>
26{
27 public:
28 Target_i386()
ead1e424
ILT
29 : Sized_target<32, false>(&i386_info),
30 got_(NULL)
14bfc3f5 31 { }
75f65a3e 32
92e059d8 33 // Scan the relocations to look for symbol adjustments.
61ba1cf9 34 void
92e059d8
ILT
35 scan_relocs(const General_options& options,
36 Symbol_table* symtab,
ead1e424 37 Layout* layout,
f6ce93d6 38 Sized_relobj<32, false>* object,
92e059d8
ILT
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);
61ba1cf9 45
92e059d8
ILT
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
61ba1cf9
ILT
59 {
60 inline void
ead1e424
ILT
61 local(const General_options& options, Symbol_table* symtab,
62 Layout* layout, Target_i386* target,
f6ce93d6 63 Sized_relobj<32, false>* object,
92e059d8
ILT
64 const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
65 const elfcpp::Sym<32, false>& lsym);
61ba1cf9 66
92e059d8 67 inline void
ead1e424
ILT
68 global(const General_options& options, Symbol_table* symtab,
69 Layout* layout, Target_i386* target,
f6ce93d6 70 Sized_relobj<32, false>* object,
92e059d8
ILT
71 const elfcpp::Rel<32, false>& reloc, unsigned int r_type,
72 Symbol* gsym);
61ba1cf9
ILT
73 };
74
92e059d8
ILT
75 // The class which implements relocation.
76 class Relocate
77 {
78 public:
ead1e424
ILT
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,
92e059d8
ILT
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.
ead1e424 106 inline void
92e059d8
ILT
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
ead1e424
ILT
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
92e059d8
ILT
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);
ead1e424
ILT
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_;
92e059d8
ILT
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
ead1e424
ILT
151 // Get the GOT section, creating it if necessary.
152 Output_section_got<32, false>*
153 got_section(Symbol_table*, Layout*);
154
92e059d8
ILT
155 // Information about this specific target which we pass to the
156 // general Target structure.
75f65a3e 157 static const Target::Target_info i386_info;
ead1e424
ILT
158
159 // The GOT section.
160 Output_section_got<32, false>* got_;
75f65a3e
ILT
161};
162
163const Target::Target_info Target_i386::i386_info =
164{
61ba1cf9
ILT
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
14bfc3f5
ILT
173};
174
ead1e424
ILT
175// Get the GOT section, creating it if necessary.
176
177Output_section_got<32, false>*
178Target_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
92e059d8
ILT
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
207unsigned int
208Target_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
263inline void
264Target_i386::Scan::local(const General_options& options,
ead1e424
ILT
265 Symbol_table* symtab,
266 Layout* layout,
267 Target_i386* target,
f6ce93d6 268 Sized_relobj<32, false>* object,
92e059d8
ILT
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
ead1e424
ILT
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
92e059d8
ILT
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:
92e059d8
ILT
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
366inline void
367Target_i386::Scan::global(const General_options& options,
ead1e424
ILT
368 Symbol_table* symtab,
369 Layout* layout,
370 Target_i386* target,
f6ce93d6 371 Sized_relobj<32, false>* object,
92e059d8
ILT
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
ead1e424
ILT
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
92e059d8
ILT
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,
ead1e424 450 gsym->is_resolved_locally(),
92e059d8
ILT
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
92e059d8
ILT
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
495void
496Target_i386::scan_relocs(const General_options& options,
497 Symbol_table* symtab,
ead1e424 498 Layout* layout,
f6ce93d6 499 Sized_relobj<32, false>* object,
92e059d8
ILT
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
ead1e424
ILT
514 gold::scan_relocs<32, false, Target_i386, elfcpp::SHT_REL,
515 Target_i386::Scan>(
92e059d8
ILT
516 options,
517 symtab,
ead1e424
ILT
518 layout,
519 this,
92e059d8
ILT
520 object,
521 prelocs,
522 reloc_count,
523 local_symbol_count,
524 plocal_symbols,
525 global_symbols);
526}
527
61ba1cf9
ILT
528// Perform a relocation.
529
ead1e424 530inline bool
92e059d8 531Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
ead1e424 532 Target_i386* target,
92e059d8
ILT
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)
61ba1cf9 541{
ead1e424
ILT
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
61ba1cf9
ILT
559 switch (r_type)
560 {
561 case elfcpp::R_386_NONE:
92e059d8
ILT
562 case elfcpp::R_386_GNU_VTINHERIT:
563 case elfcpp::R_386_GNU_VTENTRY:
61ba1cf9
ILT
564 break;
565
566 case elfcpp::R_386_32:
92e059d8 567 Relocate_functions<32, false>::rel32(view, value);
61ba1cf9
ILT
568 break;
569
570 case elfcpp::R_386_PC32:
92e059d8
ILT
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);
61ba1cf9
ILT
580 break;
581
92e059d8
ILT
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
ead1e424
ILT
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
92e059d8
ILT
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:
ead1e424
ILT
644 this->relocate_tls(relinfo, relnum, rel, r_type, gsym, value, view,
645 address, view_size);
92e059d8
ILT
646 break;
647
92e059d8
ILT
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:
61ba1cf9
ILT
658 default:
659 fprintf(stderr, _("%s: %s: unsupported reloc %u\n"),
92e059d8
ILT
660 program_name,
661 relinfo->location(relnum, rel.get_r_offset()).c_str(),
662 r_type);
61ba1cf9 663 // gold_exit(false);
92e059d8
ILT
664 break;
665 }
ead1e424
ILT
666
667 return true;
92e059d8
ILT
668}
669
670// Perform a TLS relocation.
671
672inline void
673Target_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
ead1e424 692 const bool is_local = gsym == NULL || gsym->is_resolved_locally();
92e059d8
ILT
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:
ead1e424
ILT
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
92e059d8
ILT
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
755inline void
756Target_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
ead1e424
ILT
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;
92e059d8
ILT
845
846 Relocate_functions<32, false>::rel32(view, value);
847}
848
ead1e424
ILT
849// Do a relocation in which we convert a TLS Global-Dynamic to a
850// Local-Exec.
851
852inline void
853Target_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
92e059d8
ILT
915// Check the range for a TLS relocation.
916
917inline void
918Target_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
935inline void
936Target_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);
61ba1cf9
ILT
948 }
949}
950
951// Relocate section data.
952
953void
92e059d8 954Target_i386::relocate_section(const Relocate_info<32, false>* relinfo,
61ba1cf9
ILT
955 unsigned int sh_type,
956 const unsigned char* prelocs,
957 size_t reloc_count,
61ba1cf9
ILT
958 unsigned char* view,
959 elfcpp::Elf_types<32>::Elf_Addr address,
960 off_t view_size)
961{
92e059d8 962 assert(sh_type == elfcpp::SHT_REL);
61ba1cf9 963
ead1e424
ILT
964 gold::relocate_section<32, false, Target_i386, elfcpp::SHT_REL,
965 Target_i386::Relocate>(
92e059d8 966 relinfo,
ead1e424 967 this,
61ba1cf9
ILT
968 prelocs,
969 reloc_count,
61ba1cf9
ILT
970 view,
971 address,
972 view_size);
973}
974
14bfc3f5
ILT
975// The selector for i386 object files.
976
977class Target_selector_i386 : public Target_selector
978{
979public:
980 Target_selector_i386()
981 : Target_selector(elfcpp::EM_386, 32, false)
982 { }
983
984 Target*
ead1e424
ILT
985 recognize(int machine, int osabi, int abiversion);
986
987 private:
988 Target_i386* target_;
14bfc3f5
ILT
989};
990
991// Recognize an i386 object file when we already know that the machine
992// number is EM_386.
993
994Target*
ead1e424 995Target_selector_i386::recognize(int, int, int)
14bfc3f5 996{
ead1e424
ILT
997 if (this->target_ == NULL)
998 this->target_ = new Target_i386();
999 return this->target_;
14bfc3f5
ILT
1000}
1001
1002Target_selector_i386 target_selector_i386;
1003
1004} // End anonymous namespace.
This page took 0.092586 seconds and 4 git commands to generate.