1 // tilegx.cc -- tilegx target support for gold. 2 3 // Copyright (C) 2012-2018 Free Software Foundation, Inc. 4 // Written by Jiong Wang (jiwang@tilera.com) 5 6 // This file is part of gold. 7 8 // This program is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as published by 10 // the Free Software Foundation; either version 3 of the License, or 11 // (at your option) any later version. 12 13 // This program is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // You should have received a copy of the GNU General Public License 19 // along with this program; if not, write to the Free Software 20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 // MA 02110-1301, USA. 22 23 #include "gold.h" 24 25 #include <cstring> 26 27 #include "elfcpp.h" 28 #include "dwarf.h" 29 #include "parameters.h" 30 #include "reloc.h" 31 #include "tilegx.h" 32 #include "object.h" 33 #include "symtab.h" 34 #include "layout.h" 35 #include "output.h" 36 #include "copy-relocs.h" 37 #include "target.h" 38 #include "target-reloc.h" 39 #include "target-select.h" 40 #include "tls.h" 41 #include "gc.h" 42 #include "icf.h" 43 44 // the first got entry reserved 45 const int32_t TILEGX_GOT_RESERVE_COUNT = 1; 46 47 // the first two .got.plt entry reserved 48 const int32_t TILEGX_GOTPLT_RESERVE_COUNT = 2; 49 50 // 1. for both 64/32 bit mode, the instruction bundle is always 64bit. 51 // 2. thus .plt section should always be aligned to 64 bit. 52 const int32_t TILEGX_INST_BUNDLE_SIZE = 64; 53 54 namespace 55 { 56 57 using namespace gold; 58 59 // A class to handle the PLT data. 60 // This is an abstract base class that handles most of the linker details 61 // but does not know the actual contents of PLT entries. The derived 62 // classes below fill in those details. 63 64 template<int size, bool big_endian> 65 class Output_data_plt_tilegx : public Output_section_data 66 { 67 public: 68 typedef Output_data_reloc<elfcpp::SHT_RELA, true,size, big_endian> 69 Reloc_section; 70 71 Output_data_plt_tilegx(Layout* layout, uint64_t addralign, 72 Output_data_got<size, big_endian>* got, 73 Output_data_space* got_plt, 74 Output_data_space* got_irelative) 75 : Output_section_data(addralign), layout_(layout), 76 irelative_rel_(NULL), got_(got), got_plt_(got_plt), 77 got_irelative_(got_irelative), count_(0), 78 irelative_count_(0), free_list_() 79 { this->init(layout); } 80 81 Output_data_plt_tilegx(Layout* layout, uint64_t plt_entry_size, 82 Output_data_got<size, big_endian>* got, 83 Output_data_space* got_plt, 84 Output_data_space* got_irelative, 85 unsigned int plt_count) 86 : Output_section_data((plt_count + 1) * plt_entry_size, 87 TILEGX_INST_BUNDLE_SIZE, false), 88 layout_(layout), irelative_rel_(NULL), got_(got), 89 got_plt_(got_plt), got_irelative_(got_irelative), count_(plt_count), 90 irelative_count_(0), free_list_() 91 { 92 this->init(layout); 93 94 // Initialize the free list and reserve the first entry. 95 this->free_list_.init((plt_count + 1) * plt_entry_size, false); 96 this->free_list_.remove(0, plt_entry_size); 97 } 98 99 // Initialize the PLT section. 100 void 101 init(Layout* layout); 102 103 // Add an entry to the PLT. 104 void 105 add_entry(Symbol_table*, Layout*, Symbol* gsym); 106 107 // Add an entry to the PLT for a local STT_GNU_IFUNC symbol. 108 unsigned int 109 add_local_ifunc_entry(Symbol_table*, Layout*, 110 Sized_relobj_file<size, big_endian>*, unsigned int); 111 112 // Add the relocation for a PLT entry. 113 void 114 add_relocation(Symbol_table*, Layout*, Symbol*, unsigned int); 115 116 // Return the .rela.plt section data. 117 Reloc_section* 118 rela_plt() 119 { return this->rel_; } 120 121 // Return where the IRELATIVE relocations should go in the PLT 122 // relocations. 123 Reloc_section* 124 rela_irelative(Symbol_table*, Layout*); 125 126 // Return whether we created a section for IRELATIVE relocations. 127 bool 128 has_irelative_section() const 129 { return this->irelative_rel_ != NULL; } 130 131 // Return the number of PLT entries. 132 unsigned int 133 entry_count() const 134 { return this->count_ + this->irelative_count_; } 135 136 // Return the offset of the first non-reserved PLT entry. 137 unsigned int 138 first_plt_entry_offset() 139 { return this->get_plt_entry_size(); } 140 141 // Return the size of a PLT entry. 142 unsigned int 143 get_plt_entry_size() const 144 { return plt_entry_size; } 145 146 // Reserve a slot in the PLT for an existing symbol in an incremental update. 147 void 148 reserve_slot(unsigned int plt_index) 149 { 150 this->free_list_.remove((plt_index + 1) * this->get_plt_entry_size(), 151 (plt_index + 2) * this->get_plt_entry_size()); 152 } 153 154 // Return the PLT address to use for a global symbol. 155 uint64_t 156 address_for_global(const Symbol*); 157 158 // Return the PLT address to use for a local symbol. 159 uint64_t 160 address_for_local(const Relobj*, unsigned int symndx); 161 162 protected: 163 // Fill in the first PLT entry. 164 void 165 fill_first_plt_entry(unsigned char*); 166 167 // Fill in a normal PLT entry. Returns the offset into the entry that 168 // should be the initial GOT slot value. 169 void 170 fill_plt_entry(unsigned char*, 171 typename elfcpp::Elf_types<size>::Elf_Addr, 172 unsigned int, 173 typename elfcpp::Elf_types<size>::Elf_Addr, 174 unsigned int, unsigned int); 175 176 void 177 do_adjust_output_section(Output_section* os); 178 179 // Write to a map file. 180 void 181 do_print_to_mapfile(Mapfile* mapfile) const 182 { mapfile->print_output_data(this, _("** PLT")); } 183 184 private: 185 // Set the final size. 186 void 187 set_final_data_size(); 188 189 // Write out the PLT data. 190 void 191 do_write(Output_file*); 192 193 // A pointer to the Layout class, so that we can find the .dynamic 194 // section when we write out the GOT PLT section. 195 Layout* layout_; 196 // The reloc section. 197 Reloc_section* rel_; 198 // The IRELATIVE relocs, if necessary. These must follow the 199 // regular PLT relocations. 200 Reloc_section* irelative_rel_; 201 // The .got section. 202 Output_data_got<size, big_endian>* got_; 203 // The .got.plt section. 204 Output_data_space* got_plt_; 205 // The part of the .got.plt section used for IRELATIVE relocs. 206 Output_data_space* got_irelative_; 207 // The number of PLT entries. 208 unsigned int count_; 209 // Number of PLT entries with R_TILEGX_IRELATIVE relocs. These 210 // follow the regular PLT entries. 211 unsigned int irelative_count_; 212 // List of available regions within the section, for incremental 213 // update links. 214 Free_list free_list_; 215 // The size of an entry in the PLT. 216 static const int plt_entry_size = 40; 217 // The first entry in the PLT. 218 static const unsigned char first_plt_entry[plt_entry_size]; 219 // Other entries in the PLT for an executable. 220 static const unsigned char plt_entry[plt_entry_size]; 221 }; 222 223 // The tilegx target class. 224 // See the ABI at 225 // http://www.tilera.com/scm 226 // TLS info comes from 227 // http://people.redhat.com/drepper/tls.pdf 228 229 template<int size, bool big_endian> 230 class Target_tilegx : public Sized_target<size, big_endian> 231 { 232 public: 233 // TileGX use RELA 234 typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> 235 Reloc_section; 236 237 Target_tilegx(const Target::Target_info* info = &tilegx_info) 238 : Sized_target<size, big_endian>(info), 239 got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL), 240 global_offset_table_(NULL), tilegx_dynamic_(NULL), rela_dyn_(NULL), 241 rela_irelative_(NULL), copy_relocs_(elfcpp::R_TILEGX_COPY), 242 got_mod_index_offset_(-1U), 243 tls_get_addr_sym_defined_(false) 244 { } 245 246 // Scan the relocations to look for symbol adjustments. 247 void 248 gc_process_relocs(Symbol_table* symtab, 249 Layout* layout, 250 Sized_relobj_file<size, big_endian>* object, 251 unsigned int data_shndx, 252 unsigned int sh_type, 253 const unsigned char* prelocs, 254 size_t reloc_count, 255 Output_section* output_section, 256 bool needs_special_offset_handling, 257 size_t local_symbol_count, 258 const unsigned char* plocal_symbols); 259 260 // Scan the relocations to look for symbol adjustments. 261 void 262 scan_relocs(Symbol_table* symtab, 263 Layout* layout, 264 Sized_relobj_file<size, big_endian>* object, 265 unsigned int data_shndx, 266 unsigned int sh_type, 267 const unsigned char* prelocs, 268 size_t reloc_count, 269 Output_section* output_section, 270 bool needs_special_offset_handling, 271 size_t local_symbol_count, 272 const unsigned char* plocal_symbols); 273 274 // Finalize the sections. 275 void 276 do_finalize_sections(Layout*, const Input_objects*, Symbol_table*); 277 278 // Return the value to use for a dynamic which requires special 279 // treatment. 280 uint64_t 281 do_dynsym_value(const Symbol*) const; 282 283 // Relocate a section. 284 void 285 relocate_section(const Relocate_info<size, big_endian>*, 286 unsigned int sh_type, 287 const unsigned char* prelocs, 288 size_t reloc_count, 289 Output_section* output_section, 290 bool needs_special_offset_handling, 291 unsigned char* view, 292 typename elfcpp::Elf_types<size>::Elf_Addr view_address, 293 section_size_type view_size, 294 const Reloc_symbol_changes*); 295 296 // Scan the relocs during a relocatable link. 297 void 298 scan_relocatable_relocs(Symbol_table* symtab, 299 Layout* layout, 300 Sized_relobj_file<size, big_endian>* object, 301 unsigned int data_shndx, 302 unsigned int sh_type, 303 const unsigned char* prelocs, 304 size_t reloc_count, 305 Output_section* output_section, 306 bool needs_special_offset_handling, 307 size_t local_symbol_count, 308 const unsigned char* plocal_symbols, 309 Relocatable_relocs*); 310 311 // Scan the relocs for --emit-relocs. 312 void 313 emit_relocs_scan(Symbol_table* symtab, 314 Layout* layout, 315 Sized_relobj_file<size, big_endian>* object, 316 unsigned int data_shndx, 317 unsigned int sh_type, 318 const unsigned char* prelocs, 319 size_t reloc_count, 320 Output_section* output_section, 321 bool needs_special_offset_handling, 322 size_t local_symbol_count, 323 const unsigned char* plocal_syms, 324 Relocatable_relocs* rr); 325 326 // Relocate a section during a relocatable link. 327 void 328 relocate_relocs( 329 const Relocate_info<size, big_endian>*, 330 unsigned int sh_type, 331 const unsigned char* prelocs, 332 size_t reloc_count, 333 Output_section* output_section, 334 typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section, 335 unsigned char* view, 336 typename elfcpp::Elf_types<size>::Elf_Addr view_address, 337 section_size_type view_size, 338 unsigned char* reloc_view, 339 section_size_type reloc_view_size); 340 341 // Return whether SYM is defined by the ABI. 342 bool 343 do_is_defined_by_abi(const Symbol* sym) const 344 { return strcmp(sym->name(), "__tls_get_addr") == 0; } 345 346 // define tilegx specific symbols 347 virtual void 348 do_define_standard_symbols(Symbol_table*, Layout*); 349 350 // Return the PLT section. 351 uint64_t 352 do_plt_address_for_global(const Symbol* gsym) const 353 { return this->plt_section()->address_for_global(gsym); } 354 355 uint64_t 356 do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const 357 { return this->plt_section()->address_for_local(relobj, symndx); } 358 359 // This function should be defined in targets that can use relocation 360 // types to determine (implemented in local_reloc_may_be_function_pointer 361 // and global_reloc_may_be_function_pointer) 362 // if a function's pointer is taken. ICF uses this in safe mode to only 363 // fold those functions whose pointer is defintely not taken. For tilegx 364 // pie binaries, safe ICF cannot be done by looking at relocation types. 365 bool 366 do_can_check_for_function_pointers() const 367 { return true; } 368 369 // Return the base for a DW_EH_PE_datarel encoding. 370 uint64_t 371 do_ehframe_datarel_base() const; 372 373 // Return whether there is a GOT section. 374 bool 375 has_got_section() const 376 { return this->got_ != NULL; } 377 378 // Return the size of the GOT section. 379 section_size_type 380 got_size() const 381 { 382 gold_assert(this->got_ != NULL); 383 return this->got_->data_size(); 384 } 385 386 // Return the number of entries in the GOT. 387 unsigned int 388 got_entry_count() const 389 { 390 if (this->got_ == NULL) 391 return 0; 392 return this->got_size() / (size / 8); 393 } 394 395 // Return the number of entries in the PLT. 396 unsigned int 397 plt_entry_count() const; 398 399 // Return the offset of the first non-reserved PLT entry. 400 unsigned int 401 first_plt_entry_offset() const; 402 403 // Return the size of each PLT entry. 404 unsigned int 405 plt_entry_size() const; 406 407 // Create the GOT section for an incremental update. 408 Output_data_got_base* 409 init_got_plt_for_update(Symbol_table* symtab, 410 Layout* layout, 411 unsigned int got_count, 412 unsigned int plt_count); 413 414 // Reserve a GOT entry for a local symbol, and regenerate any 415 // necessary dynamic relocations. 416 void 417 reserve_local_got_entry(unsigned int got_index, 418 Sized_relobj<size, big_endian>* obj, 419 unsigned int r_sym, 420 unsigned int got_type); 421 422 // Reserve a GOT entry for a global symbol, and regenerate any 423 // necessary dynamic relocations. 424 void 425 reserve_global_got_entry(unsigned int got_index, Symbol* gsym, 426 unsigned int got_type); 427 428 // Register an existing PLT entry for a global symbol. 429 void 430 register_global_plt_entry(Symbol_table*, Layout*, unsigned int plt_index, 431 Symbol* gsym); 432 433 // Force a COPY relocation for a given symbol. 434 void 435 emit_copy_reloc(Symbol_table*, Symbol*, Output_section*, off_t); 436 437 // Apply an incremental relocation. 438 void 439 apply_relocation(const Relocate_info<size, big_endian>* relinfo, 440 typename elfcpp::Elf_types<size>::Elf_Addr r_offset, 441 unsigned int r_type, 442 typename elfcpp::Elf_types<size>::Elf_Swxword r_addend, 443 const Symbol* gsym, 444 unsigned char* view, 445 typename elfcpp::Elf_types<size>::Elf_Addr address, 446 section_size_type view_size); 447 448 private: 449 // The class which scans relocations. 450 class Scan 451 { 452 public: 453 Scan() 454 : issued_non_pic_error_(false) 455 { } 456 457 static inline int 458 get_reference_flags(unsigned int r_type); 459 460 inline void 461 local(Symbol_table* symtab, Layout* layout, Target_tilegx* target, 462 Sized_relobj_file<size, big_endian>* object, 463 unsigned int data_shndx, 464 Output_section* output_section, 465 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type, 466 const elfcpp::Sym<size, big_endian>& lsym, 467 bool is_discarded); 468 469 inline void 470 global(Symbol_table* symtab, Layout* layout, Target_tilegx* target, 471 Sized_relobj_file<size, big_endian>* object, 472 unsigned int data_shndx, 473 Output_section* output_section, 474 const elfcpp::Rela<size, big_endian>& reloc, unsigned int r_type, 475 Symbol* gsym); 476 477 inline bool 478 local_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout, 479 Target_tilegx* target, 480 Sized_relobj_file<size, big_endian>* object, 481 unsigned int data_shndx, 482 Output_section* output_section, 483 const elfcpp::Rela<size, big_endian>& reloc, 484 unsigned int r_type, 485 const elfcpp::Sym<size, big_endian>& lsym); 486 487 inline bool 488 global_reloc_may_be_function_pointer(Symbol_table* symtab, Layout* layout, 489 Target_tilegx* target, 490 Sized_relobj_file<size, big_endian>* object, 491 unsigned int data_shndx, 492 Output_section* output_section, 493 const elfcpp::Rela<size, big_endian>& reloc, 494 unsigned int r_type, 495 Symbol* gsym); 496 497 private: 498 static void 499 unsupported_reloc_local(Sized_relobj_file<size, big_endian>*, 500 unsigned int r_type); 501 502 static void 503 unsupported_reloc_global(Sized_relobj_file<size, big_endian>*, 504 unsigned int r_type, Symbol*); 505 506 void 507 check_non_pic(Relobj*, unsigned int r_type); 508 509 inline bool 510 possible_function_pointer_reloc(unsigned int r_type); 511 512 bool 513 reloc_needs_plt_for_ifunc(Sized_relobj_file<size, big_endian>*, 514 unsigned int r_type); 515 516 // Whether we have issued an error about a non-PIC compilation. 517 bool issued_non_pic_error_; 518 }; 519 520 // The class which implements relocation. 521 class Relocate 522 { 523 public: 524 Relocate() 525 { } 526 527 ~Relocate() 528 { 529 } 530 531 // Do a relocation. Return false if the caller should not issue 532 // any warnings about this relocation. 533 inline bool 534 relocate(const Relocate_info<size, big_endian>*, unsigned int, 535 Target_tilegx*, Output_section*, size_t, const unsigned char*, 536 const Sized_symbol<size>*, const Symbol_value<size>*, 537 unsigned char*, typename elfcpp::Elf_types<size>::Elf_Addr, 538 section_size_type); 539 }; 540 541 // Adjust TLS relocation type based on the options and whether this 542 // is a local symbol. 543 static tls::Tls_optimization 544 optimize_tls_reloc(bool is_final, int r_type); 545 546 // Get the GOT section, creating it if necessary. 547 Output_data_got<size, big_endian>* 548 got_section(Symbol_table*, Layout*); 549 550 // Get the GOT PLT section. 551 Output_data_space* 552 got_plt_section() const 553 { 554 gold_assert(this->got_plt_ != NULL); 555 return this->got_plt_; 556 } 557 558 // Create the PLT section. 559 void 560 make_plt_section(Symbol_table* symtab, Layout* layout); 561 562 // Create a PLT entry for a global symbol. 563 void 564 make_plt_entry(Symbol_table*, Layout*, Symbol*); 565 566 // Create a PLT entry for a local STT_GNU_IFUNC symbol. 567 void 568 make_local_ifunc_plt_entry(Symbol_table*, Layout*, 569 Sized_relobj_file<size, big_endian>* relobj, 570 unsigned int local_sym_index); 571 572 // Create a GOT entry for the TLS module index. 573 unsigned int 574 got_mod_index_entry(Symbol_table* symtab, Layout* layout, 575 Sized_relobj_file<size, big_endian>* object); 576 577 // Get the PLT section. 578 Output_data_plt_tilegx<size, big_endian>* 579 plt_section() const 580 { 581 gold_assert(this->plt_ != NULL); 582 return this->plt_; 583 } 584 585 // Get the dynamic reloc section, creating it if necessary. 586 Reloc_section* 587 rela_dyn_section(Layout*); 588 589 // Get the section to use for IRELATIVE relocations. 590 Reloc_section* 591 rela_irelative_section(Layout*); 592 593 // Add a potential copy relocation. 594 void 595 copy_reloc(Symbol_table* symtab, Layout* layout, 596 Sized_relobj_file<size, big_endian>* object, 597 unsigned int shndx, Output_section* output_section, 598 Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc) 599 { 600 unsigned int r_type = elfcpp::elf_r_type<size>(reloc.get_r_info()); 601 this->copy_relocs_.copy_reloc(symtab, layout, 602 symtab->get_sized_symbol<size>(sym), 603 object, shndx, output_section, 604 r_type, reloc.get_r_offset(), 605 reloc.get_r_addend(), 606 this->rela_dyn_section(layout)); 607 } 608 609 // Information about this specific target which we pass to the 610 // general Target structure. 611 static const Target::Target_info tilegx_info; 612 613 // The types of GOT entries needed for this platform. 614 // These values are exposed to the ABI in an incremental link. 615 // Do not renumber existing values without changing the version 616 // number of the .gnu_incremental_inputs section. 617 enum Got_type 618 { 619 GOT_TYPE_STANDARD = 0, // GOT entry for a regular symbol 620 GOT_TYPE_TLS_OFFSET = 1, // GOT entry for TLS offset 621 GOT_TYPE_TLS_PAIR = 2, // GOT entry for TLS module/offset pair 622 GOT_TYPE_TLS_DESC = 3 // GOT entry for TLS_DESC pair 623 }; 624 625 // This type is used as the argument to the target specific 626 // relocation routines. The only target specific reloc is 627 // R_X86_64_TLSDESC against a local symbol. 628 struct Tlsdesc_info 629 { 630 Tlsdesc_info(Sized_relobj_file<size, big_endian>* a_object, 631 unsigned int a_r_sym) 632 : object(a_object), r_sym(a_r_sym) 633 { } 634 635 // The object in which the local symbol is defined. 636 Sized_relobj_file<size, big_endian>* object; 637 // The local symbol index in the object. 638 unsigned int r_sym; 639 }; 640 641 // The GOT section. 642 Output_data_got<size, big_endian>* got_; 643 // The PLT section. 644 Output_data_plt_tilegx<size, big_endian>* plt_; 645 // The GOT PLT section. 646 Output_data_space* got_plt_; 647 // The GOT section for IRELATIVE relocations. 648 Output_data_space* got_irelative_; 649 // The _GLOBAL_OFFSET_TABLE_ symbol. 650 Symbol* global_offset_table_; 651 // The _TILEGX_DYNAMIC_ symbol. 652 Symbol* tilegx_dynamic_; 653 // The dynamic reloc section. 654 Reloc_section* rela_dyn_; 655 // The section to use for IRELATIVE relocs. 656 Reloc_section* rela_irelative_; 657 // Relocs saved to avoid a COPY reloc. 658 Copy_relocs<elfcpp::SHT_RELA, size, big_endian> copy_relocs_; 659 // Offset of the GOT entry for the TLS module index. 660 unsigned int got_mod_index_offset_; 661 // True if the _tls_get_addr symbol has been defined. 662 bool tls_get_addr_sym_defined_; 663 }; 664 665 template<> 666 const Target::Target_info Target_tilegx<64, false>::tilegx_info = 667 { 668 64, // size 669 false, // is_big_endian 670 elfcpp::EM_TILEGX, // machine_code 671 false, // has_make_symbol 672 false, // has_resolve 673 false, // has_code_fill 674 true, // is_default_stack_executable 675 false, // can_icf_inline_merge_sections 676 '\0', // wrap_char 677 "/lib/ld.so.1", // program interpreter 678 0x10000, // default_text_segment_address 679 0x10000, // abi_pagesize (overridable by -z max-page-size) 680 0x10000, // common_pagesize (overridable by -z common-page-size) 681 false, // isolate_execinstr 682 0, // rosegment_gap 683 elfcpp::SHN_UNDEF, // small_common_shndx 684 elfcpp::SHN_UNDEF, // large_common_shndx 685 0, // small_common_section_flags 686 0, // large_common_section_flags 687 NULL, // attributes_section 688 NULL, // attributes_vendor 689 "_start", // entry_symbol_name 690 32, // hash_entry_size 691 elfcpp::SHT_PROGBITS, // unwind_section_type 692 }; 693 694 template<> 695 const Target::Target_info Target_tilegx<32, false>::tilegx_info = 696 { 697 32, // size 698 false, // is_big_endian 699 elfcpp::EM_TILEGX, // machine_code 700 false, // has_make_symbol 701 false, // has_resolve 702 false, // has_code_fill 703 true, // is_default_stack_executable 704 false, // can_icf_inline_merge_sections 705 '\0', // wrap_char 706 "/lib32/ld.so.1", // program interpreter 707 0x10000, // default_text_segment_address 708 0x10000, // abi_pagesize (overridable by -z max-page-size) 709 0x10000, // common_pagesize (overridable by -z common-page-size) 710 false, // isolate_execinstr 711 0, // rosegment_gap 712 elfcpp::SHN_UNDEF, // small_common_shndx 713 elfcpp::SHN_UNDEF, // large_common_shndx 714 0, // small_common_section_flags 715 0, // large_common_section_flags 716 NULL, // attributes_section 717 NULL, // attributes_vendor 718 "_start", // entry_symbol_name 719 32, // hash_entry_size 720 elfcpp::SHT_PROGBITS, // unwind_section_type 721 }; 722 723 template<> 724 const Target::Target_info Target_tilegx<64, true>::tilegx_info = 725 { 726 64, // size 727 true, // is_big_endian 728 elfcpp::EM_TILEGX, // machine_code 729 false, // has_make_symbol 730 false, // has_resolve 731 false, // has_code_fill 732 true, // is_default_stack_executable 733 false, // can_icf_inline_merge_sections 734 '\0', // wrap_char 735 "/lib/ld.so.1", // program interpreter 736 0x10000, // default_text_segment_address 737 0x10000, // abi_pagesize (overridable by -z max-page-size) 738 0x10000, // common_pagesize (overridable by -z common-page-size) 739 false, // isolate_execinstr 740 0, // rosegment_gap 741 elfcpp::SHN_UNDEF, // small_common_shndx 742 elfcpp::SHN_UNDEF, // large_common_shndx 743 0, // small_common_section_flags 744 0, // large_common_section_flags 745 NULL, // attributes_section 746 NULL, // attributes_vendor 747 "_start", // entry_symbol_name 748 32, // hash_entry_size 749 elfcpp::SHT_PROGBITS, // unwind_section_type 750 }; 751 752 template<> 753 const Target::Target_info Target_tilegx<32, true>::tilegx_info = 754 { 755 32, // size 756 true, // is_big_endian 757 elfcpp::EM_TILEGX, // machine_code 758 false, // has_make_symbol 759 false, // has_resolve 760 false, // has_code_fill 761 true, // is_default_stack_executable 762 false, // can_icf_inline_merge_sections 763 '\0', // wrap_char 764 "/lib32/ld.so.1", // program interpreter 765 0x10000, // default_text_segment_address 766 0x10000, // abi_pagesize (overridable by -z max-page-size) 767 0x10000, // common_pagesize (overridable by -z common-page-size) 768 false, // isolate_execinstr 769 0, // rosegment_gap 770 elfcpp::SHN_UNDEF, // small_common_shndx 771 elfcpp::SHN_UNDEF, // large_common_shndx 772 0, // small_common_section_flags 773 0, // large_common_section_flags 774 NULL, // attributes_section 775 NULL, // attributes_vendor 776 "_start", // entry_symbol_name 777 32, // hash_entry_size 778 elfcpp::SHT_PROGBITS, // unwind_section_type 779 }; 780 781 // tilegx relocation handlers 782 template<int size, bool big_endian> 783 class Tilegx_relocate_functions 784 { 785 public: 786 // overflow check will be supported later 787 typedef enum 788 { 789 STATUS_OKAY, // No error during relocation. 790 STATUS_OVERFLOW, // Relocation overflow. 791 STATUS_BAD_RELOC // Relocation cannot be applied. 792 } Status; 793 794 struct Tilegx_howto 795 { 796 // right shift operand by this number of bits. 797 unsigned char srshift; 798 799 // the offset to apply relocation. 800 unsigned char doffset; 801 802 // set to 1 for pc-relative relocation. 803 unsigned char is_pcrel; 804 805 // size in bits, or 0 if this table entry should be ignored. 806 unsigned char bsize; 807 808 // whether we need to check overflow. 809 unsigned char overflow; 810 }; 811 812 static const Tilegx_howto howto[elfcpp::R_TILEGX_NUM]; 813 814 private: 815 816 // Do a simple rela relocation 817 template<int valsize> 818 static inline void 819 rela(unsigned char* view, 820 const Sized_relobj_file<size, big_endian>* object, 821 const Symbol_value<size>* psymval, 822 typename elfcpp::Swap<size, big_endian>::Valtype addend, 823 elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset, 824 elfcpp::Elf_Xword bitmask) 825 { 826 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 827 Valtype* wv = reinterpret_cast<Valtype*>(view); 828 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv); 829 Valtype reloc = 0; 830 if (size == 32) 831 reloc = Bits<32>::sign_extend(psymval->value(object, addend)) >> srshift; 832 else 833 reloc = psymval->value(object, addend) >> srshift; 834 835 elfcpp::Elf_Xword dst_mask = bitmask << doffset; 836 837 val &= ~dst_mask; 838 reloc &= bitmask; 839 840 elfcpp::Swap<valsize, big_endian>::writeval(wv, val | (reloc<<doffset)); 841 } 842 843 // Do a simple rela relocation 844 template<int valsize> 845 static inline void 846 rela_ua(unsigned char* view, 847 const Sized_relobj_file<size, big_endian>* object, 848 const Symbol_value<size>* psymval, 849 typename elfcpp::Swap<size, big_endian>::Valtype addend, 850 elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset, 851 elfcpp::Elf_Xword bitmask) 852 { 853 typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype 854 Valtype; 855 unsigned char* wv = view; 856 Valtype val = elfcpp::Swap_unaligned<valsize, big_endian>::readval(wv); 857 Valtype reloc = 0; 858 if (size == 32) 859 reloc = Bits<32>::sign_extend(psymval->value(object, addend)) >> srshift; 860 else 861 reloc = psymval->value(object, addend) >> srshift; 862 863 elfcpp::Elf_Xword dst_mask = bitmask << doffset; 864 865 val &= ~dst_mask; 866 reloc &= bitmask; 867 868 elfcpp::Swap_unaligned<valsize, big_endian>::writeval(wv, 869 val | (reloc<<doffset)); 870 } 871 872 template<int valsize> 873 static inline void 874 rela(unsigned char* view, 875 const Sized_relobj_file<size, big_endian>* object, 876 const Symbol_value<size>* psymval, 877 typename elfcpp::Swap<size, big_endian>::Valtype addend, 878 elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset1, 879 elfcpp::Elf_Xword bitmask1, elfcpp::Elf_Xword doffset2, 880 elfcpp::Elf_Xword bitmask2) 881 { 882 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 883 Valtype* wv = reinterpret_cast<Valtype*>(view); 884 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv); 885 Valtype reloc = 0; 886 if (size == 32) 887 reloc = Bits<32>::sign_extend(psymval->value(object, addend)) >> srshift; 888 else 889 reloc = psymval->value(object, addend) >> srshift; 890 891 elfcpp::Elf_Xword dst_mask = (bitmask1 << doffset1) 892 | (bitmask2 << doffset2); 893 val &= ~dst_mask; 894 reloc = ((reloc & bitmask1) << doffset1) 895 | ((reloc & bitmask2) << doffset2); 896 897 elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc); 898 899 } 900 901 // Do a simple PC relative relocation with a Symbol_value with the 902 // addend in the relocation. 903 template<int valsize> 904 static inline void 905 pcrela(unsigned char* view, 906 const Sized_relobj_file<size, big_endian>* object, 907 const Symbol_value<size>* psymval, 908 typename elfcpp::Swap<size, big_endian>::Valtype addend, 909 typename elfcpp::Elf_types<size>::Elf_Addr address, 910 elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset, 911 elfcpp::Elf_Xword bitmask) 912 913 { 914 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 915 Valtype* wv = reinterpret_cast<Valtype*>(view); 916 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv); 917 Valtype reloc = 0; 918 if (size == 32) 919 reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address) 920 >> srshift; 921 else 922 reloc = (psymval->value(object, addend) - address) >> srshift; 923 924 elfcpp::Elf_Xword dst_mask = bitmask << doffset; 925 val &= ~dst_mask; 926 reloc &= bitmask; 927 928 elfcpp::Swap<valsize, big_endian>::writeval(wv, val | (reloc<<doffset)); 929 } 930 931 template<int valsize> 932 static inline void 933 pcrela_ua(unsigned char* view, 934 const Sized_relobj_file<size, big_endian>* object, 935 const Symbol_value<size>* psymval, 936 typename elfcpp::Swap<size, big_endian>::Valtype addend, 937 typename elfcpp::Elf_types<size>::Elf_Addr address, 938 elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset, 939 elfcpp::Elf_Xword bitmask) 940 941 { 942 typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype 943 Valtype; 944 unsigned char* wv = view; 945 Valtype reloc = 0; 946 if (size == 32) 947 reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address) 948 >> srshift; 949 else 950 reloc = (psymval->value(object, addend) - address) >> srshift; 951 952 reloc &= bitmask; 953 954 elfcpp::Swap<valsize, big_endian>::writeval(wv, reloc << doffset); 955 } 956 957 template<int valsize> 958 static inline void 959 pcrela(unsigned char* view, 960 const Sized_relobj_file<size, big_endian>* object, 961 const Symbol_value<size>* psymval, 962 typename elfcpp::Swap<size, big_endian>::Valtype addend, 963 typename elfcpp::Elf_types<size>::Elf_Addr address, 964 elfcpp::Elf_Xword srshift, elfcpp::Elf_Xword doffset1, 965 elfcpp::Elf_Xword bitmask1, elfcpp::Elf_Xword doffset2, 966 elfcpp::Elf_Xword bitmask2) 967 968 { 969 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 970 Valtype* wv = reinterpret_cast<Valtype*>(view); 971 Valtype val = elfcpp::Swap<valsize, big_endian>::readval(wv); 972 Valtype reloc = 0; 973 if (size == 32) 974 reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address) 975 >> srshift; 976 else 977 reloc = (psymval->value(object, addend) - address) >> srshift; 978 979 elfcpp::Elf_Xword dst_mask = (bitmask1 << doffset1) 980 | (bitmask2 << doffset2); 981 val &= ~dst_mask; 982 reloc = ((reloc & bitmask1) << doffset1) 983 | ((reloc & bitmask2) << doffset2); 984 985 elfcpp::Swap<valsize, big_endian>::writeval(wv, val | reloc); 986 } 987 988 typedef Tilegx_relocate_functions<size, big_endian> This; 989 typedef Relocate_functions<size, big_endian> Base; 990 991 public: 992 993 static inline void 994 abs64(unsigned char* view, 995 const Sized_relobj_file<size, big_endian>* object, 996 const Symbol_value<size>* psymval, 997 typename elfcpp::Elf_types<size>::Elf_Addr addend) 998 { 999 This::template rela_ua<64>(view, object, psymval, addend, 0, 0, 1000 0xffffffffffffffffllu); 1001 } 1002 1003 static inline void 1004 abs32(unsigned char* view, 1005 const Sized_relobj_file<size, big_endian>* object, 1006 const Symbol_value<size>* psymval, 1007 typename elfcpp::Elf_types<size>::Elf_Addr addend) 1008 { 1009 This::template rela_ua<32>(view, object, psymval, addend, 0, 0, 1010 0xffffffff); 1011 } 1012 1013 static inline void 1014 abs16(unsigned char* view, 1015 const Sized_relobj_file<size, big_endian>* object, 1016 const Symbol_value<size>* psymval, 1017 typename elfcpp::Elf_types<size>::Elf_Addr addend) 1018 { 1019 This::template rela_ua<16>(view, object, psymval, addend, 0, 0, 1020 0xffff); 1021 } 1022 1023 static inline void 1024 pc_abs64(unsigned char* view, 1025 const Sized_relobj_file<size, big_endian>* object, 1026 const Symbol_value<size>* psymval, 1027 typename elfcpp::Elf_types<size>::Elf_Addr addend, 1028 typename elfcpp::Elf_types<size>::Elf_Addr address) 1029 { 1030 This::template pcrela_ua<64>(view, object, psymval, addend, address, 0, 0, 1031 0xffffffffffffffffllu); 1032 } 1033 1034 static inline void 1035 pc_abs32(unsigned char* view, 1036 const Sized_relobj_file<size, big_endian>* object, 1037 const Symbol_value<size>* psymval, 1038 typename elfcpp::Elf_types<size>::Elf_Addr addend, 1039 typename elfcpp::Elf_types<size>::Elf_Addr address) 1040 { 1041 This::template pcrela_ua<32>(view, object, psymval, addend, address, 0, 0, 1042 0xffffffff); 1043 } 1044 1045 static inline void 1046 pc_abs16(unsigned char* view, 1047 const Sized_relobj_file<size, big_endian>* object, 1048 const Symbol_value<size>* psymval, 1049 typename elfcpp::Elf_types<size>::Elf_Addr addend, 1050 typename elfcpp::Elf_types<size>::Elf_Addr address) 1051 { 1052 This::template pcrela_ua<16>(view, object, psymval, addend, address, 0, 0, 1053 0xffff); 1054 } 1055 1056 static inline void 1057 imm_x_general(unsigned char* view, 1058 const Sized_relobj_file<size, big_endian>* object, 1059 const Symbol_value<size>* psymval, 1060 typename elfcpp::Elf_types<size>::Elf_Addr addend, 1061 Tilegx_howto &r_howto) 1062 { 1063 This::template rela<64>(view, object, psymval, addend, 1064 (elfcpp::Elf_Xword)(r_howto.srshift), 1065 (elfcpp::Elf_Xword)(r_howto.doffset), 1066 (elfcpp::Elf_Xword)((1 << r_howto.bsize) - 1)); 1067 } 1068 1069 static inline void 1070 imm_x_pcrel_general(unsigned char* view, 1071 const Sized_relobj_file<size, big_endian>* object, 1072 const Symbol_value<size>* psymval, 1073 typename elfcpp::Elf_types<size>::Elf_Addr addend, 1074 typename elfcpp::Elf_types<size>::Elf_Addr address, 1075 Tilegx_howto &r_howto) 1076 { 1077 This::template pcrela<64>(view, object, psymval, addend, address, 1078 (elfcpp::Elf_Xword)(r_howto.srshift), 1079 (elfcpp::Elf_Xword)(r_howto.doffset), 1080 (elfcpp::Elf_Xword)((1 << r_howto.bsize) - 1)); 1081 } 1082 1083 static inline void 1084 imm_x_two_part_general(unsigned char* view, 1085 const Sized_relobj_file<size, big_endian>* object, 1086 const Symbol_value<size>* psymval, 1087 typename elfcpp::Elf_types<size>::Elf_Addr addend, 1088 typename elfcpp::Elf_types<size>::Elf_Addr address, 1089 unsigned int r_type) 1090 { 1091 1092 elfcpp::Elf_Xword doffset1 = 0llu; 1093 elfcpp::Elf_Xword doffset2 = 0llu; 1094 elfcpp::Elf_Xword dmask1 = 0llu; 1095 elfcpp::Elf_Xword dmask2 = 0llu; 1096 elfcpp::Elf_Xword rshift = 0llu; 1097 unsigned int pc_rel = 0; 1098 1099 switch (r_type) 1100 { 1101 case elfcpp::R_TILEGX_BROFF_X1: 1102 doffset1 = 31llu; 1103 doffset2 = 37llu; 1104 dmask1 = 0x3fllu; 1105 dmask2 = 0x1ffc0llu; 1106 rshift = 3llu; 1107 pc_rel = 1; 1108 break; 1109 case elfcpp::R_TILEGX_DEST_IMM8_X1: 1110 doffset1 = 31llu; 1111 doffset2 = 43llu; 1112 dmask1 = 0x3fllu; 1113 dmask2 = 0xc0llu; 1114 rshift = 0llu; 1115 break; 1116 } 1117 1118 if (pc_rel) 1119 This::template pcrela<64>(view, object, psymval, addend, address, 1120 rshift, doffset1, dmask1, doffset2, dmask2); 1121 else 1122 This::template rela<64>(view, object, psymval, addend, rshift, 1123 doffset1, dmask1, doffset2, dmask2); 1124 1125 } 1126 1127 static inline void 1128 tls_relax(unsigned char* view, unsigned int r_type, 1129 tls::Tls_optimization opt_t) 1130 { 1131 1132 const uint64_t TILEGX_X_MOVE_R0_R0 = 0x283bf8005107f000llu; 1133 const uint64_t TILEGX_Y_MOVE_R0_R0 = 0xae05f800540bf000llu; 1134 const uint64_t TILEGX_X_LD = 0x286ae80000000000llu; 1135 const uint64_t TILEGX_X_LD4S = 0x286a980000000000llu; 1136 const uint64_t TILEGX_X1_FULL_MASK = 0x3fffffff80000000llu; 1137 const uint64_t TILEGX_X0_RRR_MASK = 0x000000007ffc0000llu; 1138 const uint64_t TILEGX_X1_RRR_MASK = 0x3ffe000000000000llu; 1139 const uint64_t TILEGX_Y0_RRR_MASK = 0x00000000780c0000llu; 1140 const uint64_t TILEGX_Y1_RRR_MASK = 0x3c06000000000000llu; 1141 const uint64_t TILEGX_X0_RRR_SRCB_MASK = 0x000000007ffff000llu; 1142 const uint64_t TILEGX_X1_RRR_SRCB_MASK = 0x3ffff80000000000llu; 1143 const uint64_t TILEGX_Y0_RRR_SRCB_MASK = 0x00000000780ff000llu; 1144 const uint64_t TILEGX_Y1_RRR_SRCB_MASK = 0x3c07f80000000000llu; 1145 const uint64_t TILEGX_X_ADD_R0_R0_TP = 0x2807a800500f5000llu; 1146 const uint64_t TILEGX_Y_ADD_R0_R0_TP = 0x9a13a8002c275000llu; 1147 const uint64_t TILEGX_X_ADDX_R0_R0_TP = 0x2805a800500b5000llu; 1148 const uint64_t TILEGX_Y_ADDX_R0_R0_TP = 0x9a01a8002c035000llu; 1149 1150 const uint64_t R_TILEGX_IMM8_X0_TLS_ADD_MASK = 1151 (TILEGX_X0_RRR_MASK | (0x3Fllu << 12)); 1152 1153 const uint64_t R_TILEGX_IMM8_X1_TLS_ADD_MASK = 1154 (TILEGX_X1_RRR_MASK | (0x3Fllu << 43)); 1155 1156 const uint64_t R_TILEGX_IMM8_Y0_TLS_ADD_MASK = 1157 (TILEGX_Y0_RRR_MASK | (0x3Fllu << 12)); 1158 1159 const uint64_t R_TILEGX_IMM8_Y1_TLS_ADD_MASK = 1160 (TILEGX_Y1_RRR_MASK | (0x3Fllu << 43)); 1161 1162 const uint64_t R_TILEGX_IMM8_X0_TLS_ADD_LE_MASK = 1163 (TILEGX_X0_RRR_SRCB_MASK | (0x3Fllu << 6)); 1164 1165 const uint64_t R_TILEGX_IMM8_X1_TLS_ADD_LE_MASK = 1166 (TILEGX_X1_RRR_SRCB_MASK | (0x3Fllu << 37)); 1167 1168 const uint64_t R_TILEGX_IMM8_Y0_TLS_ADD_LE_MASK = 1169 (TILEGX_Y0_RRR_SRCB_MASK | (0x3Fllu << 6)); 1170 1171 const uint64_t R_TILEGX_IMM8_Y1_TLS_ADD_LE_MASK = 1172 (TILEGX_Y1_RRR_SRCB_MASK | (0x3Fllu << 37)); 1173 1174 typedef typename elfcpp::Swap<64, big_endian>::Valtype Valtype; 1175 Valtype* wv = reinterpret_cast<Valtype*>(view); 1176 Valtype val = elfcpp::Swap<64, big_endian>::readval(wv); 1177 Valtype reloc = 0; 1178 1179 switch (r_type) 1180 { 1181 case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: 1182 if (opt_t == tls::TLSOPT_NONE) { 1183 // GD/IE: 1. copy dest operand into the second source operand 1184 // 2. change the opcode to "add" 1185 reloc = (val & 0x3Fllu) << 12; // featch the dest reg 1186 reloc |= ((size == 32 1187 ? TILEGX_X_ADDX_R0_R0_TP 1188 : TILEGX_X_ADD_R0_R0_TP) 1189 & TILEGX_X0_RRR_MASK); // change opcode 1190 val &= ~R_TILEGX_IMM8_X0_TLS_ADD_MASK; 1191 } else if (opt_t == tls::TLSOPT_TO_LE) { 1192 // LE: 1. copy dest operand into the first source operand 1193 // 2. change the opcode to "move" 1194 reloc = (val & 0x3Fllu) << 6; 1195 reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK); 1196 val &= ~R_TILEGX_IMM8_X0_TLS_ADD_LE_MASK; 1197 } else 1198 gold_unreachable(); 1199 break; 1200 case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD: 1201 if (opt_t == tls::TLSOPT_NONE) { 1202 reloc = (val & (0x3Fllu << 31)) << 12; 1203 reloc |= ((size == 32 1204 ? TILEGX_X_ADDX_R0_R0_TP 1205 : TILEGX_X_ADD_R0_R0_TP) 1206 & TILEGX_X1_RRR_MASK); 1207 val &= ~R_TILEGX_IMM8_X1_TLS_ADD_MASK; 1208 } else if (opt_t == tls::TLSOPT_TO_LE) { 1209 reloc = (val & (0x3Fllu << 31)) << 6; 1210 reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X1_RRR_SRCB_MASK); 1211 val &= ~R_TILEGX_IMM8_X1_TLS_ADD_LE_MASK; 1212 } else 1213 gold_unreachable(); 1214 break; 1215 case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD: 1216 if (opt_t == tls::TLSOPT_NONE) { 1217 reloc = (val & 0x3Fllu) << 12; 1218 reloc |= ((size == 32 1219 ? TILEGX_Y_ADDX_R0_R0_TP 1220 : TILEGX_Y_ADD_R0_R0_TP) 1221 & TILEGX_Y0_RRR_MASK); 1222 val &= ~R_TILEGX_IMM8_Y0_TLS_ADD_MASK; 1223 } else if (opt_t == tls::TLSOPT_TO_LE) { 1224 reloc = (val & 0x3Fllu) << 6; 1225 reloc |= (TILEGX_Y_MOVE_R0_R0 & TILEGX_Y0_RRR_SRCB_MASK); 1226 val &= ~R_TILEGX_IMM8_Y0_TLS_ADD_LE_MASK; 1227 } else 1228 gold_unreachable(); 1229 break; 1230 case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD: 1231 if (opt_t == tls::TLSOPT_NONE) { 1232 reloc = (val & (0x3Fllu << 31)) << 12; 1233 reloc |= ((size == 32 1234 ? TILEGX_Y_ADDX_R0_R0_TP 1235 : TILEGX_Y_ADD_R0_R0_TP) 1236 & TILEGX_Y1_RRR_MASK); 1237 val &= ~R_TILEGX_IMM8_Y1_TLS_ADD_MASK; 1238 } else if (opt_t == tls::TLSOPT_TO_LE) { 1239 reloc = (val & (0x3Fllu << 31)) << 6; 1240 reloc |= (TILEGX_Y_MOVE_R0_R0 & TILEGX_Y1_RRR_SRCB_MASK); 1241 val &= ~R_TILEGX_IMM8_Y1_TLS_ADD_LE_MASK; 1242 } else 1243 gold_unreachable(); 1244 break; 1245 case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: 1246 if (opt_t == tls::TLSOPT_NONE) { 1247 // GD see comments for optimize_tls_reloc 1248 reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK; 1249 val &= ~TILEGX_X0_RRR_SRCB_MASK; 1250 } else if (opt_t == tls::TLSOPT_TO_IE 1251 || opt_t == tls::TLSOPT_TO_LE) { 1252 // IE/LE 1253 reloc = (size == 32 1254 ? TILEGX_X_ADDX_R0_R0_TP 1255 : TILEGX_X_ADD_R0_R0_TP) 1256 & TILEGX_X0_RRR_SRCB_MASK; 1257 val &= ~TILEGX_X0_RRR_SRCB_MASK; 1258 } 1259 break; 1260 case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD: 1261 if (opt_t == tls::TLSOPT_NONE) { 1262 reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X1_RRR_SRCB_MASK; 1263 val &= ~TILEGX_X1_RRR_SRCB_MASK; 1264 } else if (opt_t == tls::TLSOPT_TO_IE 1265 || opt_t == tls::TLSOPT_TO_LE) { 1266 reloc = (size == 32 1267 ? TILEGX_X_ADDX_R0_R0_TP 1268 : TILEGX_X_ADD_R0_R0_TP) 1269 & TILEGX_X1_RRR_SRCB_MASK; 1270 val &= ~TILEGX_X1_RRR_SRCB_MASK; 1271 } 1272 break; 1273 case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: 1274 if (opt_t == tls::TLSOPT_NONE) { 1275 reloc = TILEGX_Y_MOVE_R0_R0 & TILEGX_Y0_RRR_SRCB_MASK; 1276 val &= ~TILEGX_Y0_RRR_SRCB_MASK; 1277 } else if (opt_t == tls::TLSOPT_TO_IE 1278 || opt_t == tls::TLSOPT_TO_LE) { 1279 reloc = (size == 32 1280 ? TILEGX_Y_ADDX_R0_R0_TP 1281 : TILEGX_Y_ADD_R0_R0_TP) 1282 & TILEGX_Y0_RRR_SRCB_MASK; 1283 val &= ~TILEGX_Y0_RRR_SRCB_MASK; 1284 } 1285 break; 1286 case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: 1287 if (opt_t == tls::TLSOPT_NONE) { 1288 reloc = TILEGX_Y_MOVE_R0_R0 & TILEGX_Y1_RRR_SRCB_MASK; 1289 val &= ~TILEGX_Y1_RRR_SRCB_MASK; 1290 } else if (opt_t == tls::TLSOPT_TO_IE 1291 || opt_t == tls::TLSOPT_TO_LE) { 1292 reloc = (size == 32 1293 ? TILEGX_Y_ADDX_R0_R0_TP 1294 : TILEGX_Y_ADD_R0_R0_TP) 1295 & TILEGX_Y1_RRR_SRCB_MASK; 1296 val &= ~TILEGX_Y1_RRR_SRCB_MASK; 1297 } 1298 break; 1299 case elfcpp::R_TILEGX_TLS_IE_LOAD: 1300 if (opt_t == tls::TLSOPT_NONE) { 1301 // IE 1302 reloc = (size == 32 1303 ? TILEGX_X_LD4S 1304 : TILEGX_X_LD) 1305 & TILEGX_X1_RRR_SRCB_MASK; 1306 val &= ~TILEGX_X1_RRR_SRCB_MASK; 1307 } else if (opt_t == tls::TLSOPT_TO_LE) { 1308 // LE 1309 reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X1_RRR_SRCB_MASK; 1310 val &= ~TILEGX_X1_RRR_SRCB_MASK; 1311 } else 1312 gold_unreachable(); 1313 break; 1314 case elfcpp::R_TILEGX_TLS_GD_CALL: 1315 if (opt_t == tls::TLSOPT_TO_IE) { 1316 // ld/ld4s r0, r0 1317 reloc = (size == 32 1318 ? TILEGX_X_LD4S 1319 : TILEGX_X_LD) & TILEGX_X1_FULL_MASK; 1320 val &= ~TILEGX_X1_FULL_MASK; 1321 } else if (opt_t == tls::TLSOPT_TO_LE) { 1322 // move r0, r0 1323 reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X1_FULL_MASK; 1324 val &= ~TILEGX_X1_FULL_MASK; 1325 } else 1326 // should be handled in ::relocate 1327 gold_unreachable(); 1328 break; 1329 default: 1330 gold_unreachable(); 1331 break; 1332 } 1333 elfcpp::Swap<64, big_endian>::writeval(wv, val | reloc); 1334 } 1335 }; 1336 1337 template<> 1338 const Tilegx_relocate_functions<64, false>::Tilegx_howto 1339 Tilegx_relocate_functions<64, false>::howto[elfcpp::R_TILEGX_NUM] = 1340 { 1341 { 0, 0, 0, 0, 0}, // R_TILEGX_NONE 1342 { 0, 0, 0, 64, 0}, // R_TILEGX_64 1343 { 0, 0, 0, 32, 0}, // R_TILEGX_32 1344 { 0, 0, 0, 16, 0}, // R_TILEGX_16 1345 { 0, 0, 0, 8, 0}, // R_TILEGX_8 1346 { 0, 0, 1, 64, 0}, // R_TILEGX_64_PCREL 1347 { 0, 0, 1, 32, 0}, // R_TILEGX_32_PCREL 1348 { 0, 0, 1, 16, 0}, // R_TILEGX_16_PCREL 1349 { 0, 0, 1, 8, 0}, // R_TILEGX_8_PCREL 1350 { 0, 0, 0, 0, 0}, // R_TILEGX_HW0 1351 { 16, 0, 0, 0, 0}, // R_TILEGX_HW1 1352 { 32, 0, 0, 0, 0}, // R_TILEGX_HW2 1353 { 48, 0, 0, 0, 0}, // R_TILEGX_HW3 1354 { 0, 0, 0, 0, 0}, // R_TILEGX_HW0_LAST 1355 { 16, 0, 0, 0, 0}, // R_TILEGX_HW1_LAST 1356 { 32, 0, 0, 0, 0}, // R_TILEGX_HW2_LAST 1357 { 0, 0, 0, 0, 0}, // R_TILEGX_COPY 1358 { 0, 0, 0, 8, 0}, // R_TILEGX_GLOB_DAT 1359 { 0, 0, 0, 0, 0}, // R_TILEGX_JMP_SLOT 1360 { 0, 0, 0, 0, 0}, // R_TILEGX_RELATIVE 1361 { 3, 1, 1, 0, 0}, // R_TILEGX_BROFF_X1 1362 { 3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1 1363 { 3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1_PLT 1364 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_X0 1365 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_Y0 1366 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_X1 1367 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_Y1 1368 { 0, 1, 0, 8, 0}, // R_TILEGX_DEST_IMM8_X1 1369 { 0, 1, 0, 8, 0}, // R_TILEGX_MT_IMM14_X1 1370 { 0, 1, 0, 8, 0}, // R_TILEGX_MF_IMM14_X1 1371 { 0, 1, 0, 8, 0}, // R_TILEGX_MMSTART_X0 1372 { 0, 1, 0, 8, 0}, // R_TILEGX_MMEND_X0 1373 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_X0 1374 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_X1 1375 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_Y0 1376 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_Y1 1377 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0 1378 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0 1379 { 16, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW1 1380 { 16, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW1 1381 { 32, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW2 1382 { 32, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW2 1383 { 48, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW3 1384 { 48, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW3 1385 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST 1386 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST 1387 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST 1388 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST 1389 { 32, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST 1390 { 32, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST 1391 { 0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PCREL 1392 { 0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PCREL 1393 { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PCREL 1394 { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PCREL 1395 { 32, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PCREL 1396 { 32, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PCREL 1397 { 48, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW3_PCREL 1398 { 48, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW3_PCREL 1399 { 0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PCREL 1400 { 0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PCREL 1401 { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PCREL 1402 { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PCREL 1403 { 32, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PCREL 1404 { 32, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PCREL 1405 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_GOT 1406 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_GOT 1407 { 0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PLT_PCREL 1408 { 0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PLT_PCREL 1409 { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PLT_PCREL 1410 { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PLT_PCREL 1411 { 32, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PLT_PCREL 1412 { 32, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PLT_PCREL 1413 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_GOT 1414 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_GOT 1415 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_GOT 1416 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_GOT 1417 { 32, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_GOT 1418 { 32, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_GOT 1419 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_GD 1420 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_GD 1421 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_LE 1422 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_LE 1423 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 1424 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 1425 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 1426 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 1427 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 1428 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 1429 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 1430 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 1431 { 0, 0, 0, 0, 0}, // R_TILEGX_IRELATIVE 1432 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1433 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_IE 1434 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_IE 1435 { 0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 1436 { 0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 1437 { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 1438 { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 1439 { 32, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 1440 { 32, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 1441 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 1442 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 1443 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 1444 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 1445 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1446 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1447 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPMOD64 1448 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPOFF64 1449 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_TPOFF64 1450 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPMOD32 1451 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPOFF32 1452 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_TPOFF32 1453 { 3, 31, 1, 27, 0}, // R_TILEGX_TLS_GD_CALL 1454 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X0_TLS_GD_ADD 1455 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X1_TLS_GD_ADD 1456 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y0_TLS_GD_ADD 1457 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y1_TLS_GD_ADD 1458 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_IE_LOAD 1459 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X0_TLS_ADD 1460 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X1_TLS_ADD 1461 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y0_TLS_ADD 1462 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y1_TLS_ADD 1463 { 0, 0, 0, 0, 0}, // R_TILEGX_GNU_VTINHERIT 1464 { 0, 0, 0, 0, 0}, // R_TILEGX_GNU_VTENTRY 1465 }; 1466 1467 template<> 1468 const Tilegx_relocate_functions<32, false>::Tilegx_howto 1469 Tilegx_relocate_functions<32, false>::howto[elfcpp::R_TILEGX_NUM] = 1470 { 1471 { 0, 0, 0, 0, 0}, // R_TILEGX_NONE 1472 { 0, 0, 0, 64, 0}, // R_TILEGX_64 1473 { 0, 0, 0, 32, 0}, // R_TILEGX_32 1474 { 0, 0, 0, 16, 0}, // R_TILEGX_16 1475 { 0, 0, 0, 8, 0}, // R_TILEGX_8 1476 { 0, 0, 1, 64, 0}, // R_TILEGX_64_PCREL 1477 { 0, 0, 1, 32, 0}, // R_TILEGX_32_PCREL 1478 { 0, 0, 1, 16, 0}, // R_TILEGX_16_PCREL 1479 { 0, 0, 1, 8, 0}, // R_TILEGX_8_PCREL 1480 { 0, 0, 0, 0, 0}, // R_TILEGX_HW0 1481 { 16, 0, 0, 0, 0}, // R_TILEGX_HW1 1482 { 31, 0, 0, 0, 0}, // R_TILEGX_HW2 1483 { 31, 0, 0, 0, 0}, // R_TILEGX_HW3 1484 { 0, 0, 0, 0, 0}, // R_TILEGX_HW0_LAST 1485 { 16, 0, 0, 0, 0}, // R_TILEGX_HW1_LAST 1486 { 31, 0, 0, 0, 0}, // R_TILEGX_HW2_LAST 1487 { 0, 0, 0, 0, 0}, // R_TILEGX_COPY 1488 { 0, 0, 0, 8, 0}, // R_TILEGX_GLOB_DAT 1489 { 0, 0, 0, 0, 0}, // R_TILEGX_JMP_SLOT 1490 { 0, 0, 0, 0, 0}, // R_TILEGX_RELATIVE 1491 { 3, 1, 1, 0, 0}, // R_TILEGX_BROFF_X1 1492 { 3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1 1493 { 3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1_PLT 1494 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_X0 1495 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_Y0 1496 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_X1 1497 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_Y1 1498 { 0, 1, 0, 8, 0}, // R_TILEGX_DEST_IMM8_X1 1499 { 0, 1, 0, 8, 0}, // R_TILEGX_MT_IMM14_X1 1500 { 0, 1, 0, 8, 0}, // R_TILEGX_MF_IMM14_X1 1501 { 0, 1, 0, 8, 0}, // R_TILEGX_MMSTART_X0 1502 { 0, 1, 0, 8, 0}, // R_TILEGX_MMEND_X0 1503 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_X0 1504 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_X1 1505 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_Y0 1506 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_Y1 1507 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0 1508 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0 1509 { 16, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW1 1510 { 16, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW1 1511 { 31, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW2 1512 { 31, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW2 1513 { 31, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW3 1514 { 31, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW3 1515 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST 1516 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST 1517 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST 1518 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST 1519 { 31, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST 1520 { 31, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST 1521 { 0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PCREL 1522 { 0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PCREL 1523 { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PCREL 1524 { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PCREL 1525 { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PCREL 1526 { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PCREL 1527 { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW3_PCREL 1528 { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW3_PCREL 1529 { 0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PCREL 1530 { 0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PCREL 1531 { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PCREL 1532 { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PCREL 1533 { 31, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PCREL 1534 { 31, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PCREL 1535 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_GOT 1536 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_GOT 1537 { 0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PLT_PCREL 1538 { 0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PLT_PCREL 1539 { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PLT_PCREL 1540 { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PLT_PCREL 1541 { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PLT_PCREL 1542 { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PLT_PCREL 1543 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_GOT 1544 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_GOT 1545 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_GOT 1546 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_GOT 1547 { 31, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_GOT 1548 { 31, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_GOT 1549 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_GD 1550 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_GD 1551 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_LE 1552 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_LE 1553 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 1554 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 1555 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 1556 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 1557 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 1558 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 1559 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 1560 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 1561 { 0, 0, 0, 0, 0}, // R_TILEGX_IRELATIVE 1562 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1563 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_IE 1564 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_IE 1565 { 0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 1566 { 0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 1567 { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 1568 { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 1569 { 31, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 1570 { 31, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 1571 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 1572 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 1573 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 1574 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 1575 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1576 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1577 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPMOD64 1578 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPOFF64 1579 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_TPOFF64 1580 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPMOD32 1581 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPOFF32 1582 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_TPOFF32 1583 { 3, 31, 1, 27, 0}, // R_TILEGX_TLS_GD_CALL 1584 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X0_TLS_GD_ADD 1585 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X1_TLS_GD_ADD 1586 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y0_TLS_GD_ADD 1587 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y1_TLS_GD_ADD 1588 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_IE_LOAD 1589 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X0_TLS_ADD 1590 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X1_TLS_ADD 1591 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y0_TLS_ADD 1592 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y1_TLS_ADD 1593 { 0, 0, 0, 0, 0}, // R_TILEGX_GNU_VTINHERIT 1594 { 0, 0, 0, 0, 0}, // R_TILEGX_GNU_VTENTRY 1595 }; 1596 1597 template<> 1598 const Tilegx_relocate_functions<64, true>::Tilegx_howto 1599 Tilegx_relocate_functions<64, true>::howto[elfcpp::R_TILEGX_NUM] = 1600 { 1601 { 0, 0, 0, 0, 0}, // R_TILEGX_NONE 1602 { 0, 0, 0, 64, 0}, // R_TILEGX_64 1603 { 0, 0, 0, 32, 0}, // R_TILEGX_32 1604 { 0, 0, 0, 16, 0}, // R_TILEGX_16 1605 { 0, 0, 0, 8, 0}, // R_TILEGX_8 1606 { 0, 0, 1, 64, 0}, // R_TILEGX_64_PCREL 1607 { 0, 0, 1, 32, 0}, // R_TILEGX_32_PCREL 1608 { 0, 0, 1, 16, 0}, // R_TILEGX_16_PCREL 1609 { 0, 0, 1, 8, 0}, // R_TILEGX_8_PCREL 1610 { 0, 0, 0, 0, 0}, // R_TILEGX_HW0 1611 { 16, 0, 0, 0, 0}, // R_TILEGX_HW1 1612 { 32, 0, 0, 0, 0}, // R_TILEGX_HW2 1613 { 48, 0, 0, 0, 0}, // R_TILEGX_HW3 1614 { 0, 0, 0, 0, 0}, // R_TILEGX_HW0_LAST 1615 { 16, 0, 0, 0, 0}, // R_TILEGX_HW1_LAST 1616 { 32, 0, 0, 0, 0}, // R_TILEGX_HW2_LAST 1617 { 0, 0, 0, 0, 0}, // R_TILEGX_COPY 1618 { 0, 0, 0, 8, 0}, // R_TILEGX_GLOB_DAT 1619 { 0, 0, 0, 0, 0}, // R_TILEGX_JMP_SLOT 1620 { 0, 0, 0, 0, 0}, // R_TILEGX_RELATIVE 1621 { 3, 1, 1, 0, 0}, // R_TILEGX_BROFF_X1 1622 { 3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1 1623 { 3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1_PLT 1624 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_X0 1625 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_Y0 1626 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_X1 1627 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_Y1 1628 { 0, 1, 0, 8, 0}, // R_TILEGX_DEST_IMM8_X1 1629 { 0, 1, 0, 8, 0}, // R_TILEGX_MT_IMM14_X1 1630 { 0, 1, 0, 8, 0}, // R_TILEGX_MF_IMM14_X1 1631 { 0, 1, 0, 8, 0}, // R_TILEGX_MMSTART_X0 1632 { 0, 1, 0, 8, 0}, // R_TILEGX_MMEND_X0 1633 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_X0 1634 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_X1 1635 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_Y0 1636 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_Y1 1637 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0 1638 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0 1639 { 16, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW1 1640 { 16, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW1 1641 { 32, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW2 1642 { 32, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW2 1643 { 48, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW3 1644 { 48, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW3 1645 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST 1646 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST 1647 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST 1648 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST 1649 { 32, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST 1650 { 32, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST 1651 { 0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PCREL 1652 { 0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PCREL 1653 { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PCREL 1654 { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PCREL 1655 { 32, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PCREL 1656 { 32, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PCREL 1657 { 48, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW3_PCREL 1658 { 48, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW3_PCREL 1659 { 0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PCREL 1660 { 0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PCREL 1661 { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PCREL 1662 { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PCREL 1663 { 32, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PCREL 1664 { 32, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PCREL 1665 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_GOT 1666 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_GOT 1667 { 0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PLT_PCREL 1668 { 0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PLT_PCREL 1669 { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PLT_PCREL 1670 { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PLT_PCREL 1671 { 32, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PLT_PCREL 1672 { 32, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PLT_PCREL 1673 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_GOT 1674 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_GOT 1675 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_GOT 1676 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_GOT 1677 { 32, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_GOT 1678 { 32, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_GOT 1679 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_GD 1680 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_GD 1681 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_LE 1682 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_LE 1683 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 1684 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 1685 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 1686 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 1687 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 1688 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 1689 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 1690 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 1691 { 0, 0, 0, 0, 0}, // R_TILEGX_IRELATIVE 1692 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1693 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_IE 1694 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_IE 1695 { 0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 1696 { 0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 1697 { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 1698 { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 1699 { 32, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 1700 { 32, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 1701 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 1702 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 1703 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 1704 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 1705 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1706 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1707 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPMOD64 1708 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPOFF64 1709 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_TPOFF64 1710 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPMOD32 1711 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPOFF32 1712 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_TPOFF32 1713 { 3, 31, 1, 27, 0}, // R_TILEGX_TLS_GD_CALL 1714 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X0_TLS_GD_ADD 1715 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X1_TLS_GD_ADD 1716 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y0_TLS_GD_ADD 1717 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y1_TLS_GD_ADD 1718 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_IE_LOAD 1719 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X0_TLS_ADD 1720 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X1_TLS_ADD 1721 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y0_TLS_ADD 1722 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y1_TLS_ADD 1723 { 0, 0, 0, 0, 0}, // R_TILEGX_GNU_VTINHERIT 1724 { 0, 0, 0, 0, 0}, // R_TILEGX_GNU_VTENTRY 1725 }; 1726 1727 template<> 1728 const Tilegx_relocate_functions<32, true>::Tilegx_howto 1729 Tilegx_relocate_functions<32, true>::howto[elfcpp::R_TILEGX_NUM] = 1730 { 1731 { 0, 0, 0, 0, 0}, // R_TILEGX_NONE 1732 { 0, 0, 0, 64, 0}, // R_TILEGX_64 1733 { 0, 0, 0, 32, 0}, // R_TILEGX_32 1734 { 0, 0, 0, 16, 0}, // R_TILEGX_16 1735 { 0, 0, 0, 8, 0}, // R_TILEGX_8 1736 { 0, 0, 1, 64, 0}, // R_TILEGX_64_PCREL 1737 { 0, 0, 1, 32, 0}, // R_TILEGX_32_PCREL 1738 { 0, 0, 1, 16, 0}, // R_TILEGX_16_PCREL 1739 { 0, 0, 1, 8, 0}, // R_TILEGX_8_PCREL 1740 { 0, 0, 0, 0, 0}, // R_TILEGX_HW0 1741 { 16, 0, 0, 0, 0}, // R_TILEGX_HW1 1742 { 31, 0, 0, 0, 0}, // R_TILEGX_HW2 1743 { 31, 0, 0, 0, 0}, // R_TILEGX_HW3 1744 { 0, 0, 0, 0, 0}, // R_TILEGX_HW0_LAST 1745 { 16, 0, 0, 0, 0}, // R_TILEGX_HW1_LAST 1746 { 31, 0, 0, 0, 0}, // R_TILEGX_HW2_LAST 1747 { 0, 0, 0, 0, 0}, // R_TILEGX_COPY 1748 { 0, 0, 0, 8, 0}, // R_TILEGX_GLOB_DAT 1749 { 0, 0, 0, 0, 0}, // R_TILEGX_JMP_SLOT 1750 { 0, 0, 0, 0, 0}, // R_TILEGX_RELATIVE 1751 { 3, 1, 1, 0, 0}, // R_TILEGX_BROFF_X1 1752 { 3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1 1753 { 3, 31, 1, 27, 0}, // R_TILEGX_JUMPOFF_X1_PLT 1754 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_X0 1755 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_Y0 1756 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_X1 1757 { 0, 1, 0, 8, 0}, // R_TILEGX_IMM8_Y1 1758 { 0, 1, 0, 8, 0}, // R_TILEGX_DEST_IMM8_X1 1759 { 0, 1, 0, 8, 0}, // R_TILEGX_MT_IMM14_X1 1760 { 0, 1, 0, 8, 0}, // R_TILEGX_MF_IMM14_X1 1761 { 0, 1, 0, 8, 0}, // R_TILEGX_MMSTART_X0 1762 { 0, 1, 0, 8, 0}, // R_TILEGX_MMEND_X0 1763 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_X0 1764 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_X1 1765 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_Y0 1766 { 0, 1, 0, 8, 0}, // R_TILEGX_SHAMT_Y1 1767 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0 1768 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0 1769 { 16, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW1 1770 { 16, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW1 1771 { 31, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW2 1772 { 31, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW2 1773 { 31, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW3 1774 { 31, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW3 1775 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST 1776 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST 1777 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST 1778 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST 1779 { 31, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST 1780 { 31, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST 1781 { 0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PCREL 1782 { 0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PCREL 1783 { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PCREL 1784 { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PCREL 1785 { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PCREL 1786 { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PCREL 1787 { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW3_PCREL 1788 { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW3_PCREL 1789 { 0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PCREL 1790 { 0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PCREL 1791 { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PCREL 1792 { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PCREL 1793 { 31, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PCREL 1794 { 31, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PCREL 1795 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_GOT 1796 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_GOT 1797 { 0, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW0_PLT_PCREL 1798 { 0, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW0_PLT_PCREL 1799 { 16, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW1_PLT_PCREL 1800 { 16, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW1_PLT_PCREL 1801 { 31, 12, 1, 16, 0}, // R_TILEGX_IMM16_X0_HW2_PLT_PCREL 1802 { 31, 43, 1, 16, 0}, // R_TILEGX_IMM16_X1_HW2_PLT_PCREL 1803 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_GOT 1804 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_GOT 1805 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_GOT 1806 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_GOT 1807 { 31, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_GOT 1808 { 31, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_GOT 1809 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_GD 1810 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_GD 1811 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_LE 1812 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_LE 1813 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 1814 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 1815 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 1816 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 1817 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 1818 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 1819 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 1820 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 1821 { 0, 0, 0, 0, 0}, // R_TILEGX_IRELATIVE 1822 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1823 { 0, 12, 0, 16, 0}, // R_TILEGX_IMM16_X0_HW0_TLS_IE 1824 { 0, 43, 0, 16, 0}, // R_TILEGX_IMM16_X1_HW0_TLS_IE 1825 { 0, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 1826 { 0, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 1827 { 16, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 1828 { 16, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 1829 { 31, 12, 1, 16, 1}, // R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 1830 { 31, 43, 1, 16, 1}, // R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 1831 { 0, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 1832 { 0, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 1833 { 16, 12, 0, 16, 1}, // R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 1834 { 16, 43, 0, 16, 1}, // R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 1835 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1836 { 0, 0, 0, 0, 0}, // R_TILEGX_INVALID 1837 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPMOD64 1838 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPOFF64 1839 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_TPOFF64 1840 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPMOD32 1841 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_DTPOFF32 1842 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_TPOFF32 1843 { 3, 31, 1, 27, 0}, // R_TILEGX_TLS_GD_CALL 1844 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X0_TLS_GD_ADD 1845 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X1_TLS_GD_ADD 1846 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y0_TLS_GD_ADD 1847 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y1_TLS_GD_ADD 1848 { 0, 0, 0, 0, 0}, // R_TILEGX_TLS_IE_LOAD 1849 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X0_TLS_ADD 1850 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_X1_TLS_ADD 1851 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y0_TLS_ADD 1852 { 0, 0, 0, 0, 0}, // R_TILEGX_IMM8_Y1_TLS_ADD 1853 { 0, 0, 0, 0, 0}, // R_TILEGX_GNU_VTINHERIT 1854 { 0, 0, 0, 0, 0}, // R_TILEGX_GNU_VTENTRY 1855 }; 1856 1857 // Get the GOT section, creating it if necessary. 1858 1859 template<int size, bool big_endian> 1860 Output_data_got<size, big_endian>* 1861 Target_tilegx<size, big_endian>::got_section(Symbol_table* symtab, 1862 Layout* layout) 1863 { 1864 if (this->got_ == NULL) 1865 { 1866 gold_assert(symtab != NULL && layout != NULL); 1867 1868 // When using -z now, we can treat .got.plt as a relro section. 1869 // Without -z now, it is modified after program startup by lazy 1870 // PLT relocations. 1871 bool is_got_plt_relro = parameters->options().now(); 1872 Output_section_order got_order = (is_got_plt_relro 1873 ? ORDER_RELRO 1874 : ORDER_RELRO_LAST); 1875 Output_section_order got_plt_order = (is_got_plt_relro 1876 ? ORDER_RELRO 1877 : ORDER_NON_RELRO_FIRST); 1878 1879 this->got_ = new Output_data_got<size, big_endian>(); 1880 1881 layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, 1882 (elfcpp::SHF_ALLOC 1883 | elfcpp::SHF_WRITE), 1884 this->got_, got_order, true); 1885 1886 // Define _GLOBAL_OFFSET_TABLE_ at the start of the PLT. 1887 this->global_offset_table_ = 1888 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, 1889 Symbol_table::PREDEFINED, 1890 this->got_, 1891 0, 0, elfcpp::STT_OBJECT, 1892 elfcpp::STB_LOCAL, 1893 elfcpp::STV_HIDDEN, 0, 1894 false, false); 1895 1896 if (parameters->options().shared()) { 1897 // we need to keep the address of .dynamic section in the 1898 // first got entry for .so 1899 this->tilegx_dynamic_ = 1900 symtab->define_in_output_data("_TILEGX_DYNAMIC_", NULL, 1901 Symbol_table::PREDEFINED, 1902 layout->dynamic_section(), 1903 0, 0, elfcpp::STT_OBJECT, 1904 elfcpp::STB_LOCAL, 1905 elfcpp::STV_HIDDEN, 0, 1906 false, false); 1907 1908 this->got_->add_global(this->tilegx_dynamic_, GOT_TYPE_STANDARD); 1909 } else 1910 // for executable, just set the first entry to zero. 1911 this->got_->set_current_data_size(size / 8); 1912 1913 this->got_plt_ = new Output_data_space(size / 8, "** GOT PLT"); 1914 layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, 1915 (elfcpp::SHF_ALLOC 1916 | elfcpp::SHF_WRITE), 1917 this->got_plt_, got_plt_order, 1918 is_got_plt_relro); 1919 1920 // The first two entries are reserved. 1921 this->got_plt_->set_current_data_size 1922 (TILEGX_GOTPLT_RESERVE_COUNT * (size / 8)); 1923 1924 if (!is_got_plt_relro) 1925 { 1926 // Those bytes can go into the relro segment. 1927 layout->increase_relro(size / 8); 1928 } 1929 1930 1931 // If there are any IRELATIVE relocations, they get GOT entries 1932 // in .got.plt after the jump slot entries. 1933 this->got_irelative_ 1934 = new Output_data_space(size / 8, "** GOT IRELATIVE PLT"); 1935 layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, 1936 (elfcpp::SHF_ALLOC 1937 | elfcpp::SHF_WRITE), 1938 this->got_irelative_, 1939 got_plt_order, is_got_plt_relro); 1940 } 1941 1942 return this->got_; 1943 } 1944 1945 // Get the dynamic reloc section, creating it if necessary. 1946 1947 template<int size, bool big_endian> 1948 typename Target_tilegx<size, big_endian>::Reloc_section* 1949 Target_tilegx<size, big_endian>::rela_dyn_section(Layout* layout) 1950 { 1951 if (this->rela_dyn_ == NULL) 1952 { 1953 gold_assert(layout != NULL); 1954 this->rela_dyn_ = new Reloc_section(parameters->options().combreloc()); 1955 layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, 1956 elfcpp::SHF_ALLOC, this->rela_dyn_, 1957 ORDER_DYNAMIC_RELOCS, false); 1958 } 1959 return this->rela_dyn_; 1960 } 1961 1962 // Get the section to use for IRELATIVE relocs, creating it if 1963 // necessary. These go in .rela.dyn, but only after all other dynamic 1964 // relocations. They need to follow the other dynamic relocations so 1965 // that they can refer to global variables initialized by those 1966 // relocs. 1967 1968 template<int size, bool big_endian> 1969 typename Target_tilegx<size, big_endian>::Reloc_section* 1970 Target_tilegx<size, big_endian>::rela_irelative_section(Layout* layout) 1971 { 1972 if (this->rela_irelative_ == NULL) 1973 { 1974 // Make sure we have already created the dynamic reloc section. 1975 this->rela_dyn_section(layout); 1976 this->rela_irelative_ = new Reloc_section(false); 1977 layout->add_output_section_data(".rela.dyn", elfcpp::SHT_RELA, 1978 elfcpp::SHF_ALLOC, this->rela_irelative_, 1979 ORDER_DYNAMIC_RELOCS, false); 1980 gold_assert(this->rela_dyn_->output_section() 1981 == this->rela_irelative_->output_section()); 1982 } 1983 return this->rela_irelative_; 1984 } 1985 1986 // Initialize the PLT section. 1987 1988 template<int size, bool big_endian> 1989 void 1990 Output_data_plt_tilegx<size, big_endian>::init(Layout* layout) 1991 { 1992 this->rel_ = new Reloc_section(false); 1993 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, 1994 elfcpp::SHF_ALLOC, this->rel_, 1995 ORDER_DYNAMIC_PLT_RELOCS, false); 1996 } 1997 1998 template<int size, bool big_endian> 1999 void 2000 Output_data_plt_tilegx<size, big_endian>::do_adjust_output_section( 2001 Output_section* os) 2002 { 2003 os->set_entsize(this->get_plt_entry_size()); 2004 } 2005 2006 // Add an entry to the PLT. 2007 2008 template<int size, bool big_endian> 2009 void 2010 Output_data_plt_tilegx<size, big_endian>::add_entry(Symbol_table* symtab, 2011 Layout* layout, Symbol* gsym) 2012 { 2013 gold_assert(!gsym->has_plt_offset()); 2014 2015 unsigned int plt_index; 2016 off_t plt_offset; 2017 section_offset_type got_offset; 2018 2019 unsigned int* pcount; 2020 unsigned int reserved; 2021 Output_data_space* got; 2022 if (gsym->type() == elfcpp::STT_GNU_IFUNC 2023 && gsym->can_use_relative_reloc(false)) 2024 { 2025 pcount = &this->irelative_count_; 2026 reserved = 0; 2027 got = this->got_irelative_; 2028 } 2029 else 2030 { 2031 pcount = &this->count_; 2032 reserved = TILEGX_GOTPLT_RESERVE_COUNT; 2033 got = this->got_plt_; 2034 } 2035 2036 if (!this->is_data_size_valid()) 2037 { 2038 plt_index = *pcount; 2039 2040 // TILEGX .plt section layout 2041 // 2042 // ---- 2043 // plt_header 2044 // ---- 2045 // plt stub 2046 // ---- 2047 // ... 2048 // ---- 2049 // 2050 // TILEGX .got.plt section layout 2051 // 2052 // ---- 2053 // reserv1 2054 // ---- 2055 // reserv2 2056 // ---- 2057 // entries for normal function 2058 // ---- 2059 // ... 2060 // ---- 2061 // entries for ifunc 2062 // ---- 2063 // ... 2064 // ---- 2065 if (got == this->got_irelative_) 2066 plt_offset = plt_index * this->get_plt_entry_size(); 2067 else 2068 plt_offset = (plt_index + 1) * this->get_plt_entry_size(); 2069 2070 ++*pcount; 2071 2072 got_offset = (plt_index + reserved) * (size / 8); 2073 gold_assert(got_offset == got->current_data_size()); 2074 2075 // Every PLT entry needs a GOT entry which points back to the PLT 2076 // entry (this will be changed by the dynamic linker, normally 2077 // lazily when the function is called). 2078 got->set_current_data_size(got_offset + size / 8); 2079 } 2080 else 2081 { 2082 // FIXME: This is probably not correct for IRELATIVE relocs. 2083 2084 // For incremental updates, find an available slot. 2085 plt_offset = this->free_list_.allocate(this->get_plt_entry_size(), 2086 this->get_plt_entry_size(), 0); 2087 if (plt_offset == -1) 2088 gold_fallback(_("out of patch space (PLT);" 2089 " relink with --incremental-full")); 2090 2091 // The GOT and PLT entries have a 1-1 correspondance, so the GOT offset 2092 // can be calculated from the PLT index, adjusting for the three 2093 // reserved entries at the beginning of the GOT. 2094 plt_index = plt_offset / this->get_plt_entry_size() - 1; 2095 got_offset = (plt_index + reserved) * (size / 8); 2096 } 2097 2098 gsym->set_plt_offset(plt_offset); 2099 2100 // Every PLT entry needs a reloc. 2101 this->add_relocation(symtab, layout, gsym, got_offset); 2102 2103 // Note that we don't need to save the symbol. The contents of the 2104 // PLT are independent of which symbols are used. The symbols only 2105 // appear in the relocations. 2106 } 2107 2108 // Add an entry to the PLT for a local STT_GNU_IFUNC symbol. Return 2109 // the PLT offset. 2110 2111 template<int size, bool big_endian> 2112 unsigned int 2113 Output_data_plt_tilegx<size, big_endian>::add_local_ifunc_entry( 2114 Symbol_table* symtab, 2115 Layout* layout, 2116 Sized_relobj_file<size, big_endian>* relobj, 2117 unsigned int local_sym_index) 2118 { 2119 unsigned int plt_offset = 2120 this->irelative_count_ * this->get_plt_entry_size(); 2121 ++this->irelative_count_; 2122 2123 section_offset_type got_offset = this->got_irelative_->current_data_size(); 2124 2125 // Every PLT entry needs a GOT entry which points back to the PLT 2126 // entry. 2127 this->got_irelative_->set_current_data_size(got_offset + size / 8); 2128 2129 // Every PLT entry needs a reloc. 2130 Reloc_section* rela = this->rela_irelative(symtab, layout); 2131 rela->add_symbolless_local_addend(relobj, local_sym_index, 2132 elfcpp::R_TILEGX_IRELATIVE, 2133 this->got_irelative_, got_offset, 0); 2134 2135 return plt_offset; 2136 } 2137 2138 // Add the relocation for a PLT entry. 2139 2140 template<int size, bool big_endian> 2141 void 2142 Output_data_plt_tilegx<size, big_endian>::add_relocation(Symbol_table* symtab, 2143 Layout* layout, 2144 Symbol* gsym, 2145 unsigned int got_offset) 2146 { 2147 if (gsym->type() == elfcpp::STT_GNU_IFUNC 2148 && gsym->can_use_relative_reloc(false)) 2149 { 2150 Reloc_section* rela = this->rela_irelative(symtab, layout); 2151 rela->add_symbolless_global_addend(gsym, elfcpp::R_TILEGX_IRELATIVE, 2152 this->got_irelative_, got_offset, 0); 2153 } 2154 else 2155 { 2156 gsym->set_needs_dynsym_entry(); 2157 this->rel_->add_global(gsym, elfcpp::R_TILEGX_JMP_SLOT, this->got_plt_, 2158 got_offset, 0); 2159 } 2160 } 2161 2162 // Return where the IRELATIVE relocations should go in the PLT. These 2163 // follow the JUMP_SLOT and the TLSDESC relocations. 2164 2165 template<int size, bool big_endian> 2166 typename Output_data_plt_tilegx<size, big_endian>::Reloc_section* 2167 Output_data_plt_tilegx<size, big_endian>::rela_irelative(Symbol_table* symtab, 2168 Layout* layout) 2169 { 2170 if (this->irelative_rel_ == NULL) 2171 { 2172 // case we see any later on. 2173 this->irelative_rel_ = new Reloc_section(false); 2174 layout->add_output_section_data(".rela.plt", elfcpp::SHT_RELA, 2175 elfcpp::SHF_ALLOC, this->irelative_rel_, 2176 ORDER_DYNAMIC_PLT_RELOCS, false); 2177 gold_assert(this->irelative_rel_->output_section() 2178 == this->rel_->output_section()); 2179 2180 if (parameters->doing_static_link()) 2181 { 2182 // A statically linked executable will only have a .rela.plt 2183 // section to hold R_TILEGX_IRELATIVE relocs for 2184 // STT_GNU_IFUNC symbols. The library will use these 2185 // symbols to locate the IRELATIVE relocs at program startup 2186 // time. 2187 symtab->define_in_output_data("__rela_iplt_start", NULL, 2188 Symbol_table::PREDEFINED, 2189 this->irelative_rel_, 0, 0, 2190 elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, 2191 elfcpp::STV_HIDDEN, 0, false, true); 2192 symtab->define_in_output_data("__rela_iplt_end", NULL, 2193 Symbol_table::PREDEFINED, 2194 this->irelative_rel_, 0, 0, 2195 elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL, 2196 elfcpp::STV_HIDDEN, 0, true, true); 2197 } 2198 } 2199 return this->irelative_rel_; 2200 } 2201 2202 // Return the PLT address to use for a global symbol. 2203 2204 template<int size, bool big_endian> 2205 uint64_t 2206 Output_data_plt_tilegx<size, big_endian>::address_for_global( 2207 const Symbol* gsym) 2208 { 2209 uint64_t offset = 0; 2210 if (gsym->type() == elfcpp::STT_GNU_IFUNC 2211 && gsym->can_use_relative_reloc(false)) 2212 offset = (this->count_ + 1) * this->get_plt_entry_size(); 2213 return this->address() + offset + gsym->plt_offset(); 2214 } 2215 2216 // Return the PLT address to use for a local symbol. These are always 2217 // IRELATIVE relocs. 2218 2219 template<int size, bool big_endian> 2220 uint64_t 2221 Output_data_plt_tilegx<size, big_endian>::address_for_local( 2222 const Relobj* object, 2223 unsigned int r_sym) 2224 { 2225 return (this->address() 2226 + (this->count_ + 1) * this->get_plt_entry_size() 2227 + object->local_plt_offset(r_sym)); 2228 } 2229 2230 // Set the final size. 2231 template<int size, bool big_endian> 2232 void 2233 Output_data_plt_tilegx<size, big_endian>::set_final_data_size() 2234 { 2235 unsigned int count = this->count_ + this->irelative_count_; 2236 this->set_data_size((count + 1) * this->get_plt_entry_size()); 2237 } 2238 2239 // The first entry in the PLT for an executable. 2240 template<> 2241 const unsigned char 2242 Output_data_plt_tilegx<64, false>::first_plt_entry[plt_entry_size] = 2243 { 2244 0x00, 0x30, 0x48, 0x51, 2245 0x6e, 0x43, 0xa0, 0x18, // { ld_add r28, r27, 8 } 2246 0x00, 0x30, 0xbc, 0x35, 2247 0x00, 0x40, 0xde, 0x9e, // { ld r27, r27 } 2248 0xff, 0xaf, 0x30, 0x40, 2249 0x60, 0x73, 0x6a, 0x28, // { info 10 ; jr r27 } 2250 // padding 2251 0x00, 0x00, 0x00, 0x00, 2252 0x00, 0x00, 0x00, 0x00, 2253 0x00, 0x00, 0x00, 0x00, 2254 0x00, 0x00, 0x00, 0x00 2255 }; 2256 2257 template<> 2258 const unsigned char 2259 Output_data_plt_tilegx<32, false>::first_plt_entry[plt_entry_size] = 2260 { 2261 0x00, 0x30, 0x48, 0x51, 2262 0x6e, 0x23, 0x58, 0x18, // { ld4s_add r28, r27, 4 } 2263 0x00, 0x30, 0xbc, 0x35, 2264 0x00, 0x40, 0xde, 0x9c, // { ld4s r27, r27 } 2265 0xff, 0xaf, 0x30, 0x40, 2266 0x60, 0x73, 0x6a, 0x28, // { info 10 ; jr r27 } 2267 // padding 2268 0x00, 0x00, 0x00, 0x00, 2269 0x00, 0x00, 0x00, 0x00, 2270 0x00, 0x00, 0x00, 0x00, 2271 0x00, 0x00, 0x00, 0x00 2272 }; 2273 2274 template<> 2275 const unsigned char 2276 Output_data_plt_tilegx<64, true>::first_plt_entry[plt_entry_size] = 2277 { 2278 0x00, 0x30, 0x48, 0x51, 2279 0x6e, 0x43, 0xa0, 0x18, // { ld_add r28, r27, 8 } 2280 0x00, 0x30, 0xbc, 0x35, 2281 0x00, 0x40, 0xde, 0x9e, // { ld r27, r27 } 2282 0xff, 0xaf, 0x30, 0x40, 2283 0x60, 0x73, 0x6a, 0x28, // { info 10 ; jr r27 } 2284 // padding 2285 0x00, 0x00, 0x00, 0x00, 2286 0x00, 0x00, 0x00, 0x00, 2287 0x00, 0x00, 0x00, 0x00, 2288 0x00, 0x00, 0x00, 0x00 2289 }; 2290 2291 template<> 2292 const unsigned char 2293 Output_data_plt_tilegx<32, true>::first_plt_entry[plt_entry_size] = 2294 { 2295 0x00, 0x30, 0x48, 0x51, 2296 0x6e, 0x23, 0x58, 0x18, // { ld4s_add r28, r27, 4 } 2297 0x00, 0x30, 0xbc, 0x35, 2298 0x00, 0x40, 0xde, 0x9c, // { ld4s r27, r27 } 2299 0xff, 0xaf, 0x30, 0x40, 2300 0x60, 0x73, 0x6a, 0x28, // { info 10 ; jr r27 } 2301 // padding 2302 0x00, 0x00, 0x00, 0x00, 2303 0x00, 0x00, 0x00, 0x00, 2304 0x00, 0x00, 0x00, 0x00, 2305 0x00, 0x00, 0x00, 0x00 2306 }; 2307 2308 template<int size, bool big_endian> 2309 void 2310 Output_data_plt_tilegx<size, big_endian>::fill_first_plt_entry( 2311 unsigned char* pov) 2312 { 2313 memcpy(pov, first_plt_entry, plt_entry_size); 2314 } 2315 2316 // Subsequent entries in the PLT for an executable. 2317 2318 template<> 2319 const unsigned char 2320 Output_data_plt_tilegx<64, false>::plt_entry[plt_entry_size] = 2321 { 2322 0xdc, 0x0f, 0x00, 0x10, 2323 0x0d, 0xf0, 0x6a, 0x28, // { moveli r28, 0 ; lnk r26 } 2324 0xdb, 0x0f, 0x00, 0x10, 2325 0x8e, 0x03, 0x00, 0x38, // { moveli r27, 0 ; shl16insli r28, r28, 0 } 2326 0x9c, 0xc6, 0x0d, 0xd0, 2327 0x6d, 0x03, 0x00, 0x38, // { add r28, r26, r28 ; shl16insli r27, r27, 0 } 2328 0x9b, 0xb6, 0xc5, 0xad, 2329 0xff, 0x57, 0xe0, 0x8e, // { add r27, r26, r27 ; info 10 ; ld r28, r28 } 2330 0xdd, 0x0f, 0x00, 0x70, 2331 0x80, 0x73, 0x6a, 0x28, // { shl16insli r29, zero, 0 ; jr r28 } 2332 2333 }; 2334 2335 template<> 2336 const unsigned char 2337 Output_data_plt_tilegx<32, false>::plt_entry[plt_entry_size] = 2338 { 2339 0xdc, 0x0f, 0x00, 0x10, 2340 0x0d, 0xf0, 0x6a, 0x28, // { moveli r28, 0 ; lnk r26 } 2341 0xdb, 0x0f, 0x00, 0x10, 2342 0x8e, 0x03, 0x00, 0x38, // { moveli r27, 0 ; shl16insli r28, r28, 0 } 2343 0x9c, 0xc6, 0x0d, 0xd0, 2344 0x6d, 0x03, 0x00, 0x38, // { add r28, r26, r28 ; shl16insli r27, r27, 0 } 2345 0x9b, 0xb6, 0xc5, 0xad, 2346 0xff, 0x57, 0xe0, 0x8c, // { add r27, r26, r27 ; info 10 ; ld4s r28, r28 } 2347 0xdd, 0x0f, 0x00, 0x70, 2348 0x80, 0x73, 0x6a, 0x28, // { shl16insli r29, zero, 0 ; jr r28 } 2349 }; 2350 2351 template<> 2352 const unsigned char 2353 Output_data_plt_tilegx<64, true>::plt_entry[plt_entry_size] = 2354 { 2355 0xdc, 0x0f, 0x00, 0x10, 2356 0x0d, 0xf0, 0x6a, 0x28, // { moveli r28, 0 ; lnk r26 } 2357 0xdb, 0x0f, 0x00, 0x10, 2358 0x8e, 0x03, 0x00, 0x38, // { moveli r27, 0 ; shl16insli r28, r28, 0 } 2359 0x9c, 0xc6, 0x0d, 0xd0, 2360 0x6d, 0x03, 0x00, 0x38, // { add r28, r26, r28 ; shl16insli r27, r27, 0 } 2361 0x9b, 0xb6, 0xc5, 0xad, 2362 0xff, 0x57, 0xe0, 0x8e, // { add r27, r26, r27 ; info 10 ; ld r28, r28 } 2363 0xdd, 0x0f, 0x00, 0x70, 2364 0x80, 0x73, 0x6a, 0x28, // { shl16insli r29, zero, 0 ; jr r28 } 2365 2366 }; 2367 2368 template<> 2369 const unsigned char 2370 Output_data_plt_tilegx<32, true>::plt_entry[plt_entry_size] = 2371 { 2372 0xdc, 0x0f, 0x00, 0x10, 2373 0x0d, 0xf0, 0x6a, 0x28, // { moveli r28, 0 ; lnk r26 } 2374 0xdb, 0x0f, 0x00, 0x10, 2375 0x8e, 0x03, 0x00, 0x38, // { moveli r27, 0 ; shl16insli r28, r28, 0 } 2376 0x9c, 0xc6, 0x0d, 0xd0, 2377 0x6d, 0x03, 0x00, 0x38, // { add r28, r26, r28 ; shl16insli r27, r27, 0 } 2378 0x9b, 0xb6, 0xc5, 0xad, 2379 0xff, 0x57, 0xe0, 0x8c, // { add r27, r26, r27 ; info 10 ; ld4s r28, r28 } 2380 0xdd, 0x0f, 0x00, 0x70, 2381 0x80, 0x73, 0x6a, 0x28, // { shl16insli r29, zero, 0 ; jr r28 } 2382 }; 2383 2384 template<int size, bool big_endian> 2385 void 2386 Output_data_plt_tilegx<size, big_endian>::fill_plt_entry( 2387 unsigned char* pov, 2388 typename elfcpp::Elf_types<size>::Elf_Addr gotplt_base, 2389 unsigned int got_offset, 2390 typename elfcpp::Elf_types<size>::Elf_Addr plt_base, 2391 unsigned int plt_offset, unsigned int plt_index) 2392 { 2393 2394 const uint32_t TILEGX_IMM16_MASK = 0xFFFF; 2395 const uint32_t TILEGX_X0_IMM16_BITOFF = 12; 2396 const uint32_t TILEGX_X1_IMM16_BITOFF = 43; 2397 2398 typedef typename elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::Valtype 2399 Valtype; 2400 memcpy(pov, plt_entry, plt_entry_size); 2401 2402 // first bundle in plt stub - x0 2403 Valtype* wv = reinterpret_cast<Valtype*>(pov); 2404 Valtype val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv); 2405 Valtype reloc = 2406 ((gotplt_base + got_offset) - (plt_base + plt_offset + 8)) >> 16; 2407 elfcpp::Elf_Xword dst_mask = 2408 (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X0_IMM16_BITOFF; 2409 val &= ~dst_mask; 2410 reloc &= TILEGX_IMM16_MASK; 2411 elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv, 2412 val | (reloc<<TILEGX_X0_IMM16_BITOFF)); 2413 2414 // second bundle in plt stub - x1 2415 wv = reinterpret_cast<Valtype*>(pov + 8); 2416 val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv); 2417 reloc = (gotplt_base + got_offset) - (plt_base + plt_offset + 8); 2418 dst_mask = (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X1_IMM16_BITOFF; 2419 val &= ~dst_mask; 2420 reloc &= TILEGX_IMM16_MASK; 2421 elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv, 2422 val | (reloc<<TILEGX_X1_IMM16_BITOFF)); 2423 2424 // second bundle in plt stub - x0 2425 wv = reinterpret_cast<Valtype*>(pov + 8); 2426 val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv); 2427 reloc = (gotplt_base - (plt_base + plt_offset + 8)) >> 16; 2428 dst_mask = (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X0_IMM16_BITOFF; 2429 val &= ~dst_mask; 2430 reloc &= TILEGX_IMM16_MASK; 2431 elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv, 2432 val | (reloc<<TILEGX_X0_IMM16_BITOFF)); 2433 2434 // third bundle in plt stub - x1 2435 wv = reinterpret_cast<Valtype*>(pov + 16); 2436 val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv); 2437 reloc = gotplt_base - (plt_base + plt_offset + 8); 2438 dst_mask = (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X1_IMM16_BITOFF; 2439 val &= ~dst_mask; 2440 reloc &= TILEGX_IMM16_MASK; 2441 elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv, 2442 val | (reloc<<TILEGX_X1_IMM16_BITOFF)); 2443 2444 // fifth bundle in plt stub - carry plt_index x0 2445 wv = reinterpret_cast<Valtype*>(pov + 32); 2446 val = elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::readval(wv); 2447 dst_mask = (elfcpp::Elf_Xword)(TILEGX_IMM16_MASK) << TILEGX_X0_IMM16_BITOFF; 2448 val &= ~dst_mask; 2449 plt_index &= TILEGX_IMM16_MASK; 2450 elfcpp::Swap<TILEGX_INST_BUNDLE_SIZE, big_endian>::writeval(wv, 2451 val | (plt_index<<TILEGX_X0_IMM16_BITOFF)); 2452 2453 } 2454 2455 // Write out the PLT. This uses the hand-coded instructions above. 2456 2457 template<int size, bool big_endian> 2458 void 2459 Output_data_plt_tilegx<size, big_endian>::do_write(Output_file* of) 2460 { 2461 const off_t offset = this->offset(); 2462 const section_size_type oview_size = 2463 convert_to_section_size_type(this->data_size()); 2464 unsigned char* const oview = of->get_output_view(offset, oview_size); 2465 2466 const off_t got_file_offset = this->got_plt_->offset(); 2467 gold_assert(parameters->incremental_update() 2468 || (got_file_offset + this->got_plt_->data_size() 2469 == this->got_irelative_->offset())); 2470 const section_size_type got_size = 2471 convert_to_section_size_type(this->got_plt_->data_size() 2472 + this->got_irelative_->data_size()); 2473 unsigned char* const got_view = of->get_output_view(got_file_offset, 2474 got_size); 2475 2476 unsigned char* pov = oview; 2477 2478 // The base address of the .plt section. 2479 typename elfcpp::Elf_types<size>::Elf_Addr plt_address = this->address(); 2480 typename elfcpp::Elf_types<size>::Elf_Addr got_address = 2481 this->got_plt_->address(); 2482 2483 this->fill_first_plt_entry(pov); 2484 pov += this->get_plt_entry_size(); 2485 2486 unsigned char* got_pov = got_view; 2487 2488 // first entry of .got.plt are set to -1 2489 // second entry of .got.plt are set to 0 2490 memset(got_pov, 0xff, size / 8); 2491 got_pov += size / 8; 2492 memset(got_pov, 0x0, size / 8); 2493 got_pov += size / 8; 2494 2495 unsigned int plt_offset = this->get_plt_entry_size(); 2496 const unsigned int count = this->count_ + this->irelative_count_; 2497 unsigned int got_offset = (size / 8) * TILEGX_GOTPLT_RESERVE_COUNT; 2498 for (unsigned int plt_index = 0; 2499 plt_index < count; 2500 ++plt_index, 2501 pov += this->get_plt_entry_size(), 2502 got_pov += size / 8, 2503 plt_offset += this->get_plt_entry_size(), 2504 got_offset += size / 8) 2505 { 2506 // Set and adjust the PLT entry itself. 2507 this->fill_plt_entry(pov, got_address, got_offset, 2508 plt_address, plt_offset, plt_index); 2509 2510 // Initialize entry in .got.plt to plt start address 2511 elfcpp::Swap<size, big_endian>::writeval(got_pov, plt_address); 2512 } 2513 2514 gold_assert(static_cast<section_size_type>(pov - oview) == oview_size); 2515 gold_assert(static_cast<section_size_type>(got_pov - got_view) == got_size); 2516 2517 of->write_output_view(offset, oview_size, oview); 2518 of->write_output_view(got_file_offset, got_size, got_view); 2519 } 2520 2521 // Create the PLT section. 2522 2523 template<int size, bool big_endian> 2524 void 2525 Target_tilegx<size, big_endian>::make_plt_section(Symbol_table* symtab, 2526 Layout* layout) 2527 { 2528 if (this->plt_ == NULL) 2529 { 2530 // Create the GOT sections first. 2531 this->got_section(symtab, layout); 2532 2533 // Ensure that .rela.dyn always appears before .rela.plt, 2534 // because on TILE-Gx, .rela.dyn needs to include .rela.plt 2535 // in it's range. 2536 this->rela_dyn_section(layout); 2537 2538 this->plt_ = new Output_data_plt_tilegx<size, big_endian>(layout, 2539 TILEGX_INST_BUNDLE_SIZE, this->got_, this->got_plt_, 2540 this->got_irelative_); 2541 2542 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, 2543 (elfcpp::SHF_ALLOC 2544 | elfcpp::SHF_EXECINSTR), 2545 this->plt_, ORDER_NON_RELRO_FIRST, 2546 false); 2547 2548 // Make the sh_info field of .rela.plt point to .plt. 2549 Output_section* rela_plt_os = this->plt_->rela_plt()->output_section(); 2550 rela_plt_os->set_info_section(this->plt_->output_section()); 2551 } 2552 } 2553 2554 // Create a PLT entry for a global symbol. 2555 2556 template<int size, bool big_endian> 2557 void 2558 Target_tilegx<size, big_endian>::make_plt_entry(Symbol_table* symtab, 2559 Layout* layout, Symbol* gsym) 2560 { 2561 if (gsym->has_plt_offset()) 2562 return; 2563 2564 if (this->plt_ == NULL) 2565 this->make_plt_section(symtab, layout); 2566 2567 this->plt_->add_entry(symtab, layout, gsym); 2568 } 2569 2570 // Make a PLT entry for a local STT_GNU_IFUNC symbol. 2571 2572 template<int size, bool big_endian> 2573 void 2574 Target_tilegx<size, big_endian>::make_local_ifunc_plt_entry( 2575 Symbol_table* symtab, Layout* layout, 2576 Sized_relobj_file<size, big_endian>* relobj, 2577 unsigned int local_sym_index) 2578 { 2579 if (relobj->local_has_plt_offset(local_sym_index)) 2580 return; 2581 if (this->plt_ == NULL) 2582 this->make_plt_section(symtab, layout); 2583 unsigned int plt_offset = this->plt_->add_local_ifunc_entry(symtab, layout, 2584 relobj, 2585 local_sym_index); 2586 relobj->set_local_plt_offset(local_sym_index, plt_offset); 2587 } 2588 2589 // Return the number of entries in the PLT. 2590 2591 template<int size, bool big_endian> 2592 unsigned int 2593 Target_tilegx<size, big_endian>::plt_entry_count() const 2594 { 2595 if (this->plt_ == NULL) 2596 return 0; 2597 return this->plt_->entry_count(); 2598 } 2599 2600 // Return the offset of the first non-reserved PLT entry. 2601 2602 template<int size, bool big_endian> 2603 unsigned int 2604 Target_tilegx<size, big_endian>::first_plt_entry_offset() const 2605 { 2606 return this->plt_->first_plt_entry_offset(); 2607 } 2608 2609 // Return the size of each PLT entry. 2610 2611 template<int size, bool big_endian> 2612 unsigned int 2613 Target_tilegx<size, big_endian>::plt_entry_size() const 2614 { 2615 return this->plt_->get_plt_entry_size(); 2616 } 2617 2618 // Create the GOT and PLT sections for an incremental update. 2619 2620 template<int size, bool big_endian> 2621 Output_data_got_base* 2622 Target_tilegx<size, big_endian>::init_got_plt_for_update(Symbol_table* symtab, 2623 Layout* layout, 2624 unsigned int got_count, 2625 unsigned int plt_count) 2626 { 2627 gold_assert(this->got_ == NULL); 2628 2629 this->got_ = 2630 new Output_data_got<size, big_endian>((got_count 2631 + TILEGX_GOT_RESERVE_COUNT) 2632 * (size / 8)); 2633 layout->add_output_section_data(".got", elfcpp::SHT_PROGBITS, 2634 (elfcpp::SHF_ALLOC 2635 | elfcpp::SHF_WRITE), 2636 this->got_, ORDER_RELRO_LAST, 2637 true); 2638 2639 // Define _GLOBAL_OFFSET_TABLE_ at the start of the GOT. 2640 this->global_offset_table_ = 2641 symtab->define_in_output_data("_GLOBAL_OFFSET_TABLE_", NULL, 2642 Symbol_table::PREDEFINED, 2643 this->got_, 2644 0, 0, elfcpp::STT_OBJECT, 2645 elfcpp::STB_LOCAL, 2646 elfcpp::STV_HIDDEN, 0, 2647 false, false); 2648 2649 if (parameters->options().shared()) { 2650 this->tilegx_dynamic_ = 2651 symtab->define_in_output_data("_TILEGX_DYNAMIC_", NULL, 2652 Symbol_table::PREDEFINED, 2653 layout->dynamic_section(), 2654 0, 0, elfcpp::STT_OBJECT, 2655 elfcpp::STB_LOCAL, 2656 elfcpp::STV_HIDDEN, 0, 2657 false, false); 2658 2659 this->got_->add_global(this->tilegx_dynamic_, GOT_TYPE_STANDARD); 2660 } else 2661 this->got_->set_current_data_size(size / 8); 2662 2663 // Add the two reserved entries. 2664 this->got_plt_ 2665 = new Output_data_space((plt_count + TILEGX_GOTPLT_RESERVE_COUNT) 2666 * (size / 8), size / 8, "** GOT PLT"); 2667 layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, 2668 (elfcpp::SHF_ALLOC 2669 | elfcpp::SHF_WRITE), 2670 this->got_plt_, ORDER_NON_RELRO_FIRST, 2671 false); 2672 2673 // If there are any IRELATIVE relocations, they get GOT entries in 2674 // .got.plt after the jump slot. 2675 this->got_irelative_ 2676 = new Output_data_space(0, size / 8, "** GOT IRELATIVE PLT"); 2677 layout->add_output_section_data(".got.plt", elfcpp::SHT_PROGBITS, 2678 elfcpp::SHF_ALLOC | elfcpp::SHF_WRITE, 2679 this->got_irelative_, 2680 ORDER_NON_RELRO_FIRST, false); 2681 2682 // Create the PLT section. 2683 this->plt_ = new Output_data_plt_tilegx<size, big_endian>(layout, 2684 this->plt_entry_size(), this->got_, this->got_plt_, this->got_irelative_, 2685 plt_count); 2686 2687 layout->add_output_section_data(".plt", elfcpp::SHT_PROGBITS, 2688 elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR, 2689 this->plt_, ORDER_PLT, false); 2690 2691 // Make the sh_info field of .rela.plt point to .plt. 2692 Output_section* rela_plt_os = this->plt_->rela_plt()->output_section(); 2693 rela_plt_os->set_info_section(this->plt_->output_section()); 2694 2695 // Create the rela_dyn section. 2696 this->rela_dyn_section(layout); 2697 2698 return this->got_; 2699 } 2700 2701 // Reserve a GOT entry for a local symbol, and regenerate any 2702 // necessary dynamic relocations. 2703 2704 template<int size, bool big_endian> 2705 void 2706 Target_tilegx<size, big_endian>::reserve_local_got_entry( 2707 unsigned int got_index, 2708 Sized_relobj<size, big_endian>* obj, 2709 unsigned int r_sym, 2710 unsigned int got_type) 2711 { 2712 unsigned int got_offset = (got_index + TILEGX_GOT_RESERVE_COUNT) 2713 * (size / 8); 2714 Reloc_section* rela_dyn = this->rela_dyn_section(NULL); 2715 2716 this->got_->reserve_local(got_index, obj, r_sym, got_type); 2717 switch (got_type) 2718 { 2719 case GOT_TYPE_STANDARD: 2720 if (parameters->options().output_is_position_independent()) 2721 rela_dyn->add_local_relative(obj, r_sym, elfcpp::R_TILEGX_RELATIVE, 2722 this->got_, got_offset, 0, false); 2723 break; 2724 case GOT_TYPE_TLS_OFFSET: 2725 rela_dyn->add_local(obj, r_sym, 2726 size == 32 ? elfcpp::R_TILEGX_TLS_DTPOFF32 2727 : elfcpp::R_TILEGX_TLS_DTPOFF64, 2728 this->got_, got_offset, 0); 2729 break; 2730 case GOT_TYPE_TLS_PAIR: 2731 this->got_->reserve_slot(got_index + 1); 2732 rela_dyn->add_local(obj, r_sym, 2733 size == 32 ? elfcpp::R_TILEGX_TLS_DTPMOD32 2734 : elfcpp::R_TILEGX_TLS_DTPMOD64, 2735 this->got_, got_offset, 0); 2736 break; 2737 case GOT_TYPE_TLS_DESC: 2738 gold_fatal(_("TLS_DESC not yet supported for incremental linking")); 2739 break; 2740 default: 2741 gold_unreachable(); 2742 } 2743 } 2744 2745 // Reserve a GOT entry for a global symbol, and regenerate any 2746 // necessary dynamic relocations. 2747 2748 template<int size, bool big_endian> 2749 void 2750 Target_tilegx<size, big_endian>::reserve_global_got_entry( 2751 unsigned int got_index, Symbol* gsym, unsigned int got_type) 2752 { 2753 unsigned int got_offset = (got_index + TILEGX_GOT_RESERVE_COUNT) 2754 * (size / 8); 2755 Reloc_section* rela_dyn = this->rela_dyn_section(NULL); 2756 2757 this->got_->reserve_global(got_index, gsym, got_type); 2758 switch (got_type) 2759 { 2760 case GOT_TYPE_STANDARD: 2761 if (!gsym->final_value_is_known()) 2762 { 2763 if (gsym->is_from_dynobj() 2764 || gsym->is_undefined() 2765 || gsym->is_preemptible() 2766 || gsym->type() == elfcpp::STT_GNU_IFUNC) 2767 rela_dyn->add_global(gsym, elfcpp::R_TILEGX_GLOB_DAT, 2768 this->got_, got_offset, 0); 2769 else 2770 rela_dyn->add_global_relative(gsym, elfcpp::R_TILEGX_RELATIVE, 2771 this->got_, got_offset, 0, false); 2772 } 2773 break; 2774 case GOT_TYPE_TLS_OFFSET: 2775 rela_dyn->add_global_relative(gsym, 2776 size == 32 ? elfcpp::R_TILEGX_TLS_TPOFF32 2777 : elfcpp::R_TILEGX_TLS_TPOFF64, 2778 this->got_, got_offset, 0, false); 2779 break; 2780 case GOT_TYPE_TLS_PAIR: 2781 this->got_->reserve_slot(got_index + 1); 2782 rela_dyn->add_global_relative(gsym, 2783 size == 32 ? elfcpp::R_TILEGX_TLS_DTPMOD32 2784 : elfcpp::R_TILEGX_TLS_DTPMOD64, 2785 this->got_, got_offset, 0, false); 2786 rela_dyn->add_global_relative(gsym, 2787 size == 32 ? elfcpp::R_TILEGX_TLS_DTPOFF32 2788 : elfcpp::R_TILEGX_TLS_DTPOFF64, 2789 this->got_, got_offset + size / 8, 2790 0, false); 2791 break; 2792 case GOT_TYPE_TLS_DESC: 2793 gold_fatal(_("TLS_DESC not yet supported for TILEGX")); 2794 break; 2795 default: 2796 gold_unreachable(); 2797 } 2798 } 2799 2800 // Register an existing PLT entry for a global symbol. 2801 2802 template<int size, bool big_endian> 2803 void 2804 Target_tilegx<size, big_endian>::register_global_plt_entry( 2805 Symbol_table* symtab, Layout* layout, unsigned int plt_index, Symbol* gsym) 2806 { 2807 gold_assert(this->plt_ != NULL); 2808 gold_assert(!gsym->has_plt_offset()); 2809 2810 this->plt_->reserve_slot(plt_index); 2811 2812 gsym->set_plt_offset((plt_index + 1) * this->plt_entry_size()); 2813 2814 unsigned int got_offset = (plt_index + 2) * (size / 8); 2815 this->plt_->add_relocation(symtab, layout, gsym, got_offset); 2816 } 2817 2818 // Force a COPY relocation for a given symbol. 2819 2820 template<int size, bool big_endian> 2821 void 2822 Target_tilegx<size, big_endian>::emit_copy_reloc( 2823 Symbol_table* symtab, Symbol* sym, Output_section* os, off_t offset) 2824 { 2825 this->copy_relocs_.emit_copy_reloc(symtab, 2826 symtab->get_sized_symbol<size>(sym), 2827 os, 2828 offset, 2829 this->rela_dyn_section(NULL)); 2830 } 2831 2832 // Create a GOT entry for the TLS module index. 2833 2834 template<int size, bool big_endian> 2835 unsigned int 2836 Target_tilegx<size, big_endian>::got_mod_index_entry(Symbol_table* symtab, 2837 Layout* layout, 2838 Sized_relobj_file<size, big_endian>* object) 2839 { 2840 if (this->got_mod_index_offset_ == -1U) 2841 { 2842 gold_assert(symtab != NULL && layout != NULL && object != NULL); 2843 Reloc_section* rela_dyn = this->rela_dyn_section(layout); 2844 Output_data_got<size, big_endian>* got 2845 = this->got_section(symtab, layout); 2846 unsigned int got_offset = got->add_constant(0); 2847 rela_dyn->add_local(object, 0, 2848 size == 32 ? elfcpp::R_TILEGX_TLS_DTPMOD32 2849 : elfcpp::R_TILEGX_TLS_DTPMOD64, got, 2850 got_offset, 0); 2851 got->add_constant(0); 2852 this->got_mod_index_offset_ = got_offset; 2853 } 2854 return this->got_mod_index_offset_; 2855 } 2856 2857 // Optimize the TLS relocation type based on what we know about the 2858 // symbol. IS_FINAL is true if the final address of this symbol is 2859 // known at link time. 2860 // 2861 // the transformation rules is described below: 2862 // 2863 // compiler GD reference 2864 // | 2865 // V 2866 // moveli tmp, hw1_last_tls_gd(x) X0/X1 2867 // shl16insli r0, tmp, hw0_tls_gd(x) X0/X1 2868 // addi r0, got, tls_add(x) Y0/Y1/X0/X1 2869 // jal tls_gd_call(x) X1 2870 // addi adr, r0, tls_gd_add(x) Y0/Y1/X0/X1 2871 // 2872 // linker tranformation of GD insn sequence 2873 // | 2874 // V 2875 // ==> GD: 2876 // moveli tmp, hw1_last_tls_gd(x) X0/X1 2877 // shl16insli r0, tmp, hw0_tls_gd(x) X0/X1 2878 // add r0, got, r0 Y0/Y1/X0/X1 2879 // jal plt(__tls_get_addr) X1 2880 // move adr, r0 Y0/Y1/X0/X1 2881 // ==> IE: 2882 // moveli tmp, hw1_last_tls_ie(x) X0/X1 2883 // shl16insli r0, tmp, hw0_tls_ie(x) X0/X1 2884 // add r0, got, r0 Y0/Y1/X0/X1 2885 // ld r0, r0 X1 2886 // add adr, r0, tp Y0/Y1/X0/X1 2887 // ==> LE: 2888 // moveli tmp, hw1_last_tls_le(x) X0/X1 2889 // shl16insli r0, tmp, hw0_tls_le(x) X0/X1 2890 // move r0, r0 Y0/Y1/X0/X1 2891 // move r0, r0 Y0/Y1/X0/X1 2892 // add adr, r0, tp Y0/Y1/X0/X1 2893 // 2894 // 2895 // compiler IE reference 2896 // | 2897 // V 2898 // moveli tmp, hw1_last_tls_ie(x) X0/X1 2899 // shl16insli tmp, tmp, hw0_tls_ie(x) X0/X1 2900 // addi tmp, got, tls_add(x) Y0/Y1/X0/X1 2901 // ld_tls tmp, tmp, tls_ie_load(x) X1 2902 // add adr, tmp, tp Y0/Y1/X0/X1 2903 // 2904 // linker transformation for IE insn sequence 2905 // | 2906 // V 2907 // ==> IE: 2908 // moveli tmp, hw1_last_tls_ie(x) X0/X1 2909 // shl16insli tmp, tmp, hw0_tls_ie(x) X0/X1 2910 // add tmp, got, tmp Y0/Y1/X0/X1 2911 // ld tmp, tmp X1 2912 // add adr, tmp, tp Y0/Y1/X0/X1 2913 // ==> LE: 2914 // moveli tmp, hw1_last_tls_le(x) X0/X1 2915 // shl16insli tmp, tmp, hw0_tls_le(x) X0/X1 2916 // move tmp, tmp Y0/Y1/X0/X1 2917 // move tmp, tmp Y0/Y1/X0/X1 2918 // 2919 // 2920 // compiler LE reference 2921 // | 2922 // V 2923 // moveli tmp, hw1_last_tls_le(x) X0/X1 2924 // shl16insli tmp, tmp, hw0_tls_le(x) X0/X1 2925 // add adr, tmp, tp Y0/Y1/X0/X1 2926 2927 template<int size, bool big_endian> 2928 tls::Tls_optimization 2929 Target_tilegx<size, big_endian>::optimize_tls_reloc(bool is_final, int r_type) 2930 { 2931 // If we are generating a shared library, then we can't do anything 2932 // in the linker. 2933 if (parameters->options().shared()) 2934 return tls::TLSOPT_NONE; 2935 2936 switch (r_type) 2937 { 2938 // unique GD relocations 2939 case elfcpp::R_TILEGX_TLS_GD_CALL: 2940 case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: 2941 case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD: 2942 case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: 2943 case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: 2944 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: 2945 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: 2946 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: 2947 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: 2948 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: 2949 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: 2950 // These are General-Dynamic which permits fully general TLS 2951 // access. Since we know that we are generating an executable, 2952 // we can convert this to Initial-Exec. If we also know that 2953 // this is a local symbol, we can further switch to Local-Exec. 2954 if (is_final) 2955 return tls::TLSOPT_TO_LE; 2956 return tls::TLSOPT_TO_IE; 2957 2958 // unique IE relocations 2959 case elfcpp::R_TILEGX_TLS_IE_LOAD: 2960 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE: 2961 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE: 2962 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: 2963 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: 2964 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: 2965 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: 2966 // These are Initial-Exec relocs which get the thread offset 2967 // from the GOT. If we know that we are linking against the 2968 // local symbol, we can switch to Local-Exec, which links the 2969 // thread offset into the instruction. 2970 if (is_final) 2971 return tls::TLSOPT_TO_LE; 2972 return tls::TLSOPT_NONE; 2973 2974 // could be created for both GD and IE 2975 // but they are expanded into the same 2976 // instruction in GD and IE. 2977 case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: 2978 case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD: 2979 case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD: 2980 case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD: 2981 if (is_final) 2982 return tls::TLSOPT_TO_LE; 2983 return tls::TLSOPT_NONE; 2984 2985 // unique LE relocations 2986 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE: 2987 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE: 2988 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: 2989 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: 2990 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: 2991 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: 2992 // When we already have Local-Exec, there is nothing further we 2993 // can do. 2994 return tls::TLSOPT_NONE; 2995 2996 default: 2997 gold_unreachable(); 2998 } 2999 } 3000 3001 // Get the Reference_flags for a particular relocation. 3002 3003 template<int size, bool big_endian> 3004 int 3005 Target_tilegx<size, big_endian>::Scan::get_reference_flags(unsigned int r_type) 3006 { 3007 switch (r_type) 3008 { 3009 case elfcpp::R_TILEGX_NONE: 3010 case elfcpp::R_TILEGX_GNU_VTINHERIT: 3011 case elfcpp::R_TILEGX_GNU_VTENTRY: 3012 // No symbol reference. 3013 return 0; 3014 3015 case elfcpp::R_TILEGX_64: 3016 case elfcpp::R_TILEGX_32: 3017 case elfcpp::R_TILEGX_16: 3018 case elfcpp::R_TILEGX_8: 3019 return Symbol::ABSOLUTE_REF; 3020 3021 case elfcpp::R_TILEGX_BROFF_X1: 3022 case elfcpp::R_TILEGX_64_PCREL: 3023 case elfcpp::R_TILEGX_32_PCREL: 3024 case elfcpp::R_TILEGX_16_PCREL: 3025 case elfcpp::R_TILEGX_8_PCREL: 3026 case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL: 3027 case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL: 3028 case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL: 3029 case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL: 3030 case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL: 3031 case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL: 3032 case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL: 3033 case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL: 3034 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL: 3035 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL: 3036 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL: 3037 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL: 3038 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL: 3039 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL: 3040 return Symbol::RELATIVE_REF; 3041 3042 case elfcpp::R_TILEGX_JUMPOFF_X1: 3043 case elfcpp::R_TILEGX_JUMPOFF_X1_PLT: 3044 case elfcpp::R_TILEGX_IMM16_X0_HW0_PLT_PCREL: 3045 case elfcpp::R_TILEGX_IMM16_X1_HW0_PLT_PCREL: 3046 case elfcpp::R_TILEGX_IMM16_X0_HW1_PLT_PCREL: 3047 case elfcpp::R_TILEGX_IMM16_X1_HW1_PLT_PCREL: 3048 case elfcpp::R_TILEGX_IMM16_X0_HW2_PLT_PCREL: 3049 case elfcpp::R_TILEGX_IMM16_X1_HW2_PLT_PCREL: 3050 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: 3051 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: 3052 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: 3053 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: 3054 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: 3055 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: 3056 return Symbol::FUNCTION_CALL | Symbol::RELATIVE_REF; 3057 3058 case elfcpp::R_TILEGX_IMM16_X0_HW0: 3059 case elfcpp::R_TILEGX_IMM16_X1_HW0: 3060 case elfcpp::R_TILEGX_IMM16_X0_HW1: 3061 case elfcpp::R_TILEGX_IMM16_X1_HW1: 3062 case elfcpp::R_TILEGX_IMM16_X0_HW2: 3063 case elfcpp::R_TILEGX_IMM16_X1_HW2: 3064 case elfcpp::R_TILEGX_IMM16_X0_HW3: 3065 case elfcpp::R_TILEGX_IMM16_X1_HW3: 3066 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST: 3067 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST: 3068 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST: 3069 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST: 3070 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST: 3071 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST: 3072 return Symbol::ABSOLUTE_REF; 3073 3074 case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT: 3075 case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT: 3076 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT: 3077 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT: 3078 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT: 3079 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT: 3080 // Absolute in GOT. 3081 return Symbol::ABSOLUTE_REF; 3082 3083 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: 3084 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: 3085 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE: 3086 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE: 3087 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: 3088 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: 3089 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: 3090 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: 3091 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: 3092 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: 3093 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: 3094 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: 3095 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE: 3096 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE: 3097 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: 3098 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: 3099 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: 3100 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: 3101 case elfcpp::R_TILEGX_TLS_DTPOFF64: 3102 case elfcpp::R_TILEGX_TLS_DTPMOD32: 3103 case elfcpp::R_TILEGX_TLS_DTPOFF32: 3104 case elfcpp::R_TILEGX_TLS_TPOFF32: 3105 case elfcpp::R_TILEGX_TLS_GD_CALL: 3106 case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: 3107 case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD: 3108 case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: 3109 case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: 3110 case elfcpp::R_TILEGX_TLS_IE_LOAD: 3111 case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: 3112 case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD: 3113 case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD: 3114 case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD: 3115 return Symbol::TLS_REF; 3116 3117 case elfcpp::R_TILEGX_COPY: 3118 case elfcpp::R_TILEGX_GLOB_DAT: 3119 case elfcpp::R_TILEGX_JMP_SLOT: 3120 case elfcpp::R_TILEGX_RELATIVE: 3121 case elfcpp::R_TILEGX_TLS_TPOFF64: 3122 case elfcpp::R_TILEGX_TLS_DTPMOD64: 3123 default: 3124 // Not expected. We will give an error later. 3125 return 0; 3126 } 3127 } 3128 3129 // Report an unsupported relocation against a local symbol. 3130 3131 template<int size, bool big_endian> 3132 void 3133 Target_tilegx<size, big_endian>::Scan::unsupported_reloc_local( 3134 Sized_relobj_file<size, big_endian>* object, 3135 unsigned int r_type) 3136 { 3137 gold_error(_("%s: unsupported reloc %u against local symbol"), 3138 object->name().c_str(), r_type); 3139 } 3140 3141 // We are about to emit a dynamic relocation of type R_TYPE. If the 3142 // dynamic linker does not support it, issue an error. 3143 template<int size, bool big_endian> 3144 void 3145 Target_tilegx<size, big_endian>::Scan::check_non_pic(Relobj* object, 3146 unsigned int r_type) 3147 { 3148 switch (r_type) 3149 { 3150 // These are the relocation types supported by glibc for tilegx 3151 // which should always work. 3152 case elfcpp::R_TILEGX_RELATIVE: 3153 case elfcpp::R_TILEGX_GLOB_DAT: 3154 case elfcpp::R_TILEGX_JMP_SLOT: 3155 case elfcpp::R_TILEGX_TLS_DTPMOD64: 3156 case elfcpp::R_TILEGX_TLS_DTPOFF64: 3157 case elfcpp::R_TILEGX_TLS_TPOFF64: 3158 case elfcpp::R_TILEGX_8: 3159 case elfcpp::R_TILEGX_16: 3160 case elfcpp::R_TILEGX_32: 3161 case elfcpp::R_TILEGX_64: 3162 case elfcpp::R_TILEGX_COPY: 3163 case elfcpp::R_TILEGX_IMM16_X0_HW0: 3164 case elfcpp::R_TILEGX_IMM16_X1_HW0: 3165 case elfcpp::R_TILEGX_IMM16_X0_HW1: 3166 case elfcpp::R_TILEGX_IMM16_X1_HW1: 3167 case elfcpp::R_TILEGX_IMM16_X0_HW2: 3168 case elfcpp::R_TILEGX_IMM16_X1_HW2: 3169 case elfcpp::R_TILEGX_IMM16_X0_HW3: 3170 case elfcpp::R_TILEGX_IMM16_X1_HW3: 3171 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST: 3172 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST: 3173 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST: 3174 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST: 3175 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST: 3176 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST: 3177 case elfcpp::R_TILEGX_BROFF_X1: 3178 case elfcpp::R_TILEGX_JUMPOFF_X1: 3179 case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL: 3180 case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL: 3181 case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL: 3182 case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL: 3183 case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL: 3184 case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL: 3185 case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL: 3186 case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL: 3187 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL: 3188 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL: 3189 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL: 3190 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL: 3191 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL: 3192 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL: 3193 return; 3194 3195 default: 3196 // This prevents us from issuing more than one error per reloc 3197 // section. But we can still wind up issuing more than one 3198 // error per object file. 3199 if (this->issued_non_pic_error_) 3200 return; 3201 gold_assert(parameters->options().output_is_position_independent()); 3202 object->error(_("requires unsupported dynamic reloc %u; " 3203 "recompile with -fPIC"), 3204 r_type); 3205 this->issued_non_pic_error_ = true; 3206 return; 3207 3208 case elfcpp::R_TILEGX_NONE: 3209 gold_unreachable(); 3210 } 3211 } 3212 3213 // Return whether we need to make a PLT entry for a relocation of the 3214 // given type against a STT_GNU_IFUNC symbol. 3215 3216 template<int size, bool big_endian> 3217 bool 3218 Target_tilegx<size, big_endian>::Scan::reloc_needs_plt_for_ifunc( 3219 Sized_relobj_file<size, big_endian>* object, unsigned int r_type) 3220 { 3221 int flags = Scan::get_reference_flags(r_type); 3222 if (flags & Symbol::TLS_REF) 3223 gold_error(_("%s: unsupported TLS reloc %u for IFUNC symbol"), 3224 object->name().c_str(), r_type); 3225 return flags != 0; 3226 } 3227 3228 // Scan a relocation for a local symbol. 3229 3230 template<int size, bool big_endian> 3231 inline void 3232 Target_tilegx<size, big_endian>::Scan::local(Symbol_table* symtab, 3233 Layout* layout, 3234 Target_tilegx<size, big_endian>* target, 3235 Sized_relobj_file<size, big_endian>* object, 3236 unsigned int data_shndx, 3237 Output_section* output_section, 3238 const elfcpp::Rela<size, big_endian>& reloc, 3239 unsigned int r_type, 3240 const elfcpp::Sym<size, big_endian>& lsym, 3241 bool is_discarded) 3242 { 3243 if (is_discarded) 3244 return; 3245 3246 // A local STT_GNU_IFUNC symbol may require a PLT entry. 3247 bool is_ifunc = lsym.get_st_type() == elfcpp::STT_GNU_IFUNC; 3248 if (is_ifunc && this->reloc_needs_plt_for_ifunc(object, r_type)) 3249 { 3250 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info()); 3251 target->make_local_ifunc_plt_entry(symtab, layout, object, r_sym); 3252 } 3253 3254 switch (r_type) 3255 { 3256 case elfcpp::R_TILEGX_NONE: 3257 case elfcpp::R_TILEGX_GNU_VTINHERIT: 3258 case elfcpp::R_TILEGX_GNU_VTENTRY: 3259 break; 3260 3261 // If building a shared library (or a position-independent 3262 // executable), because the runtime address needs plus 3263 // the module base address, so generate a R_TILEGX_RELATIVE. 3264 case elfcpp::R_TILEGX_32: 3265 case elfcpp::R_TILEGX_64: 3266 if (parameters->options().output_is_position_independent()) 3267 { 3268 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info()); 3269 Reloc_section* rela_dyn = target->rela_dyn_section(layout); 3270 rela_dyn->add_local_relative(object, r_sym, 3271 elfcpp::R_TILEGX_RELATIVE, 3272 output_section, data_shndx, 3273 reloc.get_r_offset(), 3274 reloc.get_r_addend(), is_ifunc); 3275 } 3276 break; 3277 3278 // If building a shared library (or a position-independent 3279 // executable), we need to create a dynamic relocation for this 3280 // location. 3281 case elfcpp::R_TILEGX_8: 3282 case elfcpp::R_TILEGX_16: 3283 case elfcpp::R_TILEGX_IMM16_X0_HW0: 3284 case elfcpp::R_TILEGX_IMM16_X1_HW0: 3285 case elfcpp::R_TILEGX_IMM16_X0_HW1: 3286 case elfcpp::R_TILEGX_IMM16_X1_HW1: 3287 case elfcpp::R_TILEGX_IMM16_X0_HW2: 3288 case elfcpp::R_TILEGX_IMM16_X1_HW2: 3289 case elfcpp::R_TILEGX_IMM16_X0_HW3: 3290 case elfcpp::R_TILEGX_IMM16_X1_HW3: 3291 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST: 3292 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST: 3293 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST: 3294 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST: 3295 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST: 3296 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST: 3297 if (parameters->options().output_is_position_independent()) 3298 { 3299 this->check_non_pic(object, r_type); 3300 3301 Reloc_section* rela_dyn = target->rela_dyn_section(layout); 3302 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info()); 3303 if (lsym.get_st_type() != elfcpp::STT_SECTION) 3304 rela_dyn->add_local(object, r_sym, r_type, output_section, 3305 data_shndx, reloc.get_r_offset(), 3306 reloc.get_r_addend()); 3307 else 3308 { 3309 gold_assert(lsym.get_st_value() == 0); 3310 rela_dyn->add_symbolless_local_addend(object, r_sym, r_type, 3311 output_section, 3312 data_shndx, 3313 reloc.get_r_offset(), 3314 reloc.get_r_addend()); 3315 3316 } 3317 } 3318 break; 3319 3320 // R_TILEGX_JUMPOFF_X1_PLT against local symbol 3321 // may happen for ifunc case. 3322 case elfcpp::R_TILEGX_JUMPOFF_X1_PLT: 3323 case elfcpp::R_TILEGX_JUMPOFF_X1: 3324 case elfcpp::R_TILEGX_64_PCREL: 3325 case elfcpp::R_TILEGX_32_PCREL: 3326 case elfcpp::R_TILEGX_16_PCREL: 3327 case elfcpp::R_TILEGX_8_PCREL: 3328 case elfcpp::R_TILEGX_BROFF_X1: 3329 case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL: 3330 case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL: 3331 case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL: 3332 case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL: 3333 case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL: 3334 case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL: 3335 case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL: 3336 case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL: 3337 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL: 3338 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL: 3339 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL: 3340 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL: 3341 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL: 3342 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL: 3343 case elfcpp::R_TILEGX_IMM16_X0_HW0_PLT_PCREL: 3344 case elfcpp::R_TILEGX_IMM16_X1_HW0_PLT_PCREL: 3345 case elfcpp::R_TILEGX_IMM16_X0_HW1_PLT_PCREL: 3346 case elfcpp::R_TILEGX_IMM16_X1_HW1_PLT_PCREL: 3347 case elfcpp::R_TILEGX_IMM16_X0_HW2_PLT_PCREL: 3348 case elfcpp::R_TILEGX_IMM16_X1_HW2_PLT_PCREL: 3349 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: 3350 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: 3351 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: 3352 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: 3353 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: 3354 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: 3355 break; 3356 3357 case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT: 3358 case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT: 3359 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT: 3360 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT: 3361 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT: 3362 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT: 3363 { 3364 // The symbol requires a GOT entry. 3365 Output_data_got<size, big_endian>* got 3366 = target->got_section(symtab, layout); 3367 unsigned int r_sym = elfcpp::elf_r_sym<size>(reloc.get_r_info()); 3368 3369 // For a STT_GNU_IFUNC symbol we want the PLT offset. That 3370 // lets function pointers compare correctly with shared 3371 // libraries. Otherwise we would need an IRELATIVE reloc. 3372 bool is_new; 3373 if (is_ifunc) 3374 is_new = got->add_local_plt(object, r_sym, GOT_TYPE_STANDARD); 3375 else 3376 is_new = got->add_local(object, r_sym, GOT_TYPE_STANDARD); 3377 if (is_new) 3378 { 3379 // tilegx dynamic linker will not update local got entry, 3380 // so, if we are generating a shared object, we need to add a 3381 // dynamic relocation for this symbol's GOT entry to inform 3382 // dynamic linker plus the load base explicitly. 3383 if (parameters->options().output_is_position_independent()) 3384 { 3385 unsigned int got_offset 3386 = object->local_got_offset(r_sym, GOT_TYPE_STANDARD); 3387 3388 Reloc_section* rela_dyn = target->rela_dyn_section(layout); 3389 rela_dyn->add_local_relative(object, r_sym, 3390 r_type, 3391 got, got_offset, 0, is_ifunc); 3392 } 3393 } 3394 } 3395 break; 3396 3397 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: 3398 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: 3399 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE: 3400 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE: 3401 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: 3402 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: 3403 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: 3404 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: 3405 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: 3406 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: 3407 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: 3408 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: 3409 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE: 3410 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE: 3411 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: 3412 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: 3413 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: 3414 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: 3415 case elfcpp::R_TILEGX_TLS_GD_CALL: 3416 case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: 3417 case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD: 3418 case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: 3419 case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: 3420 case elfcpp::R_TILEGX_TLS_IE_LOAD: 3421 case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: 3422 case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD: 3423 case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD: 3424 case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD: 3425 { 3426 bool output_is_shared = parameters->options().shared(); 3427 const tls::Tls_optimization opt_t = 3428 Target_tilegx<size, big_endian>::optimize_tls_reloc( 3429 !output_is_shared, r_type); 3430 3431 switch (r_type) 3432 { 3433 case elfcpp::R_TILEGX_TLS_GD_CALL: 3434 // FIXME: predefine __tls_get_addr 3435 // 3436 // R_TILEGX_TLS_GD_CALL implicitly reference __tls_get_addr, 3437 // while all other target, x86/arm/mips/powerpc/sparc 3438 // generate tls relocation against __tls_get_addr explicitly, 3439 // so for TILEGX, we need the following hack. 3440 if (opt_t == tls::TLSOPT_NONE) { 3441 if (!target->tls_get_addr_sym_defined_) { 3442 Symbol* sym = NULL; 3443 options::parse_set(NULL, "__tls_get_addr", 3444 (gold::options::String_set*) 3445 ¶meters->options().undefined()); 3446 symtab->add_undefined_symbols_from_command_line(layout); 3447 target->tls_get_addr_sym_defined_ = true; 3448 sym = symtab->lookup("__tls_get_addr"); 3449 sym->set_in_reg(); 3450 } 3451 target->make_plt_entry(symtab, layout, 3452 symtab->lookup("__tls_get_addr")); 3453 } 3454 break; 3455 3456 // only make effect when applying relocation 3457 case elfcpp::R_TILEGX_TLS_IE_LOAD: 3458 case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: 3459 case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD: 3460 case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD: 3461 case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD: 3462 case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: 3463 case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD: 3464 case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: 3465 case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: 3466 break; 3467 3468 // GD: requires two GOT entry for module index and offset 3469 // IE: requires one GOT entry for tp-relative offset 3470 // LE: shouldn't happen for global symbol 3471 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: 3472 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: 3473 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: 3474 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: 3475 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: 3476 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: 3477 { 3478 if (opt_t == tls::TLSOPT_NONE) { 3479 Output_data_got<size, big_endian> *got 3480 = target->got_section(symtab, layout); 3481 unsigned int r_sym 3482 = elfcpp::elf_r_sym<size>(reloc.get_r_info()); 3483 unsigned int shndx = lsym.get_st_shndx(); 3484 bool is_ordinary; 3485 shndx = object->adjust_sym_shndx(r_sym, shndx, 3486 &is_ordinary); 3487 if (!is_ordinary) 3488 object->error(_("local symbol %u has bad shndx %u"), 3489 r_sym, shndx); 3490 else 3491 got->add_local_pair_with_rel(object, r_sym, shndx, 3492 GOT_TYPE_TLS_PAIR, 3493 target->rela_dyn_section(layout), 3494 size == 32 3495 ? elfcpp::R_TILEGX_TLS_DTPMOD32 3496 : elfcpp::R_TILEGX_TLS_DTPMOD64); 3497 } else if (opt_t == tls::TLSOPT_TO_IE) { 3498 Output_data_got<size, big_endian>* got 3499 = target->got_section(symtab, layout); 3500 Reloc_section* rela_dyn 3501 = target->rela_dyn_section(layout); 3502 unsigned int r_sym 3503 = elfcpp::elf_r_sym<size>(reloc.get_r_info()); 3504 unsigned int off = got->add_constant(0); 3505 object->set_local_got_offset(r_sym, 3506 GOT_TYPE_TLS_OFFSET,off); 3507 rela_dyn->add_symbolless_local_addend(object, r_sym, 3508 size == 32 3509 ? elfcpp::R_TILEGX_TLS_TPOFF32 3510 : elfcpp::R_TILEGX_TLS_TPOFF64, 3511 got, off, 0); 3512 } else if (opt_t != tls::TLSOPT_TO_LE) 3513 // only TO_LE is allowed for local symbol 3514 unsupported_reloc_local(object, r_type); 3515 } 3516 break; 3517 3518 // IE 3519 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE: 3520 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE: 3521 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: 3522 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: 3523 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: 3524 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: 3525 { 3526 layout->set_has_static_tls(); 3527 if (opt_t == tls::TLSOPT_NONE) { 3528 Output_data_got<size, big_endian>* got 3529 = target->got_section(symtab, layout); 3530 Reloc_section* rela_dyn 3531 = target->rela_dyn_section(layout); 3532 unsigned int r_sym 3533 = elfcpp::elf_r_sym<size>(reloc.get_r_info()); 3534 unsigned int off = got->add_constant(0); 3535 object->set_local_got_offset(r_sym, 3536 GOT_TYPE_TLS_OFFSET, off); 3537 rela_dyn->add_symbolless_local_addend(object, r_sym, 3538 size == 32 3539 ? elfcpp::R_TILEGX_TLS_TPOFF32 3540 : elfcpp::R_TILEGX_TLS_TPOFF64, 3541 got, off, 0); 3542 } else if (opt_t != tls::TLSOPT_TO_LE) 3543 unsupported_reloc_local(object, r_type); 3544 } 3545 break; 3546 3547 // LE 3548 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE: 3549 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE: 3550 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: 3551 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: 3552 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: 3553 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: 3554 layout->set_has_static_tls(); 3555 if (parameters->options().shared()) { 3556 // defer to dynamic linker 3557 gold_assert(lsym.get_st_type() != elfcpp::STT_SECTION); 3558 unsigned int r_sym 3559 = elfcpp::elf_r_sym<size>(reloc.get_r_info()); 3560 Reloc_section* rela_dyn = target->rela_dyn_section(layout); 3561 rela_dyn->add_symbolless_local_addend(object, r_sym, r_type, 3562 output_section, data_shndx, 3563 reloc.get_r_offset(), 0); 3564 } 3565 break; 3566 3567 default: 3568 gold_unreachable(); 3569 } 3570 } 3571 break; 3572 3573 case elfcpp::R_TILEGX_COPY: 3574 case elfcpp::R_TILEGX_GLOB_DAT: 3575 case elfcpp::R_TILEGX_JMP_SLOT: 3576 case elfcpp::R_TILEGX_RELATIVE: 3577 // These are outstanding tls relocs, which are unexpected when linking 3578 case elfcpp::R_TILEGX_TLS_TPOFF32: 3579 case elfcpp::R_TILEGX_TLS_TPOFF64: 3580 case elfcpp::R_TILEGX_TLS_DTPMOD32: 3581 case elfcpp::R_TILEGX_TLS_DTPMOD64: 3582 case elfcpp::R_TILEGX_TLS_DTPOFF32: 3583 case elfcpp::R_TILEGX_TLS_DTPOFF64: 3584 gold_error(_("%s: unexpected reloc %u in object file"), 3585 object->name().c_str(), r_type); 3586 break; 3587 3588 default: 3589 gold_error(_("%s: unsupported reloc %u against local symbol"), 3590 object->name().c_str(), r_type); 3591 break; 3592 } 3593 } 3594 3595 3596 // Report an unsupported relocation against a global symbol. 3597 3598 template<int size, bool big_endian> 3599 void 3600 Target_tilegx<size, big_endian>::Scan::unsupported_reloc_global( 3601 Sized_relobj_file<size, big_endian>* object, 3602 unsigned int r_type, 3603 Symbol* gsym) 3604 { 3605 gold_error(_("%s: unsupported reloc %u against global symbol %s"), 3606 object->name().c_str(), r_type, gsym->demangled_name().c_str()); 3607 } 3608 3609 // Returns true if this relocation type could be that of a function pointer. 3610 template<int size, bool big_endian> 3611 inline bool 3612 Target_tilegx<size, big_endian>::Scan::possible_function_pointer_reloc( 3613 unsigned int r_type) 3614 { 3615 switch (r_type) 3616 { 3617 case elfcpp::R_TILEGX_IMM16_X0_HW0: 3618 case elfcpp::R_TILEGX_IMM16_X1_HW0: 3619 case elfcpp::R_TILEGX_IMM16_X0_HW1: 3620 case elfcpp::R_TILEGX_IMM16_X1_HW1: 3621 case elfcpp::R_TILEGX_IMM16_X0_HW2: 3622 case elfcpp::R_TILEGX_IMM16_X1_HW2: 3623 case elfcpp::R_TILEGX_IMM16_X0_HW3: 3624 case elfcpp::R_TILEGX_IMM16_X1_HW3: 3625 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST: 3626 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST: 3627 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST: 3628 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST: 3629 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST: 3630 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST: 3631 case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL: 3632 case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL: 3633 case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL: 3634 case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL: 3635 case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL: 3636 case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL: 3637 case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL: 3638 case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL: 3639 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL: 3640 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL: 3641 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL: 3642 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL: 3643 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL: 3644 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL: 3645 case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT: 3646 case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT: 3647 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT: 3648 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT: 3649 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT: 3650 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT: 3651 { 3652 return true; 3653 } 3654 } 3655 return false; 3656 } 3657 3658 // For safe ICF, scan a relocation for a local symbol to check if it 3659 // corresponds to a function pointer being taken. In that case mark 3660 // the function whose pointer was taken as not foldable. 3661 3662 template<int size, bool big_endian> 3663 inline bool 3664 Target_tilegx<size, big_endian>::Scan::local_reloc_may_be_function_pointer( 3665 Symbol_table* , 3666 Layout* , 3667 Target_tilegx<size, big_endian>* , 3668 Sized_relobj_file<size, big_endian>* , 3669 unsigned int , 3670 Output_section* , 3671 const elfcpp::Rela<size, big_endian>& , 3672 unsigned int r_type, 3673 const elfcpp::Sym<size, big_endian>&) 3674 { 3675 return possible_function_pointer_reloc(r_type); 3676 } 3677 3678 // For safe ICF, scan a relocation for a global symbol to check if it 3679 // corresponds to a function pointer being taken. In that case mark 3680 // the function whose pointer was taken as not foldable. 3681 3682 template<int size, bool big_endian> 3683 inline bool 3684 Target_tilegx<size, big_endian>::Scan::global_reloc_may_be_function_pointer( 3685 Symbol_table*, 3686 Layout* , 3687 Target_tilegx<size, big_endian>* , 3688 Sized_relobj_file<size, big_endian>* , 3689 unsigned int , 3690 Output_section* , 3691 const elfcpp::Rela<size, big_endian>& , 3692 unsigned int r_type, 3693 Symbol* gsym) 3694 { 3695 // GOT is not a function. 3696 if (strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0) 3697 return false; 3698 3699 // When building a shared library, do not fold symbols whose visibility 3700 // is hidden, internal or protected. 3701 return ((parameters->options().shared() 3702 && (gsym->visibility() == elfcpp::STV_INTERNAL 3703 || gsym->visibility() == elfcpp::STV_PROTECTED 3704 || gsym->visibility() == elfcpp::STV_HIDDEN)) 3705 || possible_function_pointer_reloc(r_type)); 3706 } 3707 3708 // Scan a relocation for a global symbol. 3709 3710 template<int size, bool big_endian> 3711 inline void 3712 Target_tilegx<size, big_endian>::Scan::global(Symbol_table* symtab, 3713 Layout* layout, 3714 Target_tilegx<size, big_endian>* target, 3715 Sized_relobj_file<size, big_endian>* object, 3716 unsigned int data_shndx, 3717 Output_section* output_section, 3718 const elfcpp::Rela<size, big_endian>& reloc, 3719 unsigned int r_type, 3720 Symbol* gsym) 3721 { 3722 // A reference to _GLOBAL_OFFSET_TABLE_ implies that we need a got 3723 // section. We check here to avoid creating a dynamic reloc against 3724 // _GLOBAL_OFFSET_TABLE_. 3725 if (!target->has_got_section() 3726 && strcmp(gsym->name(), "_GLOBAL_OFFSET_TABLE_") == 0) 3727 target->got_section(symtab, layout); 3728 3729 // A STT_GNU_IFUNC symbol may require a PLT entry. 3730 if (gsym->type() == elfcpp::STT_GNU_IFUNC 3731 && this->reloc_needs_plt_for_ifunc(object, r_type)) 3732 target->make_plt_entry(symtab, layout, gsym); 3733 3734 switch (r_type) 3735 { 3736 case elfcpp::R_TILEGX_NONE: 3737 case elfcpp::R_TILEGX_GNU_VTINHERIT: 3738 case elfcpp::R_TILEGX_GNU_VTENTRY: 3739 break; 3740 3741 case elfcpp::R_TILEGX_DEST_IMM8_X1: 3742 case elfcpp::R_TILEGX_IMM16_X0_HW0: 3743 case elfcpp::R_TILEGX_IMM16_X1_HW0: 3744 case elfcpp::R_TILEGX_IMM16_X0_HW1: 3745 case elfcpp::R_TILEGX_IMM16_X1_HW1: 3746 case elfcpp::R_TILEGX_IMM16_X0_HW2: 3747 case elfcpp::R_TILEGX_IMM16_X1_HW2: 3748 case elfcpp::R_TILEGX_IMM16_X0_HW3: 3749 case elfcpp::R_TILEGX_IMM16_X1_HW3: 3750 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST: 3751 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST: 3752 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST: 3753 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST: 3754 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST: 3755 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST: 3756 case elfcpp::R_TILEGX_64: 3757 case elfcpp::R_TILEGX_32: 3758 case elfcpp::R_TILEGX_16: 3759 case elfcpp::R_TILEGX_8: 3760 { 3761 // Make a PLT entry if necessary. 3762 if (gsym->needs_plt_entry()) 3763 { 3764 target->make_plt_entry(symtab, layout, gsym); 3765 // Since this is not a PC-relative relocation, we may be 3766 // taking the address of a function. In that case we need to 3767 // set the entry in the dynamic symbol table to the address of 3768 // the PLT entry. 3769 if (gsym->is_from_dynobj() && !parameters->options().shared()) 3770 gsym->set_needs_dynsym_value(); 3771 } 3772 // Make a dynamic relocation if necessary. 3773 if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) 3774 { 3775 if (!parameters->options().output_is_position_independent() 3776 && gsym->may_need_copy_reloc()) 3777 { 3778 target->copy_reloc(symtab, layout, object, 3779 data_shndx, output_section, gsym, reloc); 3780 } 3781 else if (((size == 64 && r_type == elfcpp::R_TILEGX_64) 3782 || (size == 32 && r_type == elfcpp::R_TILEGX_32)) 3783 && gsym->type() == elfcpp::STT_GNU_IFUNC 3784 && gsym->can_use_relative_reloc(false) 3785 && !gsym->is_from_dynobj() 3786 && !gsym->is_undefined() 3787 && !gsym->is_preemptible()) 3788 { 3789 // Use an IRELATIVE reloc for a locally defined 3790 // STT_GNU_IFUNC symbol. This makes a function 3791 // address in a PIE executable match the address in a 3792 // shared library that it links against. 3793 Reloc_section* rela_dyn = 3794 target->rela_irelative_section(layout); 3795 unsigned int r_type = elfcpp::R_TILEGX_IRELATIVE; 3796 rela_dyn->add_symbolless_global_addend(gsym, r_type, 3797 output_section, object, 3798 data_shndx, 3799 reloc.get_r_offset(), 3800 reloc.get_r_addend()); 3801 } else if ((r_type == elfcpp::R_TILEGX_64 3802 || r_type == elfcpp::R_TILEGX_32) 3803 && gsym->can_use_relative_reloc(false)) 3804 { 3805 Reloc_section* rela_dyn = target->rela_dyn_section(layout); 3806 rela_dyn->add_global_relative(gsym, elfcpp::R_TILEGX_RELATIVE, 3807 output_section, object, 3808 data_shndx, 3809 reloc.get_r_offset(), 3810 reloc.get_r_addend(), false); 3811 } 3812 else 3813 { 3814 this->check_non_pic(object, r_type); 3815 Reloc_section* rela_dyn = target->rela_dyn_section(layout); 3816 rela_dyn->add_global(gsym, r_type, output_section, object, 3817 data_shndx, reloc.get_r_offset(), 3818 reloc.get_r_addend()); 3819 } 3820 } 3821 } 3822 break; 3823 3824 case elfcpp::R_TILEGX_BROFF_X1: 3825 case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL: 3826 case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL: 3827 case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL: 3828 case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL: 3829 case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL: 3830 case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL: 3831 case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL: 3832 case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL: 3833 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL: 3834 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL: 3835 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL: 3836 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL: 3837 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL: 3838 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL: 3839 case elfcpp::R_TILEGX_64_PCREL: 3840 case elfcpp::R_TILEGX_32_PCREL: 3841 case elfcpp::R_TILEGX_16_PCREL: 3842 case elfcpp::R_TILEGX_8_PCREL: 3843 { 3844 // Make a PLT entry if necessary. 3845 if (gsym->needs_plt_entry()) 3846 target->make_plt_entry(symtab, layout, gsym); 3847 // Make a dynamic relocation if necessary. 3848 if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) 3849 { 3850 if (parameters->options().output_is_executable() 3851 && gsym->may_need_copy_reloc()) 3852 { 3853 target->copy_reloc(symtab, layout, object, 3854 data_shndx, output_section, gsym, reloc); 3855 } 3856 else 3857 { 3858 this->check_non_pic(object, r_type); 3859 Reloc_section* rela_dyn = target->rela_dyn_section(layout); 3860 rela_dyn->add_global(gsym, r_type, output_section, object, 3861 data_shndx, reloc.get_r_offset(), 3862 reloc.get_r_addend()); 3863 } 3864 } 3865 } 3866 break; 3867 3868 case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT: 3869 case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT: 3870 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT: 3871 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT: 3872 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT: 3873 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT: 3874 { 3875 // The symbol requires a GOT entry. 3876 Output_data_got<size, big_endian>* got 3877 = target->got_section(symtab, layout); 3878 if (gsym->final_value_is_known()) 3879 { 3880 // For a STT_GNU_IFUNC symbol we want the PLT address. 3881 if (gsym->type() == elfcpp::STT_GNU_IFUNC) 3882 got->add_global_plt(gsym, GOT_TYPE_STANDARD); 3883 else 3884 got->add_global(gsym, GOT_TYPE_STANDARD); 3885 } 3886 else 3887 { 3888 // If this symbol is not fully resolved, we need to add a 3889 // dynamic relocation for it. 3890 Reloc_section* rela_dyn = target->rela_dyn_section(layout); 3891 3892 // Use a GLOB_DAT rather than a RELATIVE reloc if: 3893 // 3894 // 1) The symbol may be defined in some other module. 3895 // 3896 // 2) We are building a shared library and this is a 3897 // protected symbol; using GLOB_DAT means that the dynamic 3898 // linker can use the address of the PLT in the main 3899 // executable when appropriate so that function address 3900 // comparisons work. 3901 // 3902 // 3) This is a STT_GNU_IFUNC symbol in position dependent 3903 // code, again so that function address comparisons work. 3904 if (gsym->is_from_dynobj() 3905 || gsym->is_undefined() 3906 || gsym->is_preemptible() 3907 || (gsym->visibility() == elfcpp::STV_PROTECTED 3908 && parameters->options().shared()) 3909 || (gsym->type() == elfcpp::STT_GNU_IFUNC 3910 && parameters->options().output_is_position_independent())) 3911 got->add_global_with_rel(gsym, GOT_TYPE_STANDARD, rela_dyn, 3912 elfcpp::R_TILEGX_GLOB_DAT); 3913 else 3914 { 3915 // For a STT_GNU_IFUNC symbol we want to write the PLT 3916 // offset into the GOT, so that function pointer 3917 // comparisons work correctly. 3918 bool is_new; 3919 if (gsym->type() != elfcpp::STT_GNU_IFUNC) 3920 is_new = got->add_global(gsym, GOT_TYPE_STANDARD); 3921 else 3922 { 3923 is_new = got->add_global_plt(gsym, GOT_TYPE_STANDARD); 3924 // Tell the dynamic linker to use the PLT address 3925 // when resolving relocations. 3926 if (gsym->is_from_dynobj() 3927 && !parameters->options().shared()) 3928 gsym->set_needs_dynsym_value(); 3929 } 3930 if (is_new) 3931 { 3932 unsigned int got_off = gsym->got_offset(GOT_TYPE_STANDARD); 3933 rela_dyn->add_global_relative(gsym, 3934 r_type, 3935 got, got_off, 0, false); 3936 } 3937 } 3938 } 3939 } 3940 break; 3941 3942 // a minor difference here for R_TILEGX_JUMPOFF_X1 3943 // between bfd linker and gold linker for gold, when 3944 // R_TILEGX_JUMPOFF_X1 against global symbol, we 3945 // turn it into JUMPOFF_X1_PLT, otherwise the distance 3946 // to the symbol function may overflow at runtime. 3947 case elfcpp::R_TILEGX_JUMPOFF_X1: 3948 3949 case elfcpp::R_TILEGX_JUMPOFF_X1_PLT: 3950 case elfcpp::R_TILEGX_IMM16_X0_HW0_PLT_PCREL: 3951 case elfcpp::R_TILEGX_IMM16_X1_HW0_PLT_PCREL: 3952 case elfcpp::R_TILEGX_IMM16_X0_HW1_PLT_PCREL: 3953 case elfcpp::R_TILEGX_IMM16_X1_HW1_PLT_PCREL: 3954 case elfcpp::R_TILEGX_IMM16_X0_HW2_PLT_PCREL: 3955 case elfcpp::R_TILEGX_IMM16_X1_HW2_PLT_PCREL: 3956 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: 3957 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: 3958 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: 3959 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: 3960 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: 3961 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: 3962 // If the symbol is fully resolved, this is just a PC32 reloc. 3963 // Otherwise we need a PLT entry. 3964 if (gsym->final_value_is_known()) 3965 break; 3966 // If building a shared library, we can also skip the PLT entry 3967 // if the symbol is defined in the output file and is protected 3968 // or hidden. 3969 if (gsym->is_defined() 3970 && !gsym->is_from_dynobj() 3971 && !gsym->is_preemptible()) 3972 break; 3973 target->make_plt_entry(symtab, layout, gsym); 3974 break; 3975 3976 3977 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: 3978 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: 3979 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE: 3980 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE: 3981 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: 3982 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: 3983 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: 3984 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: 3985 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: 3986 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: 3987 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: 3988 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: 3989 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE: 3990 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE: 3991 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: 3992 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: 3993 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: 3994 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: 3995 case elfcpp::R_TILEGX_TLS_GD_CALL: 3996 case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: 3997 case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD: 3998 case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: 3999 case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: 4000 case elfcpp::R_TILEGX_TLS_IE_LOAD: 4001 case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: 4002 case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD: 4003 case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD: 4004 case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD: 4005 { 4006 const bool is_final = gsym->final_value_is_known(); 4007 const tls::Tls_optimization opt_t = 4008 Target_tilegx<size, big_endian>::optimize_tls_reloc(is_final, 4009 r_type); 4010 4011 switch (r_type) 4012 { 4013 // only expand to plt against __tls_get_addr in GD model 4014 case elfcpp::R_TILEGX_TLS_GD_CALL: 4015 if (opt_t == tls::TLSOPT_NONE) { 4016 // FIXME: it's better '__tls_get_addr' referenced explictly 4017 if (!target->tls_get_addr_sym_defined_) { 4018 Symbol* sym = NULL; 4019 options::parse_set(NULL, "__tls_get_addr", 4020 (gold::options::String_set*) 4021 ¶meters->options().undefined()); 4022 symtab->add_undefined_symbols_from_command_line(layout); 4023 target->tls_get_addr_sym_defined_ = true; 4024 sym = symtab->lookup("__tls_get_addr"); 4025 sym->set_in_reg(); 4026 } 4027 target->make_plt_entry(symtab, layout, 4028 symtab->lookup("__tls_get_addr")); 4029 } 4030 break; 4031 4032 // only make effect when applying relocation 4033 case elfcpp::R_TILEGX_TLS_IE_LOAD: 4034 case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: 4035 case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD: 4036 case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD: 4037 case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD: 4038 case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: 4039 case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD: 4040 case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: 4041 case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: 4042 break; 4043 4044 // GD: requires two GOT entry for module index and offset 4045 // IE: requires one GOT entry for tp-relative offset 4046 // LE: shouldn't happen for global symbol 4047 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: 4048 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: 4049 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: 4050 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: 4051 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: 4052 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: 4053 { 4054 if (opt_t == tls::TLSOPT_NONE) { 4055 Output_data_got<size, big_endian>* got 4056 = target->got_section(symtab, layout); 4057 got->add_global_pair_with_rel(gsym, GOT_TYPE_TLS_PAIR, 4058 target->rela_dyn_section(layout), 4059 size == 32 4060 ? elfcpp::R_TILEGX_TLS_DTPMOD32 4061 : elfcpp::R_TILEGX_TLS_DTPMOD64, 4062 size == 32 4063 ? elfcpp::R_TILEGX_TLS_DTPOFF32 4064 : elfcpp::R_TILEGX_TLS_DTPOFF64); 4065 } else if (opt_t == tls::TLSOPT_TO_IE) { 4066 // Create a GOT entry for the tp-relative offset. 4067 Output_data_got<size, big_endian>* got 4068 = target->got_section(symtab, layout); 4069 got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET, 4070 target->rela_dyn_section(layout), 4071 size == 32 4072 ? elfcpp::R_TILEGX_TLS_TPOFF32 4073 : elfcpp::R_TILEGX_TLS_TPOFF64); 4074 } else if (opt_t != tls::TLSOPT_TO_LE) 4075 // exteranl symbol should not be optimized to TO_LE 4076 unsupported_reloc_global(object, r_type, gsym); 4077 } 4078 break; 4079 4080 // IE 4081 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE: 4082 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE: 4083 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: 4084 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: 4085 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: 4086 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: 4087 { 4088 layout->set_has_static_tls(); 4089 if (opt_t == tls::TLSOPT_NONE) { 4090 // Create a GOT entry for the tp-relative offset. 4091 Output_data_got<size, big_endian>* got 4092 = target->got_section(symtab, layout); 4093 got->add_global_with_rel(gsym, GOT_TYPE_TLS_OFFSET, 4094 target->rela_dyn_section(layout), 4095 size == 32 4096 ? elfcpp::R_TILEGX_TLS_TPOFF32 4097 : elfcpp::R_TILEGX_TLS_TPOFF64); 4098 } else if (opt_t != tls::TLSOPT_TO_LE) 4099 unsupported_reloc_global(object, r_type, gsym); 4100 } 4101 break; 4102 4103 // LE 4104 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE: 4105 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE: 4106 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: 4107 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: 4108 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: 4109 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: 4110 layout->set_has_static_tls(); 4111 if (parameters->options().shared()) { 4112 // defer to dynamic linker 4113 Reloc_section* rela_dyn = target->rela_dyn_section(layout); 4114 rela_dyn->add_symbolless_global_addend(gsym, r_type, 4115 output_section, object, 4116 data_shndx, 4117 reloc.get_r_offset(), 0); 4118 } 4119 break; 4120 4121 default: 4122 gold_unreachable(); 4123 } 4124 } 4125 break; 4126 4127 // below are outstanding relocs 4128 // should not existed in static linking stage 4129 case elfcpp::R_TILEGX_COPY: 4130 case elfcpp::R_TILEGX_GLOB_DAT: 4131 case elfcpp::R_TILEGX_JMP_SLOT: 4132 case elfcpp::R_TILEGX_RELATIVE: 4133 case elfcpp::R_TILEGX_TLS_TPOFF32: 4134 case elfcpp::R_TILEGX_TLS_TPOFF64: 4135 case elfcpp::R_TILEGX_TLS_DTPMOD32: 4136 case elfcpp::R_TILEGX_TLS_DTPMOD64: 4137 case elfcpp::R_TILEGX_TLS_DTPOFF32: 4138 case elfcpp::R_TILEGX_TLS_DTPOFF64: 4139 gold_error(_("%s: unexpected reloc %u in object file"), 4140 object->name().c_str(), r_type); 4141 break; 4142 4143 default: 4144 gold_error(_("%s: unsupported reloc %u against global symbol %s"), 4145 object->name().c_str(), r_type, 4146 gsym->demangled_name().c_str()); 4147 break; 4148 } 4149 } 4150 4151 template<int size, bool big_endian> 4152 void 4153 Target_tilegx<size, big_endian>::gc_process_relocs(Symbol_table* symtab, 4154 Layout* layout, 4155 Sized_relobj_file<size, big_endian>* object, 4156 unsigned int data_shndx, 4157 unsigned int sh_type, 4158 const unsigned char* prelocs, 4159 size_t reloc_count, 4160 Output_section* output_section, 4161 bool needs_special_offset_handling, 4162 size_t local_symbol_count, 4163 const unsigned char* plocal_symbols) 4164 { 4165 typedef Target_tilegx<size, big_endian> Tilegx; 4166 typedef typename Target_tilegx<size, big_endian>::Scan Scan; 4167 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian> 4168 Classify_reloc; 4169 4170 if (sh_type == elfcpp::SHT_REL) 4171 { 4172 return; 4173 } 4174 4175 gold::gc_process_relocs<size, big_endian, Tilegx, Scan, Classify_reloc>( 4176 symtab, 4177 layout, 4178 this, 4179 object, 4180 data_shndx, 4181 prelocs, 4182 reloc_count, 4183 output_section, 4184 needs_special_offset_handling, 4185 local_symbol_count, 4186 plocal_symbols); 4187 } 4188 // Scan relocations for a section. 4189 4190 template<int size, bool big_endian> 4191 void 4192 Target_tilegx<size, big_endian>::scan_relocs(Symbol_table* symtab, 4193 Layout* layout, 4194 Sized_relobj_file<size, big_endian>* object, 4195 unsigned int data_shndx, 4196 unsigned int sh_type, 4197 const unsigned char* prelocs, 4198 size_t reloc_count, 4199 Output_section* output_section, 4200 bool needs_special_offset_handling, 4201 size_t local_symbol_count, 4202 const unsigned char* plocal_symbols) 4203 { 4204 typedef Target_tilegx<size, big_endian> Tilegx; 4205 typedef typename Target_tilegx<size, big_endian>::Scan Scan; 4206 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian> 4207 Classify_reloc; 4208 4209 if (sh_type == elfcpp::SHT_REL) 4210 { 4211 gold_error(_("%s: unsupported REL reloc section"), 4212 object->name().c_str()); 4213 return; 4214 } 4215 4216 gold::scan_relocs<size, big_endian, Tilegx, Scan, Classify_reloc>( 4217 symtab, 4218 layout, 4219 this, 4220 object, 4221 data_shndx, 4222 prelocs, 4223 reloc_count, 4224 output_section, 4225 needs_special_offset_handling, 4226 local_symbol_count, 4227 plocal_symbols); 4228 } 4229 4230 template<int size, bool big_endian> 4231 void 4232 Target_tilegx<size, big_endian>::do_define_standard_symbols( 4233 Symbol_table* symtab, 4234 Layout* layout) 4235 { 4236 Output_section* feedback_section = layout->find_output_section(".feedback"); 4237 4238 if (feedback_section != NULL) 4239 { 4240 symtab->define_in_output_data("__feedback_section_end", 4241 NULL, 4242 Symbol_table::PREDEFINED, 4243 feedback_section, 4244 0, 4245 0, 4246 elfcpp::STT_NOTYPE, 4247 elfcpp::STB_GLOBAL, 4248 elfcpp::STV_HIDDEN, 4249 0, 4250 true, // offset_is_from_end 4251 false); 4252 } 4253 } 4254 4255 // Finalize the sections. 4256 4257 template<int size, bool big_endian> 4258 void 4259 Target_tilegx<size, big_endian>::do_finalize_sections( 4260 Layout* layout, 4261 const Input_objects*, 4262 Symbol_table* symtab) 4263 { 4264 const Reloc_section* rel_plt = (this->plt_ == NULL 4265 ? NULL 4266 : this->plt_->rela_plt()); 4267 layout->add_target_dynamic_tags(false, this->got_plt_, rel_plt, 4268 this->rela_dyn_, true, true); 4269 4270 // Emit any relocs we saved in an attempt to avoid generating COPY 4271 // relocs. 4272 if (this->copy_relocs_.any_saved_relocs()) 4273 this->copy_relocs_.emit(this->rela_dyn_section(layout)); 4274 4275 // Set the size of the _GLOBAL_OFFSET_TABLE_ symbol to the size of 4276 // the .got section. 4277 Symbol* sym = this->global_offset_table_; 4278 if (sym != NULL) 4279 { 4280 uint64_t data_size = this->got_->current_data_size(); 4281 symtab->get_sized_symbol<size>(sym)->set_symsize(data_size); 4282 4283 // If the .got section is more than 0x8000 bytes, we add 4284 // 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16 4285 // bit relocations have a greater chance of working. 4286 if (data_size >= 0x8000) 4287 symtab->get_sized_symbol<size>(sym)->set_value( 4288 symtab->get_sized_symbol<size>(sym)->value() + 0x8000); 4289 } 4290 4291 if (parameters->doing_static_link() 4292 && (this->plt_ == NULL || !this->plt_->has_irelative_section())) 4293 { 4294 // If linking statically, make sure that the __rela_iplt symbols 4295 // were defined if necessary, even if we didn't create a PLT. 4296 static const Define_symbol_in_segment syms[] = 4297 { 4298 { 4299 "__rela_iplt_start", // name 4300 elfcpp::PT_LOAD, // segment_type 4301 elfcpp::PF_W, // segment_flags_set 4302 elfcpp::PF(0), // segment_flags_clear 4303 0, // value 4304 0, // size 4305 elfcpp::STT_NOTYPE, // type 4306 elfcpp::STB_GLOBAL, // binding 4307 elfcpp::STV_HIDDEN, // visibility 4308 0, // nonvis 4309 Symbol::SEGMENT_START, // offset_from_base 4310 true // only_if_ref 4311 }, 4312 { 4313 "__rela_iplt_end", // name 4314 elfcpp::PT_LOAD, // segment_type 4315 elfcpp::PF_W, // segment_flags_set 4316 elfcpp::PF(0), // segment_flags_clear 4317 0, // value 4318 0, // size 4319 elfcpp::STT_NOTYPE, // type 4320 elfcpp::STB_GLOBAL, // binding 4321 elfcpp::STV_HIDDEN, // visibility 4322 0, // nonvis 4323 Symbol::SEGMENT_START, // offset_from_base 4324 true // only_if_ref 4325 } 4326 }; 4327 4328 symtab->define_symbols(layout, 2, syms, 4329 layout->script_options()->saw_sections_clause()); 4330 } 4331 } 4332 4333 // Perform a relocation. 4334 4335 template<int size, bool big_endian> 4336 inline bool 4337 Target_tilegx<size, big_endian>::Relocate::relocate( 4338 const Relocate_info<size, big_endian>* relinfo, 4339 unsigned int, 4340 Target_tilegx<size, big_endian>* target, 4341 Output_section*, 4342 size_t relnum, 4343 const unsigned char* preloc, 4344 const Sized_symbol<size>* gsym, 4345 const Symbol_value<size>* psymval, 4346 unsigned char* view, 4347 typename elfcpp::Elf_types<size>::Elf_Addr address, 4348 section_size_type) 4349 { 4350 if (view == NULL) 4351 return true; 4352 4353 typedef Tilegx_relocate_functions<size, big_endian> TilegxReloc; 4354 typename TilegxReloc::Tilegx_howto r_howto; 4355 4356 const elfcpp::Rela<size, big_endian> rela(preloc); 4357 unsigned int r_type = elfcpp::elf_r_type<size>(rela.get_r_info()); 4358 const Sized_relobj_file<size, big_endian>* object = relinfo->object; 4359 4360 // Pick the value to use for symbols defined in the PLT. 4361 Symbol_value<size> symval; 4362 if (gsym != NULL 4363 && gsym->use_plt_offset(Scan::get_reference_flags(r_type))) 4364 { 4365 symval.set_output_value(target->plt_address_for_global(gsym)); 4366 psymval = &symval; 4367 } 4368 else if (gsym == NULL && psymval->is_ifunc_symbol()) 4369 { 4370 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info()); 4371 if (object->local_has_plt_offset(r_sym)) 4372 { 4373 symval.set_output_value(target->plt_address_for_local(object, r_sym)); 4374 psymval = &symval; 4375 } 4376 } 4377 4378 elfcpp::Elf_Xword addend = rela.get_r_addend(); 4379 4380 // Get the GOT offset if needed. 4381 // For tilegx, the GOT pointer points to the start of the GOT section. 4382 bool have_got_offset = false; 4383 int got_offset = 0; 4384 int got_base = target->got_ != NULL 4385 ? target->got_->current_data_size() >= 0x8000 ? 0x8000 : 0 4386 : 0; 4387 unsigned int got_type = GOT_TYPE_STANDARD; 4388 bool always_apply_relocation = false; 4389 switch (r_type) 4390 { 4391 case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT: 4392 case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT: 4393 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT: 4394 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT: 4395 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT: 4396 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT: 4397 if (gsym != NULL) 4398 { 4399 gold_assert(gsym->has_got_offset(got_type)); 4400 got_offset = gsym->got_offset(got_type) - got_base; 4401 } 4402 else 4403 { 4404 unsigned int r_sym = elfcpp::elf_r_sym<size>(rela.get_r_info()); 4405 gold_assert(object->local_has_got_offset(r_sym, got_type)); 4406 got_offset = 4407 object->local_got_offset(r_sym, got_type) - got_base; 4408 } 4409 have_got_offset = true; 4410 break; 4411 4412 default: 4413 break; 4414 } 4415 4416 r_howto = TilegxReloc::howto[r_type]; 4417 switch (r_type) 4418 { 4419 case elfcpp::R_TILEGX_NONE: 4420 case elfcpp::R_TILEGX_GNU_VTINHERIT: 4421 case elfcpp::R_TILEGX_GNU_VTENTRY: 4422 break; 4423 4424 case elfcpp::R_TILEGX_IMM16_X0_HW0_GOT: 4425 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_GOT: 4426 case elfcpp::R_TILEGX_IMM16_X1_HW0_GOT: 4427 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_GOT: 4428 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_GOT: 4429 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_GOT: 4430 gold_assert(have_got_offset); 4431 symval.set_output_value(got_offset); 4432 psymval = &symval; 4433 always_apply_relocation = true; 4434 addend = 0; 4435 // Fall through. 4436 4437 // when under PIC mode, these relocations are deferred to rtld 4438 case elfcpp::R_TILEGX_IMM16_X0_HW0: 4439 case elfcpp::R_TILEGX_IMM16_X1_HW0: 4440 case elfcpp::R_TILEGX_IMM16_X0_HW1: 4441 case elfcpp::R_TILEGX_IMM16_X1_HW1: 4442 case elfcpp::R_TILEGX_IMM16_X0_HW2: 4443 case elfcpp::R_TILEGX_IMM16_X1_HW2: 4444 case elfcpp::R_TILEGX_IMM16_X0_HW3: 4445 case elfcpp::R_TILEGX_IMM16_X1_HW3: 4446 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST: 4447 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST: 4448 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST: 4449 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST: 4450 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST: 4451 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST: 4452 if (always_apply_relocation 4453 || !parameters->options().output_is_position_independent()) 4454 TilegxReloc::imm_x_general(view, object, psymval, addend, r_howto); 4455 break; 4456 4457 case elfcpp::R_TILEGX_JUMPOFF_X1: 4458 case elfcpp::R_TILEGX_JUMPOFF_X1_PLT: 4459 gold_assert(gsym == NULL 4460 || gsym->has_plt_offset() 4461 || gsym->final_value_is_known() 4462 || (gsym->is_defined() 4463 && !gsym->is_from_dynobj() 4464 && !gsym->is_preemptible())); 4465 TilegxReloc::imm_x_pcrel_general(view, object, psymval, addend, 4466 address, r_howto); 4467 break; 4468 4469 4470 case elfcpp::R_TILEGX_IMM16_X0_HW0_PLT_PCREL: 4471 case elfcpp::R_TILEGX_IMM16_X0_HW0_PCREL: 4472 case elfcpp::R_TILEGX_IMM16_X1_HW0_PLT_PCREL: 4473 case elfcpp::R_TILEGX_IMM16_X1_HW0_PCREL: 4474 case elfcpp::R_TILEGX_IMM16_X0_HW1_PLT_PCREL: 4475 case elfcpp::R_TILEGX_IMM16_X0_HW1_PCREL: 4476 case elfcpp::R_TILEGX_IMM16_X1_HW1_PLT_PCREL: 4477 case elfcpp::R_TILEGX_IMM16_X1_HW1_PCREL: 4478 case elfcpp::R_TILEGX_IMM16_X0_HW2_PLT_PCREL: 4479 case elfcpp::R_TILEGX_IMM16_X0_HW2_PCREL: 4480 case elfcpp::R_TILEGX_IMM16_X1_HW2_PLT_PCREL: 4481 case elfcpp::R_TILEGX_IMM16_X1_HW2_PCREL: 4482 case elfcpp::R_TILEGX_IMM16_X0_HW3_PCREL: 4483 case elfcpp::R_TILEGX_IMM16_X1_HW3_PCREL: 4484 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL: 4485 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_PCREL: 4486 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL: 4487 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_PCREL: 4488 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL: 4489 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_PCREL: 4490 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL: 4491 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_PCREL: 4492 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL: 4493 case elfcpp::R_TILEGX_IMM16_X0_HW2_LAST_PCREL: 4494 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL: 4495 case elfcpp::R_TILEGX_IMM16_X1_HW2_LAST_PCREL: 4496 TilegxReloc::imm_x_pcrel_general(view, object, psymval, addend, 4497 address, r_howto); 4498 break; 4499 4500 case elfcpp::R_TILEGX_BROFF_X1: 4501 case elfcpp::R_TILEGX_DEST_IMM8_X1: 4502 TilegxReloc::imm_x_two_part_general(view, object, psymval, 4503 addend, address, r_type); 4504 break; 4505 4506 4507 // below are general relocation types, which can be 4508 // handled by target-independent handlers 4509 case elfcpp::R_TILEGX_64: 4510 TilegxReloc::abs64(view, object, psymval, addend); 4511 break; 4512 4513 case elfcpp::R_TILEGX_64_PCREL: 4514 TilegxReloc::pc_abs64(view, object, psymval, addend, address); 4515 break; 4516 4517 case elfcpp::R_TILEGX_32: 4518 TilegxReloc::abs32(view, object, psymval, addend); 4519 break; 4520 4521 case elfcpp::R_TILEGX_32_PCREL: 4522 TilegxReloc::pc_abs32(view, object, psymval, addend, address); 4523 break; 4524 4525 case elfcpp::R_TILEGX_16: 4526 TilegxReloc::abs16(view, object, psymval, addend); 4527 break; 4528 4529 case elfcpp::R_TILEGX_16_PCREL: 4530 TilegxReloc::pc_abs16(view, object, psymval, addend, address); 4531 break; 4532 4533 case elfcpp::R_TILEGX_8: 4534 Relocate_functions<size, big_endian>::rela8(view, object, 4535 psymval, addend); 4536 break; 4537 4538 case elfcpp::R_TILEGX_8_PCREL: 4539 Relocate_functions<size, big_endian>::pcrela8(view, object, 4540 psymval, addend, address); 4541 break; 4542 4543 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: 4544 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: 4545 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE: 4546 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE: 4547 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: 4548 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: 4549 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: 4550 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: 4551 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: 4552 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: 4553 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: 4554 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: 4555 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE: 4556 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE: 4557 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: 4558 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: 4559 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: 4560 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: 4561 case elfcpp::R_TILEGX_TLS_GD_CALL: 4562 case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: 4563 case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD: 4564 case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: 4565 case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: 4566 case elfcpp::R_TILEGX_TLS_IE_LOAD: 4567 case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: 4568 case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD: 4569 case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD: 4570 case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD: 4571 { 4572 const bool is_final = (gsym == NULL 4573 ? !parameters->options().shared() 4574 : gsym->final_value_is_known()); 4575 tls::Tls_optimization opt_t = 4576 Target_tilegx<size, big_endian>::optimize_tls_reloc(is_final, 4577 r_type); 4578 4579 switch (r_type) 4580 { 4581 4582 case elfcpp::R_TILEGX_TLS_GD_CALL: 4583 { 4584 if (opt_t == tls::TLSOPT_NONE) { 4585 Symbol *tls_sym = relinfo->symtab->lookup("__tls_get_addr"); 4586 symval.set_output_value( 4587 target->plt_address_for_global(tls_sym)); 4588 psymval = &symval; 4589 TilegxReloc::imm_x_pcrel_general(view, object, psymval, 4590 addend, address, r_howto); 4591 } 4592 else if (opt_t == tls::TLSOPT_TO_IE 4593 || opt_t == tls::TLSOPT_TO_LE) 4594 TilegxReloc::tls_relax(view, r_type, opt_t); 4595 } 4596 break; 4597 4598 // XX_TLS_GD is the same as normal X_GOT relocation 4599 // except allocating a got entry pair, 4600 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: 4601 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: 4602 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD: 4603 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD: 4604 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD: 4605 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD: 4606 if (opt_t == tls::TLSOPT_NONE) { 4607 got_type = GOT_TYPE_TLS_PAIR; 4608 have_got_offset = true; 4609 } else if (opt_t == tls::TLSOPT_TO_IE) { 4610 got_type = GOT_TYPE_TLS_OFFSET; 4611 have_got_offset = true; 4612 } 4613 goto do_update_value; 4614 // XX_TLS_IE is the same as normal X_GOT relocation 4615 // except allocating one additional runtime relocation 4616 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE: 4617 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE: 4618 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE: 4619 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE: 4620 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE: 4621 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE: 4622 if (opt_t == tls::TLSOPT_NONE) { 4623 got_type = GOT_TYPE_TLS_OFFSET; 4624 have_got_offset = true; 4625 } 4626 // Fall through. 4627 do_update_value: 4628 if (have_got_offset) { 4629 if (gsym != NULL) { 4630 gold_assert(gsym->has_got_offset(got_type)); 4631 got_offset = gsym->got_offset(got_type) - got_base; 4632 } else { 4633 unsigned int r_sym 4634 = elfcpp::elf_r_sym<size>(rela.get_r_info()); 4635 gold_assert(object->local_has_got_offset(r_sym, got_type)); 4636 got_offset = 4637 object->local_got_offset(r_sym, got_type) - got_base; 4638 } 4639 } 4640 4641 if (opt_t == tls::TLSOPT_NONE 4642 || opt_t == tls::TLSOPT_TO_IE) { 4643 // for both GD/IE, these relocations 4644 // actually calculate got offset, so 4645 // there behavior are the same 4646 gold_assert(have_got_offset); 4647 symval.set_output_value(got_offset); 4648 psymval = &symval; 4649 addend = 0; 4650 TilegxReloc::imm_x_general(view, object, psymval, 4651 addend, r_howto); 4652 break; 4653 } // else if (opt_t == tls::TLSOPT_TO_LE) 4654 // both GD/IE are turned into LE, which 4655 // is absolute relocation. 4656 // Fall through. 4657 4658 // LE 4659 // 4660 // tp 4661 // | 4662 // V 4663 // t_var1 | t_var2 | t_var3 | ... 4664 // -------------------------------------------------- 4665 // 4666 // so offset to tp should be negative, we get offset 4667 // from the following formular for LE 4668 // 4669 // t_var1_off = t_var1_sym_value - tls_section_start 4670 // 4671 case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE: 4672 case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE: 4673 case elfcpp::R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE: 4674 case elfcpp::R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE: 4675 case elfcpp::R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE: 4676 case elfcpp::R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE: 4677 { 4678 Output_segment *tls_segment = relinfo->layout->tls_segment(); 4679 if (tls_segment == NULL) { 4680 gold_assert(parameters->errors()->error_count() > 0 4681 || issue_undefined_symbol_error(gsym)); 4682 return false; 4683 } 4684 4685 typename elfcpp::Elf_types<size>::Elf_Addr value 4686 = psymval->value(relinfo->object, 0); 4687 symval.set_output_value(value); 4688 psymval = &symval; 4689 TilegxReloc::imm_x_general(view, object, psymval, 4690 addend, r_howto); 4691 } 4692 break; 4693 4694 // tls relaxation 4695 case elfcpp::R_TILEGX_TLS_IE_LOAD: 4696 case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: 4697 case elfcpp::R_TILEGX_IMM8_X1_TLS_ADD: 4698 case elfcpp::R_TILEGX_IMM8_Y0_TLS_ADD: 4699 case elfcpp::R_TILEGX_IMM8_Y1_TLS_ADD: 4700 case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: 4701 case elfcpp::R_TILEGX_IMM8_X1_TLS_GD_ADD: 4702 case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: 4703 case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: 4704 TilegxReloc::tls_relax(view, r_type, opt_t); 4705 break; 4706 4707 default: 4708 gold_unreachable(); 4709 } 4710 } 4711 break; 4712 4713 // below are outstanding relocs 4714 // should not existed in static linking stage 4715 case elfcpp::R_TILEGX_COPY: 4716 case elfcpp::R_TILEGX_GLOB_DAT: 4717 case elfcpp::R_TILEGX_JMP_SLOT: 4718 case elfcpp::R_TILEGX_RELATIVE: 4719 case elfcpp::R_TILEGX_TLS_TPOFF32: 4720 case elfcpp::R_TILEGX_TLS_TPOFF64: 4721 case elfcpp::R_TILEGX_TLS_DTPMOD32: 4722 case elfcpp::R_TILEGX_TLS_DTPMOD64: 4723 case elfcpp::R_TILEGX_TLS_DTPOFF32: 4724 case elfcpp::R_TILEGX_TLS_DTPOFF64: 4725 gold_error_at_location(relinfo, relnum, rela.get_r_offset(), 4726 _("unexpected reloc %u in object file"), 4727 r_type); 4728 break; 4729 4730 default: 4731 gold_error_at_location(relinfo, relnum, rela.get_r_offset(), 4732 _("unsupported reloc %u"), 4733 r_type); 4734 break; 4735 } 4736 4737 return true; 4738 } 4739 4740 // Relocate section data. 4741 4742 template<int size, bool big_endian> 4743 void 4744 Target_tilegx<size, big_endian>::relocate_section( 4745 const Relocate_info<size, big_endian>* relinfo, 4746 unsigned int sh_type, 4747 const unsigned char* prelocs, 4748 size_t reloc_count, 4749 Output_section* output_section, 4750 bool needs_special_offset_handling, 4751 unsigned char* view, 4752 typename elfcpp::Elf_types<size>::Elf_Addr address, 4753 section_size_type view_size, 4754 const Reloc_symbol_changes* reloc_symbol_changes) 4755 { 4756 typedef Target_tilegx<size, big_endian> Tilegx; 4757 typedef typename Target_tilegx<size, big_endian>::Relocate Tilegx_relocate; 4758 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian> 4759 Classify_reloc; 4760 4761 gold_assert(sh_type == elfcpp::SHT_RELA); 4762 4763 gold::relocate_section<size, big_endian, Tilegx, Tilegx_relocate, 4764 gold::Default_comdat_behavior, Classify_reloc>( 4765 relinfo, 4766 this, 4767 prelocs, 4768 reloc_count, 4769 output_section, 4770 needs_special_offset_handling, 4771 view, 4772 address, 4773 view_size, 4774 reloc_symbol_changes); 4775 } 4776 4777 // Apply an incremental relocation. Incremental relocations always refer 4778 // to global symbols. 4779 4780 template<int size, bool big_endian> 4781 void 4782 Target_tilegx<size, big_endian>::apply_relocation( 4783 const Relocate_info<size, big_endian>* relinfo, 4784 typename elfcpp::Elf_types<size>::Elf_Addr r_offset, 4785 unsigned int r_type, 4786 typename elfcpp::Elf_types<size>::Elf_Swxword r_addend, 4787 const Symbol* gsym, 4788 unsigned char* view, 4789 typename elfcpp::Elf_types<size>::Elf_Addr address, 4790 section_size_type view_size) 4791 { 4792 gold::apply_relocation<size, big_endian, Target_tilegx<size, big_endian>, 4793 typename Target_tilegx<size, big_endian>::Relocate>( 4794 relinfo, 4795 this, 4796 r_offset, 4797 r_type, 4798 r_addend, 4799 gsym, 4800 view, 4801 address, 4802 view_size); 4803 } 4804 4805 // Scan the relocs during a relocatable link. 4806 4807 template<int size, bool big_endian> 4808 void 4809 Target_tilegx<size, big_endian>::scan_relocatable_relocs( 4810 Symbol_table* symtab, 4811 Layout* layout, 4812 Sized_relobj_file<size, big_endian>* object, 4813 unsigned int data_shndx, 4814 unsigned int sh_type, 4815 const unsigned char* prelocs, 4816 size_t reloc_count, 4817 Output_section* output_section, 4818 bool needs_special_offset_handling, 4819 size_t local_symbol_count, 4820 const unsigned char* plocal_symbols, 4821 Relocatable_relocs* rr) 4822 { 4823 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian> 4824 Classify_reloc; 4825 typedef gold::Default_scan_relocatable_relocs<Classify_reloc> 4826 Scan_relocatable_relocs; 4827 4828 gold_assert(sh_type == elfcpp::SHT_RELA); 4829 4830 gold::scan_relocatable_relocs<size, big_endian, Scan_relocatable_relocs>( 4831 symtab, 4832 layout, 4833 object, 4834 data_shndx, 4835 prelocs, 4836 reloc_count, 4837 output_section, 4838 needs_special_offset_handling, 4839 local_symbol_count, 4840 plocal_symbols, 4841 rr); 4842 } 4843 4844 // Scan the relocs for --emit-relocs. 4845 4846 template<int size, bool big_endian> 4847 void 4848 Target_tilegx<size, big_endian>::emit_relocs_scan( 4849 Symbol_table* symtab, 4850 Layout* layout, 4851 Sized_relobj_file<size, big_endian>* object, 4852 unsigned int data_shndx, 4853 unsigned int sh_type, 4854 const unsigned char* prelocs, 4855 size_t reloc_count, 4856 Output_section* output_section, 4857 bool needs_special_offset_handling, 4858 size_t local_symbol_count, 4859 const unsigned char* plocal_syms, 4860 Relocatable_relocs* rr) 4861 { 4862 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian> 4863 Classify_reloc; 4864 typedef gold::Default_emit_relocs_strategy<Classify_reloc> 4865 Emit_relocs_strategy; 4866 4867 gold_assert(sh_type == elfcpp::SHT_RELA); 4868 4869 gold::scan_relocatable_relocs<size, big_endian, Emit_relocs_strategy>( 4870 symtab, 4871 layout, 4872 object, 4873 data_shndx, 4874 prelocs, 4875 reloc_count, 4876 output_section, 4877 needs_special_offset_handling, 4878 local_symbol_count, 4879 plocal_syms, 4880 rr); 4881 } 4882 4883 // Relocate a section during a relocatable link. 4884 4885 template<int size, bool big_endian> 4886 void 4887 Target_tilegx<size, big_endian>::relocate_relocs( 4888 const Relocate_info<size, big_endian>* relinfo, 4889 unsigned int sh_type, 4890 const unsigned char* prelocs, 4891 size_t reloc_count, 4892 Output_section* output_section, 4893 typename elfcpp::Elf_types<size>::Elf_Off offset_in_output_section, 4894 unsigned char* view, 4895 typename elfcpp::Elf_types<size>::Elf_Addr view_address, 4896 section_size_type view_size, 4897 unsigned char* reloc_view, 4898 section_size_type reloc_view_size) 4899 { 4900 typedef gold::Default_classify_reloc<elfcpp::SHT_RELA, size, big_endian> 4901 Classify_reloc; 4902 4903 gold_assert(sh_type == elfcpp::SHT_RELA); 4904 4905 gold::relocate_relocs<size, big_endian, Classify_reloc>( 4906 relinfo, 4907 prelocs, 4908 reloc_count, 4909 output_section, 4910 offset_in_output_section, 4911 view, 4912 view_address, 4913 view_size, 4914 reloc_view, 4915 reloc_view_size); 4916 } 4917 4918 // Return the value to use for a dynamic which requires special 4919 // treatment. This is how we support equality comparisons of function 4920 // pointers across shared library boundaries, as described in the 4921 // processor specific ABI supplement. 4922 4923 template<int size, bool big_endian> 4924 uint64_t 4925 Target_tilegx<size, big_endian>::do_dynsym_value(const Symbol* gsym) const 4926 { 4927 gold_assert(gsym->is_from_dynobj() && gsym->has_plt_offset()); 4928 return this->plt_address_for_global(gsym); 4929 } 4930 4931 // Return the value to use for the base of a DW_EH_PE_datarel offset 4932 // in an FDE. Solaris and SVR4 use DW_EH_PE_datarel because their 4933 // assembler can not write out the difference between two labels in 4934 // different sections, so instead of using a pc-relative value they 4935 // use an offset from the GOT. 4936 4937 template<int size, bool big_endian> 4938 uint64_t 4939 Target_tilegx<size, big_endian>::do_ehframe_datarel_base() const 4940 { 4941 gold_assert(this->global_offset_table_ != NULL); 4942 Symbol* sym = this->global_offset_table_; 4943 Sized_symbol<size>* ssym = static_cast<Sized_symbol<size>*>(sym); 4944 return ssym->value(); 4945 } 4946 4947 // The selector for tilegx object files. 4948 4949 template<int size, bool big_endian> 4950 class Target_selector_tilegx : public Target_selector 4951 { 4952 public: 4953 Target_selector_tilegx() 4954 : Target_selector(elfcpp::EM_TILEGX, size, big_endian, 4955 (size == 64 4956 ? (big_endian ? "elf64-tilegx-be" : "elf64-tilegx-le") 4957 : (big_endian ? "elf32-tilegx-be" 4958 : "elf32-tilegx-le")), 4959 (size == 64 4960 ? (big_endian ? "elf64tilegx_be" : "elf64tilegx") 4961 : (big_endian ? "elf32tilegx_be" : "elf32tilegx"))) 4962 { } 4963 4964 Target* 4965 do_instantiate_target() 4966 { return new Target_tilegx<size, big_endian>(); } 4967 4968 }; 4969 4970 Target_selector_tilegx<64, false> target_selector_tilegx64_le; 4971 Target_selector_tilegx<32, false> target_selector_tilegx32_le; 4972 Target_selector_tilegx<64, true> target_selector_tilegx64_be; 4973 Target_selector_tilegx<32, true> target_selector_tilegx32_be; 4974 } // End anonymous namespace. 4975