diff options
author | Cary Coutant <ccoutant@google.com> | 2011-05-26 18:44:27 +0000 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2011-05-26 18:44:27 +0000 |
commit | 89d8a36b24e188ccbb032c55e302425b94516e74 (patch) | |
tree | d2f12e016f2502c4a2a088ab09891d197565de9b /gold/incremental.cc | |
parent | d8b344530cba74a754ec101ccdd8869b3a48ec90 (diff) | |
download | fsf-binutils-gdb-89d8a36b24e188ccbb032c55e302425b94516e74.zip fsf-binutils-gdb-89d8a36b24e188ccbb032c55e302425b94516e74.tar.gz fsf-binutils-gdb-89d8a36b24e188ccbb032c55e302425b94516e74.tar.bz2 |
* incremental-dump.cc (dump_incremental_inputs): Print COMDAT groups.
* incremental.cc (Incremental_inputs::report_input_section): Fix
comment, indentation.
(Incremental_inputs::report_comdat_group): New function.
(Output_section_incremental_inputs::set_final_data_size): Adjust size
of data for incremental input file entry.
(Output_section_incremental_inputs::write_info_blocks): Write COMDAT
group count, COMDAT group signatures.
(Sized_incr_relobj::do_layout): Record kept COMDAT group info from
an unchanged input file.
* incremental.h (Incremental_object_entry::Incremental_object_entry):
Initialize new data member.
(Incremental_object_entry::add_comdat_group): New function.
(Incremental_object_entry::get_comdat_group_count): New function.
(Incremental_object_entry::get_comdat_signature_key): New function.
(Incremental_object_entry::groups_): New data member.
(Incremental_inputs::report_comdat_group): New function.
(Incremental_input_entry_reader::get_symbol_offset): Adjust size of
data for incremental input file entry.
(Incremental_input_entry_reader::get_comdat_group_count): New function.
(Incremental_input_entry_reader::get_input_section): Adjust size of
data for incremental input file entry.
(Incremental_input_entry_reader::get_global_symbol_reader): Likewise.
(Incremental_input_entry_reader::get_comdat_group_signature): New
function.
* object.cc (Sized_relobj::include_section_group): Report kept
COMDAT groups for incremental links.
Diffstat (limited to 'gold/incremental.cc')
-rw-r--r-- | gold/incremental.cc | 56 |
1 files changed, 49 insertions, 7 deletions
diff --git a/gold/incremental.cc b/gold/incremental.cc index a27afee..f4eb22c 100644 --- a/gold/incremental.cc +++ b/gold/incremental.cc @@ -1028,9 +1028,7 @@ Incremental_inputs::report_object(Object* obj, unsigned int arg_serial, } } -// Record the input object file OBJ. If ARCH is not NULL, attach -// the object file to the archive. This is called by the -// Add_symbols task after finding out the type of the file. +// Record an input section SHNDX from object file OBJ. void Incremental_inputs::report_input_section(Object* obj, unsigned int shndx, @@ -1039,13 +1037,27 @@ Incremental_inputs::report_input_section(Object* obj, unsigned int shndx, Stringpool::Key key = 0; if (name != NULL) - this->strtab_->add(name, true, &key); + this->strtab_->add(name, true, &key); gold_assert(obj == this->current_object_); gold_assert(this->current_object_entry_ != NULL); this->current_object_entry_->add_input_section(shndx, key, sh_size); } +// Record a kept COMDAT group belonging to object file OBJ. + +void +Incremental_inputs::report_comdat_group(Object* obj, const char* name) +{ + Stringpool::Key key = 0; + + if (name != NULL) + this->strtab_->add(name, true, &key); + gold_assert(obj == this->current_object_); + gold_assert(this->current_object_entry_ != NULL); + this->current_object_entry_->add_comdat_group(key); +} + // Record that the input argument INPUT is a script SCRIPT. This is // called by read_script after parsing the script and reading the list // of inputs added by this script. @@ -1173,14 +1185,17 @@ Output_section_incremental_inputs<size, big_endian>::set_final_data_size() gold_assert(entry != NULL); (*p)->set_info_offset(info_offset); // Input section count, global symbol count, local symbol offset, - // local symbol count, first dynamic reloc, dynamic reloc count. - info_offset += 24; + // local symbol count, first dynamic reloc, dynamic reloc count, + // comdat group count. + info_offset += 28; // Each input section. info_offset += (entry->get_input_section_count() * (8 + 2 * sizeof_addr)); // Each global symbol. const Object::Symbols* syms = entry->object()->get_global_symbols(); info_offset += syms->size() * 20; + // Each comdat group. + info_offset += entry->get_comdat_group_count() * 4; } break; case INCREMENTAL_INPUT_SHARED_LIBRARY: @@ -1424,13 +1439,15 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks( unsigned int nlocals = relobj->output_local_symbol_count(); unsigned int first_dynrel = relobj->first_dyn_reloc(); unsigned int ndynrel = relobj->dyn_reloc_count(); + unsigned int ncomdat = entry->get_comdat_group_count(); Swap32::writeval(pov, nsections); Swap32::writeval(pov + 4, nsyms); Swap32::writeval(pov + 8, static_cast<unsigned int>(locals_offset)); Swap32::writeval(pov + 12, nlocals); Swap32::writeval(pov + 16, first_dynrel); Swap32::writeval(pov + 20, ndynrel); - pov += 24; + Swap32::writeval(pov + 24, ncomdat); + pov += 28; // Build a temporary array to map input section indexes // from the original object file index to the index in the @@ -1507,6 +1524,17 @@ Output_section_incremental_inputs<size, big_endian>::write_info_blocks( pov += 20; } + // For each kept COMDAT group, write the group signature. + for (unsigned int i = 0; i < ncomdat; i++) + { + Stringpool::Key key = entry->get_comdat_signature_key(i); + off_t name_offset = 0; + if (key != 0) + name_offset = strtab->get_offset_from_key(key); + Swap32::writeval(pov, name_offset); + pov += 4; + } + delete[] index_map; } break; @@ -1862,6 +1890,20 @@ Sized_relobj_incr<size, big_endian>::do_layout( out_sections[i] = os; this->section_offsets()[i] = static_cast<Address>(sect.sh_offset); } + + // Process the COMDAT groups. + unsigned int ncomdat = this->input_reader_.get_comdat_group_count(); + for (unsigned int i = 0; i < ncomdat; i++) + { + const char* signature = this->input_reader_.get_comdat_group_signature(i); + if (signature == NULL || signature[0] == '\0') + this->error(_("COMDAT group has no signature")); + bool keep = layout->find_or_add_kept_section(signature, this, i, true, + true, NULL); + if (!keep) + this->error(_("COMDAT group %s included twice in incremental link"), + signature); + } } // Layout sections whose layout was deferred while waiting for |