X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Fsparc.cc;h=c97c32ceb70dae85f640e84295297cf0d8ba2d6d;hb=4d625b70fc3fb7facc7159feb8d49b78ac6641f9;hp=57659cc8ae48bd98ab38ce940a4a154337f551ee;hpb=43819297ce3e76908a840fa66159ca83c1560fe5;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/sparc.cc b/gold/sparc.cc index 57659cc8ae..c97c32ceb7 100644 --- a/gold/sparc.cc +++ b/gold/sparc.cc @@ -1,6 +1,6 @@ // sparc.cc -- sparc target support for gold. -// Copyright 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. +// Copyright (C) 2008-2016 Free Software Foundation, Inc. // Written by David S. Miller . // This file is part of gold. @@ -131,6 +131,21 @@ class Target_sparc : 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); + // Emit relocations for a section. void relocate_relocs(const Relocate_info*, @@ -140,7 +155,6 @@ class Target_sparc : public Sized_target Output_section* output_section, typename elfcpp::Elf_types::Elf_Off offset_in_output_section, - const Relocatable_relocs*, unsigned char* view, typename elfcpp::Elf_types::Elf_Addr view_address, section_size_type view_size, @@ -217,7 +231,7 @@ class Target_sparc : public Sized_target const elfcpp::Ehdr& ehdr); void - do_adjust_elf_header(unsigned char* view, int len) const; + do_adjust_elf_header(unsigned char* view, int len); private: @@ -316,13 +330,10 @@ class Target_sparc : 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_sparc*, - 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, + relocate(const Relocate_info*, unsigned int, + Target_sparc*, Output_section*, size_t, const unsigned char*, + const Sized_symbol*, const Symbol_value*, + unsigned char*, typename elfcpp::Elf_types::Elf_Addr, section_size_type); private: @@ -349,15 +360,6 @@ class Target_sparc : public Sized_target unsigned char *reloc_adjust_addr_; }; - // 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*); - }; - // Get the GOT section, creating it if necessary. Output_data_got* got_section(Symbol_table*, Layout*); @@ -415,10 +417,13 @@ class Target_sparc : 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 @@ -482,7 +487,8 @@ Target::Target_info Target_sparc<32, true>::sparc_info = 0, // large_common_section_flags NULL, // attributes_section NULL, // attributes_vendor - "_start" // entry_symbol_name + "_start", // entry_symbol_name + 32, // hash_entry_size }; template<> @@ -509,7 +515,8 @@ Target::Target_info Target_sparc<64, true>::sparc_info = 0, // large_common_section_flags NULL, // attributes_section NULL, // attributes_vendor - "_start" // entry_symbol_name + "_start", // entry_symbol_name + 32, // hash_entry_size }; // We have to take care here, even when operating in little-endian @@ -1107,13 +1114,12 @@ public: // R_SPARC_GOTDATA_OP_HIX22: @gdopoff(Symbol + Addend) >> 10 static inline void gdop_hix22(unsigned char* view, - typename elfcpp::Elf_types::Elf_Addr value, - typename elfcpp::Elf_types::Elf_Addr addend) + typename elfcpp::Elf_types::Elf_Addr value) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); - int32_t reloc = static_cast(value + addend); + int32_t reloc = static_cast(value); val &= ~0x3fffff; @@ -1170,13 +1176,12 @@ public: // R_SPARC_GOTDATA_OP_LOX10: (@gdopoff(Symbol + Addend) & 0x3ff) | 0x1c00 static inline void gdop_lox10(unsigned char* view, - typename elfcpp::Elf_types::Elf_Addr value, - typename elfcpp::Elf_types::Elf_Addr addend) + typename elfcpp::Elf_types::Elf_Addr value) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); - int32_t reloc = static_cast(value + addend); + int32_t reloc = static_cast(value); if (reloc < 0) reloc = (reloc & 0x3ff) | 0x1c00; @@ -2634,7 +2639,8 @@ Target_sparc::Scan::global( // 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, @@ -2723,7 +2729,8 @@ Target_sparc::Scan::global( break; } - 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); @@ -3035,9 +3042,10 @@ Target_sparc::gc_process_relocs( { typedef Target_sparc Sparc; typedef typename Target_sparc::Scan Scan; + typedef gold::Default_classify_reloc + Classify_reloc; - gold::gc_process_relocs( + gold::gc_process_relocs( symtab, layout, this, @@ -3069,7 +3077,8 @@ Target_sparc::scan_relocs( const unsigned char* plocal_symbols) { typedef Target_sparc Sparc; - typedef typename Target_sparc::Scan Scan; + typedef gold::Default_classify_reloc + Classify_reloc; if (sh_type == elfcpp::SHT_REL) { @@ -3078,7 +3087,7 @@ Target_sparc::scan_relocs( return; } - gold::scan_relocs( + gold::scan_relocs( symtab, layout, this, @@ -3164,17 +3173,19 @@ template inline bool Target_sparc::Relocate::relocate( const Relocate_info* relinfo, + unsigned int, Target_sparc* 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 view_size) { + const elfcpp::Rela rela(preloc); + unsigned int r_type = elfcpp::elf_r_type(rela.get_r_info()); bool orig_is_ifunc = psymval->is_ifunc_symbol(); r_type &= 0xff; @@ -3242,7 +3253,7 @@ Target_sparc::Relocate::relocate( && !gsym->is_preemptible() && !orig_is_ifunc)) { - got_offset = psymval->value(object, 0) - target->got_address(); + got_offset = psymval->value(object, addend) - target->got_address(); gdop_valid = true; break; } @@ -3382,7 +3393,7 @@ Target_sparc::Relocate::relocate( case elfcpp::R_SPARC_GOTDATA_OP_LOX10: if (gdop_valid) { - Reloc::gdop_lox10(view, got_offset, addend); + Reloc::gdop_lox10(view, got_offset); break; } /* Fall through. */ @@ -3393,7 +3404,7 @@ Target_sparc::Relocate::relocate( case elfcpp::R_SPARC_GOTDATA_OP_HIX22: if (gdop_valid) { - Reloc::gdop_hix22(view, got_offset, addend); + Reloc::gdop_hix22(view, got_offset); break; } /* Fall through. */ @@ -4139,11 +4150,13 @@ Target_sparc::relocate_section( { typedef Target_sparc Sparc; typedef typename Target_sparc::Relocate Sparc_relocate; + typedef gold::Default_classify_reloc + Classify_reloc; gold_assert(sh_type == elfcpp::SHT_RELA); - gold::relocate_section( + gold::relocate_section( relinfo, this, prelocs, @@ -4156,20 +4169,6 @@ Target_sparc::relocate_section( reloc_symbol_changes); } -// Return the size of a relocation while scanning during a relocatable -// link. - -template -unsigned int -Target_sparc::Relocatable_size_for_reloc::get_size_for_reloc( - unsigned int, - Relobj*) -{ - // We are always SHT_RELA, so we should never get here. - gold_unreachable(); - return 0; -} - // Scan the relocs during a relocatable link. template @@ -4188,13 +4187,14 @@ Target_sparc::scan_relocatable_relocs( const unsigned char* plocal_symbols, Relocatable_relocs* rr) { - gold_assert(sh_type == elfcpp::SHT_RELA); + typedef gold::Default_classify_reloc + Classify_reloc; + typedef gold::Default_scan_relocatable_relocs + Scan_relocatable_relocs; - 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, @@ -4208,6 +4208,45 @@ Target_sparc::scan_relocatable_relocs( rr); } +// Scan the relocs for --emit-relocs. + +template +void +Target_sparc::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) +{ + typedef gold::Default_classify_reloc + Classify_reloc; + typedef gold::Default_emit_relocs_strategy + Emit_relocs_strategy; + + 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_syms, + rr); +} + // Emit relocations for a section. template @@ -4219,22 +4258,23 @@ Target_sparc::relocate_relocs( size_t reloc_count, Output_section* output_section, typename elfcpp::Elf_types::Elf_Off offset_in_output_section, - const Relocatable_relocs* rr, 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, @@ -4339,7 +4379,7 @@ template void Target_sparc::do_adjust_elf_header( unsigned char* view, - int len) const + int len) { elfcpp::Ehdr_write oehdr(view);