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