aboutsummaryrefslogtreecommitdiff
path: root/src/common/dwarf/dwarf2reader.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/dwarf/dwarf2reader.cc')
-rw-r--r--src/common/dwarf/dwarf2reader.cc109
1 files changed, 78 insertions, 31 deletions
diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc
index 6b9ce2b4..4f0c31dd 100644
--- a/src/common/dwarf/dwarf2reader.cc
+++ b/src/common/dwarf/dwarf2reader.cc
@@ -33,7 +33,6 @@
#include "common/dwarf/dwarf2reader.h"
-#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -60,6 +59,7 @@ CompilationUnit::CompilationUnit(const string& path,
: path_(path), offset_from_section_start_(offset), reader_(reader),
sections_(sections), handler_(handler), abbrevs_(),
string_buffer_(NULL), string_buffer_length_(0),
+ line_string_buffer_(NULL), line_string_buffer_length_(0),
str_offsets_buffer_(NULL), str_offsets_buffer_length_(0),
addr_buffer_(NULL), addr_buffer_length_(0),
is_split_dwarf_(false), dwo_id_(0), dwo_name_(),
@@ -99,12 +99,8 @@ void CompilationUnit::ReadAbbrevs() {
if (abbrevs_)
return;
- // First get the debug_abbrev section. ".debug_abbrev" is the name
- // recommended in the DWARF spec, and used on Linux;
- // "__debug_abbrev" is the name used in Mac OS X Mach-O files.
- SectionMap::const_iterator iter = sections_.find(".debug_abbrev");
- if (iter == sections_.end())
- iter = sections_.find("__debug_abbrev");
+ // First get the debug_abbrev section.
+ SectionMap::const_iterator iter = GetSectionByName(".debug_abbrev");
assert(iter != sections_.end());
abbrevs_ = new std::vector<Abbrev>;
@@ -189,12 +185,17 @@ const uint8_t *CompilationUnit::SkipAttribute(const uint8_t *start,
case DW_FORM_data1:
case DW_FORM_flag:
case DW_FORM_ref1:
+ case DW_FORM_strx1:
return start + 1;
case DW_FORM_ref2:
case DW_FORM_data2:
+ case DW_FORM_strx2:
return start + 2;
+ case DW_FORM_strx3:
+ return start + 3;
case DW_FORM_ref4:
case DW_FORM_data4:
+ case DW_FORM_strx4:
return start + 4;
case DW_FORM_ref8:
case DW_FORM_data8:
@@ -204,6 +205,7 @@ const uint8_t *CompilationUnit::SkipAttribute(const uint8_t *start,
return start + strlen(reinterpret_cast<const char *>(start)) + 1;
case DW_FORM_udata:
case DW_FORM_ref_udata:
+ case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_addr_index:
reader_->ReadUnsignedLEB128(start, &len);
@@ -237,6 +239,8 @@ const uint8_t *CompilationUnit::SkipAttribute(const uint8_t *start,
return start + size + len;
}
case DW_FORM_strp:
+ case DW_FORM_line_strp:
+ case DW_FORM_strp_sup:
case DW_FORM_sec_offset:
return start + reader_->OffsetSize();
}
@@ -284,12 +288,8 @@ void CompilationUnit::ReadHeader() {
}
uint64_t CompilationUnit::Start() {
- // First get the debug_info section. ".debug_info" is the name
- // recommended in the DWARF spec, and used on Linux; "__debug_info"
- // is the name used in Mac OS X Mach-O files.
- SectionMap::const_iterator iter = sections_.find(".debug_info");
- if (iter == sections_.end())
- iter = sections_.find("__debug_info");
+ // First get the debug_info section.
+ SectionMap::const_iterator iter = GetSectionByName(".debug_info");
assert(iter != sections_.end());
// Set up our buffer
@@ -319,26 +319,29 @@ uint64_t CompilationUnit::Start() {
// Otherwise, continue by reading our abbreviation entries.
ReadAbbrevs();
- // Set the string section if we have one. ".debug_str" is the name
- // recommended in the DWARF spec, and used on Linux; "__debug_str"
- // is the name used in Mac OS X Mach-O files.
- iter = sections_.find(".debug_str");
- if (iter == sections_.end())
- iter = sections_.find("__debug_str");
+ // Set the string section if we have one.
+ iter = GetSectionByName(".debug_str");
if (iter != sections_.end()) {
string_buffer_ = iter->second.first;
string_buffer_length_ = iter->second.second;
}
+ // Set the line string section if we have one.
+ iter = GetSectionByName(".debug_line_str");
+ if (iter != sections_.end()) {
+ line_string_buffer_ = iter->second.first;
+ line_string_buffer_length_ = iter->second.second;
+ }
+
// Set the string offsets section if we have one.
- iter = sections_.find(".debug_str_offsets");
+ iter = GetSectionByName(".debug_str_offsets");
if (iter != sections_.end()) {
str_offsets_buffer_ = iter->second.first;
str_offsets_buffer_length_ = iter->second.second;
}
// Set the address section if we have one.
- iter = sections_.find(".debug_addr");
+ iter = GetSectionByName(".debug_addr");
if (iter != sections_.end()) {
addr_buffer_ = iter->second.first;
addr_buffer_length_ = iter->second.second;
@@ -358,6 +361,20 @@ uint64_t CompilationUnit::Start() {
return ourlength;
}
+void CompilationUnit::ProcessFormStringIndex(
+ uint64_t dieoffset, enum DwarfAttribute attr, enum DwarfForm form,
+ uint64_t str_index) {
+ const uint8_t* offset_ptr =
+ str_offsets_buffer_ + str_index * reader_->OffsetSize();
+ const uint64_t offset = reader_->ReadOffset(offset_ptr);
+ if (offset >= string_buffer_length_) {
+ return;
+ }
+
+ const char* str = reinterpret_cast<const char*>(string_buffer_) + offset;
+ ProcessAttributeString(dieoffset, attr, form, str);
+}
+
// If one really wanted, you could merge SkipAttribute and
// ProcessAttribute
// This is all boring data manipulation and calling of the handler.
@@ -498,21 +515,51 @@ const uint8_t *CompilationUnit::ProcessAttribute(
ProcessAttributeString(dieoffset, attr, form, str);
return start + reader_->OffsetSize();
}
+ case DW_FORM_line_strp: {
+ assert(line_string_buffer_ != NULL);
- case DW_FORM_GNU_str_index: {
- uint64_t str_index = reader_->ReadUnsignedLEB128(start, &len);
- const uint8_t* offset_ptr =
- str_offsets_buffer_ + str_index * reader_->OffsetSize();
- const uint64_t offset = reader_->ReadOffset(offset_ptr);
- if (offset >= string_buffer_length_) {
- return NULL;
- }
+ const uint64_t offset = reader_->ReadOffset(start);
+ assert(line_string_buffer_ + offset <
+ line_string_buffer_ + line_string_buffer_length_);
- const char* str = reinterpret_cast<const char *>(string_buffer_) + offset;
+ const char* str =
+ reinterpret_cast<const char*>(line_string_buffer_ + offset);
ProcessAttributeString(dieoffset, attr, form, str);
+ return start + reader_->OffsetSize();
+ }
+ case DW_FORM_strp_sup:
+ // No support currently for suplementary object files.
+ fprintf(stderr, "Unhandled form type: DW_FORM_strp_sup\n");
+ return start + 4;
+
+ case DW_FORM_strx:
+ case DW_FORM_GNU_str_index: {
+ uint64_t str_index = reader_->ReadUnsignedLEB128(start, &len);
+ ProcessFormStringIndex(dieoffset, attr, form, str_index);
return start + len;
- break;
}
+ case DW_FORM_strx1: {
+ uint64_t str_index = reader_->ReadOneByte(start);
+ ProcessFormStringIndex(dieoffset, attr, form, str_index);
+ return start + 1;
+ }
+ case DW_FORM_strx2: {
+ uint64_t str_index = reader_->ReadTwoBytes(start);
+ ProcessFormStringIndex(dieoffset, attr, form, str_index);
+ return start + 2;
+ }
+ case DW_FORM_strx3: {
+ uint64_t str_index = reader_->ReadTwoBytes(start);
+ str_index *= reader_->ReadOneByte(start + 2);
+ ProcessFormStringIndex(dieoffset, attr, form, str_index);
+ return start + 3;
+ }
+ case DW_FORM_strx4: {
+ uint64_t str_index = reader_->ReadFourBytes(start);
+ ProcessFormStringIndex(dieoffset, attr, form, str_index);
+ return start + 4;
+ }
+
case DW_FORM_GNU_addr_index: {
uint64_t addr_index = reader_->ReadUnsignedLEB128(start, &len);
const uint8_t* addr_ptr =