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