// dwarf_reader.cc -- parse dwarf2/3 debug information
-// Copyright 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2007-2015 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of gold.
#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;
+ 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_);
// 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.
- offset -= this->output_section_offset_;
-
if (offset < 0 || offset + 14 >= this->buffer_end_ - this->buffer_)
return false;
this->unit_length_ = unit_length + 4;
this->offset_size_ = 4;
}
+ this->end_of_table_ = pinfo + unit_length;
+
+ // If unit_length is too big, maybe we should reject the whole table,
+ // but in cases we know about, it seems OK to assume that the table
+ // is valid through the actual end of the section.
+ if (this->end_of_table_ > this->buffer_end_)
+ this->end_of_table_ = this->buffer_end_;
// 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_ =