* 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:
parent
d8b344530c
commit
89d8a36b24
@ -1,3 +1,33 @@
|
|||||||
|
2011-05-26 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
2011-05-24 David Meyer <pdox@google.com>
|
2011-05-24 David Meyer <pdox@google.com>
|
||||||
|
|
||||||
* dirsearch.cc (Dirsearch::find): Replace n1 and n2 parameters
|
* dirsearch.cc (Dirsearch::find): Replace n1 and n2 parameters
|
||||||
|
@ -153,6 +153,8 @@ dump_incremental_inputs(const char* argv0, const char* filename,
|
|||||||
input_file.get_first_dyn_reloc());
|
input_file.get_first_dyn_reloc());
|
||||||
printf(" Dynamic reloc count: %d\n",
|
printf(" Dynamic reloc count: %d\n",
|
||||||
input_file.get_dyn_reloc_count());
|
input_file.get_dyn_reloc_count());
|
||||||
|
printf(" COMDAT group count: %d\n",
|
||||||
|
input_file.get_comdat_group_count());
|
||||||
break;
|
break;
|
||||||
case INCREMENTAL_INPUT_ARCHIVE:
|
case INCREMENTAL_INPUT_ARCHIVE:
|
||||||
printf("Archive\n");
|
printf("Archive\n");
|
||||||
@ -212,6 +214,11 @@ dump_incremental_inputs(const char* argv0, const char* filename,
|
|||||||
static_cast<long long>(info.sh_size),
|
static_cast<long long>(info.sh_size),
|
||||||
info.name);
|
info.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ncomdat = input_file.get_comdat_group_count();
|
||||||
|
for (unsigned int i = 0; i < ncomdat; ++i)
|
||||||
|
printf(" Comdat group: %s\n",
|
||||||
|
input_file.get_comdat_group_signature(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a view of the .symtab section.
|
// Get a view of the .symtab section.
|
||||||
|
@ -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
|
// Record an input section SHNDX from object file OBJ.
|
||||||
// the object file to the archive. This is called by the
|
|
||||||
// Add_symbols task after finding out the type of the file.
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Incremental_inputs::report_input_section(Object* obj, unsigned int shndx,
|
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;
|
Stringpool::Key key = 0;
|
||||||
|
|
||||||
if (name != NULL)
|
if (name != NULL)
|
||||||
this->strtab_->add(name, true, &key);
|
this->strtab_->add(name, true, &key);
|
||||||
|
|
||||||
gold_assert(obj == this->current_object_);
|
gold_assert(obj == this->current_object_);
|
||||||
gold_assert(this->current_object_entry_ != NULL);
|
gold_assert(this->current_object_entry_ != NULL);
|
||||||
this->current_object_entry_->add_input_section(shndx, key, sh_size);
|
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
|
// Record that the input argument INPUT is a script SCRIPT. This is
|
||||||
// called by read_script after parsing the script and reading the list
|
// called by read_script after parsing the script and reading the list
|
||||||
// of inputs added by this script.
|
// 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);
|
gold_assert(entry != NULL);
|
||||||
(*p)->set_info_offset(info_offset);
|
(*p)->set_info_offset(info_offset);
|
||||||
// Input section count, global symbol count, local symbol offset,
|
// Input section count, global symbol count, local symbol offset,
|
||||||
// local symbol count, first dynamic reloc, dynamic reloc count.
|
// local symbol count, first dynamic reloc, dynamic reloc count,
|
||||||
info_offset += 24;
|
// comdat group count.
|
||||||
|
info_offset += 28;
|
||||||
// Each input section.
|
// Each input section.
|
||||||
info_offset += (entry->get_input_section_count()
|
info_offset += (entry->get_input_section_count()
|
||||||
* (8 + 2 * sizeof_addr));
|
* (8 + 2 * sizeof_addr));
|
||||||
// Each global symbol.
|
// Each global symbol.
|
||||||
const Object::Symbols* syms = entry->object()->get_global_symbols();
|
const Object::Symbols* syms = entry->object()->get_global_symbols();
|
||||||
info_offset += syms->size() * 20;
|
info_offset += syms->size() * 20;
|
||||||
|
// Each comdat group.
|
||||||
|
info_offset += entry->get_comdat_group_count() * 4;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case INCREMENTAL_INPUT_SHARED_LIBRARY:
|
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 nlocals = relobj->output_local_symbol_count();
|
||||||
unsigned int first_dynrel = relobj->first_dyn_reloc();
|
unsigned int first_dynrel = relobj->first_dyn_reloc();
|
||||||
unsigned int ndynrel = relobj->dyn_reloc_count();
|
unsigned int ndynrel = relobj->dyn_reloc_count();
|
||||||
|
unsigned int ncomdat = entry->get_comdat_group_count();
|
||||||
Swap32::writeval(pov, nsections);
|
Swap32::writeval(pov, nsections);
|
||||||
Swap32::writeval(pov + 4, nsyms);
|
Swap32::writeval(pov + 4, nsyms);
|
||||||
Swap32::writeval(pov + 8, static_cast<unsigned int>(locals_offset));
|
Swap32::writeval(pov + 8, static_cast<unsigned int>(locals_offset));
|
||||||
Swap32::writeval(pov + 12, nlocals);
|
Swap32::writeval(pov + 12, nlocals);
|
||||||
Swap32::writeval(pov + 16, first_dynrel);
|
Swap32::writeval(pov + 16, first_dynrel);
|
||||||
Swap32::writeval(pov + 20, ndynrel);
|
Swap32::writeval(pov + 20, ndynrel);
|
||||||
pov += 24;
|
Swap32::writeval(pov + 24, ncomdat);
|
||||||
|
pov += 28;
|
||||||
|
|
||||||
// Build a temporary array to map input section indexes
|
// Build a temporary array to map input section indexes
|
||||||
// from the original object file index to the index in the
|
// 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;
|
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;
|
delete[] index_map;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1862,6 +1890,20 @@ Sized_relobj_incr<size, big_endian>::do_layout(
|
|||||||
out_sections[i] = os;
|
out_sections[i] = os;
|
||||||
this->section_offsets()[i] = static_cast<Address>(sect.sh_offset);
|
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
|
// Layout sections whose layout was deferred while waiting for
|
||||||
|
@ -325,7 +325,7 @@ class Incremental_object_entry : public Incremental_input_entry
|
|||||||
Incremental_object_entry(Stringpool::Key filename_key, Object* obj,
|
Incremental_object_entry(Stringpool::Key filename_key, Object* obj,
|
||||||
unsigned int arg_serial, Timespec mtime)
|
unsigned int arg_serial, Timespec mtime)
|
||||||
: Incremental_input_entry(filename_key, arg_serial, mtime), obj_(obj),
|
: Incremental_input_entry(filename_key, arg_serial, mtime), obj_(obj),
|
||||||
is_member_(false), sections_()
|
is_member_(false), sections_(), groups_()
|
||||||
{ this->sections_.reserve(obj->shnum()); }
|
{ this->sections_.reserve(obj->shnum()); }
|
||||||
|
|
||||||
// Get the object.
|
// Get the object.
|
||||||
@ -368,6 +368,21 @@ class Incremental_object_entry : public Incremental_input_entry
|
|||||||
get_input_section_size(unsigned int n) const
|
get_input_section_size(unsigned int n) const
|
||||||
{ return this->sections_[n].sh_size_; }
|
{ return this->sections_[n].sh_size_; }
|
||||||
|
|
||||||
|
// Add a kept COMDAT group.
|
||||||
|
void
|
||||||
|
add_comdat_group(Stringpool::Key signature_key)
|
||||||
|
{ this->groups_.push_back(signature_key); }
|
||||||
|
|
||||||
|
// Return the number of COMDAT groups.
|
||||||
|
unsigned int
|
||||||
|
get_comdat_group_count() const
|
||||||
|
{ return this->groups_.size(); }
|
||||||
|
|
||||||
|
// Return the stringpool key for the signature of the Nth comdat group.
|
||||||
|
Stringpool::Key
|
||||||
|
get_comdat_signature_key(unsigned int n) const
|
||||||
|
{ return this->groups_[n]; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual Incremental_input_type
|
virtual Incremental_input_type
|
||||||
do_type() const
|
do_type() const
|
||||||
@ -400,6 +415,9 @@ class Incremental_object_entry : public Incremental_input_entry
|
|||||||
off_t sh_size_;
|
off_t sh_size_;
|
||||||
};
|
};
|
||||||
std::vector<Input_section> sections_;
|
std::vector<Input_section> sections_;
|
||||||
|
|
||||||
|
// COMDAT groups.
|
||||||
|
std::vector<Stringpool::Key> groups_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Class for recording shared library input files.
|
// Class for recording shared library input files.
|
||||||
@ -546,6 +564,10 @@ class Incremental_inputs
|
|||||||
report_input_section(Object* obj, unsigned int shndx, const char* name,
|
report_input_section(Object* obj, unsigned int shndx, const char* name,
|
||||||
off_t sh_size);
|
off_t sh_size);
|
||||||
|
|
||||||
|
// Record a kept COMDAT group belonging to object file OBJ.
|
||||||
|
void
|
||||||
|
report_comdat_group(Object* obj, const char* name);
|
||||||
|
|
||||||
// Record the info for input script SCRIPT.
|
// Record the info for input script SCRIPT.
|
||||||
void
|
void
|
||||||
report_script(Script_info* script, unsigned int arg_serial,
|
report_script(Script_info* script, unsigned int arg_serial,
|
||||||
@ -814,7 +836,7 @@ class Incremental_inputs_reader
|
|||||||
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
|
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
|
||||||
|
|
||||||
unsigned int section_count = this->get_input_section_count();
|
unsigned int section_count = this->get_input_section_count();
|
||||||
return (this->info_offset_ + 24
|
return (this->info_offset_ + 28
|
||||||
+ section_count * input_section_entry_size
|
+ section_count * input_section_entry_size
|
||||||
+ symndx * 20);
|
+ symndx * 20);
|
||||||
}
|
}
|
||||||
@ -869,6 +891,16 @@ class Incremental_inputs_reader
|
|||||||
return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 20);
|
return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 20);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the COMDAT group count -- for objects only.
|
||||||
|
unsigned int
|
||||||
|
get_comdat_group_count() const
|
||||||
|
{
|
||||||
|
gold_assert(this->type() == INCREMENTAL_INPUT_OBJECT
|
||||||
|
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
|
||||||
|
|
||||||
|
return Swap32::readval(this->inputs_->p_ + this->info_offset_ + 24);
|
||||||
|
}
|
||||||
|
|
||||||
// Return the object count -- for scripts only.
|
// Return the object count -- for scripts only.
|
||||||
unsigned int
|
unsigned int
|
||||||
get_object_count() const
|
get_object_count() const
|
||||||
@ -939,7 +971,7 @@ class Incremental_inputs_reader
|
|||||||
{
|
{
|
||||||
Input_section_info info;
|
Input_section_info info;
|
||||||
const unsigned char* p = (this->inputs_->p_
|
const unsigned char* p = (this->inputs_->p_
|
||||||
+ this->info_offset_ + 24
|
+ this->info_offset_ + 28
|
||||||
+ n * input_section_entry_size);
|
+ n * input_section_entry_size);
|
||||||
unsigned int name_offset = Swap32::readval(p);
|
unsigned int name_offset = Swap32::readval(p);
|
||||||
info.name = this->inputs_->get_string(name_offset);
|
info.name = this->inputs_->get_string(name_offset);
|
||||||
@ -957,12 +989,27 @@ class Incremental_inputs_reader
|
|||||||
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
|
|| this->type() == INCREMENTAL_INPUT_ARCHIVE_MEMBER);
|
||||||
unsigned int section_count = this->get_input_section_count();
|
unsigned int section_count = this->get_input_section_count();
|
||||||
const unsigned char* p = (this->inputs_->p_
|
const unsigned char* p = (this->inputs_->p_
|
||||||
+ this->info_offset_ + 24
|
+ this->info_offset_ + 28
|
||||||
+ section_count * input_section_entry_size
|
+ section_count * input_section_entry_size
|
||||||
+ n * 20);
|
+ n * 20);
|
||||||
return Incremental_global_symbol_reader<big_endian>(p);
|
return Incremental_global_symbol_reader<big_endian>(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the signature of the Nth comdat group -- for objects only.
|
||||||
|
const char*
|
||||||
|
get_comdat_group_signature(unsigned int n) const
|
||||||
|
{
|
||||||
|
unsigned int section_count = this->get_input_section_count();
|
||||||
|
unsigned int symbol_count = this->get_global_symbol_count();
|
||||||
|
const unsigned char* p = (this->inputs_->p_
|
||||||
|
+ this->info_offset_ + 28
|
||||||
|
+ section_count * input_section_entry_size
|
||||||
|
+ symbol_count * 20
|
||||||
|
+ n * 4);
|
||||||
|
unsigned int name_offset = Swap32::readval(p);
|
||||||
|
return this->inputs_->get_string(name_offset);
|
||||||
|
}
|
||||||
|
|
||||||
// Return the output symbol index for the Nth global symbol -- for shared
|
// Return the output symbol index for the Nth global symbol -- for shared
|
||||||
// libraries only. Sets *IS_DEF to TRUE if the symbol is defined in this
|
// libraries only. Sets *IS_DEF to TRUE if the symbol is defined in this
|
||||||
// input file.
|
// input file.
|
||||||
|
@ -825,6 +825,13 @@ Sized_relobj_file<size, big_endian>::include_section_group(
|
|||||||
is_comdat = true;
|
is_comdat = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_comdat && include_group)
|
||||||
|
{
|
||||||
|
Incremental_inputs* incremental_inputs = layout->incremental_inputs();
|
||||||
|
if (incremental_inputs != NULL)
|
||||||
|
incremental_inputs->report_comdat_group(this, signature.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
size_t count = shdr.get_sh_size() / sizeof(elfcpp::Elf_Word);
|
size_t count = shdr.get_sh_size() / sizeof(elfcpp::Elf_Word);
|
||||||
|
|
||||||
std::vector<unsigned int> shndxes;
|
std::vector<unsigned int> shndxes;
|
||||||
|
Loading…
Reference in New Issue
Block a user