diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index 53ceff99e3..b55ce1ac11 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -37,6 +37,7 @@ #include "StackFrame.h" #include "Statement.h" #include "StringUtils.h" +#include "TargetAddressRangeList.h" #include "TeamMemory.h" #include "UnsupportedLanguage.h" @@ -230,9 +231,8 @@ printf(" %ld compilation units\n", fFile->CountCompilationUnits()); continue; // get the address ranges - TargetAddressRangeList* rangeList - = subprogramEntry->AddressRanges(); - Reference rangeListReference(rangeList); + TargetAddressRangeList* rangeList = fFile->ResolveRangeList(unit, + subprogramEntry->AddressRangesOffset()); if (rangeList == NULL) { target_addr_t lowPC = subprogramEntry->LowPC(); target_addr_t highPC = subprogramEntry->HighPC(); @@ -244,8 +244,9 @@ printf(" %ld compilation units\n", fFile->CountCompilationUnits()); if (rangeList == NULL) return B_NO_MEMORY; // TODO: Clean up already added functions! - rangeListReference.SetTo(rangeList, true); } + Reference rangeListReference(rangeList, + true); // get the source location const char* directoryPath = NULL; diff --git a/src/apps/debugger/dwarf/AttributeValue.h b/src/apps/debugger/dwarf/AttributeValue.h index 4edeac79a3..e4a096f5f1 100644 --- a/src/apps/debugger/dwarf/AttributeValue.h +++ b/src/apps/debugger/dwarf/AttributeValue.h @@ -6,7 +6,6 @@ #define ATTRIBUTE_VALUE_H #include "AttributeClasses.h" -#include "TargetAddressRangeList.h" #include "Types.h" @@ -22,7 +21,6 @@ struct AttributeValue { } block; uint64 constant; bool flag; - TargetAddressRangeList* rangeList; off_t pointer; DebugInfoEntry* reference; const char* string; @@ -94,13 +92,11 @@ struct AttributeValue { this->pointer = value; } - void SetToRangeList(TargetAddressRangeList* rangeList) + void SetToRangeListPointer(off_t value) { Unset(); attributeClass = ATTRIBUTE_CLASS_RANGELISTPTR; - this->rangeList = rangeList; - if (rangeList != NULL) - rangeList->AddReference(); + this->pointer = value; } void SetToReference(DebugInfoEntry* entry) @@ -119,10 +115,6 @@ struct AttributeValue { void Unset() { - if (attributeClass == ATTRIBUTE_CLASS_RANGELISTPTR - && rangeList != NULL) { - rangeList->RemoveReference(); - } attributeClass = ATTRIBUTE_CLASS_UNKNOWN; } diff --git a/src/apps/debugger/dwarf/CompilationUnit.cpp b/src/apps/debugger/dwarf/CompilationUnit.cpp index 4eb9792a87..585e755022 100644 --- a/src/apps/debugger/dwarf/CompilationUnit.cpp +++ b/src/apps/debugger/dwarf/CompilationUnit.cpp @@ -3,10 +3,14 @@ * Distributed under the terms of the MIT License. */ + #include "CompilationUnit.h" #include +#include "DebugInfoEntries.h" +#include "TargetAddressRangeList.h" + struct CompilationUnit::File { BString fileName; @@ -32,6 +36,7 @@ CompilationUnit::CompilationUnit(off_t headerOffset, off_t contentOffset, fAbbreviationOffset(abbreviationOffset), fAbbreviationTable(NULL), fUnitEntry(NULL), + fAddressRanges(NULL), fDirectories(10, true), fFiles(10, true), fLineNumberProgram(addressSize), @@ -43,6 +48,7 @@ CompilationUnit::CompilationUnit(off_t headerOffset, off_t contentOffset, CompilationUnit::~CompilationUnit() { + SetAddressRanges(NULL); } @@ -74,6 +80,29 @@ CompilationUnit::SetUnitEntry(DIECompileUnitBase* entry) } +void +CompilationUnit::SetAddressRanges(TargetAddressRangeList* ranges) +{ + if (fAddressRanges != NULL) + fAddressRanges->ReleaseReference(); + + fAddressRanges = ranges; + + if (fAddressRanges != NULL) + fAddressRanges->AcquireReference(); +} + + +target_addr_t +CompilationUnit::AddressRangeBase() const +{ + if (fAddressRanges != NULL) + return fAddressRanges->LowestAddress(); + + return fUnitEntry != NULL ? fUnitEntry->LowPC() : 0; +} + + int CompilationUnit::CountEntries() const { diff --git a/src/apps/debugger/dwarf/CompilationUnit.h b/src/apps/debugger/dwarf/CompilationUnit.h index 5210fa9cc6..3dc0ebbdd7 100644 --- a/src/apps/debugger/dwarf/CompilationUnit.h +++ b/src/apps/debugger/dwarf/CompilationUnit.h @@ -5,6 +5,7 @@ #ifndef COMPILATION_UNIT_H #define COMPILATION_UNIT_H + #include #include @@ -17,6 +18,7 @@ class AbbreviationTable; class DebugInfoEntry; class DIECompileUnitBase; +class TargetAddressRangeList; class CompilationUnit { @@ -51,6 +53,13 @@ public: DIECompileUnitBase* UnitEntry() const { return fUnitEntry; } void SetUnitEntry(DIECompileUnitBase* entry); + TargetAddressRangeList* AddressRanges() const + { return fAddressRanges; } + void SetAddressRanges( + TargetAddressRangeList* ranges); + + target_addr_t AddressRangeBase() const; + LineNumberProgram& GetLineNumberProgram() { return fLineNumberProgram; } @@ -82,6 +91,7 @@ private: off_t fAbbreviationOffset; AbbreviationTable* fAbbreviationTable; DIECompileUnitBase* fUnitEntry; + TargetAddressRangeList* fAddressRanges; Array fEntries; Array fEntryOffsets; DirectoryList fDirectories; diff --git a/src/apps/debugger/dwarf/DebugInfoEntries.cpp b/src/apps/debugger/dwarf/DebugInfoEntries.cpp index bd2927ccb0..d8a54df97d 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntries.cpp +++ b/src/apps/debugger/dwarf/DebugInfoEntries.cpp @@ -21,10 +21,9 @@ DIECompileUnitBase::DIECompileUnitBase() fCompilationDir(NULL), fLowPC(0), fHighPC(0), - fStatementListOffset(0), - fMacroInfoOffset(0), - // TODO: Is 0 a good invalid offset? - fAddressRanges(NULL), + fStatementListOffset(-1), + fMacroInfoOffset(-1), + fAddressRangesOffset(-1), fBaseTypesUnit(NULL), fLanguage(0), fIdentifierCase(0), @@ -35,8 +34,6 @@ DIECompileUnitBase::DIECompileUnitBase() DIECompileUnitBase::~DIECompileUnitBase() { - if (fAddressRanges != NULL) - fAddressRanges->RemoveReference(); } @@ -73,16 +70,6 @@ DIECompileUnitBase::Name() const } -target_addr_t -DIECompileUnitBase::AddressRangeBase() const -{ - if (fAddressRanges != NULL) - return fAddressRanges->LowestAddress(); - - return fLowPC; -} - - status_t DIECompileUnitBase::AddChild(DebugInfoEntry* child) { @@ -197,14 +184,7 @@ status_t DIECompileUnitBase::AddAttribute_ranges(uint16 attributeName, const AttributeValue& value) { - if (fAddressRanges != NULL) - fAddressRanges->RemoveReference(); - - fAddressRanges = value.rangeList; - - if (fAddressRanges != NULL) - fAddressRanges->AddReference(); - + fAddressRangesOffset = value.pointer; return B_OK; } @@ -1547,7 +1527,7 @@ DIESubprogram::DIESubprogram() : fLowPC(0), fHighPC(0), - fAddressRanges(NULL), + fAddressRangesOffset(-1), fSpecification(NULL), fAbstractOrigin(NULL), fReturnType(NULL), @@ -1560,8 +1540,6 @@ DIESubprogram::DIESubprogram() DIESubprogram::~DIESubprogram() { - if (fAddressRanges != NULL) - fAddressRanges->RemoveReference(); } @@ -1609,14 +1587,7 @@ status_t DIESubprogram::AddAttribute_ranges(uint16 attributeName, const AttributeValue& value) { - if (fAddressRanges != NULL) - fAddressRanges->RemoveReference(); - - fAddressRanges = value.rangeList; - - if (fAddressRanges != NULL) - fAddressRanges->AddReference(); - + fAddressRangesOffset = value.pointer; return B_OK; } diff --git a/src/apps/debugger/dwarf/DebugInfoEntries.h b/src/apps/debugger/dwarf/DebugInfoEntries.h index e974e5cec0..0cccb7a2ed 100644 --- a/src/apps/debugger/dwarf/DebugInfoEntries.h +++ b/src/apps/debugger/dwarf/DebugInfoEntries.h @@ -151,12 +151,11 @@ public: const DebugInfoEntryList& Types() const { return fTypes; } const DebugInfoEntryList& OtherChildren() const { return fOtherChildren; } - TargetAddressRangeList* AddressRanges() const - { return fAddressRanges; } + off_t AddressRangesOffset() const + { return fAddressRangesOffset; } target_addr_t LowPC() const { return fLowPC; } target_addr_t HighPC() const { return fHighPC; } - target_addr_t AddressRangeBase() const; off_t StatementListOffset() const { return fStatementListOffset; } @@ -202,7 +201,7 @@ protected: target_addr_t fHighPC; off_t fStatementListOffset; off_t fMacroInfoOffset; - TargetAddressRangeList* fAddressRanges; + off_t fAddressRangesOffset; DIECompileUnitBase* fBaseTypesUnit; DebugInfoEntryList fTypes; DebugInfoEntryList fOtherChildren; @@ -1025,8 +1024,8 @@ public: virtual DebugInfoEntry* Specification() const; virtual DebugInfoEntry* AbstractOrigin() const; - TargetAddressRangeList* AddressRanges() const - { return fAddressRanges; } + off_t AddressRangesOffset() const + { return fAddressRangesOffset; } target_addr_t LowPC() const { return fLowPC; } target_addr_t HighPC() const { return fHighPC; } @@ -1057,7 +1056,7 @@ public: protected: target_addr_t fLowPC; target_addr_t fHighPC; - TargetAddressRangeList* fAddressRanges; + off_t fAddressRangesOffset; DIESubprogram* fSpecification; DIESubprogram* fAbstractOrigin; DIEType* fReturnType; diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp b/src/apps/debugger/dwarf/DwarfFile.cpp index dc544f74d1..65b8c4130c 100644 --- a/src/apps/debugger/dwarf/DwarfFile.cpp +++ b/src/apps/debugger/dwarf/DwarfFile.cpp @@ -223,6 +223,52 @@ DwarfFile::CompilationUnitForDIE(const DebugInfoEntry* entry) const } +TargetAddressRangeList* +DwarfFile::ResolveRangeList(CompilationUnit* unit, uint64 offset) const +{ + if (unit == NULL || fDebugRangesSection == NULL) + return NULL; + + if (offset < 0 || offset >= (uint64)fDebugRangesSection->Size()) + return NULL; + + TargetAddressRangeList* ranges = new(std::nothrow) TargetAddressRangeList; + if (ranges == NULL) { + fprintf(stderr, "Out of memory.\n"); + return NULL; + } + Reference rangesReference(ranges, true); + + target_addr_t baseAddress = unit->AddressRangeBase(); + target_addr_t maxAddress = unit->MaxAddress(); + + DataReader dataReader((uint8*)fDebugRangesSection->Data() + offset, + fDebugRangesSection->Size() - offset, unit->AddressSize()); + while (true) { + target_addr_t start = dataReader.ReadAddress(0); + target_addr_t end = dataReader.ReadAddress(0); + if (dataReader.HasOverflow()) + return NULL; + + if (start == 0 && end == 0) + break; + if (start == maxAddress) { + baseAddress = end; + continue; + } + if (start == end) + continue; + + if (!ranges->AddRange(baseAddress + start, end - start)) { + fprintf(stderr, "Out of memory.\n"); + return NULL; + } + } + + return rangesReference.Detach(); +} + + status_t DwarfFile::UnwindCallFrame(CompilationUnit* unit, target_addr_t location, const DwarfTargetInterface* inputInterface, @@ -581,6 +627,13 @@ printf("entry %p at %lld\n", entry, offset); } } + // resolve the compilation unit's address range list + if (TargetAddressRangeList* ranges = ResolveRangeList(unit, + unit->UnitEntry()->AddressRangesOffset())) { + unit->SetAddressRanges(ranges); + ranges->ReleaseReference(); + } + // add compilation dir to directory list const char* compilationDir = unit->UnitEntry()->CompilationDir(); if (!unit->AddDirectory(compilationDir != NULL ? compilationDir : ".")) @@ -743,15 +796,8 @@ DwarfFile::_ParseEntryAttributes(DataReader& dataReader, attributeValue.SetToMacroPointer(value); break; case ATTRIBUTE_CLASS_RANGELISTPTR: - { - if (entry != NULL) { - TargetAddressRangeList* rangeList - = _ResolveRangeList(value); - Reference reference(rangeList); - attributeValue.SetToRangeList(rangeList); - } + attributeValue.SetToRangeListPointer(value); break; - } case ATTRIBUTE_CLASS_REFERENCE: if (entry != NULL) { attributeValue.SetToReference(_ResolveReference(value, @@ -1334,51 +1380,3 @@ DwarfFile::_ResolveReference(uint64 offset, bool localReference) const // TODO: Implement program-global references! return NULL; } - - -TargetAddressRangeList* -DwarfFile::_ResolveRangeList(uint64 offset) -{ - if (fDebugRangesSection == NULL) - return NULL; - - if (offset >= (uint64)fDebugRangesSection->Size()) - return NULL; - - TargetAddressRangeList* ranges = new(std::nothrow) TargetAddressRangeList; - if (ranges == NULL) { - fprintf(stderr, "Out of memory.\n"); - return NULL; - } - Reference rangesReference(ranges); - - target_addr_t baseAddress - = fCurrentCompilationUnit->UnitEntry()->AddressRangeBase(); - target_addr_t maxAddress = fCurrentCompilationUnit->MaxAddress(); - - DataReader dataReader((uint8*)fDebugRangesSection->Data() + offset, - fDebugRangesSection->Size() - offset, - fCurrentCompilationUnit->AddressSize()); - while (true) { - target_addr_t start = dataReader.ReadAddress(0); - target_addr_t end = dataReader.ReadAddress(0); - if (dataReader.HasOverflow()) - return NULL; - - if (start == 0 && end == 0) - break; - if (start == maxAddress) { - baseAddress = end; - continue; - } - if (start == end) - continue; - - if (!ranges->AddRange(baseAddress + start, end - start)) { - fprintf(stderr, "Out of memory.\n"); - return NULL; - } - } - - return rangesReference.Detach(); -} diff --git a/src/apps/debugger/dwarf/DwarfFile.h b/src/apps/debugger/dwarf/DwarfFile.h index 46d5f0eb21..27fb2cd889 100644 --- a/src/apps/debugger/dwarf/DwarfFile.h +++ b/src/apps/debugger/dwarf/DwarfFile.h @@ -39,6 +39,9 @@ public: CompilationUnit* CompilationUnitForDIE( const DebugInfoEntry* entry) const; + TargetAddressRangeList* ResolveRangeList(CompilationUnit* unit, + uint64 offset) const; + status_t UnwindCallFrame(CompilationUnit* unit, target_addr_t location, const DwarfTargetInterface* inputInterface,