summaryrefslogtreecommitdiff
path: root/gold/dwarf_reader.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gold/dwarf_reader.cc')
-rw-r--r--gold/dwarf_reader.cc75
1 files changed, 54 insertions, 21 deletions
diff --git a/gold/dwarf_reader.cc b/gold/dwarf_reader.cc
index 4233954d17..3aad27f7b3 100644
--- a/gold/dwarf_reader.cc
+++ b/gold/dwarf_reader.cc
@@ -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_;