HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Nougat 7.0
|
7.0.0_r31
下载
查看原文件
收藏
根目录
toolchain
binutils
binutils-2.25
gold
sparc.cc
// sparc.cc -- sparc target support for gold. // Copyright (C) 2008-2014 Free Software Foundation, Inc. // Written by David S. Miller
. // This file is part of gold. // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, // MA 02110-1301, USA. #include "gold.h" #include
#include
#include
#include "elfcpp.h" #include "parameters.h" #include "reloc.h" #include "sparc.h" #include "object.h" #include "symtab.h" #include "layout.h" #include "output.h" #include "copy-relocs.h" #include "target.h" #include "target-reloc.h" #include "target-select.h" #include "tls.h" #include "errors.h" #include "gc.h" namespace { using namespace gold; template
class Output_data_plt_sparc; template
class Target_sparc : public Sized_target
{ public: typedef Output_data_reloc
Reloc_section; Target_sparc() : Sized_target
(&sparc_info), got_(NULL), plt_(NULL), rela_dyn_(NULL), rela_ifunc_(NULL), copy_relocs_(elfcpp::R_SPARC_COPY), got_mod_index_offset_(-1U), tls_get_addr_sym_(NULL), elf_machine_(sparc_info.machine_code), elf_flags_(0), elf_flags_set_(false) { } // Process the relocations to determine unreferenced sections for // garbage collection. void gc_process_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); // Scan the relocations to look for symbol adjustments. void scan_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); // Finalize the sections. void do_finalize_sections(Layout*, const Input_objects*, Symbol_table*); // Return the value to use for a dynamic which requires special // treatment. uint64_t do_dynsym_value(const Symbol*) const; // Relocate a section. void relocate_section(const Relocate_info
*, unsigned int sh_type, const unsigned char* prelocs, size_t reloc_count, Output_section* output_section, bool needs_special_offset_handling, unsigned char* view, typename elfcpp::Elf_types
::Elf_Addr view_address, section_size_type view_size, const Reloc_symbol_changes*); // Scan the relocs during a relocatable link. void 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*); // Emit relocations for a section. void relocate_relocs(const Relocate_info
*, unsigned int sh_type, const unsigned char* prelocs, size_t reloc_count, 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, unsigned char* reloc_view, section_size_type reloc_view_size); // Return whether SYM is defined by the ABI. bool do_is_defined_by_abi(const Symbol* sym) const { // XXX Really need to support this better... if (sym->type() == elfcpp::STT_SPARC_REGISTER) return 1; return strcmp(sym->name(), "___tls_get_addr") == 0; } // Return the PLT address to use for a global symbol. uint64_t do_plt_address_for_global(const Symbol* gsym) const { return this->plt_section()->address_for_global(gsym); } uint64_t do_plt_address_for_local(const Relobj* relobj, unsigned int symndx) const { return this->plt_section()->address_for_local(relobj, symndx); } // Return whether there is a GOT section. bool has_got_section() const { return this->got_ != NULL; } // Return the size of the GOT section. section_size_type got_size() const { gold_assert(this->got_ != NULL); return this->got_->data_size(); } // Return the number of entries in the GOT. unsigned int got_entry_count() const { if (this->got_ == NULL) return 0; return this->got_size() / (size / 8); } // Return the address of the GOT. uint64_t got_address() const { if (this->got_ == NULL) return 0; return this->got_->address(); } // Return the number of entries in the PLT. unsigned int plt_entry_count() const; // Return the offset of the first non-reserved PLT entry. unsigned int first_plt_entry_offset() const; // Return the size of each PLT entry. unsigned int plt_entry_size() const; protected: // Make an ELF object. Object* do_make_elf_object(const std::string&, Input_file*, off_t, const elfcpp::Ehdr
& ehdr); void do_adjust_elf_header(unsigned char* view, int len); private: // The class which scans relocations. class Scan { public: Scan() : issued_non_pic_error_(false) { } static inline int get_reference_flags(unsigned int r_type); inline void local(Symbol_table* symtab, Layout* layout, Target_sparc* target, Sized_relobj_file
* object, unsigned int data_shndx, Output_section* output_section, const elfcpp::Rela
& reloc, unsigned int r_type, const elfcpp::Sym
& lsym, bool is_discarded); inline void global(Symbol_table* symtab, Layout* layout, Target_sparc* target, Sized_relobj_file
* object, unsigned int data_shndx, Output_section* output_section, const elfcpp::Rela
& reloc, unsigned int r_type, Symbol* gsym); inline bool local_reloc_may_be_function_pointer(Symbol_table* , Layout* , Target_sparc* , Sized_relobj_file
* , unsigned int , Output_section* , const elfcpp::Rela
& , unsigned int , const elfcpp::Sym
&) { return false; } inline bool global_reloc_may_be_function_pointer(Symbol_table* , Layout* , Target_sparc* , Sized_relobj_file
* , unsigned int , Output_section* , const elfcpp::Rela
& , unsigned int , Symbol*) { return false; } private: static void unsupported_reloc_local(Sized_relobj_file
*, unsigned int r_type); static void unsupported_reloc_global(Sized_relobj_file
*, unsigned int r_type, Symbol*); static void generate_tls_call(Symbol_table* symtab, Layout* layout, Target_sparc* target); void check_non_pic(Relobj*, unsigned int r_type); bool reloc_needs_plt_for_ifunc(Sized_relobj_file
*, unsigned int r_type); // Whether we have issued an error about a non-PIC compilation. bool issued_non_pic_error_; }; // The class which implements relocation. class Relocate { public: Relocate() : ignore_gd_add_(false), reloc_adjust_addr_(NULL) { } ~Relocate() { if (this->ignore_gd_add_) { // FIXME: This needs to specify the location somehow. gold_error(_("missing expected TLS relocation")); } } // 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, section_size_type); private: // Do a TLS relocation. inline void relocate_tls(const Relocate_info
*, Target_sparc* target, 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); inline void relax_call(Target_sparc
* target, unsigned char* view, const elfcpp::Rela
& rela, section_size_type view_size); // Ignore the next relocation which should be R_SPARC_TLS_GD_ADD bool ignore_gd_add_; // If we hit a reloc at this view address, adjust it back by 4 bytes. 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*); // Create the PLT section. void make_plt_section(Symbol_table* symtab, Layout* layout); // Create a PLT entry for a global symbol. void make_plt_entry(Symbol_table*, Layout*, Symbol*); // Create a PLT entry for a local STT_GNU_IFUNC symbol. void make_local_ifunc_plt_entry(Symbol_table*, Layout*, Sized_relobj_file
* relobj, unsigned int local_sym_index); // Create a GOT entry for the TLS module index. unsigned int got_mod_index_entry(Symbol_table* symtab, Layout* layout, Sized_relobj_file
* object); // Return the gsym for "__tls_get_addr". Cache if not already // cached. Symbol* tls_get_addr_sym(Symbol_table* symtab) { if (!this->tls_get_addr_sym_) this->tls_get_addr_sym_ = symtab->lookup("__tls_get_addr", NULL); gold_assert(this->tls_get_addr_sym_); return this->tls_get_addr_sym_; } // Get the PLT section. Output_data_plt_sparc
* plt_section() const { gold_assert(this->plt_ != NULL); return this->plt_; } // Get the dynamic reloc section, creating it if necessary. Reloc_section* rela_dyn_section(Layout*); // Get the section to use for IFUNC relocations. Reloc_section* rela_ifunc_section(Layout*); // Copy a relocation against a global symbol. void copy_reloc(Symbol_table* symtab, Layout* layout, Sized_relobj_file
* object, unsigned int shndx, Output_section* output_section, Symbol* sym, const elfcpp::Rela
& reloc) { this->copy_relocs_.copy_reloc(symtab, layout, symtab->get_sized_symbol
(sym), object, shndx, output_section, reloc, this->rela_dyn_section(layout)); } // Information about this specific target which we pass to the // general Target structure. static Target::Target_info sparc_info; // The types of GOT entries needed for this platform. // These values are exposed to the ABI in an incremental link. // Do not renumber existing values without changing the version // number of the .gnu_incremental_inputs section. enum Got_type { GOT_TYPE_STANDARD = 0, // GOT entry for a regular symbol GOT_TYPE_TLS_OFFSET = 1, // GOT entry for TLS offset GOT_TYPE_TLS_PAIR = 2, // GOT entry for TLS module/offset pair }; // The GOT section. Output_data_got
* got_; // The PLT section. Output_data_plt_sparc
* plt_; // The dynamic reloc section. Reloc_section* rela_dyn_; // The section to use for IFUNC relocs. Reloc_section* rela_ifunc_; // Relocs saved to avoid a COPY reloc. Copy_relocs
copy_relocs_; // Offset of the GOT entry for the TLS module index; unsigned int got_mod_index_offset_; // Cached pointer to __tls_get_addr symbol Symbol* tls_get_addr_sym_; // Accumulated elf machine type elfcpp::Elf_Half elf_machine_; // Accumulated elf header flags elfcpp::Elf_Word elf_flags_; // Whether elf_flags_ has been set for the first time yet bool elf_flags_set_; }; template<> Target::Target_info Target_sparc<32, true>::sparc_info = { 32, // size true, // is_big_endian elfcpp::EM_SPARC, // machine_code false, // has_make_symbol false, // has_resolve false, // has_code_fill true, // is_default_stack_executable false, // can_icf_inline_merge_sections '\0', // wrap_char "/usr/lib/ld.so.1", // dynamic_linker 0x00010000, // default_text_segment_address 64 * 1024, // abi_pagesize (overridable by -z max-page-size) 8 * 1024, // common_pagesize (overridable by -z common-page-size) false, // isolate_execinstr 0, // rosegment_gap elfcpp::SHN_UNDEF, // small_common_shndx elfcpp::SHN_UNDEF, // large_common_shndx 0, // small_common_section_flags 0, // large_common_section_flags NULL, // attributes_section NULL, // attributes_vendor "_start" // entry_symbol_name }; template<> Target::Target_info Target_sparc<64, true>::sparc_info = { 64, // size true, // is_big_endian elfcpp::EM_SPARCV9, // machine_code false, // has_make_symbol false, // has_resolve false, // has_code_fill true, // is_default_stack_executable false, // can_icf_inline_merge_sections '\0', // wrap_char "/usr/lib/sparcv9/ld.so.1", // dynamic_linker 0x100000, // default_text_segment_address 64 * 1024, // abi_pagesize (overridable by -z max-page-size) 8 * 1024, // common_pagesize (overridable by -z common-page-size) false, // isolate_execinstr 0, // rosegment_gap elfcpp::SHN_UNDEF, // small_common_shndx elfcpp::SHN_UNDEF, // large_common_shndx 0, // small_common_section_flags 0, // large_common_section_flags NULL, // attributes_section NULL, // attributes_vendor "_start" // entry_symbol_name }; // We have to take care here, even when operating in little-endian // mode, sparc instructions are still big endian. template
class Sparc_relocate_functions { private: // Do a simple relocation with the addend in the relocation. template
static inline void rela(unsigned char* view, unsigned int right_shift, typename elfcpp::Elf_types
::Elf_Addr dst_mask, typename elfcpp::Swap
::Valtype value, typename elfcpp::Swap
::Valtype addend) { typedef typename elfcpp::Swap
::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap
::readval(wv); Valtype reloc = ((value + addend) >> right_shift); val &= ~dst_mask; reloc &= dst_mask; elfcpp::Swap
::writeval(wv, val | reloc); } // Do a simple relocation using a symbol value with the addend in // the relocation. template
static inline void rela(unsigned char* view, unsigned int right_shift, typename elfcpp::Elf_types
::Elf_Addr dst_mask, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Swap
::Valtype addend) { typedef typename elfcpp::Swap
::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap
::readval(wv); Valtype reloc = (psymval->value(object, addend) >> right_shift); val &= ~dst_mask; reloc &= dst_mask; elfcpp::Swap
::writeval(wv, val | reloc); } // Do a simple relocation using a symbol value with the addend in // the relocation, unaligned. template
static inline void rela_ua(unsigned char* view, unsigned int right_shift, elfcpp::Elf_Xword dst_mask, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Swap
::Valtype addend) { typedef typename elfcpp::Swap_unaligned
::Valtype Valtype; unsigned char* wv = view; Valtype val = elfcpp::Swap_unaligned
::readval(wv); Valtype reloc = (psymval->value(object, addend) >> right_shift); val &= ~dst_mask; reloc &= dst_mask; elfcpp::Swap_unaligned
::writeval(wv, val | reloc); } // Do a simple PC relative relocation with a Symbol_value with the // addend in the relocation. template
static inline void pcrela(unsigned char* view, unsigned int right_shift, typename elfcpp::Elf_types
::Elf_Addr dst_mask, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Swap
::Valtype addend, typename elfcpp::Elf_types
::Elf_Addr address) { typedef typename elfcpp::Swap
::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap
::readval(wv); Valtype reloc = ((psymval->value(object, addend) - address) >> right_shift); val &= ~dst_mask; reloc &= dst_mask; elfcpp::Swap
::writeval(wv, val | reloc); } template
static inline void pcrela_unaligned(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Swap
::Valtype addend, typename elfcpp::Elf_types
::Elf_Addr address) { typedef typename elfcpp::Swap_unaligned
::Valtype Valtype; unsigned char* wv = view; Valtype reloc = (psymval->value(object, addend) - address); elfcpp::Swap_unaligned
::writeval(wv, reloc); } typedef Sparc_relocate_functions
This; typedef Sparc_relocate_functions
This_insn; public: // R_SPARC_WDISP30: (Symbol + Addend - Address) >> 2 static inline void wdisp30(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This_insn::template pcrela<32>(view, 2, 0x3fffffff, object, psymval, addend, address); } // R_SPARC_WDISP22: (Symbol + Addend - Address) >> 2 static inline void wdisp22(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This_insn::template pcrela<32>(view, 2, 0x003fffff, object, psymval, addend, address); } // R_SPARC_WDISP19: (Symbol + Addend - Address) >> 2 static inline void wdisp19(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This_insn::template pcrela<32>(view, 2, 0x0007ffff, object, psymval, addend, address); } // R_SPARC_WDISP16: (Symbol + Addend - Address) >> 2 static inline void wdisp16(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); Valtype reloc = ((psymval->value(object, addend) - address) >> 2); // The relocation value is split between the low 14 bits, // and bits 20-21. val &= ~((0x3 << 20) | 0x3fff); reloc = (((reloc & 0xc000) << (20 - 14)) | (reloc & 0x3ffff)); elfcpp::Swap<32, true>::writeval(wv, val | reloc); } // R_SPARC_WDISP10: (Symbol + Addend - Address) >> 2 static inline void wdisp10(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); Valtype reloc = ((psymval->value(object, addend) - address) >> 2); // The relocation value is split between the low bits 5-12, // and high bits 19-20. val &= ~((0x3 << 19) | (0xff << 5)); reloc = (((reloc & 0x300) << (19 - 8)) | ((reloc & 0xff) << (5 - 0))); elfcpp::Swap<32, true>::writeval(wv, val | reloc); } // R_SPARC_PC22: (Symbol + Addend - Address) >> 10 static inline void pc22(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This_insn::template pcrela<32>(view, 10, 0x003fffff, object, psymval, addend, address); } // R_SPARC_PC10: (Symbol + Addend - Address) & 0x3ff static inline void pc10(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This_insn::template pcrela<32>(view, 0, 0x000003ff, object, psymval, addend, address); } // R_SPARC_HI22: (Symbol + Addend) >> 10 static inline void hi22(unsigned char* view, typename elfcpp::Elf_types
::Elf_Addr value, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 10, 0x003fffff, value, addend); } // R_SPARC_HI22: (Symbol + Addend) >> 10 static inline void hi22(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 10, 0x003fffff, object, psymval, addend); } // R_SPARC_PCPLT22: (Symbol + Addend - Address) >> 10 static inline void pcplt22(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This_insn::template pcrela<32>(view, 10, 0x003fffff, object, psymval, addend, address); } // R_SPARC_LO10: (Symbol + Addend) & 0x3ff static inline void lo10(unsigned char* view, typename elfcpp::Elf_types
::Elf_Addr value, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x000003ff, value, addend); } // R_SPARC_LO10: (Symbol + Addend) & 0x3ff static inline void lo10(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x000003ff, object, psymval, addend); } // R_SPARC_LO10: (Symbol + Addend) & 0x3ff static inline void lo10(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This_insn::template pcrela<32>(view, 0, 0x000003ff, object, psymval, addend, address); } // R_SPARC_OLO10: ((Symbol + Addend) & 0x3ff) + Addend2 static inline void olo10(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr addend2) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); Valtype reloc = psymval->value(object, addend); val &= ~0x1fff; reloc &= 0x3ff; reloc += addend2; reloc &= 0x1fff; elfcpp::Swap<32, true>::writeval(wv, val | reloc); } // R_SPARC_22: (Symbol + Addend) static inline void rela32_22(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x003fffff, object, psymval, addend); } // R_SPARC_13: (Symbol + Addend) static inline void rela32_13(unsigned char* view, typename elfcpp::Elf_types
::Elf_Addr value, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x00001fff, value, addend); } // R_SPARC_13: (Symbol + Addend) static inline void rela32_13(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x00001fff, object, psymval, addend); } // R_SPARC_UA16: (Symbol + Addend) static inline void ua16(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This::template rela_ua<16>(view, 0, 0xffff, object, psymval, addend); } // R_SPARC_UA32: (Symbol + Addend) static inline void ua32(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This::template rela_ua<32>(view, 0, 0xffffffff, object, psymval, addend); } // R_SPARC_UA64: (Symbol + Addend) static inline void ua64(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This::template rela_ua<64>(view, 0, ~(elfcpp::Elf_Xword) 0, object, psymval, addend); } // R_SPARC_DISP8: (Symbol + Addend - Address) static inline void disp8(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This::template pcrela_unaligned<8>(view, object, psymval, addend, address); } // R_SPARC_DISP16: (Symbol + Addend - Address) static inline void disp16(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This::template pcrela_unaligned<16>(view, object, psymval, addend, address); } // R_SPARC_DISP32: (Symbol + Addend - Address) static inline void disp32(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This::template pcrela_unaligned<32>(view, object, psymval, addend, address); } // R_SPARC_DISP64: (Symbol + Addend - Address) static inline void disp64(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, elfcpp::Elf_Xword addend, typename elfcpp::Elf_types
::Elf_Addr address) { This::template pcrela_unaligned<64>(view, object, psymval, addend, address); } // R_SPARC_H34: (Symbol + Addend) >> 12 static inline void h34(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 12, 0x003fffff, object, psymval, addend); } // R_SPARC_H44: (Symbol + Addend) >> 22 static inline void h44(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 22, 0x003fffff, object, psymval, addend); } // R_SPARC_M44: ((Symbol + Addend) >> 12) & 0x3ff static inline void m44(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 12, 0x000003ff, object, psymval, addend); } // R_SPARC_L44: (Symbol + Addend) & 0xfff static inline void l44(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x00000fff, object, psymval, addend); } // R_SPARC_HH22: (Symbol + Addend) >> 42 static inline void hh22(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 42, 0x003fffff, object, psymval, addend); } // R_SPARC_PC_HH22: (Symbol + Addend - Address) >> 42 static inline void pc_hh22(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This_insn::template pcrela<32>(view, 42, 0x003fffff, object, psymval, addend, address); } // R_SPARC_HM10: ((Symbol + Addend) >> 32) & 0x3ff static inline void hm10(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 32, 0x000003ff, object, psymval, addend); } // R_SPARC_PC_HM10: ((Symbol + Addend - Address) >> 32) & 0x3ff static inline void pc_hm10(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend, typename elfcpp::Elf_types
::Elf_Addr address) { This_insn::template pcrela<32>(view, 32, 0x000003ff, object, psymval, addend, address); } // R_SPARC_11: (Symbol + Addend) static inline void rela32_11(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x000007ff, object, psymval, addend); } // R_SPARC_10: (Symbol + Addend) static inline void rela32_10(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x000003ff, object, psymval, addend); } // R_SPARC_7: (Symbol + Addend) static inline void rela32_7(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x0000007f, object, psymval, addend); } // R_SPARC_6: (Symbol + Addend) static inline void rela32_6(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x0000003f, object, psymval, addend); } // R_SPARC_5: (Symbol + Addend) static inline void rela32_5(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::template rela<32>(view, 0, 0x0000001f, object, psymval, addend); } // R_SPARC_TLS_LDO_HIX22: @dtpoff(Symbol + Addend) >> 10 static inline void ldo_hix22(unsigned char* view, typename elfcpp::Elf_types
::Elf_Addr value, typename elfcpp::Elf_types
::Elf_Addr addend) { This_insn::hi22(view, value, addend); } // R_SPARC_TLS_LDO_LOX10: @dtpoff(Symbol + Addend) & 0x3ff static inline void ldo_lox10(unsigned char* view, typename elfcpp::Elf_types
::Elf_Addr value, typename elfcpp::Elf_types
::Elf_Addr addend) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); Valtype reloc = (value + addend); val &= ~0x1fff; reloc &= 0x3ff; elfcpp::Swap<32, true>::writeval(wv, val | reloc); } // R_SPARC_TLS_LE_HIX22: (@tpoff(Symbol + Addend) ^ 0xffffffffffffffff) >> 10 static inline void hix22(unsigned char* view, typename elfcpp::Elf_types
::Elf_Addr value, typename elfcpp::Elf_types
::Elf_Addr addend) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); Valtype reloc = (value + addend); val &= ~0x3fffff; reloc ^= ~(Valtype)0; reloc >>= 10; reloc &= 0x3fffff; elfcpp::Swap<32, true>::writeval(wv, val | reloc); } // 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) { 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); val &= ~0x3fffff; if (reloc < 0) reloc ^= ~static_cast
(0); reloc >>= 10; reloc &= 0x3fffff; elfcpp::Swap<32, true>::writeval(wv, val | reloc); } // R_SPARC_HIX22: ((Symbol + Addend) ^ 0xffffffffffffffff) >> 10 static inline void hix22(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); Valtype reloc = psymval->value(object, addend); val &= ~0x3fffff; reloc ^= ~(Valtype)0; reloc >>= 10; reloc &= 0x3fffff; elfcpp::Swap<32, true>::writeval(wv, val | reloc); } // R_SPARC_TLS_LE_LOX10: (@tpoff(Symbol + Addend) & 0x3ff) | 0x1c00 static inline void lox10(unsigned char* view, typename elfcpp::Elf_types
::Elf_Addr value, typename elfcpp::Elf_types
::Elf_Addr addend) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); Valtype reloc = (value + addend); val &= ~0x1fff; reloc &= 0x3ff; reloc |= 0x1c00; elfcpp::Swap<32, true>::writeval(wv, val | reloc); } // 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) { 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); if (reloc < 0) reloc = (reloc & 0x3ff) | 0x1c00; else reloc = (reloc & 0x3ff); val &= ~0x1fff; elfcpp::Swap<32, true>::writeval(wv, val | reloc); } // R_SPARC_LOX10: ((Symbol + Addend) & 0x3ff) | 0x1c00 static inline void lox10(unsigned char* view, const Sized_relobj_file
* object, const Symbol_value
* psymval, typename elfcpp::Elf_types
::Elf_Addr addend) { typedef typename elfcpp::Swap<32, true>::Valtype Valtype; Valtype* wv = reinterpret_cast
(view); Valtype val = elfcpp::Swap<32, true>::readval(wv); Valtype reloc = psymval->value(object, addend); val &= ~0x1fff; reloc &= 0x3ff; reloc |= 0x1c00; elfcpp::Swap<32, true>::writeval(wv, val | reloc); } }; // Get the GOT section, creating it if necessary. template
Output_data_got
* Target_sparc