2013-07-22 Sterling Augustine <saugustine@google.com>

* dwarf_reader.cc (Dwarf_pubnames_table::read_section):
	Convert parameter shndx to local variable. Add parameters symtab
	and symtab_size.  Scan over section names.  Find relocation
	section corresponding to current section.  Create and initialize
	reloc_mapper_ and reloc_type_.
	(Dwarf_pubnames_table::read_header):  Add assertion.  Change
	unit_length to off_t.  Initialize member unit_length_.  Fill in field
	cu_offset_.
	* dwarf_reader.h (Dwarf_pubnames_table::Dwarf_pubnames_table):
	Initialize new fields unit_length_ and cu_offset_.
	(Dwarf_pubnames_table::read_section): Update prototype.
	(Dwarf_pubnames_table::cu_offset): New member function.
	(Dwarf_pubnames_table::subsection_size): Likewise.
	(Dwarf_pubnames_table::cu_offset_, Dwarf_pubnames_table::unit_length):
	New fields.
	(Dwarf_info_reader::symtab, Dwarf_info_reader::symtab_size): Make
	member functions public.
	* gdb_index.cc (Gdb_index_info_reader::read_pubnames_and_pubtypes):
	Update comment.  Rework logic.  Move repeated parts to...
	(Gdb_index_info_reader::read_pubtable): ...here. New function.
	(Gdb_index::Gdb_index): Initialize new fields, pubnames_table_,
	pubtypes_table_, and stmt_list_offset.
	(Gdb_index::map_pubtable_to_dies, Gdb_index::find_pubname_offset,
	Gdb_index::find_pubtype_offset,
	Gdb_index::map_pubnames_and_types_to_dies): Define new functions.
	(Gdb_index::pubnames_read): Update prototype and rework logic.
	* gdb_index.h (Gdb_index_info_reader, Dwarf_pubnames_table):
	Forward declare.
	(Gdb_index::map_pubtable_to_dies, Gdb_index::find_pubname_offset,
	Gdb_index::find_pubtype_offset, Gdb_index::pubnames_table)
	Gdb_index::pubtypes_table, Gdb_index::map_pubnames_and_types_to_dies,
	Gdb_index::map_pubtable_to_dies):
	Declare functions.
	(Gdb_index::pubnames_read): Update declaration.
	(Gdb_index::Pubname_offset_map): New type.
	(Gdb_index::cu_pubname_map_, Gdb_index::cu_pubtype_map_,
	Gdb_index::pubnames_table_, Gdb_index::pubtypes_table_,
	Gdb_index::stmt_list_offset): Declare.
	(Gdb_index::pubnames_shndx_, Gdb_index::pubnames_offet_,
	Gdb_index::pubtypes_object_, Gdb_index::pubtypes_shndx_)
	Gdb_index::pubtypes_offset_): Remove.
This commit is contained in:
Sterling Augustine 2013-07-29 18:29:12 +00:00
parent c8f30dac8c
commit 234d4ab880
5 changed files with 375 additions and 124 deletions

View File

@ -1,3 +1,47 @@
2013-07-22 Sterling Augustine <saugustine@google.com>
* dwarf_reader.cc (Dwarf_pubnames_table::read_section):
Convert parameter shndx to local variable. Add parameters symtab
and symtab_size. Scan over section names. Find relocation
section corresponding to current section. Create and initialize
reloc_mapper_ and reloc_type_.
(Dwarf_pubnames_table::read_header): Add assertion. Change
unit_length to off_t. Initialize member unit_length_. Fill in field
cu_offset_.
* dwarf_reader.h (Dwarf_pubnames_table::Dwarf_pubnames_table):
Initialize new fields unit_length_ and cu_offset_.
(Dwarf_pubnames_table::read_section): Update prototype.
(Dwarf_pubnames_table::cu_offset): New member function.
(Dwarf_pubnames_table::subsection_size): Likewise.
(Dwarf_pubnames_table::cu_offset_, Dwarf_pubnames_table::unit_length):
New fields.
(Dwarf_info_reader::symtab, Dwarf_info_reader::symtab_size): Make
member functions public.
* gdb_index.cc (Gdb_index_info_reader::read_pubnames_and_pubtypes):
Update comment. Rework logic. Move repeated parts to...
(Gdb_index_info_reader::read_pubtable): ...here. New function.
(Gdb_index::Gdb_index): Initialize new fields, pubnames_table_,
pubtypes_table_, and stmt_list_offset.
(Gdb_index::map_pubtable_to_dies, Gdb_index::find_pubname_offset,
Gdb_index::find_pubtype_offset,
Gdb_index::map_pubnames_and_types_to_dies): Define new functions.
(Gdb_index::pubnames_read): Update prototype and rework logic.
* gdb_index.h (Gdb_index_info_reader, Dwarf_pubnames_table):
Forward declare.
(Gdb_index::map_pubtable_to_dies, Gdb_index::find_pubname_offset,
Gdb_index::find_pubtype_offset, Gdb_index::pubnames_table)
Gdb_index::pubtypes_table, Gdb_index::map_pubnames_and_types_to_dies,
Gdb_index::map_pubtable_to_dies):
Declare functions.
(Gdb_index::pubnames_read): Update declaration.
(Gdb_index::Pubname_offset_map): New type.
(Gdb_index::cu_pubname_map_, Gdb_index::cu_pubtype_map_,
Gdb_index::pubnames_table_, Gdb_index::pubtypes_table_,
Gdb_index::stmt_list_offset): Declare.
(Gdb_index::pubnames_shndx_, Gdb_index::pubnames_offet_,
Gdb_index::pubtypes_object_, Gdb_index::pubtypes_shndx_)
Gdb_index::pubtypes_offset_): Remove.
2013-07-19 Roland McGrath <mcgrathr@google.com>
* options.h (General_options): Add -Trodata-segment option.

View File

@ -478,32 +478,31 @@ Dwarf_ranges_table::lookup_reloc(off_t off, off_t* target_off)
// class Dwarf_pubnames_table
// Read the pubnames section SHNDX from the object file.
// Read the pubnames section from the object file.
bool
Dwarf_pubnames_table::read_section(Relobj* object, unsigned int shndx)
Dwarf_pubnames_table::read_section(Relobj* object, const unsigned char* symtab,
off_t symtab_size)
{
section_size_type buffer_size;
unsigned int shndx = 0;
// If we don't have relocations, shndx will be 0, and
// we'll have to hunt for the .debug_pubnames/pubtypes section.
if (shndx == 0)
// Find the .debug_pubnames/pubtypes section.
const char* name = (this->is_pubtypes_
? ".debug_pubtypes"
: ".debug_pubnames");
for (unsigned int i = 1; i < object->shnum(); ++i)
{
const char* name = (this->is_pubtypes_
? ".debug_pubtypes"
: ".debug_pubnames");
for (unsigned int i = 1; i < object->shnum(); ++i)
{
if (object->section_name(i) == name)
{
shndx = i;
this->output_section_offset_ = object->output_section_offset(i);
break;
}
}
if (shndx == 0)
return false;
if (object->section_name(i) == name)
{
shndx = i;
this->output_section_offset_ = object->output_section_offset(i);
break;
}
}
if (shndx == 0)
return false;
this->buffer_ = object->decompressed_section_contents(shndx,
&buffer_size,
@ -511,6 +510,30 @@ Dwarf_pubnames_table::read_section(Relobj* object, unsigned int shndx)
if (this->buffer_ == NULL)
return false;
this->buffer_end_ = this->buffer_ + buffer_size;
// For incremental objects, we have no relocations.
if (object->is_incremental())
return true;
// Find the relocation section
unsigned int reloc_shndx = 0;
unsigned int reloc_type = 0;
for (unsigned int i = 0; i < object->shnum(); ++i)
{
reloc_type = object->section_type(i);
if ((reloc_type == elfcpp::SHT_REL
|| reloc_type == elfcpp::SHT_RELA)
&& object->section_info(i) == shndx)
{
reloc_shndx = i;
break;
}
}
this->reloc_mapper_ = make_elf_reloc_mapper(object, symtab, symtab_size);
this->reloc_mapper_->initialize(reloc_shndx, reloc_type);
this->reloc_type_ = reloc_type;
return true;
}
@ -519,6 +542,9 @@ Dwarf_pubnames_table::read_section(Relobj* object, unsigned int shndx)
bool
Dwarf_pubnames_table::read_header(off_t offset)
{
// Make sure we have actually read the section.
gold_assert(this->buffer_ != NULL);
// Correct the offset. For incremental update links, we have a
// relocated offset that is relative to the output section, but
// here we need an offset relative to the input section.
@ -530,16 +556,20 @@ Dwarf_pubnames_table::read_header(off_t offset)
const unsigned char* pinfo = this->buffer_ + offset;
// Read the unit_length field.
uint32_t unit_length = this->dwinfo_->read_from_pointer<32>(pinfo);
uint64_t unit_length = this->dwinfo_->read_from_pointer<32>(pinfo);
pinfo += 4;
if (unit_length == 0xffffffff)
{
unit_length = this->dwinfo_->read_from_pointer<64>(pinfo);
this->unit_length_ = unit_length + 12;
pinfo += 8;
this->offset_size_ = 8;
}
else
this->offset_size_ = 4;
{
this->unit_length_ = unit_length + 4;
this->offset_size_ = 4;
}
// Check the version.
unsigned int version = this->dwinfo_->read_from_pointer<16>(pinfo);
@ -547,6 +577,9 @@ Dwarf_pubnames_table::read_header(off_t offset)
if (version != 2)
return false;
this->reloc_mapper_->get_reloc_target(pinfo - this->buffer_,
&this->cu_offset_);
// Skip the debug_info_offset and debug_info_size fields.
pinfo += 2 * this->offset_size_;

View File

@ -400,7 +400,7 @@ class Dwarf_pubnames_table
Dwarf_pubnames_table(Dwarf_info_reader* dwinfo, bool is_pubtypes)
: dwinfo_(dwinfo), buffer_(NULL), buffer_end_(NULL), owns_buffer_(false),
offset_size_(0), pinfo_(NULL), is_pubtypes_(is_pubtypes),
output_section_offset_(0)
output_section_offset_(0), unit_length_(0), cu_offset_(0)
{ }
~Dwarf_pubnames_table()
@ -409,14 +409,27 @@ class Dwarf_pubnames_table
delete[] this->buffer_;
}
// Read the pubnames section SHNDX from the object file.
// Read the pubnames section from the object file, using the symbol
// table for relocating it.
bool
read_section(Relobj* object, unsigned int shndx);
read_section(Relobj* object, const unsigned char* symbol_table,
off_t symtab_size);
// Read the header for the set at OFFSET.
bool
read_header(off_t offset);
// Return the offset to the cu within the info or types section.
off_t
cu_offset()
{ return this->cu_offset_; }
// Return the size of this subsection of the table. The unit length
// doesn't include the size of its own field.
off_t
subsection_size()
{ return this->unit_length_; }
// Read the next name from the set.
const char*
next_name();
@ -440,6 +453,15 @@ class Dwarf_pubnames_table
// relocated data will be relative to the output section, and need
// to be corrected before reading data from the input section.
uint64_t output_section_offset_;
// Fields read from the header.
uint64_t unit_length_;
off_t cu_offset_;
// Track relocations for this table so we can find the CUs that
// correspond to the subsections.
Elf_reloc_mapper* reloc_mapper_;
// Type of the relocation section (SHT_REL or SHT_RELA).
unsigned int reloc_type_;
};
// This class represents a DWARF Debug Info Entry (DIE).
@ -747,6 +769,21 @@ class Dwarf_info_reader
set_abbrev_shndx(unsigned int abbrev_shndx)
{ this->abbrev_shndx_ = abbrev_shndx; }
// Return a pointer to the object file's ELF symbol table.
const unsigned char*
symtab() const
{ return this->symtab_; }
// Return the size of the object file's ELF symbol table.
off_t
symtab_size() const
{ return this->symtab_size_; }
// Return the offset of the current compilation unit.
off_t
cu_offset() const
{ return this->cu_offset_; }
protected:
// Begin parsing the debug info. This calls visit_compilation_unit()
// or visit_type_unit() for each compilation or type unit found in the
@ -785,16 +822,6 @@ class Dwarf_info_reader
object() const
{ return this->object_; }
// Return a pointer to the object file's ELF symbol table.
const unsigned char*
symtab() const
{ return this->symtab_; }
// Return the size of the object file's ELF symbol table.
off_t
symtab_size() const
{ return this->symtab_size_; }
// Checkpoint the relocation tracker.
uint64_t
get_reloc_checkpoint() const

View File

@ -273,10 +273,14 @@ class Gdb_index_info_reader : public Dwarf_info_reader
void
record_cu_ranges(Dwarf_die* die);
// Read the .debug_pubnames and .debug_pubtypes tables.
// Wrapper for read_pubtable.
bool
read_pubnames_and_pubtypes(Dwarf_die* die);
// Read the .debug_pubnames and .debug_pubtypes tables.
bool
read_pubtable(Dwarf_pubnames_table* table, off_t offset);
// Clear the declarations map.
void
clear_declarations();
@ -851,69 +855,86 @@ Gdb_index_info_reader::record_cu_ranges(Dwarf_die* die)
}
}
// Read table and add the relevant names to the index. Returns true
// if any names were added.
bool
Gdb_index_info_reader::read_pubtable(Dwarf_pubnames_table* table, off_t offset)
{
// If we couldn't read the section when building the cu_pubname_map,
// then we won't find any pubnames now.
if (table == NULL)
return false;
if (!table->read_header(offset))
return false;
while (true)
{
const char* name = table->next_name();
if (name == NULL)
break;
this->gdb_index_->add_symbol(this->cu_index_, name);
}
return true;
}
// Read the .debug_pubnames and .debug_pubtypes tables for the CU or TU.
// Returns TRUE if either a pubnames or pubtypes section was found.
bool
Gdb_index_info_reader::read_pubnames_and_pubtypes(Dwarf_die* die)
{
bool ret = false;
// We use stmt_list_off as a unique identifier for the
// compilation unit and its associated type units.
unsigned int shndx;
off_t stmt_list_off = die->ref_attribute (elfcpp::DW_AT_stmt_list,
&shndx);
// Look for the attr as either a flag or a ref.
off_t offset = die->ref_attribute(elfcpp::DW_AT_GNU_pubnames, &shndx);
// If we find a DW_AT_GNU_pubnames attribute, read the pubnames table.
unsigned int pubnames_shndx;
off_t pubnames_offset = die->ref_attribute(elfcpp::DW_AT_GNU_pubnames,
&pubnames_shndx);
if (pubnames_offset != -1)
// Newer versions of GCC generate CUs, but not TUs, with
// DW_AT_FORM_flag_present.
unsigned int flag = die->uint_attribute(elfcpp::DW_AT_GNU_pubnames);
if (offset == -1 && flag == 0)
{
if (this->gdb_index_->pubnames_read(this->object(), pubnames_shndx,
pubnames_offset))
ret = true;
// Didn't find the attribute.
if (die->tag() == elfcpp::DW_TAG_type_unit)
{
// If die is a TU, then it might correspond to a CU which we
// have read. If it does, then no need to read the pubnames.
// If it doesn't, then the caller will have to parse the
// dies manually to find the names.
return this->gdb_index_->pubnames_read(this->object(),
stmt_list_off);
}
else
{
Dwarf_pubnames_table pubnames(this, false);
if (!pubnames.read_section(this->object(), pubnames_shndx))
return false;
if (!pubnames.read_header(pubnames_offset))
return false;
while (true)
{
const char* name = pubnames.next_name();
if (name == NULL)
break;
this->gdb_index_->add_symbol(this->cu_index_, name);
}
ret = true;
}
{
// No attribute on the CU means that no pubnames were read.
return false;
}
}
// If we find a DW_AT_GNU_pubtypes attribute, read the pubtypes table.
unsigned int pubtypes_shndx;
off_t pubtypes_offset = die->ref_attribute(elfcpp::DW_AT_GNU_pubtypes,
&pubtypes_shndx);
if (pubtypes_offset != -1)
{
if (this->gdb_index_->pubtypes_read(this->object(),
pubtypes_shndx, pubtypes_offset))
ret = true;
else
{
Dwarf_pubnames_table pubtypes(this, true);
if (!pubtypes.read_section(this->object(), pubtypes_shndx))
return false;
if (!pubtypes.read_header(pubtypes_offset))
return false;
while (true)
{
const char* name = pubtypes.next_name();
if (name == NULL)
break;
this->gdb_index_->add_symbol(this->cu_index_, name);
}
ret = true;
}
}
// We found the attribute, so we can check if the corresponding
// pubnames have been read.
if (this->gdb_index_->pubnames_read(this->object(), stmt_list_off))
return true;
return ret;
this->gdb_index_->set_pubnames_read(this->object(), stmt_list_off);
// We have an attribute, and the pubnames haven't been read, so read
// them.
bool names = false;
// In some of the cases, we could rely on the previous value of
// offset here, but sorting out which cases complicates the logic
// enough that it isn't worth it. So just look up the offset again.
offset = this->gdb_index_->find_pubname_offset(this->cu_offset());
names = this->read_pubtable(this->gdb_index_->pubnames_table(), offset);
bool types = false;
offset = this->gdb_index_->find_pubtype_offset(this->cu_offset());
types = this->read_pubtable(this->gdb_index_->pubtypes_table(), offset);
return names || types;
}
// Clear the declarations map.
@ -952,6 +973,8 @@ Gdb_index_info_reader::print_stats()
Gdb_index::Gdb_index(Output_section* gdb_index_section)
: Output_section_data(4),
pubnames_table_(NULL),
pubtypes_table_(NULL),
gdb_index_section_(gdb_index_section),
comp_units_(),
type_units_(),
@ -965,11 +988,7 @@ Gdb_index::Gdb_index(Output_section* gdb_index_section)
cu_pool_offset_(0),
stringpool_offset_(0),
pubnames_object_(NULL),
pubnames_shndx_(0),
pubnames_offset_(0),
pubtypes_object_(NULL),
pubtypes_shndx_(0),
pubtypes_offset_(0)
stmt_list_offset_(-1)
{
this->gdb_symtab_ = new Gdb_hashtab<Gdb_symbol>();
}
@ -983,6 +1002,93 @@ Gdb_index::~Gdb_index()
delete this->cu_vector_list_[i];
}
// Scan the pubnames and pubtypes sections and build a map of the
// various cus and tus they refer to, so we can process the entries
// when we encounter the die for that cu or tu.
// Return the just-read table so it can be cached.
Dwarf_pubnames_table*
Gdb_index::map_pubtable_to_dies(unsigned int attr,
Gdb_index_info_reader* dwinfo,
Relobj* object,
const unsigned char* symbols,
off_t symbols_size)
{
uint64_t section_offset = 0;
Dwarf_pubnames_table* table;
Pubname_offset_map* map;
if (attr == elfcpp::DW_AT_GNU_pubnames)
{
table = new Dwarf_pubnames_table(dwinfo, false);
map = &this->cu_pubname_map_;
}
else
{
table = new Dwarf_pubnames_table(dwinfo, true);
map = &this->cu_pubtype_map_;
}
map->clear();
if (!table->read_section(object, symbols, symbols_size))
return NULL;
while (table->read_header(section_offset))
{
map->insert(std::make_pair(table->cu_offset(), section_offset));
section_offset += table->subsection_size();
}
return table;
}
// Wrapper for map_pubtable_to_dies
void
Gdb_index::map_pubnames_and_types_to_dies(Gdb_index_info_reader* dwinfo,
Relobj* object,
const unsigned char* symbols,
off_t symbols_size)
{
// This is a new object, so reset the relevant variables.
this->pubnames_object_ = object;
this->stmt_list_offset_ = -1;
delete this->pubnames_table_;
this->pubnames_table_
= this->map_pubtable_to_dies(elfcpp::DW_AT_GNU_pubnames, dwinfo,
object, symbols, symbols_size);
delete this->pubtypes_table_;
this->pubtypes_table_
= this->map_pubtable_to_dies(elfcpp::DW_AT_GNU_pubtypes, dwinfo,
object, symbols, symbols_size);
}
// Given a cu_offset, find the associated section of the pubnames
// table.
off_t
Gdb_index::find_pubname_offset(off_t cu_offset)
{
Pubname_offset_map::iterator it = this->cu_pubname_map_.find(cu_offset);
if (it != this->cu_pubname_map_.end())
return it->second;
return -1;
}
// Given a cu_offset, find the associated section of the pubnames
// table.
off_t
Gdb_index::find_pubtype_offset(off_t cu_offset)
{
Pubname_offset_map::iterator it = this->cu_pubtype_map_.find(cu_offset);
if (it != this->cu_pubtype_map_.end())
return it->second;
return -1;
}
// Scan a .debug_info or .debug_types input section.
void
@ -998,6 +1104,8 @@ Gdb_index::scan_debug_info(bool is_type_unit,
symbols, symbols_size,
shndx, reloc_shndx,
reloc_type, this);
if (object != this->pubnames_object_)
map_pubnames_and_types_to_dies(&dwinfo, object, symbols, symbols_size);
dwinfo.parse();
}
@ -1035,34 +1143,25 @@ Gdb_index::add_symbol(int cu_index, const char* sym_name)
cu_vec->push_back(cu_index);
}
// Return TRUE if we have already processed the pubnames set at
// OFFSET in section SHNDX
// Return TRUE if we have already processed the pubnames associated
// with the statement list at the given OFFSET.
bool
Gdb_index::pubnames_read(const Relobj* object, unsigned int shndx, off_t offset)
Gdb_index::pubnames_read(const Relobj* object, off_t offset)
{
bool ret = (this->pubnames_object_ == object
&& this->pubnames_shndx_ == shndx
&& this->pubnames_offset_ == offset);
this->pubnames_object_ = object;
this->pubnames_shndx_ = shndx;
this->pubnames_offset_ = offset;
&& this->stmt_list_offset_ == offset);
return ret;
}
// Return TRUE if we have already processed the pubtypes set at
// OFFSET in section SHNDX
// Record that we have processed the pubnames associated with the
// statement list for OBJECT at the given OFFSET.
bool
Gdb_index::pubtypes_read(const Relobj* object, unsigned int shndx, off_t offset)
void
Gdb_index::set_pubnames_read(const Relobj* object, off_t offset)
{
bool ret = (this->pubtypes_object_ == object
&& this->pubtypes_shndx_ == shndx
&& this->pubtypes_offset_ == offset);
this->pubtypes_object_ = object;
this->pubtypes_shndx_ = shndx;
this->pubtypes_offset_ = offset;
return ret;
this->pubnames_object_ = object;
this->stmt_list_offset_ = offset;
}
// Set the size of the .gdb_index section.

View File

@ -42,6 +42,8 @@ class Sized_relobj;
class Dwarf_range_list;
template <typename T>
class Gdb_hashtab;
class Gdb_index_info_reader;
class Dwarf_pubnames_table;
// This class manages the .gdb_index section, which is a fast
// lookup table for DWARF information used by the gdb debugger.
@ -91,15 +93,35 @@ class Gdb_index : public Output_section_data
void
add_symbol(int cu_index, const char* sym_name);
// Return TRUE if we have already processed the pubnames set for
// OBJECT at OFFSET in section SHNDX
bool
pubnames_read(const Relobj* object, unsigned int shndx, off_t offset);
// Return the offset into the pubnames table for the cu at the given
// offset.
off_t
find_pubname_offset(off_t cu_offset);
// Return TRUE if we have already processed the pubtypes set for
// OBJECT at OFFSET in section SHNDX
// Return the offset into the pubtypes table for the cu at the
// given offset.
off_t
find_pubtype_offset(off_t cu_offset);
// Return TRUE if we have already processed the pubnames and types
// set for OBJECT of the CUs and TUS associated with the statement
// list at OFFSET.
bool
pubtypes_read(const Relobj* object, unsigned int shndx, off_t offset);
pubnames_read(const Relobj* object, off_t offset);
// Record that we have already read the pubnames associated with
// OBJECT and OFFSET.
void
set_pubnames_read(const Relobj* object, off_t offset);
// Return a pointer to the given table.
Dwarf_pubnames_table*
pubnames_table()
{ return pubnames_table_; }
Dwarf_pubnames_table*
pubtypes_table()
{ return pubtypes_table_; }
// Print usage statistics.
static void
@ -125,6 +147,21 @@ class Gdb_index : public Output_section_data
do_print_to_mapfile(Mapfile* mapfile) const
{ mapfile->print_output_data(this, _("** gdb_index")); }
// Create a map from dies to pubnames.
Dwarf_pubnames_table*
map_pubtable_to_dies(unsigned int attr,
Gdb_index_info_reader* dwinfo,
Relobj* object,
const unsigned char* symbols,
off_t symbols_size);
// Wrapper for map_pubtable_to_dies
void
map_pubnames_and_types_to_dies(Gdb_index_info_reader* dwinfo,
Relobj* object,
const unsigned char* symbols,
off_t symbols_size);
private:
// An entry in the compilation unit list.
struct Comp_unit
@ -178,6 +215,21 @@ class Gdb_index : public Output_section_data
typedef std::vector<int> Cu_vector;
typedef Unordered_map<off_t, off_t> Pubname_offset_map;
Pubname_offset_map cu_pubname_map_;
Pubname_offset_map cu_pubtype_map_;
// Scan the given pubtable and build a map of the various dies it
// refers to, so we can process the entries when we encounter the
// die.
void
map_pubtable_to_dies(Dwarf_pubnames_table* table,
Pubname_offset_map* map);
// Tables to store the pubnames section of the current object.
Dwarf_pubnames_table* pubnames_table_;
Dwarf_pubnames_table* pubtypes_table_;
// The .gdb_index section.
Output_section* gdb_index_section_;
// The list of DWARF compilation units.
@ -200,14 +252,10 @@ class Gdb_index : public Output_section_data
off_t symtab_offset_;
off_t cu_pool_offset_;
off_t stringpool_offset_;
// Object, section index and offset of last read pubnames section.
// Object, stmt list offset of the CUs and TUs associated with the
// last read pubnames and pubtypes sections.
const Relobj* pubnames_object_;
unsigned int pubnames_shndx_;
off_t pubnames_offset_;
// Object, section index and offset of last read pubtypes section.
const Relobj* pubtypes_object_;
unsigned int pubtypes_shndx_;
off_t pubtypes_offset_;
off_t stmt_list_offset_;
};
} // End namespace gold.