diff options
author | Cary Coutant <ccoutant@google.com> | 2011-05-23 23:27:11 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2011-05-23 23:27:11 +0000 |
commit | 4829d394dedd7953e0ee0cf540ffccc01936499d (patch) | |
tree | eb77be5d59cedf93ed8a5ed3e7feb32530d51a65 /gold/incremental.cc | |
parent | dd931b2ff2bf7cecc09dba03e8916e4adc9406be (diff) | |
download | gdb-4829d394dedd7953e0ee0cf540ffccc01936499d.zip gdb-4829d394dedd7953e0ee0cf540ffccc01936499d.tar.gz gdb-4829d394dedd7953e0ee0cf540ffccc01936499d.tar.bz2 |
* gold.cc (queue_middle_tasks): Process existing GOT/PLT entries.
* incremental-dump.cc (dump_incremental_inputs): Mask high-order
bit when checking got_type.
* incremental.cc (Sized_incremental_binary::setup_readers):
Store symbol table and string table locations; initialize bit vector
of file status flags.
(Sized_incremental_binary::do_reserve_layout): Set bit flag for
unchanged files.
(Sized_incremental_binary::do_process_got_plt): New function.
(Sized_incremental_binary::get_symtab_view): Use stored locations.
(Output_section_incremental_inputs::set_final_data_size): Record
file index for each input file.
(Output_section_incremental_inputs::write_got_plt): Store file index
instead of input entry offset for each GOT entry.
* incremental.h
(Incremental_input_entry::Incremental_input_entry): Initialize new
data member.
(Incremental_input_entry::set_offset): Store file index.
(Incremental_input_entry::get_file_index): New function.
(Incremental_input_entry::file_index_): New data member.
(Incremental_binary::process_got_plt): New function.
(Incremental_binary::do_process_got_plt): New function.
(Sized_incremental_binary::Sized_incremental_binary): Initialize new
data members.
(Sized_incremental_binary::~Sized_incremental_binary): New destructor.
(Sized_incremental_binary::set_file_is_unchanged): New function.
(Sized_incremental_binary::file_is_unchanged): New function.
(Sized_incremental_binary::do_process_got_plt): New function.
(Sized_incremental_binary::file_status_): New data member.
(Sized_incremental_binary::main_symtab_loc_): New data member.
(Sized_incremental_binary::main_strtab_loc_): New data member.
* output.cc (Output_data_got::Got_entry::write): Add case
RESERVED_CODE.
(Output_data_got::add_global): Call add_got_entry.
(Output_data_got::add_global_plt): Likewise.
(Output_data_got::add_global_with_rel): Likewise.
(Output_data_got::add_global_with_rela): Likewise.
(Output_data_got::add_global_pair_with_rel): Call add_got_entry_pair.
(Output_data_got::add_global_pair_with_rela): Likewise.
(Output_data_got::add_local): Call add_got_entry.
(Output_data_got::add_local_plt): Likewise.
(Output_data_got::add_local_with_rel): Likewise.
(Output_data_got::add_local_with_rela): Likewise.
(Output_data_got::add_local_pair_with_rel): Call add_got_entry_pair.
(Output_data_got::add_local_pair_with_rela): Likewise.
(Output_data_got::reserve_slot): New function.
(Output_data_got::reserve_slot_for_global): New function.
(Output_data_got::add_got_entry): New function.
(Output_data_got::add_got_entry_pair): New function.
(Output_section::add_output_section_data): Edit FIXME.
* output.h
(Output_section_data_build::Output_section_data_build): New
constructor with size parameter.
(Output_data_space::Output_data_space): Likewise.
(Output_data_got::Output_data_got): Initialize new data member; new
constructor with size parameter.
(Output_data_got::add_constant): Call add_got_entry.
(Output_data_got::reserve_slot): New function.
(Output_data_got::reserve_slot_for_global): New function.
(class Output_data_got::Got_entry): Add RESERVED_CODE.
(Output_data_got::add_got_entry): New function.
(Output_data_got::add_got_entry_pair): New function.
(Output_data_got::free_list_): New data member.
* target.h (Sized_target::init_got_plt_for_update): New function.
(Sized_target::register_global_plt_entry): New function.
* x86_64.cc (Output_data_plt_x86_64::Output_data_plt_x86_64):
Initialize new data member; call init; add constructor with PLT count.
(Output_data_plt_x86_64::init): New function.
(Output_data_plt_x86_64::add_relocation): New function.
(Output_data_plt_x86_64::reserve_slot): New function.
(Output_data_plt_x86_64::free_list_): New data member.
(Target_x86_64::init_got_plt_for_update): New function.
(Target_x86_64::register_global_plt_entry): New function.
(Output_data_plt_x86_64::add_entry): Allocate from free list for
incremental updates.
(Output_data_plt_x86_64::add_relocation): New function.
* testsuite/object_unittest.cc (Object_test): Set default options.
Diffstat (limited to 'gold/incremental.cc')
-rw-r--r-- | gold/incremental.cc | 122 |
1 files changed, 106 insertions, 16 deletions
diff --git a/gold/incremental.cc b/gold/incremental.cc index 1250d70..b831b97 100644 --- a/gold/incremental.cc +++ b/gold/incremental.cc @@ -258,6 +258,19 @@ Sized_incremental_binary<size, big_endian>::setup_readers() this->got_plt_reader_ = Incremental_got_plt_reader<big_endian>(got_plt_view.data()); + // Find the main symbol table. + unsigned int main_symtab_shndx = + this->elf_file_.find_section_by_type(elfcpp::SHT_SYMTAB); + gold_assert(main_symtab_shndx != elfcpp::SHN_UNDEF); + this->main_symtab_loc_ = this->elf_file_.section_contents(main_symtab_shndx); + + // Find the main symbol string table. + unsigned int main_strtab_shndx = + this->elf_file_.section_link(main_symtab_shndx); + gold_assert(main_strtab_shndx != elfcpp::SHN_UNDEF + && main_strtab_shndx < this->elf_file_.shnum()); + this->main_strtab_loc_ = this->elf_file_.section_contents(main_strtab_shndx); + // Walk the list of input files (a) to setup an Input_reader for each // input file, and (b) to record maps of files added from archive // libraries and scripts. @@ -314,6 +327,10 @@ Sized_incremental_binary<size, big_endian>::setup_readers() unsigned int nglobals = this->symtab_reader_.symbol_count(); this->symbol_map_.resize(nglobals); + // Initialize the status of each input file. + this->file_status_ = new unsigned char[(count + 7) / 8]; + memset(this->file_status_, 0, (count + 7) / 8); + this->has_incremental_info_ = true; } @@ -507,6 +524,8 @@ Sized_incremental_binary<size, big_endian>::do_reserve_layout( Input_entry_reader input_file = this->inputs_reader_.input_file(input_file_index); + this->set_file_is_unchanged(input_file_index); + if (input_file.type() == INCREMENTAL_INPUT_SHARED_LIBRARY) return; @@ -523,6 +542,83 @@ Sized_incremental_binary<size, big_endian>::do_reserve_layout( } } +// Process the GOT and PLT entries from the existing output file. + +template<int size, bool big_endian> +void +Sized_incremental_binary<size, big_endian>::do_process_got_plt( + Symbol_table* symtab, + Layout* layout) +{ + Incremental_got_plt_reader<big_endian> got_plt_reader(this->got_plt_reader()); + Sized_target<size, big_endian>* target = + parameters->sized_target<size, big_endian>(); + + // Get the number of symbols in the main symbol table and in the + // incremental symbol table. The difference between the two counts + // is the index of the first forced-local or global symbol in the + // main symbol table. + unsigned int symtab_count = + this->main_symtab_loc_.data_size / elfcpp::Elf_sizes<size>::sym_size; + unsigned int isym_count = this->symtab_reader_.symbol_count(); + unsigned int first_global = symtab_count - isym_count; + + // Tell the target how big the GOT and PLT sections are. + unsigned int got_count = got_plt_reader.get_got_entry_count(); + unsigned int plt_count = got_plt_reader.get_plt_entry_count(); + Output_data_got<size, big_endian>* got = + target->init_got_plt_for_update(symtab, layout, got_count, plt_count); + + // Read the GOT entries from the base file and build the outgoing GOT. + for (unsigned int i = 0; i < got_count; ++i) + { + unsigned int got_type = got_plt_reader.get_got_type(i); + if ((got_type & 0x7f) == 0x7f) + { + // This is the second entry of a pair. + got->reserve_slot(i); + continue; + } + unsigned int got_desc = got_plt_reader.get_got_desc(i); + if (got_type & 0x80) + { + // This is an entry for a local symbol. GOT_DESC is the index + // of the object file entry in the list of input files. Ignore + // this entry if the object file was replaced. + gold_debug(DEBUG_INCREMENTAL, + "GOT entry %d, type %02x: (local symbol)", + i, got_type & 0x7f); + if (this->file_is_unchanged(got_desc)) + got->reserve_slot(i); + } + else + { + // This is an entry for a global symbol. GOT_DESC is the symbol + // table index. + // FIXME: This should really be a fatal error (corrupt input). + gold_assert(got_desc >= first_global && got_desc < symtab_count); + Symbol* sym = this->global_symbol(got_desc - first_global); + gold_debug(DEBUG_INCREMENTAL, + "GOT entry %d, type %02x: %s", + i, got_type, sym->name()); + got->reserve_slot_for_global(i, sym, got_type); + } + } + + // Read the PLT entries from the base file and pass each to the target. + for (unsigned int i = 0; i < plt_count; ++i) + { + unsigned int plt_desc = got_plt_reader.get_plt_desc(i); + // FIXME: This should really be a fatal error (corrupt input). + gold_assert(plt_desc >= first_global && plt_desc < symtab_count); + Symbol* sym = this->global_symbol(plt_desc - first_global); + gold_debug(DEBUG_INCREMENTAL, + "PLT entry %d: %s", + i, sym->name()); + target->register_global_plt_entry(i, sym); + } +} + // Apply incremental relocations for symbols whose values have changed. template<int size, bool big_endian> @@ -628,20 +724,12 @@ Sized_incremental_binary<size, big_endian>::get_symtab_view( unsigned int* nsyms, elfcpp::Elf_strtab* strtab) { - unsigned int symtab_shndx = - this->elf_file_.find_section_by_type(elfcpp::SHT_SYMTAB); - gold_assert(symtab_shndx != elfcpp::SHN_UNDEF); - Location symtab_location(this->elf_file_.section_contents(symtab_shndx)); - *symtab_view = this->view(symtab_location); - *nsyms = symtab_location.data_size / elfcpp::Elf_sizes<size>::sym_size; + *symtab_view = this->view(this->main_symtab_loc_); + *nsyms = this->main_symtab_loc_.data_size / elfcpp::Elf_sizes<size>::sym_size; - unsigned int strtab_shndx = this->elf_file_.section_link(symtab_shndx); - gold_assert(strtab_shndx != elfcpp::SHN_UNDEF - && strtab_shndx < this->elf_file_.shnum()); - - Location strtab_location(this->elf_file_.section_contents(strtab_shndx)); - View strtab_view(this->view(strtab_location)); - *strtab = elfcpp::Elf_strtab(strtab_view.data(), strtab_location.data_size); + View strtab_view(this->view(this->main_strtab_loc_)); + *strtab = elfcpp::Elf_strtab(strtab_view.data(), + this->main_strtab_loc_.data_size); } namespace @@ -1022,6 +1110,7 @@ Output_section_incremental_inputs<size, big_endian>::set_final_data_size() unsigned int input_offset = this->header_size; // Offset of each supplemental info block. + unsigned int file_index = 0; unsigned int info_offset = this->header_size; info_offset += this->input_entry_size * inputs->input_file_count(); @@ -1031,8 +1120,9 @@ Output_section_incremental_inputs<size, big_endian>::set_final_data_size() p != inputs->input_files().end(); ++p) { - // Set the offset of the input file entry. - (*p)->set_offset(input_offset); + // Set the index and offset of the input file entry. + (*p)->set_offset(file_index, input_offset); + ++file_index; input_offset += this->input_entry_size; // Set the offset of the supplemental info block. @@ -1655,7 +1745,7 @@ Output_section_incremental_inputs<size, big_endian>::write_got_plt( gold_assert(entry != NULL); const Object* obj = entry->object(); gold_assert(obj != NULL); - view_info.got_descriptor = (*p)->get_offset(); + view_info.got_descriptor = (*p)->get_file_index(); Got_visitor v(view_info); obj->for_all_local_got_entries(&v); } |