* 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.
This commit is contained in:
Cary Coutant
2011-05-26 18:44:27 +00:00
parent d8b344530c
commit 89d8a36b24
5 changed files with 144 additions and 11 deletions

View File

@@ -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