aboutsummaryrefslogtreecommitdiff
path: root/src/common/dwarf/dwarf2reader.cc
diff options
context:
space:
mode:
authorSterling Augustine <saugustine@google.com>2020-06-22 16:38:16 -0700
committerSterling Augustine <saugustine@google.com>2020-06-22 23:39:36 +0000
commitfeb2dca989399bc07d2ecf681a19b18af30e81a4 (patch)
tree01ad412d5a6d406959bf9763530f6b9026d1672f /src/common/dwarf/dwarf2reader.cc
parentMake symupload exit with an error code when command-line parsing fails. (diff)
downloadbreakpad-feb2dca989399bc07d2ecf681a19b18af30e81a4.tar.xz
Add and handle new dwarf5 string-related forms.
Adding the new forms by type and processing should avoid the problems with 0c0e24f709288a129d665ec27d6f089189318385, where new forms weren't handled in switch statements, breaking the build. Testing this should follow the testing for DW_FORM_GNU_str_index, very closely, but there doesn't appear to be any tests for that, or even DW_FORM_strp. Change-Id: I609d56b1dc879971bfef1070f063f8457fec6017 Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2233839 Reviewed-by: Mike Frysinger <vapier@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
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 =