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/output.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/output.cc')
-rw-r--r-- | gold/output.cc | 173 |
1 files changed, 113 insertions, 60 deletions
diff --git a/gold/output.cc b/gold/output.cc index 70379bb..c3053db 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -1358,6 +1358,13 @@ Output_data_got<size, big_endian>::Got_entry::write(unsigned char* pov) const val = this->u_.constant; break; + case RESERVED_CODE: + // If we're doing an incremental update, don't touch this GOT entry. + if (parameters->incremental_update()) + return; + val = this->u_.constant; + break; + default: { const Sized_relobj<size, big_endian>* object = this->u_.object; @@ -1393,9 +1400,8 @@ Output_data_got<size, big_endian>::add_global( if (gsym->has_got_offset(got_type)) return false; - this->entries_.push_back(Got_entry(gsym, false)); - this->set_got_size(); - gsym->set_got_offset(got_type, this->last_got_offset()); + unsigned int got_offset = this->add_got_entry(Got_entry(gsym, false)); + gsym->set_got_offset(got_type, got_offset); return true; } @@ -1409,9 +1415,8 @@ Output_data_got<size, big_endian>::add_global_plt(Symbol* gsym, if (gsym->has_got_offset(got_type)) return false; - this->entries_.push_back(Got_entry(gsym, true)); - this->set_got_size(); - gsym->set_got_offset(got_type, this->last_got_offset()); + unsigned int got_offset = this->add_got_entry(Got_entry(gsym, true)); + gsym->set_got_offset(got_type, got_offset); return true; } @@ -1429,9 +1434,7 @@ Output_data_got<size, big_endian>::add_global_with_rel( if (gsym->has_got_offset(got_type)) return; - this->entries_.push_back(Got_entry()); - this->set_got_size(); - unsigned int got_offset = this->last_got_offset(); + unsigned int got_offset = this->add_got_entry(Got_entry()); gsym->set_got_offset(got_type, got_offset); rel_dyn->add_global(gsym, r_type, this, got_offset); } @@ -1447,9 +1450,7 @@ Output_data_got<size, big_endian>::add_global_with_rela( if (gsym->has_got_offset(got_type)) return; - this->entries_.push_back(Got_entry()); - this->set_got_size(); - unsigned int got_offset = this->last_got_offset(); + unsigned int got_offset = this->add_got_entry(Got_entry()); gsym->set_got_offset(got_type, got_offset); rela_dyn->add_global(gsym, r_type, this, got_offset, 0); } @@ -1469,19 +1470,12 @@ Output_data_got<size, big_endian>::add_global_pair_with_rel( if (gsym->has_got_offset(got_type)) return; - this->entries_.push_back(Got_entry()); - unsigned int got_offset = this->last_got_offset(); + unsigned int got_offset = this->add_got_entry_pair(Got_entry(), Got_entry()); gsym->set_got_offset(got_type, got_offset); rel_dyn->add_global(gsym, r_type_1, this, got_offset); - this->entries_.push_back(Got_entry()); if (r_type_2 != 0) - { - got_offset = this->last_got_offset(); - rel_dyn->add_global(gsym, r_type_2, this, got_offset); - } - - this->set_got_size(); + rel_dyn->add_global(gsym, r_type_2, this, got_offset + size / 8); } template<int size, bool big_endian> @@ -1496,19 +1490,12 @@ Output_data_got<size, big_endian>::add_global_pair_with_rela( if (gsym->has_got_offset(got_type)) return; - this->entries_.push_back(Got_entry()); - unsigned int got_offset = this->last_got_offset(); + unsigned int got_offset = this->add_got_entry_pair(Got_entry(), Got_entry()); gsym->set_got_offset(got_type, got_offset); rela_dyn->add_global(gsym, r_type_1, this, got_offset, 0); - this->entries_.push_back(Got_entry()); if (r_type_2 != 0) - { - got_offset = this->last_got_offset(); - rela_dyn->add_global(gsym, r_type_2, this, got_offset, 0); - } - - this->set_got_size(); + rela_dyn->add_global(gsym, r_type_2, this, got_offset + size / 8, 0); } // Add an entry for a local symbol to the GOT. This returns true if @@ -1525,9 +1512,9 @@ Output_data_got<size, big_endian>::add_local( if (object->local_has_got_offset(symndx, got_type)) return false; - this->entries_.push_back(Got_entry(object, symndx, false)); - this->set_got_size(); - object->set_local_got_offset(symndx, got_type, this->last_got_offset()); + unsigned int got_offset = this->add_got_entry(Got_entry(object, symndx, + false)); + object->set_local_got_offset(symndx, got_type, got_offset); return true; } @@ -1543,9 +1530,9 @@ Output_data_got<size, big_endian>::add_local_plt( if (object->local_has_got_offset(symndx, got_type)) return false; - this->entries_.push_back(Got_entry(object, symndx, true)); - this->set_got_size(); - object->set_local_got_offset(symndx, got_type, this->last_got_offset()); + unsigned int got_offset = this->add_got_entry(Got_entry(object, symndx, + true)); + object->set_local_got_offset(symndx, got_type, got_offset); return true; } @@ -1564,9 +1551,7 @@ Output_data_got<size, big_endian>::add_local_with_rel( if (object->local_has_got_offset(symndx, got_type)) return; - this->entries_.push_back(Got_entry()); - this->set_got_size(); - unsigned int got_offset = this->last_got_offset(); + unsigned int got_offset = this->add_got_entry(Got_entry()); object->set_local_got_offset(symndx, got_type, got_offset); rel_dyn->add_local(object, symndx, r_type, this, got_offset); } @@ -1583,9 +1568,7 @@ Output_data_got<size, big_endian>::add_local_with_rela( if (object->local_has_got_offset(symndx, got_type)) return; - this->entries_.push_back(Got_entry()); - this->set_got_size(); - unsigned int got_offset = this->last_got_offset(); + unsigned int got_offset = this->add_got_entry(Got_entry()); object->set_local_got_offset(symndx, got_type, got_offset); rela_dyn->add_local(object, symndx, r_type, this, got_offset, 0); } @@ -1607,20 +1590,15 @@ Output_data_got<size, big_endian>::add_local_pair_with_rel( if (object->local_has_got_offset(symndx, got_type)) return; - this->entries_.push_back(Got_entry()); - unsigned int got_offset = this->last_got_offset(); + unsigned int got_offset = + this->add_got_entry_pair(Got_entry(), + Got_entry(object, symndx, false)); object->set_local_got_offset(symndx, got_type, got_offset); Output_section* os = object->output_section(shndx); rel_dyn->add_output_section(os, r_type_1, this, got_offset); - this->entries_.push_back(Got_entry(object, symndx, false)); if (r_type_2 != 0) - { - got_offset = this->last_got_offset(); - rel_dyn->add_output_section(os, r_type_2, this, got_offset); - } - - this->set_got_size(); + rel_dyn->add_output_section(os, r_type_2, this, got_offset + size / 8); } template<int size, bool big_endian> @@ -1637,20 +1615,37 @@ Output_data_got<size, big_endian>::add_local_pair_with_rela( if (object->local_has_got_offset(symndx, got_type)) return; - this->entries_.push_back(Got_entry()); - unsigned int got_offset = this->last_got_offset(); + unsigned int got_offset = + this->add_got_entry_pair(Got_entry(), + Got_entry(object, symndx, false)); object->set_local_got_offset(symndx, got_type, got_offset); Output_section* os = object->output_section(shndx); rela_dyn->add_output_section(os, r_type_1, this, got_offset, 0); - this->entries_.push_back(Got_entry(object, symndx, false)); if (r_type_2 != 0) - { - got_offset = this->last_got_offset(); - rela_dyn->add_output_section(os, r_type_2, this, got_offset, 0); - } + rela_dyn->add_output_section(os, r_type_2, this, got_offset + size / 8, 0); +} + +// Reserve a slot in the GOT for a local symbol or the second slot of a pair. - this->set_got_size(); +template<int size, bool big_endian> +void +Output_data_got<size, big_endian>::reserve_slot(unsigned int i) +{ + this->free_list_.remove(i * size / 8, (i + 1) * size / 8); +} + +// Reserve a slot in the GOT for a global symbol. + +template<int size, bool big_endian> +void +Output_data_got<size, big_endian>::reserve_slot_for_global( + unsigned int i, + Symbol* gsym, + unsigned int got_type) +{ + this->free_list_.remove(i * size / 8, (i + 1) * size / 8); + gsym->set_got_offset(got_type, this->got_offset(i)); } // Write out the GOT. @@ -1682,6 +1677,63 @@ Output_data_got<size, big_endian>::do_write(Output_file* of) this->entries_.clear(); } +// Create a new GOT entry and return its offset. + +template<int size, bool big_endian> +unsigned int +Output_data_got<size, big_endian>::add_got_entry(Got_entry got_entry) +{ + if (!this->is_data_size_valid()) + { + this->entries_.push_back(got_entry); + this->set_got_size(); + return this->last_got_offset(); + } + else + { + // For an incremental update, find an available slot. + off_t got_offset = this->free_list_.allocate(size / 8, size / 8, 0); + if (got_offset == -1) + gold_fatal(_("out of patch space (GOT);" + " relink with --incremental-full")); + unsigned int got_index = got_offset / (size / 8); + gold_assert(got_index < this->entries_.size()); + this->entries_[got_index] = got_entry; + return static_cast<unsigned int>(got_offset); + } +} + +// Create a pair of new GOT entries and return the offset of the first. + +template<int size, bool big_endian> +unsigned int +Output_data_got<size, big_endian>::add_got_entry_pair(Got_entry got_entry_1, + Got_entry got_entry_2) +{ + if (!this->is_data_size_valid()) + { + unsigned int got_offset; + this->entries_.push_back(got_entry_1); + got_offset = this->last_got_offset(); + this->entries_.push_back(got_entry_2); + this->set_got_size(); + return got_offset; + } + else + { + // For an incremental update, find an available pair of slots. + off_t got_offset = this->free_list_.allocate(2 * size / 8, size / 8, 0); + if (got_offset == -1) + gold_fatal(_("out of patch space (GOT);" + " relink with --incremental-full")); + unsigned int got_index = got_offset / (size / 8); + gold_assert(got_index < this->entries_.size()); + this->entries_[got_index] = got_entry_1; + this->entries_[got_index + 1] = got_entry_2; + return static_cast<unsigned int>(got_offset); + } +} + // Output_data_dynamic::Dynamic_entry methods. // Write out the entry. @@ -2335,7 +2387,8 @@ Output_section::add_output_section_data(Output_section_data* posd) uint64_t addr = this->address(); posd->set_address(addr); posd->set_file_offset(0); - // FIXME: Mark *POSD as part of a fixed-layout section. + // FIXME: This should eventually be unreachable. + // gold_unreachable(); } } |