aboutsummaryrefslogtreecommitdiff
path: root/src/common/mac
diff options
context:
space:
mode:
authorted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2008-12-08 13:12:45 +0000
committerted.mielczarek <ted.mielczarek@4c0a9323-5329-0410-9bdc-e9ce6186880e>2008-12-08 13:12:45 +0000
commit3751b053540ab3d51887cd27f1992cc4dee50542 (patch)
tree56ed47ed56de265a6e9349ca8f7859d9da6a5a74 /src/common/mac
parentIssue 284 - DWARF dumper doesn't output function names including arguments. r... (diff)
downloadbreakpad-3751b053540ab3d51887cd27f1992cc4dee50542.tar.xz
Issue 283 - DWARF dumper doesn't handle DW_AT_specification. r=nealsid
git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@303 4c0a9323-5329-0410-9bdc-e9ce6186880e
Diffstat (limited to 'src/common/mac')
-rw-r--r--src/common/mac/dwarf/functioninfo.cc38
-rw-r--r--src/common/mac/dwarf/functioninfo.h1
2 files changed, 39 insertions, 0 deletions
diff --git a/src/common/mac/dwarf/functioninfo.cc b/src/common/mac/dwarf/functioninfo.cc
index 66355ec0..b6d3f0fe 100644
--- a/src/common/mac/dwarf/functioninfo.cc
+++ b/src/common/mac/dwarf/functioninfo.cc
@@ -51,6 +51,25 @@ namespace __gnu_cxx
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),
@@ -117,6 +136,7 @@ bool CUFunctionInfoHandler::StartCompilationUnit(uint64 offset,
uint8 offset_size,
uint64 cu_length,
uint8 dwarf_version) {
+ current_compilation_unit_offset_ = offset;
return true;
}
@@ -187,6 +207,24 @@ void CUFunctionInfoHandler::ProcessAttributeUnsigned(uint64 offset,
case DW_AT_decl_file:
current_function_info_->file = files_->at(data).name;
break;
+ case DW_AT_specification: {
+ // Some functions have a "specification" attribute
+ // which means they were defined elsewhere. The name
+ // attribute is not repeated, and must be taken from
+ // 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);
+ 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);
+ }
+ break;
+ }
default:
break;
}
diff --git a/src/common/mac/dwarf/functioninfo.h b/src/common/mac/dwarf/functioninfo.h
index aa8bf705..130f182e 100644
--- a/src/common/mac/dwarf/functioninfo.h
+++ b/src/common/mac/dwarf/functioninfo.h
@@ -171,6 +171,7 @@ class CUFunctionInfoHandler: public Dwarf2Handler {
const SectionMap& sections_;
ByteReader* reader_;
FunctionInfo* current_function_info_;
+ uint64 current_compilation_unit_offset_;
};
} // namespace dwarf2reader