summaryrefslogtreecommitdiff
path: root/gold/incremental.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2011-05-26 18:44:27 +0000
committerCary Coutant <ccoutant@google.com>2011-05-26 18:44:27 +0000
commit89d8a36b24e188ccbb032c55e302425b94516e74 (patch)
treed2f12e016f2502c4a2a088ab09891d197565de9b /gold/incremental.cc
parentd8b344530cba74a754ec101ccdd8869b3a48ec90 (diff)
* 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.cc56
1 files changed, 49 insertions, 7 deletions
diff --git a/gold/incremental.cc b/gold/incremental.cc
index a27afeef1c..f4eb22c50b 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