aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-01-12 16:53:02 +0000
committerjimblandy <jimblandy@4c0a9323-5329-0410-9bdc-e9ce6186880e>2010-01-12 16:53:02 +0000
commit330ca2f7c71d84a01626b1198ef600540eb320b8 (patch)
treeb5531f2281c297c2c5d9b2372296af1632592df4 /src
parentBreakpad: Avoid warnings building with G++ 4.4.1 using -O3 -Wall. (diff)
downloadbreakpad-330ca2f7c71d84a01626b1198ef600540eb320b8.tar.xz
Google Breakpad DWARF reader: Add a handler function for DIE references.
Add a new member function to dwarf2reader::Dwarf2Handler, ProcessAttributeReference, for reporting attribute values that are references to other DIEs. This handler member function always receives an absolute offset (that is, relative to the start of the .debug_info section, not to the start of the compilation unit), regardless of the form the attribute uses. (Some forms are CU-relative, some are absolute.) a=jimblandy, r=nealsid git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@482 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src')
-rw-r--r--src/common/dwarf/dwarf2reader.cc45
-rw-r--r--src/common/dwarf/dwarf2reader.h10
-rw-r--r--src/common/dwarf/functioninfo.cc36
-rw-r--r--src/common/dwarf/functioninfo.h10
4 files changed, 70 insertions, 31 deletions
diff --git a/src/common/dwarf/dwarf2reader.cc b/src/common/dwarf/dwarf2reader.cc
index 2580606f..77c318fa 100644
--- a/src/common/dwarf/dwarf2reader.cc
+++ b/src/common/dwarf/dwarf2reader.cc
@@ -331,24 +331,20 @@ const char* CompilationUnit::ProcessAttribute(
case DW_FORM_data1:
case DW_FORM_flag:
- case DW_FORM_ref1:
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadOneByte(start));
return start + 1;
break;
- case DW_FORM_ref2:
case DW_FORM_data2:
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadTwoBytes(start));
return start + 2;
break;
- case DW_FORM_ref4:
case DW_FORM_data4:
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadFourBytes(start));
return start + 4;
break;
- case DW_FORM_ref8:
case DW_FORM_data8:
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadEightBytes(start));
@@ -362,7 +358,6 @@ const char* CompilationUnit::ProcessAttribute(
}
break;
case DW_FORM_udata:
- case DW_FORM_ref_udata:
handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
reader_->ReadUnsignedLEB128(start,
&len));
@@ -379,17 +374,49 @@ const char* CompilationUnit::ProcessAttribute(
reader_->ReadAddress(start));
return start + reader_->AddressSize();
break;
+
+ case DW_FORM_ref1:
+ handler_->ProcessAttributeReference(dieoffset, attr, form,
+ reader_->ReadOneByte(start)
+ + offset_from_section_start_);
+ return start + 1;
+ break;
+ case DW_FORM_ref2:
+ handler_->ProcessAttributeReference(dieoffset, attr, form,
+ reader_->ReadTwoBytes(start)
+ + offset_from_section_start_);
+ return start + 2;
+ break;
+ case DW_FORM_ref4:
+ handler_->ProcessAttributeReference(dieoffset, attr, form,
+ reader_->ReadFourBytes(start)
+ + offset_from_section_start_);
+ return start + 4;
+ break;
+ case DW_FORM_ref8:
+ handler_->ProcessAttributeReference(dieoffset, attr, form,
+ reader_->ReadEightBytes(start)
+ + offset_from_section_start_);
+ return start + 8;
+ break;
+ case DW_FORM_ref_udata:
+ handler_->ProcessAttributeReference(dieoffset, attr, form,
+ reader_->ReadUnsignedLEB128(start,
+ &len)
+ + offset_from_section_start_);
+ return start + len;
+ break;
case DW_FORM_ref_addr:
// DWARF2 and 3 differ on whether ref_addr is address size or
// offset size.
assert(header_.version == 2 || header_.version == 3);
if (header_.version == 2) {
- handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
- reader_->ReadAddress(start));
+ handler_->ProcessAttributeReference(dieoffset, attr, form,
+ reader_->ReadAddress(start));
return start + reader_->AddressSize();
} else if (header_.version == 3) {
- handler_->ProcessAttributeUnsigned(dieoffset, attr, form,
- reader_->ReadOffset(start));
+ handler_->ProcessAttributeReference(dieoffset, attr, form,
+ reader_->ReadOffset(start));
return start + reader_->OffsetSize();
}
break;
diff --git a/src/common/dwarf/dwarf2reader.h b/src/common/dwarf/dwarf2reader.h
index f7d379e9..57667563 100644
--- a/src/common/dwarf/dwarf2reader.h
+++ b/src/common/dwarf/dwarf2reader.h
@@ -358,6 +358,16 @@ class Dwarf2Handler {
enum DwarfForm form,
int64 data) { }
+ // Called when we have an attribute whose value is a reference to
+ // another DIE. The attribute belongs to the DIE at OFFSET from the
+ // beginning of the .debug_info section. Its name is ATTR, its form
+ // is FORM, and the offset of the DIE being referred to from the
+ // beginning of the .debug_info section is DATA.
+ virtual void ProcessAttributeReference(uint64 offset,
+ enum DwarfAttribute attr,
+ enum DwarfForm form,
+ uint64 data) { }
+
// Called when we have an attribute with a buffer of data to give to our
// handler. The attribute is for the DIE at OFFSET from the beginning of the
// .debug_info section. Its name is ATTR, its form is FORM, DATA points to
diff --git a/src/common/dwarf/functioninfo.cc b/src/common/dwarf/functioninfo.cc
index 1957153e..09aa01fd 100644
--- a/src/common/dwarf/functioninfo.cc
+++ b/src/common/dwarf/functioninfo.cc
@@ -42,25 +42,6 @@
namespace dwarf2reader {
-// Given an offset value, its form, and the base offset of the
-// compilation unit containing this value, return an absolute offset
-// within the .debug_info section.
-uint64 GetAbsoluteOffset(uint64 offset,
- enum DwarfForm form,
- uint64 compilation_unit_base) {
- switch (form) {
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata:
- return offset + compilation_unit_base;
- case DW_FORM_ref_addr:
- default:
- return offset;
- }
-}
-
CULineInfoHandler::CULineInfoHandler(vector<SourceFileInfo>* files,
vector<string>* dirs,
LineMap* linemap):linemap_(linemap),
@@ -198,6 +179,18 @@ void CUFunctionInfoHandler::ProcessAttributeUnsigned(uint64 offset,
case DW_AT_decl_file:
current_function_info_->file = files_->at(data).name;
break;
+ default:
+ break;
+ }
+ }
+}
+
+void CUFunctionInfoHandler::ProcessAttributeReference(uint64 offset,
+ enum DwarfAttribute attr,
+ enum DwarfForm form,
+ uint64 data) {
+ if (current_function_info_) {
+ switch (attr) {
case DW_AT_specification: {
// Some functions have a "specification" attribute
// which means they were defined elsewhere. The name
@@ -205,14 +198,13 @@ void CUFunctionInfoHandler::ProcessAttributeUnsigned(uint64 offset,
// the specification DIE. Here we'll assume that
// any DIE referenced in this manner will already have
// been seen, but that's not really required by the spec.
- uint64 abs_offset = GetAbsoluteOffset(data, form, current_compilation_unit_offset_);
- FunctionMap::iterator iter = offset_to_funcinfo_->find(abs_offset);
+ FunctionMap::iterator iter = offset_to_funcinfo_->find(data);
if (iter != offset_to_funcinfo_->end()) {
current_function_info_->name = iter->second->name;
current_function_info_->mangled_name = iter->second->mangled_name;
} else {
// If you hit this, this code probably needs to be rewritten.
- fprintf(stderr, "Error: DW_AT_specification was seen before the referenced DIE! (Looking for DIE at offset %08llx, in DIE at offset %08llx)\n", abs_offset, offset);
+ fprintf(stderr, "Error: DW_AT_specification was seen before the referenced DIE! (Looking for DIE at offset %08llx, in DIE at offset %08llx)\n", data, offset);
}
break;
}
diff --git a/src/common/dwarf/functioninfo.h b/src/common/dwarf/functioninfo.h
index 740f1463..3351c67c 100644
--- a/src/common/dwarf/functioninfo.h
+++ b/src/common/dwarf/functioninfo.h
@@ -146,6 +146,16 @@ class CUFunctionInfoHandler: public Dwarf2Handler {
enum DwarfForm form,
uint64 data);
+ // Called when we have an attribute with a DIE reference to give to
+ // our handler. The attribute is for the DIE at OFFSET from the
+ // beginning of the .debug_info section, has a name of ATTR, a form of
+ // FORM, and the offset of the referenced DIE from the start of the
+ // .debug_info section is in DATA.
+ virtual void ProcessAttributeReference(uint64 offset,
+ enum DwarfAttribute attr,
+ enum DwarfForm form,
+ uint64 data);
+
// Called when we have an attribute with string data to give to
// our handler. The attribute is for the DIE at OFFSET from the
// beginning of the .debug_info section, has a name of ATTR, a form of