X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Ftilegx.cc;h=f2c1038b045982f5d77b7ca01eab8322f04f1b95;hb=53fc67f8b2663261810353ae8e4f9920ae7a1c56;hp=3c618028a6400f7fabe5ba3405755b267ea5e8a8;hpb=19fec8c1d313c6757a53dc7f09776dc9770ee2ef;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/tilegx.cc b/gold/tilegx.cc index 3c618028a6..f2c1038b04 100644 --- a/gold/tilegx.cc +++ b/gold/tilegx.cc @@ -1,6 +1,6 @@ // tilegx.cc -- tilegx target support for gold. -// Copyright 2012 Free Software Foundation, Inc. +// Copyright (C) 2012-2020 Free Software Foundation, Inc. // Written by Jiong Wang (jiwang@tilera.com) // This file is part of gold. @@ -239,7 +239,7 @@ class Target_tilegx : public Sized_target got_(NULL), plt_(NULL), got_plt_(NULL), got_irelative_(NULL), global_offset_table_(NULL), tilegx_dynamic_(NULL), rela_dyn_(NULL), rela_irelative_(NULL), copy_relocs_(elfcpp::R_TILEGX_COPY), - dynbss_(NULL), got_mod_index_offset_(-1U), + got_mod_index_offset_(-1U), tls_get_addr_sym_defined_(false) { } @@ -308,6 +308,21 @@ class Target_tilegx : public Sized_target const unsigned char* plocal_symbols, Relocatable_relocs*); + // Scan the relocs for --emit-relocs. + void + emit_relocs_scan(Symbol_table* symtab, + Layout* layout, + Sized_relobj_file* object, + unsigned int data_shndx, + unsigned int sh_type, + const unsigned char* prelocs, + size_t reloc_count, + Output_section* output_section, + bool needs_special_offset_handling, + size_t local_symbol_count, + const unsigned char* plocal_syms, + Relocatable_relocs* rr); + // Relocate a section during a relocatable link. void relocate_relocs( @@ -316,8 +331,7 @@ class Target_tilegx : public Sized_target const unsigned char* prelocs, size_t reloc_count, Output_section* output_section, - off_t offset_in_output_section, - const Relocatable_relocs*, + typename elfcpp::Elf_types::Elf_Off offset_in_output_section, unsigned char* view, typename elfcpp::Elf_types::Elf_Addr view_address, section_size_type view_size, @@ -517,22 +531,11 @@ class Target_tilegx : public Sized_target // Do a relocation. Return false if the caller should not issue // any warnings about this relocation. inline bool - relocate(const Relocate_info*, Target_tilegx*, - Output_section*, - size_t relnum, const elfcpp::Rela&, - unsigned int r_type, const Sized_symbol*, - const Symbol_value*, - unsigned char*, typename elfcpp::Elf_types::Elf_Addr, - section_size_type); - }; - - // A class which returns the size required for a relocation type, - // used while scanning relocs during a relocatable link. - class Relocatable_size_for_reloc - { - public: - unsigned int - get_size_for_reloc(unsigned int, Relobj*); + relocate(const Relocate_info*, unsigned int, + Target_tilegx*, Output_section*, size_t, const unsigned char*, + const Sized_symbol*, const Symbol_value*, + unsigned char*, typename elfcpp::Elf_types::Elf_Addr, + section_size_type); }; // Adjust TLS relocation type based on the options and whether this @@ -594,10 +597,13 @@ class Target_tilegx : public Sized_target unsigned int shndx, Output_section* output_section, Symbol* sym, const elfcpp::Rela& reloc) { + unsigned int r_type = elfcpp::elf_r_type(reloc.get_r_info()); this->copy_relocs_.copy_reloc(symtab, layout, symtab->get_sized_symbol(sym), object, shndx, output_section, - reloc, this->rela_dyn_section(layout)); + r_type, reloc.get_r_offset(), + reloc.get_r_addend(), + this->rela_dyn_section(layout)); } // Information about this specific target which we pass to the @@ -650,8 +656,6 @@ class Target_tilegx : public Sized_target Reloc_section* rela_irelative_; // Relocs saved to avoid a COPY reloc. Copy_relocs copy_relocs_; - // Space for variables copied with a COPY reloc. - Output_data_space* dynbss_; // Offset of the GOT entry for the TLS module index. unsigned int got_mod_index_offset_; // True if the _tls_get_addr symbol has been defined. @@ -681,7 +685,10 @@ const Target::Target_info Target_tilegx<64, false>::tilegx_info = 0, // small_common_section_flags 0, // large_common_section_flags NULL, // attributes_section - NULL // attributes_vendor + NULL, // attributes_vendor + "_start", // entry_symbol_name + 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; template<> @@ -707,7 +714,10 @@ const Target::Target_info Target_tilegx<32, false>::tilegx_info = 0, // small_common_section_flags 0, // large_common_section_flags NULL, // attributes_section - NULL // attributes_vendor + NULL, // attributes_vendor + "_start", // entry_symbol_name + 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; template<> @@ -733,7 +743,10 @@ const Target::Target_info Target_tilegx<64, true>::tilegx_info = 0, // small_common_section_flags 0, // large_common_section_flags NULL, // attributes_section - NULL // attributes_vendor + NULL, // attributes_vendor + "_start", // entry_symbol_name + 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; template<> @@ -759,7 +772,10 @@ const Target::Target_info Target_tilegx<32, true>::tilegx_info = 0, // small_common_section_flags 0, // large_common_section_flags NULL, // attributes_section - NULL // attributes_vendor + NULL, // attributes_vendor + "_start", // entry_symbol_name + 32, // hash_entry_size + elfcpp::SHT_PROGBITS, // unwind_section_type }; // tilegx relocation handlers @@ -780,7 +796,7 @@ public: // right shift operand by this number of bits. unsigned char srshift; - // the offset to apply relocation. + // the offset to apply relocation. unsigned char doffset; // set to 1 for pc-relative relocation. @@ -899,7 +915,7 @@ private: Valtype* wv = reinterpret_cast(view); Valtype val = elfcpp::Swap::readval(wv); Valtype reloc = 0; - if (size == 32) + if (size == 32) reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address) >> srshift; else @@ -927,7 +943,7 @@ private: Valtype; unsigned char* wv = view; Valtype reloc = 0; - if (size == 32) + if (size == 32) reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address) >> srshift; else @@ -954,7 +970,7 @@ private: Valtype* wv = reinterpret_cast(view); Valtype val = elfcpp::Swap::readval(wv); Valtype reloc = 0; - if (size == 32) + if (size == 32) reloc = Bits<32>::sign_extend(psymval->value(object, addend) - address) >> srshift; else @@ -1043,7 +1059,7 @@ public: const Symbol_value* psymval, typename elfcpp::Elf_types::Elf_Addr addend, Tilegx_howto &r_howto) - { + { This::template rela<64>(view, object, psymval, addend, (elfcpp::Elf_Xword)(r_howto.srshift), (elfcpp::Elf_Xword)(r_howto.doffset), @@ -1057,7 +1073,7 @@ public: typename elfcpp::Elf_types::Elf_Addr addend, typename elfcpp::Elf_types::Elf_Addr address, Tilegx_howto &r_howto) - { + { This::template pcrela<64>(view, object, psymval, addend, address, (elfcpp::Elf_Xword)(r_howto.srshift), (elfcpp::Elf_Xword)(r_howto.doffset), @@ -1071,7 +1087,7 @@ public: typename elfcpp::Elf_types::Elf_Addr addend, typename elfcpp::Elf_types::Elf_Addr address, unsigned int r_type) - { + { elfcpp::Elf_Xword doffset1 = 0llu; elfcpp::Elf_Xword doffset2 = 0llu; @@ -1111,8 +1127,8 @@ public: static inline void tls_relax(unsigned char* view, unsigned int r_type, tls::Tls_optimization opt_t) - { - + { + const uint64_t TILEGX_X_MOVE_R0_R0 = 0x283bf8005107f000llu; const uint64_t TILEGX_Y_MOVE_R0_R0 = 0xae05f800540bf000llu; const uint64_t TILEGX_X_LD = 0x286ae80000000000llu; @@ -1176,7 +1192,7 @@ public: // LE: 1. copy dest operand into the first source operand // 2. change the opcode to "move" reloc = (val & 0x3Fllu) << 6; - reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK); + reloc |= (TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK); val &= ~R_TILEGX_IMM8_X0_TLS_ADD_LE_MASK; } else gold_unreachable(); @@ -1228,7 +1244,7 @@ public: break; case elfcpp::R_TILEGX_IMM8_X0_TLS_GD_ADD: if (opt_t == tls::TLSOPT_NONE) { - // GD see comments for optimize_tls_reloc + // GD see comments for optimize_tls_reloc reloc = TILEGX_X_MOVE_R0_R0 & TILEGX_X0_RRR_SRCB_MASK; val &= ~TILEGX_X0_RRR_SRCB_MASK; } else if (opt_t == tls::TLSOPT_TO_IE @@ -1890,7 +1906,7 @@ Target_tilegx::got_section(Symbol_table* symtab, false, false); this->got_->add_global(this->tilegx_dynamic_, GOT_TYPE_STANDARD); - } else + } else // for executable, just set the first entry to zero. this->got_->set_current_data_size(size / 8); @@ -2022,7 +2038,7 @@ Output_data_plt_tilegx::add_entry(Symbol_table* symtab, plt_index = *pcount; // TILEGX .plt section layout - // + // // ---- // plt_header // ---- @@ -2030,9 +2046,9 @@ Output_data_plt_tilegx::add_entry(Symbol_table* symtab, // ---- // ... // ---- - // + // // TILEGX .got.plt section layout - // + // // ---- // reserv1 // ---- @@ -2041,7 +2057,7 @@ Output_data_plt_tilegx::add_entry(Symbol_table* symtab, // entries for normal function // ---- // ... - // ---- + // ---- // entries for ifunc // ---- // ... @@ -2515,7 +2531,7 @@ Target_tilegx::make_plt_section(Symbol_table* symtab, this->got_section(symtab, layout); // Ensure that .rela.dyn always appears before .rela.plt, - // becuase on TILE-Gx, .rela.dyn needs to include .rela.plt + // because on TILE-Gx, .rela.dyn needs to include .rela.plt // in it's range. this->rela_dyn_section(layout); @@ -2874,8 +2890,8 @@ Target_tilegx::got_mod_index_entry(Symbol_table* symtab, // move r0, r0 Y0/Y1/X0/X1 // move r0, r0 Y0/Y1/X0/X1 // add adr, r0, tp Y0/Y1/X0/X1 -// -// +// +// // compiler IE reference // | // V @@ -3123,7 +3139,7 @@ Target_tilegx::Scan::unsupported_reloc_local( } // We are about to emit a dynamic relocation of type R_TYPE. If the -// dynamic linker does not support it, issue an error. +// dynamic linker does not support it, issue an error. template void Target_tilegx::Scan::check_non_pic(Relobj* object, @@ -3296,7 +3312,7 @@ Target_tilegx::Scan::local(Symbol_table* symtab, data_shndx, reloc.get_r_offset(), reloc.get_r_addend()); - + } } break; @@ -3363,7 +3379,7 @@ Target_tilegx::Scan::local(Symbol_table* symtab, // tilegx dynamic linker will not update local got entry, // so, if we are generating a shared object, we need to add a // dynamic relocation for this symbol's GOT entry to inform - // dynamic linker plus the load base explictly. + // dynamic linker plus the load base explicitly. if (parameters->options().output_is_position_independent()) { unsigned int got_offset @@ -3419,7 +3435,7 @@ Target_tilegx::Scan::local(Symbol_table* symtab, // // R_TILEGX_TLS_GD_CALL implicitly reference __tls_get_addr, // while all other target, x86/arm/mips/powerpc/sparc - // generate tls relocation against __tls_get_addr explictly, + // generate tls relocation against __tls_get_addr explicitly, // so for TILEGX, we need the following hack. if (opt_t == tls::TLSOPT_NONE) { if (!target->tls_get_addr_sym_defined_) { @@ -3450,7 +3466,7 @@ Target_tilegx::Scan::local(Symbol_table* symtab, break; // GD: requires two GOT entry for module index and offset - // IE: requires one GOT entry for tp-relative offset + // IE: requires one GOT entry for tp-relative offset // LE: shouldn't happen for global symbol case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: @@ -3473,7 +3489,7 @@ Target_tilegx::Scan::local(Symbol_table* symtab, r_sym, shndx); else got->add_local_pair_with_rel(object, r_sym, shndx, - GOT_TYPE_TLS_PAIR, + GOT_TYPE_TLS_PAIR, target->rela_dyn_section(layout), size == 32 ? elfcpp::R_TILEGX_TLS_DTPMOD32 @@ -3493,7 +3509,7 @@ Target_tilegx::Scan::local(Symbol_table* symtab, ? elfcpp::R_TILEGX_TLS_TPOFF32 : elfcpp::R_TILEGX_TLS_TPOFF64, got, off, 0); - } else if (opt_t != tls::TLSOPT_TO_LE) + } else if (opt_t != tls::TLSOPT_TO_LE) // only TO_LE is allowed for local symbol unsupported_reloc_local(object, r_type); } @@ -3756,7 +3772,8 @@ Target_tilegx::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (!parameters->options().output_is_position_independent() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); @@ -3830,7 +3847,8 @@ Target_tilegx::Scan::global(Symbol_table* symtab, // Make a dynamic relocation if necessary. if (gsym->needs_dynamic_reloc(Scan::get_reference_flags(r_type))) { - if (gsym->may_need_copy_reloc()) + if (parameters->options().output_is_executable() + && gsym->may_need_copy_reloc()) { target->copy_reloc(symtab, layout, object, data_shndx, output_section, gsym, reloc); @@ -4010,7 +4028,7 @@ Target_tilegx::Scan::global(Symbol_table* symtab, symtab->lookup("__tls_get_addr")); } break; - + // only make effect when applying relocation case elfcpp::R_TILEGX_TLS_IE_LOAD: case elfcpp::R_TILEGX_IMM8_X0_TLS_ADD: @@ -4022,9 +4040,9 @@ Target_tilegx::Scan::global(Symbol_table* symtab, case elfcpp::R_TILEGX_IMM8_Y0_TLS_GD_ADD: case elfcpp::R_TILEGX_IMM8_Y1_TLS_GD_ADD: break; - + // GD: requires two GOT entry for module index and offset - // IE: requires one GOT entry for tp-relative offset + // IE: requires one GOT entry for tp-relative offset // LE: shouldn't happen for global symbol case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_GD: case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_GD: @@ -4058,7 +4076,7 @@ Target_tilegx::Scan::global(Symbol_table* symtab, unsupported_reloc_global(object, r_type, gsym); } break; - + // IE case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_IE: case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_IE: @@ -4081,7 +4099,7 @@ Target_tilegx::Scan::global(Symbol_table* symtab, unsupported_reloc_global(object, r_type, gsym); } break; - + // LE case elfcpp::R_TILEGX_IMM16_X0_HW0_TLS_LE: case elfcpp::R_TILEGX_IMM16_X1_HW0_TLS_LE: @@ -4146,26 +4164,26 @@ Target_tilegx::gc_process_relocs(Symbol_table* symtab, { typedef Target_tilegx Tilegx; typedef typename Target_tilegx::Scan Scan; + typedef gold::Default_classify_reloc + Classify_reloc; if (sh_type == elfcpp::SHT_REL) { return; } - gold::gc_process_relocs::Relocatable_size_for_reloc>( - symtab, - layout, - this, - object, - data_shndx, - prelocs, - reloc_count, - output_section, - needs_special_offset_handling, - local_symbol_count, - plocal_symbols); + gold::gc_process_relocs( + symtab, + layout, + this, + object, + data_shndx, + prelocs, + reloc_count, + output_section, + needs_special_offset_handling, + local_symbol_count, + plocal_symbols); } // Scan relocations for a section. @@ -4185,6 +4203,8 @@ Target_tilegx::scan_relocs(Symbol_table* symtab, { typedef Target_tilegx Tilegx; typedef typename Target_tilegx::Scan Scan; + typedef gold::Default_classify_reloc + Classify_reloc; if (sh_type == elfcpp::SHT_REL) { @@ -4193,7 +4213,7 @@ Target_tilegx::scan_relocs(Symbol_table* symtab, return; } - gold::scan_relocs( + gold::scan_relocs( symtab, layout, this, @@ -4316,20 +4336,25 @@ template inline bool Target_tilegx::Relocate::relocate( const Relocate_info* relinfo, + unsigned int, Target_tilegx* target, Output_section*, size_t relnum, - const elfcpp::Rela& rela, - unsigned int r_type, + const unsigned char* preloc, const Sized_symbol* gsym, const Symbol_value* psymval, unsigned char* view, typename elfcpp::Elf_types::Elf_Addr address, section_size_type) { + if (view == NULL) + return true; + typedef Tilegx_relocate_functions TilegxReloc; typename TilegxReloc::Tilegx_howto r_howto; + const elfcpp::Rela rela(preloc); + unsigned int r_type = elfcpp::elf_r_type(rela.get_r_info()); const Sized_relobj_file* object = relinfo->object; // Pick the value to use for symbols defined in the PLT. @@ -4407,6 +4432,7 @@ Target_tilegx::Relocate::relocate( psymval = &symval; always_apply_relocation = true; addend = 0; + // Fall through. // when under PIC mode, these relocations are deferred to rtld case elfcpp::R_TILEGX_IMM16_X0_HW0: @@ -4597,6 +4623,7 @@ Target_tilegx::Relocate::relocate( got_type = GOT_TYPE_TLS_OFFSET; have_got_offset = true; } + // Fall through. do_update_value: if (have_got_offset) { if (gsym != NULL) { @@ -4626,16 +4653,14 @@ Target_tilegx::Relocate::relocate( } // else if (opt_t == tls::TLSOPT_TO_LE) // both GD/IE are turned into LE, which // is absolute relocation. - // - // | go through - // | - // V + // Fall through. + // LE - // + // // tp // | // V - // t_var1 | t_var2 | t_var3 | ... + // t_var1 | t_var2 | t_var3 | ... // -------------------------------------------------- // // so offset to tp should be negative, we get offset @@ -4656,7 +4681,7 @@ Target_tilegx::Relocate::relocate( || issue_undefined_symbol_error(gsym)); return false; } - + typename elfcpp::Elf_types::Elf_Addr value = psymval->value(relinfo->object, 0); symval.set_output_value(value); @@ -4730,11 +4755,13 @@ Target_tilegx::relocate_section( { typedef Target_tilegx Tilegx; typedef typename Target_tilegx::Relocate Tilegx_relocate; + typedef gold::Default_classify_reloc + Classify_reloc; gold_assert(sh_type == elfcpp::SHT_RELA); - gold::relocate_section( + gold::relocate_section( relinfo, this, prelocs, @@ -4775,24 +4802,50 @@ Target_tilegx::apply_relocation( view_size); } -// Return the size of a relocation while scanning during a relocatable -// link. +// Scan the relocs during a relocatable link. template -unsigned int -Target_tilegx::Relocatable_size_for_reloc::get_size_for_reloc( - unsigned int, Relobj*) +void +Target_tilegx::scan_relocatable_relocs( + Symbol_table* symtab, + Layout* layout, + Sized_relobj_file* object, + unsigned int data_shndx, + unsigned int sh_type, + const unsigned char* prelocs, + size_t reloc_count, + Output_section* output_section, + bool needs_special_offset_handling, + size_t local_symbol_count, + const unsigned char* plocal_symbols, + Relocatable_relocs* rr) { - // We are always SHT_RELA, so we should never get here. - gold_unreachable(); - return 0; + typedef gold::Default_classify_reloc + Classify_reloc; + typedef gold::Default_scan_relocatable_relocs + Scan_relocatable_relocs; + + gold_assert(sh_type == elfcpp::SHT_RELA); + + gold::scan_relocatable_relocs( + symtab, + layout, + object, + data_shndx, + prelocs, + reloc_count, + output_section, + needs_special_offset_handling, + local_symbol_count, + plocal_symbols, + rr); } -// Scan the relocs during a relocatable link. +// Scan the relocs for --emit-relocs. template void -Target_tilegx::scan_relocatable_relocs( +Target_tilegx::emit_relocs_scan( Symbol_table* symtab, Layout* layout, Sized_relobj_file* object, @@ -4803,16 +4856,17 @@ Target_tilegx::scan_relocatable_relocs( Output_section* output_section, bool needs_special_offset_handling, size_t local_symbol_count, - const unsigned char* plocal_symbols, + const unsigned char* plocal_syms, Relocatable_relocs* rr) { - gold_assert(sh_type == elfcpp::SHT_RELA); + typedef gold::Default_classify_reloc + Classify_reloc; + typedef gold::Default_emit_relocs_strategy + Emit_relocs_strategy; - typedef gold::Default_scan_relocatable_relocs Scan_relocatable_relocs; + gold_assert(sh_type == elfcpp::SHT_RELA); - gold::scan_relocatable_relocs( + gold::scan_relocatable_relocs( symtab, layout, object, @@ -4822,7 +4876,7 @@ Target_tilegx::scan_relocatable_relocs( output_section, needs_special_offset_handling, local_symbol_count, - plocal_symbols, + plocal_syms, rr); } @@ -4836,23 +4890,24 @@ Target_tilegx::relocate_relocs( const unsigned char* prelocs, size_t reloc_count, Output_section* output_section, - off_t offset_in_output_section, - const Relocatable_relocs* rr, + typename elfcpp::Elf_types::Elf_Off offset_in_output_section, unsigned char* view, typename elfcpp::Elf_types::Elf_Addr view_address, section_size_type view_size, unsigned char* reloc_view, section_size_type reloc_view_size) { + typedef gold::Default_classify_reloc + Classify_reloc; + gold_assert(sh_type == elfcpp::SHT_RELA); - gold::relocate_relocs( + gold::relocate_relocs( relinfo, prelocs, reloc_count, output_section, offset_in_output_section, - rr, view, view_address, view_size, @@ -4889,7 +4944,7 @@ Target_tilegx::do_ehframe_datarel_base() const return ssym->value(); } -// The selector for tilegx object files. +// The selector for tilegx object files. template class Target_selector_tilegx : public Target_selector