diff options
author | Ian Lance Taylor <ian@airs.com> | 2011-12-19 21:07:16 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2011-12-19 21:07:16 +0000 |
commit | 83896202bf93a490c4b8e6a222903d5797e16b32 (patch) | |
tree | af1d1b5cc6a8a05f394c57bd27fbb5a69f912fde /gold/output.h | |
parent | 984ac464433aa838ae9e305e216f0d084a8b550f (diff) | |
download | gdb-83896202bf93a490c4b8e6a222903d5797e16b32.zip gdb-83896202bf93a490c4b8e6a222903d5797e16b32.tar.gz gdb-83896202bf93a490c4b8e6a222903d5797e16b32.tar.bz2 |
* object.h (Relobj::local_symbol_value): New function.
(Relobj::local_plt_offset): New function.
(Relobj::local_has_got_offset): New function.
(Relobj::local_got_offset): New function.
(Relobj::set_local_got_offset): New function.
(Relobj::do_local_symbol_value): New pure virtual function.
(Relobj::do_local_plt_offset): Likewise.
(Relobj::do_local_has_got_offset): Likewise.
(Relobj::do_local_got_offset): Likewise.
(Relobj::do_set_local_got_offset): Likewise.
(Sized_relobj::do_local_has_got_offset): Rename from
local_has_got_offset.
(Sized_relobj::do_local_got_offset): Rename from local_got_offset.
(Sized_relobj::do_set_local_got_offset): Rename from
set_local_got_offset.
(Sized_relobj_file::do_local_plt_offset): Rename from
local_plt_offset.
(Sized_relobj_file::do_local_symbol_value): New function.
* object.cc (Sized_relobj_file::do_local_plt_offset): Rename from
local_plt_offset.
* output.cc (Output_data_got::Got_entry::write): Change object to
Relobj. Use local_symbol_value.
(Output_data_got::add_global_with_rel): Change rel_dyn to
Output_data_reloc_generic*. Use add_global_generic.
(Output_data_got::add_global_with_rela): Remove. Change all
callers to use add_global_with_rel.
(Output_data_got::add_global_pair_with_rel): Change rel_dyn to
Output_data_reloc_generic*. Use add_global_generic.
(Output_data_got::add_global_pair_with_rela): Remove. Change all
callers to use add_global_pair_with_rel.
(Output_data_got::add_local): Change object to Relobj*.
(Output_data_got::add_local_plt): Likewise.
(Output_data_got::add_local_with_rel): Change object to Relobj*,
change rel_dyn to Output_data_reloc_generic*. Use
add_local_generic.
(Output_data_got::add_local_with_rela): Remove. Change all
callers to use all_local_with_rel.
(Output_data_got::add_local_pair_with_rel): Change object to
Relobj*, change rel_dyn to Output_data_reloc_generic*. Use
add_output_section_generic.
(Output_data_got::add_local_pair_with_rela): Remove. Change all
callers to use add_local_pair_with_rel.
(Output_data_got::reserve_local): Change object to Relobj*.
* output.h: (class Output_data_reloc_generic): Add pure virtual
declarations for add_global_generic, add_local_generic,
add_output_section_generic.
(class Output_data_reloc) [SHT_REL, SHT_RELA]: Implement new
functions for Output_data_reloc_generic. Update declarations for
changes listed in output.cc.
(class Output_data_got): Change template parameter to got_size.
Don't define Rel_dyn or Rela_dyn. Update declarations per above.
* incremental.h (Sized_relobj_incr::do_local_symbol_value): New
function.
(Sized_relobj_incr::do_local_plt_offset): New function.
* copy-relocs.cc (Copy_relocs::Copy_reloc_entry::emit): Call
add_global_generic.
Diffstat (limited to 'gold/output.h')
-rw-r--r-- | gold/output.h | 266 |
1 files changed, 208 insertions, 58 deletions
diff --git a/gold/output.h b/gold/output.h index ef6fea1..db38236 100644 --- a/gold/output.h +++ b/gold/output.h @@ -1397,6 +1397,55 @@ class Output_data_reloc_generic : public Output_section_data_build sort_relocs() const { return this->sort_relocs_; } + // Add a reloc of type TYPE against the global symbol GSYM. The + // relocation applies to the data at offset ADDRESS within OD. + virtual void + add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, + uint64_t address, uint64_t addend) = 0; + + // Add a reloc of type TYPE against the global symbol GSYM. The + // relocation applies to data at offset ADDRESS within section SHNDX + // of object file RELOBJ. OD is the associated output section. + virtual void + add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, + Relobj* relobj, unsigned int shndx, uint64_t address, + uint64_t addend) = 0; + + // Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX + // in RELOBJ. The relocation applies to the data at offset ADDRESS + // within OD. + virtual void + add_local_generic(Relobj* relobj, unsigned int local_sym_index, + unsigned int type, Output_data* od, uint64_t address, + uint64_t addend) = 0; + + // Add a reloc of type TYPE against the local symbol LOCAL_SYM_INDEX + // in RELOBJ. The relocation applies to the data at offset ADDRESS + // within section SHNDX of RELOBJ. OD is the associated output + // section. + virtual void + add_local_generic(Relobj* relobj, unsigned int local_sym_index, + unsigned int type, Output_data* od, unsigned int shndx, + uint64_t address, uint64_t addend) = 0; + + // Add a reloc of type TYPE against the STT_SECTION symbol of the + // output section OS. The relocation applies to the data at offset + // ADDRESS within OD. + virtual void + add_output_section_generic(Output_section *os, unsigned int type, + Output_data* od, uint64_t address, + uint64_t addend) = 0; + + // Add a reloc of type TYPE against the STT_SECTION symbol of the + // output section OS. The relocation applies to the data at offset + // ADDRESS within section SHNDX of RELOBJ. OD is the associated + // output section. + virtual void + add_output_section_generic(Output_section* os, unsigned int type, + Output_data* od, Relobj* relobj, + unsigned int shndx, uint64_t address, + uint64_t addend) = 0; + protected: // Note that we've added another relative reloc. void @@ -1518,23 +1567,27 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, false, false)); } - // These are to simplify the Copy_relocs class. - void - add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address, - Address addend) + add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, + uint64_t address, uint64_t addend) { gold_assert(addend == 0); - this->add_global(gsym, type, od, address); + this->add(od, Output_reloc_type(gsym, type, od, + convert_types<Address, uint64_t>(address), + false, false)); } void - add_global(Symbol* gsym, unsigned int type, Output_data* od, - Sized_relobj<size, big_endian>* relobj, - unsigned int shndx, Address address, Address addend) + add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, + Relobj* relobj, unsigned int shndx, uint64_t address, + uint64_t addend) { gold_assert(addend == 0); - this->add_global(gsym, type, od, relobj, shndx, address); + Sized_relobj<size, big_endian>* sized_relobj = + static_cast<Sized_relobj<size, big_endian>*>(relobj); + this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx, + convert_types<Address, uint64_t>(address), + false, false)); } // Add a RELATIVE reloc against a global symbol. The final relocation @@ -1592,6 +1645,32 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> address, false, false, false, false)); } + void + add_local_generic(Relobj* relobj, unsigned int local_sym_index, + unsigned int type, Output_data* od, uint64_t address, + uint64_t addend) + { + gold_assert(addend == 0); + Sized_relobj<size, big_endian>* sized_relobj = + static_cast<Sized_relobj<size, big_endian> *>(relobj); + this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od, + convert_types<Address, uint64_t>(address), + false, false, false, false)); + } + + void + add_local_generic(Relobj* relobj, unsigned int local_sym_index, + unsigned int type, Output_data* od, unsigned int shndx, + uint64_t address, uint64_t addend) + { + gold_assert(addend == 0); + Sized_relobj<size, big_endian>* sized_relobj = + static_cast<Sized_relobj<size, big_endian>*>(relobj); + this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx, + convert_types<Address, uint64_t>(address), + false, false, false, false)); + } + // Add a RELATIVE reloc against a local symbol. void @@ -1671,6 +1750,29 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> unsigned int shndx, Address address) { this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); } + void + add_output_section_generic(Output_section* os, unsigned int type, + Output_data* od, uint64_t address, + uint64_t addend) + { + gold_assert(addend == 0); + this->add(od, Output_reloc_type(os, type, od, + convert_types<Address, uint64_t>(address))); + } + + void + add_output_section_generic(Output_section* os, unsigned int type, + Output_data* od, Relobj* relobj, + unsigned int shndx, uint64_t address, + uint64_t addend) + { + gold_assert(addend == 0); + Sized_relobj<size, big_endian>* sized_relobj = + static_cast<Sized_relobj<size, big_endian>*>(relobj); + this->add(od, Output_reloc_type(os, type, sized_relobj, shndx, + convert_types<Address, uint64_t>(address))); + } + // Add an absolute relocation. void @@ -1733,6 +1835,29 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, addend, false, false)); } + void + add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, + uint64_t address, uint64_t addend) + { + this->add(od, Output_reloc_type(gsym, type, od, + convert_types<Address, uint64_t>(address), + convert_types<Addend, uint64_t>(addend), + false, false)); + } + + void + add_global_generic(Symbol* gsym, unsigned int type, Output_data* od, + Relobj* relobj, unsigned int shndx, uint64_t address, + uint64_t addend) + { + Sized_relobj<size, big_endian>* sized_relobj = + static_cast<Sized_relobj<size, big_endian>*>(relobj); + this->add(od, Output_reloc_type(gsym, type, sized_relobj, shndx, + convert_types<Address, uint64_t>(address), + convert_types<Addend, uint64_t>(addend), + false, false)); + } + // Add a RELATIVE reloc against a global symbol. The final output // relocation will not reference the symbol, but we must keep the symbol // information long enough to set the addend of the relocation correctly @@ -1790,6 +1915,32 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> false)); } + void + add_local_generic(Relobj* relobj, unsigned int local_sym_index, + unsigned int type, Output_data* od, uint64_t address, + uint64_t addend) + { + Sized_relobj<size, big_endian>* sized_relobj = + static_cast<Sized_relobj<size, big_endian> *>(relobj); + this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, od, + convert_types<Address, uint64_t>(address), + convert_types<Addend, uint64_t>(addend), + false, false, false, false)); + } + + void + add_local_generic(Relobj* relobj, unsigned int local_sym_index, + unsigned int type, Output_data* od, unsigned int shndx, + uint64_t address, uint64_t addend) + { + Sized_relobj<size, big_endian>* sized_relobj = + static_cast<Sized_relobj<size, big_endian>*>(relobj); + this->add(od, Output_reloc_type(sized_relobj, local_sym_index, type, shndx, + convert_types<Address, uint64_t>(address), + convert_types<Addend, uint64_t>(addend), + false, false, false, false)); + } + // Add a RELATIVE reloc against a local symbol. void @@ -1875,6 +2026,29 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> { this->add(od, Output_reloc_type(os, type, relobj, shndx, address, addend)); } + void + add_output_section_generic(Output_section* os, unsigned int type, + Output_data* od, uint64_t address, + uint64_t addend) + { + this->add(od, Output_reloc_type(os, type, od, + convert_types<Address, uint64_t>(address), + convert_types<Addend, uint64_t>(addend))); + } + + void + add_output_section_generic(Output_section* os, unsigned int type, + Output_data* od, Relobj* relobj, + unsigned int shndx, uint64_t address, + uint64_t addend) + { + Sized_relobj<size, big_endian>* sized_relobj = + static_cast<Sized_relobj<size, big_endian>*>(relobj); + this->add(od, Output_reloc_type(os, type, sized_relobj, shndx, + convert_types<Address, uint64_t>(address), + convert_types<Addend, uint64_t>(addend))); + } + // Add an absolute relocation. void @@ -1974,29 +2148,28 @@ class Output_data_group : public Output_section_data // Output_data_got is used to manage a GOT. Each entry in the GOT is // for one symbol--either a global symbol or a local symbol in an // object. The target specific code adds entries to the GOT as -// needed. +// needed. The GOT_SIZE template parameter is the size in bits of a +// GOT entry, typically 32 or 64. -template<int size, bool big_endian> +template<int got_size, bool big_endian> class Output_data_got : public Output_section_data_build { public: - typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype; - typedef Output_data_reloc<elfcpp::SHT_REL, true, size, big_endian> Rel_dyn; - typedef Output_data_reloc<elfcpp::SHT_RELA, true, size, big_endian> Rela_dyn; + typedef typename elfcpp::Elf_types<got_size>::Elf_Addr Valtype; Output_data_got() - : Output_section_data_build(Output_data::default_alignment_for_size(size)), + : Output_section_data_build(Output_data::default_alignment_for_size(got_size)), entries_(), free_list_() { } Output_data_got(off_t data_size) : Output_section_data_build(data_size, - Output_data::default_alignment_for_size(size)), + Output_data::default_alignment_for_size(got_size)), entries_(), free_list_() { // For an incremental update, we have an existing GOT section. // Initialize the list of entries and the free list. - this->entries_.resize(data_size / (size / 8)); + this->entries_.resize(data_size / (got_size / 8)); this->free_list_.init(data_size, false); } @@ -2014,62 +2187,39 @@ class Output_data_got : public Output_section_data_build // relocation of type R_TYPE for the GOT entry. void add_global_with_rel(Symbol* gsym, unsigned int got_type, - Rel_dyn* rel_dyn, unsigned int r_type); - - void - add_global_with_rela(Symbol* gsym, unsigned int got_type, - Rela_dyn* rela_dyn, unsigned int r_type); + Output_data_reloc_generic* rel_dyn, unsigned int r_type); // Add a pair of entries for a global symbol to the GOT, and add // dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively. void add_global_pair_with_rel(Symbol* gsym, unsigned int got_type, - Rel_dyn* rel_dyn, unsigned int r_type_1, - unsigned int r_type_2); - - void - add_global_pair_with_rela(Symbol* gsym, unsigned int got_type, - Rela_dyn* rela_dyn, unsigned int r_type_1, - unsigned int r_type_2); + Output_data_reloc_generic* rel_dyn, + unsigned int r_type_1, unsigned int r_type_2); // Add an entry for a local symbol to the GOT. This returns true if // this is a new GOT entry, false if the symbol already has a GOT // entry. bool - add_local(Sized_relobj_file<size, big_endian>* object, unsigned int sym_index, - unsigned int got_type); + add_local(Relobj* object, unsigned int sym_index, unsigned int got_type); // Like add_local, but use the PLT offset of the local symbol if it // has one. bool - add_local_plt(Sized_relobj_file<size, big_endian>* object, - unsigned int sym_index, - unsigned int got_type); + add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type); // Add an entry for a local symbol to the GOT, and add a dynamic // relocation of type R_TYPE for the GOT entry. void - add_local_with_rel(Sized_relobj_file<size, big_endian>* object, - unsigned int sym_index, unsigned int got_type, - Rel_dyn* rel_dyn, unsigned int r_type); - - void - add_local_with_rela(Sized_relobj_file<size, big_endian>* object, - unsigned int sym_index, unsigned int got_type, - Rela_dyn* rela_dyn, unsigned int r_type); + add_local_with_rel(Relobj* object, unsigned int sym_index, + unsigned int got_type, Output_data_reloc_generic* rel_dyn, + unsigned int r_type); // Add a pair of entries for a local symbol to the GOT, and add // dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively. void - add_local_pair_with_rel(Sized_relobj_file<size, big_endian>* object, - unsigned int sym_index, unsigned int shndx, - unsigned int got_type, Rel_dyn* rel_dyn, - unsigned int r_type_1, unsigned int r_type_2); - - void - add_local_pair_with_rela(Sized_relobj_file<size, big_endian>* object, - unsigned int sym_index, unsigned int shndx, - unsigned int got_type, Rela_dyn* rela_dyn, + add_local_pair_with_rel(Relobj* object, unsigned int sym_index, + unsigned int shndx, unsigned int got_type, + Output_data_reloc_generic* rel_dyn, unsigned int r_type_1, unsigned int r_type_2); // Add a constant to the GOT. This returns the offset of the new @@ -2084,12 +2234,12 @@ class Output_data_got : public Output_section_data_build // Reserve a slot in the GOT. void reserve_slot(unsigned int i) - { this->free_list_.remove(i * size / 8, (i + 1) * size / 8); } + { this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); } // Reserve a slot in the GOT for a local symbol. void - reserve_local(unsigned int i, Sized_relobj<size, big_endian>* object, - unsigned int sym_index, unsigned int got_type); + reserve_local(unsigned int i, Relobj* object, unsigned int sym_index, + unsigned int got_type); // Reserve a slot in the GOT for a global symbol. void @@ -2121,8 +2271,8 @@ class Output_data_got : public Output_section_data_build { this->u_.gsym = gsym; } // Create a local symbol entry. - Got_entry(Sized_relobj_file<size, big_endian>* object, - unsigned int local_sym_index, bool use_plt_offset) + Got_entry(Relobj* object, unsigned int local_sym_index, + bool use_plt_offset) : local_sym_index_(local_sym_index), use_plt_offset_(use_plt_offset) { gold_assert(local_sym_index != GSYM_CODE @@ -2153,7 +2303,7 @@ class Output_data_got : public Output_section_data_build union { // For a local symbol, the object. - Sized_relobj_file<size, big_endian>* object; + Relobj* object; // For a global symbol, the symbol. Symbol* gsym; // For a constant, the constant. @@ -2179,7 +2329,7 @@ class Output_data_got : public Output_section_data_build // Return the offset into the GOT of GOT entry I. unsigned int got_offset(unsigned int i) const - { return i * (size / 8); } + { return i * (got_size / 8); } // Return the offset into the GOT of the last entry added. unsigned int |