Rather resolve range lists lazily. We need them for all functions, but there
are a lot more DIEs that have range lists. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31586 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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<TargetAddressRangeList> 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<TargetAddressRangeList> rangeListReference(rangeList,
|
||||
true);
|
||||
|
||||
// get the source location
|
||||
const char* directoryPath = NULL;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "CompilationUnit.h"
|
||||
|
||||
#include <new>
|
||||
|
||||
#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
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef COMPILATION_UNIT_H
|
||||
#define COMPILATION_UNIT_H
|
||||
|
||||
|
||||
#include <String.h>
|
||||
|
||||
#include <ObjectList.h>
|
||||
@@ -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<DebugInfoEntry*> fEntries;
|
||||
Array<off_t> fEntryOffsets;
|
||||
DirectoryList fDirectories;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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<TargetAddressRangeList> 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<TargetAddressRangeList> 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<TargetAddressRangeList> 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();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user