#include "gold.h"
#include <algorithm>
+#include <utility>
#include <vector>
#include "elfcpp_swap.h"
for (unsigned int i = 1; i < object->shnum(); ++i)
{
std::string name = object->section_name(i);
- if (name == ".debug_abbrev")
+ if (name == ".debug_abbrev" || name == ".zdebug_abbrev")
{
abbrev_shndx = i;
// Correct the offset. For incremental update links, we have a
for (unsigned int i = 1; i < object->shnum(); ++i)
{
std::string name = object->section_name(i);
- if (name == ".debug_ranges")
+ if (name == ".debug_ranges" || name == ".zdebug_ranges")
{
ranges_shndx = i;
this->output_section_offset_ = object->output_section_offset(i);
{
section_size_type buffer_size;
unsigned int shndx = 0;
+ const char* name = this->is_pubtypes_ ? "pubtypes" : "pubnames";
+ const char* gnu_name = (this->is_pubtypes_
+ ? "gnu_pubtypes"
+ : "gnu_pubnames");
- // 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)
{
- if (object->section_name(i) == name)
+ std::string section_name = object->section_name(i);
+ const char* section_name_suffix = section_name.c_str();
+ if (is_prefix_of(".debug_", section_name_suffix))
+ section_name_suffix += 7;
+ else if (is_prefix_of(".zdebug_", section_name_suffix))
+ section_name_suffix += 8;
+ else
+ continue;
+ if (strcmp(section_name_suffix, name) == 0)
+ {
+ shndx = i;
+ this->output_section_offset_ = object->output_section_offset(i);
+ break;
+ }
+ else if (strcmp(section_name_suffix, gnu_name) == 0)
{
shndx = i;
this->output_section_offset_ = object->output_section_offset(i);
+ this->is_gnu_style_ = true;
break;
}
}
if (shndx == 0)
return false;
-
this->buffer_ = object->decompressed_section_contents(shndx,
&buffer_size,
&this->owns_buffer_);
this->unit_length_ = unit_length + 4;
this->offset_size_ = 4;
}
+ this->end_of_table_ = pinfo + unit_length;
// Check the version.
unsigned int version = this->dwinfo_->read_from_pointer<16>(pinfo);
// Read the next name from the set.
const char*
-Dwarf_pubnames_table::next_name()
+Dwarf_pubnames_table::next_name(uint8_t* flag_byte)
{
const unsigned char* pinfo = this->pinfo_;
- // Read the offset within the CU. If this is zero, we have reached
- // the end of the list.
- uint32_t offset;
- if (this->offset_size_ == 4)
- offset = this->dwinfo_->read_from_pointer<32>(&pinfo);
- else
- offset = this->dwinfo_->read_from_pointer<64>(&pinfo);
- if (offset == 0)
+ // Check for end of list. The table should be terminated by an
+ // entry containing nothing but a DIE offset of 0.
+ if (pinfo + this->offset_size_ >= this->end_of_table_)
return NULL;
+ // Skip the offset within the CU. If this is zero, but we're not
+ // at the end of the table, then we have a real pubnames entry
+ // whose DIE offset is 0 (likely to be a GCC bug). Since we
+ // don't actually use the DIE offset in building .gdb_index,
+ // it's harmless.
+ pinfo += this->offset_size_;
+
+ if (this->is_gnu_style_)
+ *flag_byte = *pinfo++;
+ else
+ *flag_byte = 0;
+
// Return a pointer to the string at the current location,
// and advance the pointer to the next entry.
const char* ret = reinterpret_cast<const char*>(pinfo);
for (unsigned int i = 1; i < this->object_->shnum(); ++i)
{
std::string name = object->section_name(i);
- if (name == ".debug_str")
+ if (name == ".debug_str" || name == ".zdebug_str")
{
string_shndx = i;
this->string_output_section_offset_ =