diff options
author | Cary Coutant <ccoutant@google.com> | 2011-05-24 21:41:10 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2011-05-24 21:41:10 +0000 |
commit | 6fa2a40bf45fcc738eb580a6b644ac74b42c2d6a (patch) | |
tree | 41ae0a8dbe33a58e626c8fbcaa13f0b435b193bf /gold/incremental.h | |
parent | 2e21250dbcb81b1909ba3fbda8931a47c7215beb (diff) | |
download | fsf-binutils-gdb-6fa2a40bf45fcc738eb580a6b644ac74b42c2d6a.zip fsf-binutils-gdb-6fa2a40bf45fcc738eb580a6b644ac74b42c2d6a.tar.gz fsf-binutils-gdb-6fa2a40bf45fcc738eb580a6b644ac74b42c2d6a.tar.bz2 |
* incremental-dump.cc (dump_incremental_inputs): Print dynamic reloc
info; adjust display of GOT entries.
* incremental.cc (Sized_incremental_binary::setup_readers): Allocate
vector of input objects; remove file_status_.
(Sized_incremental_binary::do_reserve_layout): Remove file_status_.
(Sized_incremental_binary::do_process_got_plt): Adjust calls to
got_plt reader; call target hooks to reserve GOT entries.
(Output_section_incremental_inputs::set_final_data_size): Adjust size
of input file info header and GOT info entry.
(Output_section_incremental_inputs::write_info_blocks): Write dynamic
relocation info.
(Got_plt_view_info::got_descriptor): Remove.
(Got_plt_view_info::sym_index): New data member.
(Got_plt_view_info::input_index): New data member.
(Local_got_offset_visitor::visit): Write input file index.
(Global_got_offset_visitor::visit): Write 0 for input file index.
(Global_symbol_visitor_got_plt::operator()): Replace got_descriptor
with sym_index and input_index.
(Output_section_incremental_inputs::write_got_plt): Adjust size of
incremental info GOT entry; replace got_descriptor with input_index.
(Sized_relobj_incr::Sized_relobj_incr): Adjust initializers; record
map from input file index to object.
(Sized_relobj_incr::do_layout): Replace direct data member reference
with accessor function.
(Sized_relobj_incr::do_for_all_local_got_entries): Move to base class.
* incremental.h (Incremental_input_entry_reader::get_symbol_offset):
Adjust size of input file info header.
(Incremental_input_entry_reader::get_first_dyn_reloc): New function.
(Incremental_input_entry_reader::get_dyn_reloc_count): New function.
(Incremental_input_entry_reader::get_input_section): Adjust size of
input file info header.
(Incremental_got_plt_reader::Incremental_got_plt_reader): Adjust size
of incremental info GOT entry.
(Incremental_got_plt_reader::get_got_desc): Remove.
(Incremental_got_plt_reader::get_got_symndx): New function.
(Incremental_got_plt_reader::get_got_input_index): New function.
(Sized_incremental_binary::Sized_incremental_binary): Remove
file_status_; add input_objects_.
(Sized_incremental_binary::~Sized_incremental_binary): Remove.
(Sized_incremental_binary::set_file_is_unchanged): Remove.
(Sized_incremental_binary::file_is_unchanged): Remove.
(Sized_incremental_binary::set_input_object): New function.
(Sized_incremental_binary::input_object): New function.
(Sized_incremental_binary::file_status_): Remove.
(Sized_incremental_binary::input_objects_): New data member.
(Sized_relobj_incr): Rename Sized_incr_relobj to this; adjust all
references.
(Sized_relobj_incr::invalid_address): Move to base class.
(Sized_relobj_incr::is_output_section_offset_invalid): Move to base
class.
(Sized_relobj_incr::do_output_section_offset): Likewise.
(Sized_relobj_incr::do_for_all_local_got_entries): Likewise.
(Sized_relobj_incr::section_offsets_): Likewise.
* object.cc (Sized_relobj::do_for_all_local_got_entries): New
function.
(Sized_relobj_file::Sized_relobj_file): Remove local_got_offsets_.
(Sized_relobj_file::layout_section): Replace refs to section_offsets_
with accessor function.
(Sized_relobj_file::do_layout): Likewise.
(Sized_relobj_file::do_layout_deferred_sections): Likewise.
(Sized_relobj_file::do_for_all_local_got_entries): Move to base class.
(Sized_relobj_file::compute_final_local_value): Replace refs to
section_offsets_ with accessor function.
(Sized_relobj_file::do_finalize_local_symbols): Likewise.
* object.h (Relobj::Relobj): Initialize new data members.
(Relobj::add_dyn_reloc): New function.
(Relobj::first_dyn_reloc): New function.
(Relobj::dyn_reloc_count): New function.
(Relobj::first_dyn_reloc_): New data member.
(Relobj::dyn_reloc_count_): New data member.
(Sized_relobj): Rename Sized_relobj_base to this; adjust all
references.
(Sized_relobj::Address): New typedef.
(Sized_relobj::invalid_address): Move here from child class.
(Sized_relobj::Sized_relobj): Initialize new data members.
(Sized_relobj::sized_relobj): New function.
(Sized_relobj::is_output_section_offset_invalid): Move here from
child class.
(Sized_relobj::get_output_section_offset): Likewise.
(Sized_relobj::local_has_got_offset): Likewise.
(Sized_relobj::local_got_offset): Likewise.
(Sized_relobj::set_local_got_offset): Likewise.
(Sized_relobj::do_for_all_local_got_entries): Likewise.
(Sized_relobj::clear_got_offsets): New function.
(Sized_relobj::section_offsets): Move here from child class.
(Sized_relobj::do_output_section_offset): Likewise.
(Sized_relobj::do_set_section_offset): Likewise.
(Sized_relobj::Local_got_offsets): Likewise.
(Sized_relobj::local_got_offsets_): Likewise.
(Sized_relobj::section_offsets_): Likewise.
(Sized_relobj_file): Rename Sized_relobj to this; adjust all
references.
(Sized_relobj_file::is_output_section_offset_invalid): Move to base
class.
(Sized_relobj_file::sized_relobj): New function
(Sized_relobj_file::local_has_got_offset): Move to base class.
(Sized_relobj_file::local_got_offset): Likewise.
(Sized_relobj_file::set_local_got_offset): Likewise.
(Sized_relobj_file::get_output_section_offset): Likewise.
(Sized_relobj_file::do_for_all_local_got_entries): Likewise.
(Sized_relobj_file::do_output_section_offset): Likewise.
(Sized_relobj_file::do_set_section_offset): Likewise.
(Sized_relobj_file::Local_got_offsets): Likewise.
(Sized_relobj_file::local_got_offsets_): Likewise.
(Sized_relobj_file::section_offsets_): Likewise.
* output.cc (Output_reloc::Output_reloc): Adjust type of relobj
(all constructors).
(set_needs_dynsym_index): Convert relobj to derived class pointer.
(Output_reloc::get_symbol_index): Likewise.
(Output_reloc::local_section_offset): Likewise.
(Output_reloc::get_address): Likewise.
(Output_reloc::symbol_value): Likewise.
(Output_data_got::reserve_slot): Move to class definition.
(Output_data_got::reserve_local): New function.
(Output_data_got::reserve_slot_for_global): Remove.
(Output_data_got::reserve_global): New function.
* output.h (Output_reloc::Output_reloc): Adjust type of relobj
(all constructors, two instantiations).
(Output_reloc::get_relobj): New function (two instantiations).
(Output_reloc::u1_.relobj, Output_reloc::u2_.relobj): Adjust type.
(Output_data_reloc_base::add): Convert relobj to derived class pointer.
(Output_data_reloc::add_global): Adjust type of relobj.
(Output_data_reloc::add_global_relative): Likewise.
(Output_data_reloc::add_symbolless_global_addend): Likewise.
(Output_data_reloc::add_local): Likewise.
(Output_data_reloc::add_local_relative): Likewise.
(Output_data_reloc::add_symbolless_local_addend): Likewise.
(Output_data_reloc::add_local_section): Likewise.
(Output_data_reloc::add_output_section): Likewise.
(Output_data_reloc::add_absolute): Likewise.
(Output_data_reloc::add_target_specific): Likewise.
(Output_data_got::reserve_slot): Move definition here.
(Output_data_got::reserve_local): New function.
(Output_data_got::reserve_global): New function.
* reloc.cc (Sized_relobj_file::do_read_relocs): Replace refs to
section_offsets_ with accessor function.
(Sized_relobj_file::write_sections): Likewise.
(Sized_relobj_file::do_relocate_sections): Likewise.
* target.h (Sized_target::reserve_local_got_entry): New function.
(Sized_target::reserve_global_got_entry): New function.
* x86_64.cc (Target_x86_64::reserve_local_got_entry): New function.
(Target_x86_64::reserve_global_got_entry): New function.
(Target_x86_64::init_got_plt_for_update): Create rela_dyn section.
Diffstat (limited to 'gold/incremental.h')
-rw-r--r-- | gold/incremental.h | 121 |
1 files changed, 55 insertions, 66 deletions
diff --git a/gold/incremental.h b/gold/incremental.h index 5c0f937..3935186 100644 --- a/gold/incremental.h +++ b/gold/incremental.h @@ -736,7 +736,7 @@ class Incremental_inputs_reader || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER); unsigned int section_count = this->get_input_section_count(); - return (this->info_offset_ + 16 + return (this->info_offset_ + 24 + section_count * input_section_entry_size + symndx * 20); } @@ -777,6 +777,26 @@ class Incremental_inputs_reader return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 12); } + // Return the index of the first dynamic relocation -- for objects only. + unsigned int + get_first_dyn_reloc() const + { + gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT + || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER); + + return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 16); + } + + // Return the dynamic relocation count -- for objects only. + unsigned int + get_dyn_reloc_count() const + { + gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT + || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER); + + return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 20); + } + // Return the object count -- for scripts only. unsigned int get_object_count() const @@ -847,7 +867,7 @@ class Incremental_inputs_reader { Input_section_info info; const unsigned char* p = (this->inputs_->p_ - + this->info_offset_ + 16 + + this->info_offset_ + 24 + n * input_section_entry_size); unsigned int name_offset = Swap32::readval(p); info.name = this->inputs_->get_string(name_offset); @@ -865,7 +885,7 @@ class Incremental_inputs_reader || this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER); unsigned int section_count = this->get_input_section_count(); const unsigned char* p = (this->inputs_->p_ - + this->info_offset_ + 16 + + this->info_offset_ + 24 + section_count * input_section_entry_size + n * 20); return Incremental_global_symbol_reader<big_endian>(p); @@ -1064,7 +1084,7 @@ class Incremental_got_plt_reader { this->got_count_ = elfcpp::Swap<32, big_endian>::readval(p); this->got_desc_p_ = p + 8 + ((this->got_count_ + 3) & ~3); - this->plt_desc_p_ = this->got_desc_p_ + this->got_count_ * 4; + this->plt_desc_p_ = this->got_desc_p_ + this->got_count_ * 8; } // Return the GOT entry count. @@ -1088,11 +1108,18 @@ class Incremental_got_plt_reader return this->p_[8 + n]; } - // Return the GOT descriptor for GOT entry N. + // Return the symbol index for GOT entry N. + unsigned int + get_got_symndx(unsigned int n) + { + return elfcpp::Swap<32, big_endian>::readval(this->got_desc_p_ + n * 8); + } + + // Return the input file index for GOT entry N. unsigned int - get_got_desc(unsigned int n) + get_got_input_index(unsigned int n) { - return elfcpp::Swap<32, big_endian>::readval(this->got_desc_p_ + n * 4); + return elfcpp::Swap<32, big_endian>::readval(this->got_desc_p_ + n * 8 + 4); } // Return the PLT descriptor for PLT entry N. @@ -1358,6 +1385,9 @@ class Incremental_binary }; template<int size, bool big_endian> +class Sized_relobj_incr; + +template<int size, bool big_endian> class Sized_incremental_binary : public Incremental_binary { public: @@ -1365,38 +1395,29 @@ class Sized_incremental_binary : public Incremental_binary const elfcpp::Ehdr<size, big_endian>& ehdr, Target* target) : Incremental_binary(output, target), elf_file_(this, ehdr), - file_status_(NULL), section_map_(), symbol_map_(), main_symtab_loc_(), + input_objects_(), section_map_(), symbol_map_(), main_symtab_loc_(), main_strtab_loc_(), has_incremental_info_(false), inputs_reader_(), symtab_reader_(), relocs_reader_(), got_plt_reader_(), input_entry_readers_() { this->setup_readers(); } - virtual - ~Sized_incremental_binary() - { - if (this->file_status_ != NULL) - delete[] this->file_status_; - } - // Returns TRUE if the file contains incremental info. bool has_incremental_info() const { return this->has_incremental_info_; } - // Set the flag for input file N to indicate that the file is unchanged. + // Record a pointer to the object for input file N. void - set_file_is_unchanged(unsigned int n) - { - gold_assert(this->file_status_ != NULL); - this->file_status_[n / 8] |= 1U << (n % 8); - } + set_input_object(unsigned int n, + Sized_relobj_incr<size, big_endian>* obj) + { this->input_objects_[n] = obj; } - // Returns TRUE if input file N is unchanged. - bool - file_is_unchanged(unsigned int n) const + // Return a pointer to the object for input file N. + Sized_relobj_incr<size, big_endian>* + input_object(unsigned int n) const { - gold_assert(this->file_status_ != NULL); - return (this->file_status_[n / 8] & (1U << (n % 8))) != 0; + gold_assert(n < this->input_objects_.size()); + return this->input_objects_[n]; } // Return the Output_section for section index SHNDX. @@ -1537,10 +1558,9 @@ class Sized_incremental_binary : public Incremental_binary // Output as an ELF file. elfcpp::Elf_file<size, big_endian, Incremental_binary> elf_file_; - // Status flags for each input file. Each bit represents one input file; - // 0 indicates that the file was replaced; 1 indicates that the file was - // unchanged. - unsigned char* file_status_; + // Vector of pointers to the input objects for the unchanged files. + // For replaced files, the corresponding pointer is NULL. + std::vector<Sized_relobj_incr<size, big_endian>*> input_objects_; // Map section index to an Output_section in the updated layout. std::vector<Output_section*> section_map_; @@ -1566,44 +1586,22 @@ class Sized_incremental_binary : public Incremental_binary // can be used directly from the base file. template<int size, bool big_endian> -class Sized_incr_relobj : public Sized_relobj_base<size, big_endian> +class Sized_relobj_incr : public Sized_relobj<size, big_endian> { public: typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; - typedef typename Sized_relobj_base<size, big_endian>::Symbols Symbols; + typedef typename Sized_relobj<size, big_endian>::Symbols Symbols; - static const Address invalid_address = static_cast<Address>(0) - 1; - - Sized_incr_relobj(const std::string& name, + Sized_relobj_incr(const std::string& name, Sized_incremental_binary<size, big_endian>* ibase, unsigned int input_file_index); - // Checks if the offset of input section SHNDX within its output - // section is invalid. - bool - is_output_section_offset_invalid(unsigned int shndx) const - { return this->section_offsets_[shndx] == invalid_address; } - - // Get the offset of input section SHNDX within its output section. - // This is -1 if the input section requires a special mapping, such - // as a merge section. The output section can be found in the - // output_sections_ field of the parent class Incrobj. - uint64_t - do_output_section_offset(unsigned int shndx) const - { - gold_assert(shndx < this->section_offsets_.size()); - Address off = this->section_offsets_[shndx]; - if (off == invalid_address) - return -1ULL; - return off; - } - private: // For convenience. - typedef Sized_incr_relobj<size, big_endian> This; + typedef Sized_relobj_incr<size, big_endian> This; static const int sym_size = elfcpp::Elf_sizes<size>::sym_size; - typedef typename Sized_relobj_base<size, big_endian>::Output_sections + typedef typename Sized_relobj<size, big_endian>::Output_sections Output_sections; typedef Incremental_inputs_reader<size, big_endian> Inputs_reader; typedef typename Inputs_reader::Incremental_input_entry_reader @@ -1671,11 +1669,6 @@ class Sized_incr_relobj : public Sized_relobj_base<size, big_endian> do_for_all_global_symbols(Read_symbols_data* sd, Library_base::Symbol_visitor_base* v); - // Iterate over local symbols, calling a visitor class V for each GOT offset - // associated with a local symbol. - void - do_for_all_local_got_entries(Got_offset_list::Visitor* v) const; - // Get the size of a section. uint64_t do_section_size(unsigned int shndx); @@ -1801,10 +1794,6 @@ class Sized_incr_relobj : public Sized_relobj_base<size, big_endian> unsigned int local_dynsym_offset_; // The entries in the symbol table for the external symbols. Symbols symbols_; - // For each input section, the offset of the input section in its - // output section. This is INVALID_ADDRESS if the input section requires a - // special mapping. - std::vector<Address> section_offsets_; // The offset of the first incremental relocation for this object. unsigned int incr_reloc_offset_; // The number of incremental relocations for this object. |