diff options
author | Ben Cheng <bccheng@google.com> | 2012-11-01 14:19:35 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2012-11-01 14:27:04 -0700 |
commit | 6d5ce99288a663253fd2cde30516257f754cc776 (patch) | |
tree | d57b8b65cf7b807324908da748ba1845b8e2941a /binutils-2.22/gold/output.h | |
parent | 6b95f5ef54a29597409e24d7fe6670238d58ff04 (diff) | |
download | toolchain_binutils-6d5ce99288a663253fd2cde30516257f754cc776.zip toolchain_binutils-6d5ce99288a663253fd2cde30516257f754cc776.tar.gz toolchain_binutils-6d5ce99288a663253fd2cde30516257f754cc776.tar.bz2 |
Refresh binutils to 2.22.90.
Missing local patches will be added after.
Change-Id: I7e5f7529f165a48db48a07f08b85f36c2faa8d4a
Diffstat (limited to 'binutils-2.22/gold/output.h')
-rw-r--r-- | binutils-2.22/gold/output.h | 417 |
1 files changed, 306 insertions, 111 deletions
diff --git a/binutils-2.22/gold/output.h b/binutils-2.22/gold/output.h index 1bec2c0..170f0ff 100644 --- a/binutils-2.22/gold/output.h +++ b/binutils-2.22/gold/output.h @@ -1021,24 +1021,27 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> // A reloc against a global symbol. Output_reloc(Symbol* gsym, unsigned int type, Output_data* od, - Address address, bool is_relative, bool is_symbolless); + Address address, bool is_relative, bool is_symbolless, + bool use_plt_offset); Output_reloc(Symbol* gsym, unsigned int type, Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, bool is_relative, - bool is_symbolless); + bool is_symbolless, bool use_plt_offset); // A reloc against a local symbol or local section symbol. Output_reloc(Sized_relobj<size, big_endian>* relobj, unsigned int local_sym_index, unsigned int type, Output_data* od, Address address, bool is_relative, - bool is_symbolless, bool is_section_symbol); + bool is_symbolless, bool is_section_symbol, + bool use_plt_offset); Output_reloc(Sized_relobj<size, big_endian>* relobj, unsigned int local_sym_index, unsigned int type, unsigned int shndx, Address address, bool is_relative, - bool is_symbolless, bool is_section_symbol); + bool is_symbolless, bool is_section_symbol, + bool use_plt_offset); // A reloc against the STT_SECTION symbol of an output section. @@ -1216,7 +1219,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> // input file. unsigned int local_sym_index_; // The reloc type--a processor specific code. - unsigned int type_ : 29; + unsigned int type_ : 28; // True if the relocation is a RELATIVE relocation. bool is_relative_ : 1; // True if the relocation is one which should not use @@ -1224,6 +1227,9 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> bool is_symbolless_ : 1; // True if the relocation is against a section symbol. bool is_section_symbol_ : 1; + // True if the addend should be the PLT offset. + // (Used only for RELA, but stored here for space.) + bool use_plt_offset_ : 1; // If the reloc address is an input section in an object, the // section index. This is INVALID_CODE if the reloc address is // specified in some other way. @@ -1249,17 +1255,18 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> Output_reloc(Symbol* gsym, unsigned int type, Output_data* od, Address address, Addend addend, bool is_relative, - bool is_symbolless) - : rel_(gsym, type, od, address, is_relative, is_symbolless), + bool is_symbolless, bool use_plt_offset) + : rel_(gsym, type, od, address, is_relative, is_symbolless, + use_plt_offset), addend_(addend) { } Output_reloc(Symbol* gsym, unsigned int type, Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, Addend addend, - bool is_relative, bool is_symbolless) + bool is_relative, bool is_symbolless, bool use_plt_offset) : rel_(gsym, type, relobj, shndx, address, is_relative, - is_symbolless), addend_(addend) + is_symbolless, use_plt_offset), addend_(addend) { } // A reloc against a local symbol. @@ -1268,9 +1275,10 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> unsigned int local_sym_index, unsigned int type, Output_data* od, Address address, Addend addend, bool is_relative, - bool is_symbolless, bool is_section_symbol) + bool is_symbolless, bool is_section_symbol, + bool use_plt_offset) : rel_(relobj, local_sym_index, type, od, address, is_relative, - is_symbolless, is_section_symbol), + is_symbolless, is_section_symbol, use_plt_offset), addend_(addend) { } @@ -1278,9 +1286,10 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> unsigned int local_sym_index, unsigned int type, unsigned int shndx, Address address, Addend addend, bool is_relative, - bool is_symbolless, bool is_section_symbol) + bool is_symbolless, bool is_section_symbol, + bool use_plt_offset) : rel_(relobj, local_sym_index, type, shndx, address, is_relative, - is_symbolless, is_section_symbol), + is_symbolless, is_section_symbol, use_plt_offset), addend_(addend) { } @@ -1389,6 +1398,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 @@ -1450,7 +1508,8 @@ class Output_data_reloc_base : public Output_data_reloc_generic { this->relocs_.push_back(reloc); this->set_current_data_size(this->relocs_.size() * reloc_size); - od->add_dynamic_reloc(); + if (dynamic) + od->add_dynamic_reloc(); if (reloc.is_relative()) this->bump_relative_reloc_count(); Sized_relobj<size, big_endian>* relobj = reloc.get_relobj(); @@ -1500,32 +1559,36 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> void add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address) - { this->add(od, Output_reloc_type(gsym, type, od, address, false, false)); } + { this->add(od, Output_reloc_type(gsym, type, od, address, false, false, false)); } void add_global(Symbol* gsym, unsigned int type, Output_data* od, Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, - false, false)); } - - // These are to simplify the Copy_relocs class. + false, false, false)); } 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, 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, false)); } // Add a RELATIVE reloc against a global symbol. The final relocation @@ -1534,7 +1597,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> void add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, Address address) - { this->add(od, Output_reloc_type(gsym, type, od, address, true, true)); } + { this->add(od, Output_reloc_type(gsym, type, od, address, true, true, + false)); } void add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, @@ -1542,7 +1606,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> unsigned int shndx, Address address) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, - true, true)); + true, true, false)); } // Add a global relocation which does not use a symbol for the relocation, @@ -1551,7 +1615,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> void add_symbolless_global_addend(Symbol* gsym, unsigned int type, Output_data* od, Address address) - { this->add(od, Output_reloc_type(gsym, type, od, address, false, true)); } + { this->add(od, Output_reloc_type(gsym, type, od, address, false, true, + false)); } void add_symbolless_global_addend(Symbol* gsym, unsigned int type, @@ -1560,7 +1625,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> unsigned int shndx, Address address) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, - false, true)); + false, true, false)); } // Add a reloc against a local symbol. @@ -1571,7 +1636,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Output_data* od, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, - address, false, false, false)); + address, false, false, false, false)); } void @@ -1580,7 +1645,33 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Output_data* od, unsigned int shndx, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, false, false, false)); + 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. @@ -1591,7 +1682,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Output_data* od, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, - address, true, true, false)); + address, true, true, false, false)); } void @@ -1600,7 +1691,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Output_data* od, unsigned int shndx, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, true, true, false)); + address, true, true, false, false)); } // Add a local relocation which does not use a symbol for the relocation, @@ -1612,7 +1703,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Output_data* od, Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, - address, false, true, false)); + address, false, true, false, false)); } void @@ -1622,7 +1713,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Address address) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, false, true, false)); + address, false, true, false, false)); } // Add a reloc against a local section symbol. This will be @@ -1635,7 +1726,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Output_data* od, Address address) { this->add(od, Output_reloc_type(relobj, input_shndx, type, od, - address, false, false, true)); + address, false, false, true, false)); } void @@ -1644,7 +1735,7 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> Output_data* od, unsigned int shndx, Address address) { this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx, - address, false, false, true)); + address, false, false, true, false)); } // A reloc against the STT_SECTION symbol of an output section. @@ -1662,6 +1753,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 @@ -1714,7 +1828,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address, Addend addend) { this->add(od, Output_reloc_type(gsym, type, od, address, addend, - false, false)); } + false, false, false)); } void add_global(Symbol* gsym, unsigned int type, Output_data* od, @@ -1722,7 +1836,30 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> unsigned int shndx, Address address, Addend addend) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, - addend, false, false)); } + addend, false, 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, 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, false)); + } // Add a RELATIVE reloc against a global symbol. The final output // relocation will not reference the symbol, but we must keep the symbol @@ -1731,16 +1868,17 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> void add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, - Address address, Addend addend) + Address address, Addend addend, bool use_plt_offset) { this->add(od, Output_reloc_type(gsym, type, od, address, addend, true, - true)); } + true, use_plt_offset)); } void add_global_relative(Symbol* gsym, unsigned int type, Output_data* od, Sized_relobj<size, big_endian>* relobj, - unsigned int shndx, Address address, Addend addend) + unsigned int shndx, Address address, Addend addend, + bool use_plt_offset) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, - addend, true, true)); } + addend, true, true, use_plt_offset)); } // Add a global relocation which does not use a symbol for the relocation, // but which gets its addend from a symbol. @@ -1749,7 +1887,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> add_symbolless_global_addend(Symbol* gsym, unsigned int type, Output_data* od, Address address, Addend addend) { this->add(od, Output_reloc_type(gsym, type, od, address, addend, - false, true)); } + false, true, false)); } void add_symbolless_global_addend(Symbol* gsym, unsigned int type, @@ -1757,7 +1895,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> Sized_relobj<size, big_endian>* relobj, unsigned int shndx, Address address, Addend addend) { this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address, - addend, false, true)); } + addend, false, true, false)); } // Add a reloc against a local symbol. @@ -1767,7 +1905,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> Output_data* od, Address address, Addend addend) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, - addend, false, false, false)); + addend, false, false, false, false)); } void @@ -1777,7 +1915,34 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> Addend addend) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, addend, false, false, false)); + address, addend, 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) + { + 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. @@ -1785,20 +1950,23 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> void add_local_relative(Sized_relobj<size, big_endian>* relobj, unsigned int local_sym_index, unsigned int type, - Output_data* od, Address address, Addend addend) + Output_data* od, Address address, Addend addend, + bool use_plt_offset) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, - addend, true, true, false)); + addend, true, true, false, + use_plt_offset)); } void add_local_relative(Sized_relobj<size, big_endian>* relobj, unsigned int local_sym_index, unsigned int type, Output_data* od, unsigned int shndx, Address address, - Addend addend) + Addend addend, bool use_plt_offset) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, addend, true, true, false)); + address, addend, true, true, false, + use_plt_offset)); } // Add a local relocation which does not use a symbol for the relocation, @@ -1810,7 +1978,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> Output_data* od, Address address, Addend addend) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, od, address, - addend, false, true, false)); + addend, false, true, false, false)); } void @@ -1820,7 +1988,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> Address address, Addend addend) { this->add(od, Output_reloc_type(relobj, local_sym_index, type, shndx, - address, addend, false, true, false)); + address, addend, false, true, false, + false)); } // Add a reloc against a local section symbol. This will be @@ -1833,7 +2002,7 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> Output_data* od, Address address, Addend addend) { this->add(od, Output_reloc_type(relobj, input_shndx, type, od, address, - addend, false, false, true)); + addend, false, false, true, false)); } void @@ -1843,7 +2012,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> Addend addend) { this->add(od, Output_reloc_type(relobj, input_shndx, type, shndx, - address, addend, false, false, true)); + address, addend, false, false, true, + false)); } // A reloc against the STT_SECTION symbol of an output section. @@ -1860,6 +2030,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 @@ -1959,29 +2152,50 @@ 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> -class Output_data_got : public Output_section_data_build +class Output_data_got_base : public Output_section_data_build +{ + public: + Output_data_got_base(uint64_t align) + : Output_section_data_build(align) + { } + + Output_data_got_base(off_t data_size, uint64_t align) + : Output_section_data_build(data_size, align) + { } + + // Reserve the slot at index I in the GOT. + void + reserve_slot(unsigned int i) + { this->do_reserve_slot(i); } + + protected: + // Reserve the slot at index I in the GOT. + virtual void + do_reserve_slot(unsigned int i) = 0; +}; + +template<int got_size, bool big_endian> +class Output_data_got : public Output_data_got_base { 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_data_got_base(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_got_base(data_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); } @@ -1999,62 +2213,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 @@ -2066,15 +2257,10 @@ class Output_data_got : public Output_section_data_build return got_offset; } - // Reserve a slot in the GOT. - void - reserve_slot(unsigned int i) - { this->free_list_.remove(i * size / 8, (i + 1) * 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 @@ -2090,6 +2276,11 @@ class Output_data_got : public Output_section_data_build do_print_to_mapfile(Mapfile* mapfile) const { mapfile->print_output_data(this, _("** GOT")); } + // Reserve the slot at index I in the GOT. + virtual void + do_reserve_slot(unsigned int i) + { this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); } + private: // This POD class holds a single GOT entry. class Got_entry @@ -2106,8 +2297,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 @@ -2138,7 +2329,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. @@ -2164,7 +2355,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 @@ -2628,6 +2819,10 @@ class Output_fill : is_big_endian_(parameters->target().is_big_endian()) { } + virtual + ~Output_fill() + { } + // Return the smallest size chunk of free space that can be // filled with a dummy compilation unit. size_t @@ -2761,7 +2956,7 @@ class Output_section : public Output_data typedef std::map<Section_id, unsigned int> Section_layout_order; void - update_section_layout(const Section_layout_order& order_map); + update_section_layout(const Section_layout_order* order_map); // Update the output section flags based on input section flags. void |