* Got rid of dwarf_{addr,off,size}_t. Consequently use 64 bit types instead.

* Made the DWARF code fully 64 bit aware (hopefully).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31546 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-07-13 23:03:36 +00:00
parent 487862c6bc
commit 106c4d4020
19 changed files with 196 additions and 161 deletions

View File

@ -292,10 +292,15 @@ printf(" %ld compilation units\n", fFile->CountCompilationUnits());
status_t status_t
DwarfImageDebugInfo::CreateFrame(Image* image, FunctionDebugInfo* function, DwarfImageDebugInfo::CreateFrame(Image* image, FunctionDebugInfo* _function,
CpuState* cpuState, StackFrame*& _previousFrame, CpuState* cpuState, StackFrame*& _previousFrame,
CpuState*& _previousCpuState) CpuState*& _previousCpuState)
{ {
DwarfFunctionDebugInfo* function
= dynamic_cast<DwarfFunctionDebugInfo*>(_function);
if (function == NULL)
return B_BAD_VALUE;
int32 registerCount = fArchitecture->CountRegisters(); int32 registerCount = fArchitecture->CountRegisters();
const Register* registers = fArchitecture->Registers(); const Register* registers = fArchitecture->Registers();
@ -324,7 +329,7 @@ DwarfImageDebugInfo::CreateFrame(Image* image, FunctionDebugInfo* function,
// do the unwinding // do the unwinding
target_addr_t framePointer; target_addr_t framePointer;
error = fFile->UnwindCallFrame( error = fFile->UnwindCallFrame(function->GetCompilationUnit(),
cpuState->InstructionPointer() - fRelocationDelta, cpuState->InstructionPointer() - fRelocationDelta,
&inputInterface, &outputInterface, framePointer); &inputInterface, &outputInterface, framePointer);
if (error != B_OK) if (error != B_OK)
@ -610,7 +615,7 @@ DwarfImageDebugInfo::_AddSourceCodeInfo(CompilationUnit* unit,
int32 statementLine = -1; int32 statementLine = -1;
int32 statementColumn = -1; int32 statementColumn = -1;
while (program.GetNextRow(state)) { while (program.GetNextRow(state)) {
printf(" %#lx (%ld, %ld, %ld) %d\n", state.address, state.file, state.line, state.column, state.isStatement); printf(" %#llx (%ld, %ld, %ld) %d\n", state.address, state.file, state.line, state.column, state.isStatement);
bool isOurFile = state.file == fileIndex; bool isOurFile = state.file == fileIndex;
if (statementAddress != 0 if (statementAddress != 0

View File

@ -38,7 +38,8 @@ AbbreviationTable::Init(const void* section, off_t sectionSize)
if (error != B_OK) if (error != B_OK)
return error; return error;
DataReader abbrevReader(fData, fSize); DataReader abbrevReader(fData, fSize, 4);
// address size doesn't matter here
while (true) { while (true) {
bool nullEntry; bool nullEntry;

View File

@ -40,7 +40,8 @@ struct AbbreviationEntry {
void SetTo(uint32 code, const void* data, off_t size) void SetTo(uint32 code, const void* data, off_t size)
{ {
fCode = code; fCode = code;
fAttributesReader.SetTo(data, size); fAttributesReader.SetTo(data, size, 4);
// address size doesn't matter here
fTag = fAttributesReader.ReadUnsignedLEB128(0); fTag = fAttributesReader.ReadUnsignedLEB128(0);
fHasChildren = fAttributesReader.Read<uint8>(0); fHasChildren = fAttributesReader.Read<uint8>(0);
fData = fAttributesReader.Data(); fData = fAttributesReader.Data();

View File

@ -15,10 +15,10 @@ AttributeValue::ToString(char* buffer, size_t size)
{ {
switch (attributeClass) { switch (attributeClass) {
case ATTRIBUTE_CLASS_ADDRESS: case ATTRIBUTE_CLASS_ADDRESS:
snprintf(buffer, size, "%#lx", address); snprintf(buffer, size, "%#llx", address);
return buffer; return buffer;
case ATTRIBUTE_CLASS_BLOCK: case ATTRIBUTE_CLASS_BLOCK:
snprintf(buffer, size, "(%p, %#lx)", block.data, block.length); snprintf(buffer, size, "(%p, %#llx)", block.data, block.length);
return buffer; return buffer;
case ATTRIBUTE_CLASS_CONSTANT: case ATTRIBUTE_CLASS_CONSTANT:
snprintf(buffer, size, "%#llx", constant); snprintf(buffer, size, "%#llx", constant);
@ -30,7 +30,7 @@ AttributeValue::ToString(char* buffer, size_t size)
case ATTRIBUTE_CLASS_LOCLISTPTR: case ATTRIBUTE_CLASS_LOCLISTPTR:
case ATTRIBUTE_CLASS_MACPTR: case ATTRIBUTE_CLASS_MACPTR:
case ATTRIBUTE_CLASS_RANGELISTPTR: case ATTRIBUTE_CLASS_RANGELISTPTR:
snprintf(buffer, size, "%#lx", pointer); snprintf(buffer, size, "%#llx", pointer);
return buffer; return buffer;
case ATTRIBUTE_CLASS_REFERENCE: case ATTRIBUTE_CLASS_REFERENCE:
snprintf(buffer, size, "%p", reference); snprintf(buffer, size, "%p", reference);

View File

@ -6,8 +6,8 @@
#define ATTRIBUTE_VALUE_H #define ATTRIBUTE_VALUE_H
#include "AttributeClasses.h" #include "AttributeClasses.h"
#include "DwarfTypes.h"
#include "TargetAddressRangeList.h" #include "TargetAddressRangeList.h"
#include "Types.h"
class DebugInfoEntry; class DebugInfoEntry;
@ -15,15 +15,15 @@ class DebugInfoEntry;
struct AttributeValue { struct AttributeValue {
union { union {
dwarf_addr_t address; target_addr_t address;
struct { struct {
const void* data; const void* data;
dwarf_size_t length; off_t length;
} block; } block;
uint64 constant; uint64 constant;
bool flag; bool flag;
TargetAddressRangeList* rangeList; TargetAddressRangeList* rangeList;
dwarf_off_t pointer; off_t pointer;
DebugInfoEntry* reference; DebugInfoEntry* reference;
const char* string; const char* string;
}; };
@ -43,14 +43,14 @@ struct AttributeValue {
Unset(); Unset();
} }
void SetToAddress(dwarf_addr_t address) void SetToAddress(target_addr_t address)
{ {
Unset(); Unset();
attributeClass = ATTRIBUTE_CLASS_ADDRESS; attributeClass = ATTRIBUTE_CLASS_ADDRESS;
this->address = address; this->address = address;
} }
void SetToBlock(const void* data, dwarf_size_t length) void SetToBlock(const void* data, off_t length)
{ {
Unset(); Unset();
attributeClass = ATTRIBUTE_CLASS_BLOCK; attributeClass = ATTRIBUTE_CLASS_BLOCK;
@ -73,21 +73,21 @@ struct AttributeValue {
this->flag = value; this->flag = value;
} }
void SetToLinePointer(dwarf_off_t value) void SetToLinePointer(off_t value)
{ {
Unset(); Unset();
attributeClass = ATTRIBUTE_CLASS_LINEPTR; attributeClass = ATTRIBUTE_CLASS_LINEPTR;
this->pointer = value; this->pointer = value;
} }
void SetToLocationListPointer(dwarf_off_t value) void SetToLocationListPointer(off_t value)
{ {
Unset(); Unset();
attributeClass = ATTRIBUTE_CLASS_LOCLISTPTR; attributeClass = ATTRIBUTE_CLASS_LOCLISTPTR;
this->pointer = value; this->pointer = value;
} }
void SetToMacroPointer(dwarf_off_t value) void SetToMacroPointer(off_t value)
{ {
Unset(); Unset();
attributeClass = ATTRIBUTE_CLASS_MACPTR; attributeClass = ATTRIBUTE_CLASS_MACPTR;
@ -136,7 +136,7 @@ struct DynamicAttributeValue {
DebugInfoEntry* reference; DebugInfoEntry* reference;
struct { struct {
const void* data; const void* data;
dwarf_size_t length; off_t length;
} block; } block;
}; };
uint8 attributeClass; uint8 attributeClass;
@ -160,7 +160,7 @@ struct DynamicAttributeValue {
attributeClass = ATTRIBUTE_CLASS_REFERENCE; attributeClass = ATTRIBUTE_CLASS_REFERENCE;
} }
void SetTo(const void* data, dwarf_size_t length) void SetTo(const void* data, off_t length)
{ {
block.data = data; block.data = data;
block.length = length; block.length = length;
@ -175,7 +175,7 @@ struct ConstantAttributeValue {
const char* string; const char* string;
struct { struct {
const void* data; const void* data;
dwarf_size_t length; off_t length;
} block; } block;
}; };
uint8 attributeClass; uint8 attributeClass;
@ -199,7 +199,7 @@ struct ConstantAttributeValue {
attributeClass = ATTRIBUTE_CLASS_STRING; attributeClass = ATTRIBUTE_CLASS_STRING;
} }
void SetTo(const void* data, dwarf_size_t length) void SetTo(const void* data, off_t length)
{ {
block.data = data; block.data = data;
block.length = length; block.length = length;

View File

@ -9,8 +9,8 @@
#include "CfaContext.h" #include "CfaContext.h"
CfaContext::CfaContext(dwarf_addr_t targetLocation, CfaContext::CfaContext(target_addr_t targetLocation,
dwarf_addr_t initialLocation) target_addr_t initialLocation)
: :
fTargetLocation(targetLocation), fTargetLocation(targetLocation),
fLocation(initialLocation), fLocation(initialLocation),
@ -80,7 +80,7 @@ CfaContext::PopRuleSet()
void void
CfaContext::SetLocation(dwarf_addr_t location) CfaContext::SetLocation(target_addr_t location)
{ {
fLocation = location; fLocation = location;
} }

View File

@ -9,12 +9,13 @@
#include <ObjectList.h> #include <ObjectList.h>
#include "CfaRuleSet.h" #include "CfaRuleSet.h"
#include "Types.h"
class CfaContext { class CfaContext {
public: public:
CfaContext(dwarf_addr_t targetLocation, CfaContext(target_addr_t targetLocation,
dwarf_addr_t initialLocation); target_addr_t initialLocation);
~CfaContext(); ~CfaContext();
status_t Init(uint32 registerCount); status_t Init(uint32 registerCount);
@ -23,12 +24,12 @@ public:
status_t PushRuleSet(); status_t PushRuleSet();
status_t PopRuleSet(); status_t PopRuleSet();
dwarf_addr_t TargetLocation() const target_addr_t TargetLocation() const
{ return fTargetLocation; } { return fTargetLocation; }
dwarf_addr_t Location() const target_addr_t Location() const
{ return fLocation; } { return fLocation; }
void SetLocation(dwarf_addr_t location); void SetLocation(target_addr_t location);
uint32 CodeAlignment() const uint32 CodeAlignment() const
{ return fCodeAlignment; } { return fCodeAlignment; }
@ -53,8 +54,8 @@ private:
typedef BObjectList<CfaRuleSet> RuleSetList; typedef BObjectList<CfaRuleSet> RuleSetList;
private: private:
dwarf_addr_t fTargetLocation; target_addr_t fTargetLocation;
dwarf_addr_t fLocation; target_addr_t fLocation;
uint32 fCodeAlignment; uint32 fCodeAlignment;
int32 fDataAlignment; int32 fDataAlignment;
uint32 fReturnAddressRegister; uint32 fReturnAddressRegister;

View File

@ -6,7 +6,7 @@
#define CFA_RULE_H #define CFA_RULE_H
#include "DwarfTypes.h" #include "Types.h"
enum cfa_rule_type { enum cfa_rule_type {

View File

@ -22,9 +22,9 @@ struct CompilationUnit::File {
}; };
CompilationUnit::CompilationUnit(dwarf_off_t headerOffset, CompilationUnit::CompilationUnit(off_t headerOffset, off_t contentOffset,
dwarf_off_t contentOffset, dwarf_off_t totalSize, off_t totalSize, off_t abbreviationOffset, uint8 addressSize,
dwarf_off_t abbreviationOffset) bool isDwarf64)
: :
fHeaderOffset(headerOffset), fHeaderOffset(headerOffset),
fContentOffset(contentOffset), fContentOffset(contentOffset),
@ -33,7 +33,10 @@ CompilationUnit::CompilationUnit(dwarf_off_t headerOffset,
fAbbreviationTable(NULL), fAbbreviationTable(NULL),
fUnitEntry(NULL), fUnitEntry(NULL),
fDirectories(10, true), fDirectories(10, true),
fFiles(10, true) fFiles(10, true),
fLineNumberProgram(addressSize),
fAddressSize(addressSize),
fIsDwarf64(isDwarf64)
{ {
} }
@ -51,7 +54,7 @@ CompilationUnit::SetAbbreviationTable(AbbreviationTable* abbreviationTable)
status_t status_t
CompilationUnit::AddDebugInfoEntry(DebugInfoEntry* entry, dwarf_off_t offset) CompilationUnit::AddDebugInfoEntry(DebugInfoEntry* entry, off_t offset)
{ {
if (!fEntries.Add(entry)) if (!fEntries.Add(entry))
return B_NO_MEMORY; return B_NO_MEMORY;
@ -80,7 +83,7 @@ CompilationUnit::CountEntries() const
void void
CompilationUnit::GetEntryAt(int index, DebugInfoEntry*& entry, CompilationUnit::GetEntryAt(int index, DebugInfoEntry*& entry,
dwarf_off_t& offset) const off_t& offset) const
{ {
entry = fEntries[index]; entry = fEntries[index];
offset = fEntryOffsets[index]; offset = fEntryOffsets[index];
@ -88,7 +91,7 @@ CompilationUnit::GetEntryAt(int index, DebugInfoEntry*& entry,
DebugInfoEntry* DebugInfoEntry*
CompilationUnit::EntryForOffset(dwarf_off_t offset) const CompilationUnit::EntryForOffset(off_t offset) const
{ {
if (fEntries.IsEmpty()) if (fEntries.IsEmpty())
return NULL; return NULL;

View File

@ -10,8 +10,8 @@
#include <ObjectList.h> #include <ObjectList.h>
#include "Array.h" #include "Array.h"
#include "DwarfTypes.h"
#include "LineNumberProgram.h" #include "LineNumberProgram.h"
#include "Types.h"
class AbbreviationTable; class AbbreviationTable;
@ -21,23 +21,28 @@ class DIECompileUnitBase;
class CompilationUnit { class CompilationUnit {
public: public:
CompilationUnit(dwarf_off_t headerOffset, CompilationUnit(off_t headerOffset,
dwarf_off_t contentOffset, off_t contentOffset,
dwarf_off_t totalSize, off_t totalSize,
dwarf_off_t abbreviationOffset); off_t abbreviationOffset,
uint8 addressSize, bool isDwarf64);
~CompilationUnit(); ~CompilationUnit();
dwarf_off_t HeaderOffset() const { return fHeaderOffset; } off_t HeaderOffset() const { return fHeaderOffset; }
dwarf_off_t ContentOffset() const { return fContentOffset; } off_t ContentOffset() const { return fContentOffset; }
dwarf_off_t RelativeContentOffset() const off_t RelativeContentOffset() const
{ return fContentOffset - fHeaderOffset; } { return fContentOffset - fHeaderOffset; }
dwarf_off_t TotalSize() const { return fTotalSize; } off_t TotalSize() const { return fTotalSize; }
dwarf_off_t ContentSize() const off_t ContentSize() const
{ return fTotalSize { return fTotalSize
- RelativeContentOffset(); } - RelativeContentOffset(); }
dwarf_off_t AbbreviationOffset() const off_t AbbreviationOffset() const
{ return fAbbreviationOffset; } { return fAbbreviationOffset; }
uint8 AddressSize() const { return fAddressSize; }
inline target_addr_t MaxAddress() const;
bool IsDwarf64() const { return fIsDwarf64; }
AbbreviationTable* GetAbbreviationTable() const AbbreviationTable* GetAbbreviationTable() const
{ return fAbbreviationTable; } { return fAbbreviationTable; }
void SetAbbreviationTable( void SetAbbreviationTable(
@ -50,11 +55,11 @@ public:
{ return fLineNumberProgram; } { return fLineNumberProgram; }
status_t AddDebugInfoEntry(DebugInfoEntry* entry, status_t AddDebugInfoEntry(DebugInfoEntry* entry,
dwarf_off_t offset); off_t offset);
int CountEntries() const; int CountEntries() const;
void GetEntryAt(int index, DebugInfoEntry*& entry, void GetEntryAt(int index, DebugInfoEntry*& entry,
dwarf_off_t& offset) const; off_t& offset) const;
DebugInfoEntry* EntryForOffset(dwarf_off_t offset) const; DebugInfoEntry* EntryForOffset(off_t offset) const;
bool AddDirectory(const char* directory); bool AddDirectory(const char* directory);
int32 CountDirectories() const; int32 CountDirectories() const;
@ -71,18 +76,27 @@ private:
typedef BObjectList<File> FileList; typedef BObjectList<File> FileList;
private: private:
dwarf_off_t fHeaderOffset; off_t fHeaderOffset;
dwarf_off_t fContentOffset; off_t fContentOffset;
dwarf_off_t fTotalSize; off_t fTotalSize;
dwarf_off_t fAbbreviationOffset; off_t fAbbreviationOffset;
AbbreviationTable* fAbbreviationTable; AbbreviationTable* fAbbreviationTable;
DIECompileUnitBase* fUnitEntry; DIECompileUnitBase* fUnitEntry;
Array<DebugInfoEntry*> fEntries; Array<DebugInfoEntry*> fEntries;
Array<dwarf_off_t> fEntryOffsets; Array<off_t> fEntryOffsets;
DirectoryList fDirectories; DirectoryList fDirectories;
FileList fFiles; FileList fFiles;
LineNumberProgram fLineNumberProgram; LineNumberProgram fLineNumberProgram;
uint8 fAddressSize;
bool fIsDwarf64;
}; };
target_addr_t
CompilationUnit::MaxAddress() const
{
return fAddressSize == 4 ? 0xffffffffULL : 0xffffffffffffffffULL;
}
#endif // COMPILATION_UNIT_H #endif // COMPILATION_UNIT_H

View File

@ -5,7 +5,8 @@
#ifndef DATA_READER_H #ifndef DATA_READER_H
#define DATA_READER_H #define DATA_READER_H
#include <SupportDefs.h>
#include "Types.h"
class DataReader { class DataReader {
@ -15,19 +16,21 @@ public:
fData(NULL), fData(NULL),
fSize(0), fSize(0),
fInitialSize(0), fInitialSize(0),
fAddressSize(4),
fOverflow(false) fOverflow(false)
{ {
} }
DataReader(const void* data, off_t size) DataReader(const void* data, off_t size, uint8 addressSize)
{ {
SetTo(data, size); SetTo(data, size, addressSize);
} }
void SetTo(const void* data, off_t size) void SetTo(const void* data, off_t size, uint8 addressSize)
{ {
fData = (const uint8*)data; fData = (const uint8*)data;
fInitialSize = fSize = size; fInitialSize = fSize = size;
fAddressSize = addressSize;
fOverflow = false; fOverflow = false;
} }
@ -36,6 +39,16 @@ public:
return fSize > 0; return fSize > 0;
} }
uint32 AddressSize() const
{
return fAddressSize;
}
void SetAddressSize(uint8 addressSize)
{
fAddressSize = addressSize;
}
bool HasOverflow() const bool HasOverflow() const
{ {
return fOverflow; return fOverflow;
@ -85,6 +98,13 @@ public:
return data; return data;
} }
target_addr_t ReadAddress(target_addr_t defaultValue)
{
return fAddressSize == 4
? (target_addr_t)Read<uint32>(defaultValue)
: (target_addr_t)Read<uint64>(defaultValue);
}
uint64 ReadUnsignedLEB128(uint64 defaultValue) uint64 ReadUnsignedLEB128(uint64 defaultValue)
{ {
uint64 result = 0; uint64 result = 0;
@ -165,6 +185,7 @@ private:
const uint8* fData; const uint8* fData;
off_t fSize; off_t fSize;
off_t fInitialSize; off_t fInitialSize;
uint8 fAddressSize;
bool fOverflow; bool fOverflow;
}; };

View File

@ -73,7 +73,7 @@ DIECompileUnitBase::Name() const
} }
dwarf_addr_t target_addr_t
DIECompileUnitBase::AddressRangeBase() const DIECompileUnitBase::AddressRangeBase() const
{ {
if (fAddressRanges != NULL) if (fAddressRanges != NULL)
@ -1991,7 +1991,7 @@ DIECondition::Tag() const
DIESharedType::DIESharedType() DIESharedType::DIESharedType()
{ {
fBlockSize.SetTo(DWARF_ADDRESS_MAX); fBlockSize.SetTo(~(uint64)0);
} }

View File

@ -154,11 +154,11 @@ public:
TargetAddressRangeList* AddressRanges() const TargetAddressRangeList* AddressRanges() const
{ return fAddressRanges; } { return fAddressRanges; }
dwarf_addr_t LowPC() const { return fLowPC; } target_addr_t LowPC() const { return fLowPC; }
dwarf_addr_t HighPC() const { return fHighPC; } target_addr_t HighPC() const { return fHighPC; }
dwarf_addr_t AddressRangeBase() const; target_addr_t AddressRangeBase() const;
dwarf_off_t StatementListOffset() const off_t StatementListOffset() const
{ return fStatementListOffset; } { return fStatementListOffset; }
virtual status_t AddChild(DebugInfoEntry* child); virtual status_t AddChild(DebugInfoEntry* child);
@ -198,10 +198,10 @@ public:
protected: protected:
const char* fName; const char* fName;
const char* fCompilationDir; const char* fCompilationDir;
dwarf_addr_t fLowPC; target_addr_t fLowPC;
dwarf_addr_t fHighPC; target_addr_t fHighPC;
dwarf_off_t fStatementListOffset; off_t fStatementListOffset;
dwarf_off_t fMacroInfoOffset; off_t fMacroInfoOffset;
TargetAddressRangeList* fAddressRanges; TargetAddressRangeList* fAddressRanges;
DIECompileUnitBase* fBaseTypesUnit; DIECompileUnitBase* fBaseTypesUnit;
DebugInfoEntryList fTypes; DebugInfoEntryList fTypes;
@ -1028,8 +1028,8 @@ public:
TargetAddressRangeList* AddressRanges() const TargetAddressRangeList* AddressRanges() const
{ return fAddressRanges; } { return fAddressRanges; }
dwarf_addr_t LowPC() const { return fLowPC; } target_addr_t LowPC() const { return fLowPC; }
dwarf_addr_t HighPC() const { return fHighPC; } target_addr_t HighPC() const { return fHighPC; }
bool IsPrototyped() const { return fPrototyped; } bool IsPrototyped() const { return fPrototyped; }
uint8 Inline() const { return fInline; } uint8 Inline() const { return fInline; }
@ -1055,8 +1055,8 @@ public:
const AttributeValue& value); const AttributeValue& value);
protected: protected:
dwarf_addr_t fLowPC; target_addr_t fLowPC;
dwarf_addr_t fHighPC; target_addr_t fHighPC;
TargetAddressRangeList* fAddressRanges; TargetAddressRangeList* fAddressRanges;
DIESubprogram* fSpecification; DIESubprogram* fSpecification;
DIESubprogram* fAbstractOrigin; DIESubprogram* fAbstractOrigin;

View File

@ -9,7 +9,7 @@
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
#include "DwarfTypes.h" #include "Types.h"
#define DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(name) \ #define DECLARE_DEBUG_INFO_ENTRY_ATTR_SETTER(name) \

View File

@ -94,13 +94,14 @@ DwarfFile::Load(const char* fileName)
// iterate through the debug info section // iterate through the debug info section
DataReader dataReader(fDebugInfoSection->Data(), DataReader dataReader(fDebugInfoSection->Data(),
fDebugInfoSection->Size()); fDebugInfoSection->Size(), 4);
// address size doesn't matter here
while (dataReader.HasData()) { while (dataReader.HasData()) {
dwarf_off_t unitHeaderOffset = dataReader.Offset(); off_t unitHeaderOffset = dataReader.Offset();
bool dwarf64; bool dwarf64;
uint64 unitLength = dataReader.ReadInitialLength(dwarf64); uint64 unitLength = dataReader.ReadInitialLength(dwarf64);
dwarf_off_t unitLengthOffset = dataReader.Offset(); off_t unitLengthOffset = dataReader.Offset();
// the unitLength starts here // the unitLength starts here
if (unitLengthOffset + unitLength if (unitLengthOffset + unitLength
@ -131,19 +132,20 @@ DwarfFile::Load(const char* fileName)
break; break;
} }
if (addressSize != 4) { if (addressSize != 4 && addressSize != 8) {
printf("\"%s\": Unsupported address size: %d\n", fileName, printf("\"%s\": Unsupported address size: %d\n", fileName,
addressSize); addressSize);
break; break;
} }
dataReader.SetAddressSize(addressSize);
dwarf_off_t unitContentOffset = dataReader.Offset(); off_t unitContentOffset = dataReader.Offset();
// create a compilation unit object // create a compilation unit object
CompilationUnit* unit = new(std::nothrow) CompilationUnit( CompilationUnit* unit = new(std::nothrow) CompilationUnit(
unitHeaderOffset, unitContentOffset, unitHeaderOffset, unitContentOffset,
unitLength + (unitLengthOffset - unitHeaderOffset), unitLength + (unitLengthOffset - unitHeaderOffset),
abbrevOffset); abbrevOffset, addressSize, dwarf64);
if (unit == NULL || !fCompilationUnits.AddItem(unit)) { if (unit == NULL || !fCompilationUnits.AddItem(unit)) {
delete unit; delete unit;
return B_NO_MEMORY; return B_NO_MEMORY;
@ -222,7 +224,7 @@ DwarfFile::CompilationUnitForDIE(const DebugInfoEntry* entry) const
status_t status_t
DwarfFile::UnwindCallFrame(target_addr_t location, DwarfFile::UnwindCallFrame(CompilationUnit* unit, target_addr_t location,
const DwarfTargetInterface* inputInterface, const DwarfTargetInterface* inputInterface,
DwarfTargetInterface* outputInterface, target_addr_t& _framePointer) DwarfTargetInterface* outputInterface, target_addr_t& _framePointer)
{ {
@ -232,7 +234,7 @@ DwarfFile::UnwindCallFrame(target_addr_t location,
printf("DwarfFile::UnwindCallFrame(%#llx)\n", location); printf("DwarfFile::UnwindCallFrame(%#llx)\n", location);
DataReader dataReader((uint8*)fDebugFrameSection->Data(), DataReader dataReader((uint8*)fDebugFrameSection->Data(),
fDebugFrameSection->Size()); fDebugFrameSection->Size(), unit->AddressSize());
while (dataReader.BytesRemaining() > 0) { while (dataReader.BytesRemaining() > 0) {
// length // length
@ -249,8 +251,8 @@ printf("DwarfFile::UnwindCallFrame(%#llx)\n", location);
// this is a CIE -- skip it // this is a CIE -- skip it
} else { } else {
// this is a FDE // this is a FDE
dwarf_addr_t initialLocation = dataReader.Read<dwarf_addr_t>(0); target_addr_t initialLocation = dataReader.ReadAddress(0);
dwarf_size_t addressRange = dataReader.Read<dwarf_addr_t>(0); target_size_t addressRange = dataReader.ReadAddress(0);
if (dataReader.HasOverflow()) if (dataReader.HasOverflow())
return B_BAD_DATA; return B_BAD_DATA;
@ -262,7 +264,7 @@ printf("DwarfFile::UnwindCallFrame(%#llx)\n", location);
- (dataReader.Offset() - lengthOffset); - (dataReader.Offset() - lengthOffset);
if (remaining < 0) if (remaining < 0)
return B_BAD_DATA; return B_BAD_DATA;
printf(" found fde: length: %llu (%lld), CIE offset: %llu, location: %#lx, range: %#lx\n", length, remaining, cieID, printf(" found fde: length: %llu (%lld), CIE offset: %llu, location: %#llx, range: %#llx\n", length, remaining, cieID,
initialLocation, addressRange); initialLocation, addressRange);
CfaContext context(location, initialLocation); CfaContext context(location, initialLocation);
@ -285,7 +287,7 @@ initialLocation, addressRange);
} }
// process the CIE // process the CIE
error = _ParseCIE(context, cieID); error = _ParseCIE(unit, context, cieID);
if (error != B_OK) if (error != B_OK)
return error; return error;
@ -293,7 +295,7 @@ initialLocation, addressRange);
if (error != B_OK) if (error != B_OK)
return error; return error;
error = _ParseFrameInfoInstructions(context, error = _ParseFrameInfoInstructions(unit, context,
dataReader.Offset(), remaining); dataReader.Offset(), remaining);
if (error != B_OK) if (error != B_OK)
return error; return error;
@ -302,7 +304,7 @@ printf(" found row!\n");
// apply the rules of the final row // apply the rules of the final row
// get the frameAddress first // get the frameAddress first
dwarf_addr_t frameAddress; target_addr_t frameAddress;
CfaCfaRule* cfaCfaRule = context.GetCfaCfaRule(); CfaCfaRule* cfaCfaRule = context.GetCfaCfaRule();
switch (cfaCfaRule->Type()) { switch (cfaCfaRule->Type()) {
case CFA_CFA_RULE_REGISTER_OFFSET: case CFA_CFA_RULE_REGISTER_OFFSET:
@ -323,7 +325,7 @@ printf(" found row!\n");
default: default:
return B_BAD_VALUE; return B_BAD_VALUE;
} }
printf(" frame address: %#lx\n", frameAddress); printf(" frame address: %#llx\n", frameAddress);
// apply the register rules // apply the register rules
for (uint32 i = 0; i < registerCount; i++) { for (uint32 i = 0; i < registerCount; i++) {
@ -412,7 +414,7 @@ DwarfFile::_ParseCompilationUnit(CompilationUnit* unit)
DataReader dataReader( DataReader dataReader(
(const uint8*)fDebugInfoSection->Data() + unit->ContentOffset(), (const uint8*)fDebugInfoSection->Data() + unit->ContentOffset(),
unit->ContentSize()); unit->ContentSize(), unit->AddressSize());
DebugInfoEntry* entry; DebugInfoEntry* entry;
bool endOfEntryList; bool endOfEntryList;
@ -447,7 +449,7 @@ DwarfFile::_ParseDebugInfoEntry(DataReader& dataReader,
AbbreviationTable* abbreviationTable, DebugInfoEntry*& _entry, AbbreviationTable* abbreviationTable, DebugInfoEntry*& _entry,
bool& _endOfEntryList, int level) bool& _endOfEntryList, int level)
{ {
dwarf_off_t entryOffset = dataReader.Offset() off_t entryOffset = dataReader.Offset()
+ fCurrentCompilationUnit->RelativeContentOffset(); + fCurrentCompilationUnit->RelativeContentOffset();
uint32 code = dataReader.ReadUnsignedLEB128(0); uint32 code = dataReader.ReadUnsignedLEB128(0);
@ -467,7 +469,7 @@ DwarfFile::_ParseDebugInfoEntry(DataReader& dataReader,
fprintf(stderr, "No abbreviation entry for code %lu\n", code); fprintf(stderr, "No abbreviation entry for code %lu\n", code);
return B_BAD_DATA; return B_BAD_DATA;
} }
printf("%*sentry at %lu: %lu, tag: %s (%lu), children: %d\n", level * 2, "", printf("%*sentry at %lld: %lu, tag: %s (%lu), children: %d\n", level * 2, "",
entryOffset, abbreviationEntry.Code(), get_entry_tag_name(abbreviationEntry.Tag()), entryOffset, abbreviationEntry.Code(), get_entry_tag_name(abbreviationEntry.Tag()),
abbreviationEntry.Tag(), abbreviationEntry.HasChildren()); abbreviationEntry.Tag(), abbreviationEntry.HasChildren());
@ -536,10 +538,7 @@ printf("\nfinishing compilation unit %p\n", unit);
DataReader dataReader( DataReader dataReader(
(const uint8*)fDebugInfoSection->Data() + unit->HeaderOffset(), (const uint8*)fDebugInfoSection->Data() + unit->HeaderOffset(),
unit->TotalSize()); unit->TotalSize(), unit->AddressSize());
// DataReader dataReader(
// (const uint8*)fDebugInfoSection->Data() + unit->ContentOffset(),
// unit->ContentSize());
DebugInfoEntryInitInfo entryInitInfo; DebugInfoEntryInitInfo entryInitInfo;
@ -547,9 +546,9 @@ printf("\nfinishing compilation unit %p\n", unit);
for (int i = 0; i < entryCount; i++) { for (int i = 0; i < entryCount; i++) {
// get the entry // get the entry
DebugInfoEntry* entry; DebugInfoEntry* entry;
dwarf_off_t offset; off_t offset;
unit->GetEntryAt(i, entry, offset); unit->GetEntryAt(i, entry, offset);
printf("entry %p at %lu\n", entry, offset); printf("entry %p at %lld\n", entry, offset);
// seek the reader to the entry // seek the reader to the entry
dataReader.SeekAbsolute(offset); dataReader.SeekAbsolute(offset);
@ -617,12 +616,12 @@ DwarfFile::_ParseEntryAttributes(DataReader& dataReader,
// those that need additional processing, we read a temporary value // those that need additional processing, we read a temporary value
// first. // first.
uint64 value = 0; uint64 value = 0;
dwarf_size_t blockLength = 0; off_t blockLength = 0;
bool localReference = true; bool localReference = true;
switch (attributeForm) { switch (attributeForm) {
case DW_FORM_addr: case DW_FORM_addr:
value = dataReader.Read<dwarf_addr_t>(0); value = dataReader.ReadAddress(0);
break; break;
case DW_FORM_block2: case DW_FORM_block2:
blockLength = dataReader.Read<uint16>(0); blockLength = dataReader.Read<uint16>(0);
@ -661,9 +660,11 @@ DwarfFile::_ParseEntryAttributes(DataReader& dataReader,
case DW_FORM_strp: case DW_FORM_strp:
{ {
if (fDebugStringSection != NULL) { if (fDebugStringSection != NULL) {
dwarf_off_t offset = dataReader.Read<dwarf_off_t>(0); off_t offset = fCurrentCompilationUnit->IsDwarf64()
? (off_t)dataReader.Read<uint64>(0)
: (off_t)dataReader.Read<uint32>(0);
if (offset >= fDebugStringSection->Size()) { if (offset >= fDebugStringSection->Size()) {
fprintf(stderr, "Invalid DW_FORM_strp offset: %lu\n", fprintf(stderr, "Invalid DW_FORM_strp offset: %lld\n",
offset); offset);
return B_BAD_DATA; return B_BAD_DATA;
} }
@ -680,7 +681,9 @@ DwarfFile::_ParseEntryAttributes(DataReader& dataReader,
value = dataReader.ReadUnsignedLEB128(0); value = dataReader.ReadUnsignedLEB128(0);
break; break;
case DW_FORM_ref_addr: case DW_FORM_ref_addr:
value = dataReader.Read<dwarf_off_t>(0); value = fCurrentCompilationUnit->IsDwarf64()
? dataReader.Read<uint64>(0)
: (uint64)dataReader.Read<uint32>(0);
localReference = false; localReference = false;
break; break;
case DW_FORM_ref1: case DW_FORM_ref1:
@ -818,11 +821,11 @@ printf(" -> no attribute setter!\n");
status_t status_t
DwarfFile::_ParseLineInfo(CompilationUnit* unit) DwarfFile::_ParseLineInfo(CompilationUnit* unit)
{ {
dwarf_off_t offset = unit->UnitEntry()->StatementListOffset(); off_t offset = unit->UnitEntry()->StatementListOffset();
printf("DwarfFile::_ParseLineInfo(%p), offset: %lu\n", unit, offset); printf("DwarfFile::_ParseLineInfo(%p), offset: %lld\n", unit, offset);
DataReader dataReader((uint8*)fDebugLineSection->Data() + offset, DataReader dataReader((uint8*)fDebugLineSection->Data() + offset,
fDebugLineSection->Size() - offset); fDebugLineSection->Size() - offset, unit->AddressSize());
// unit length // unit length
bool dwarf64; bool dwarf64;
@ -921,13 +924,14 @@ printf("DwarfFile::_ParseLineInfo(%p), offset: %lu\n", unit, offset);
status_t status_t
DwarfFile::_ParseCIE(CfaContext& context, dwarf_off_t cieOffset) DwarfFile::_ParseCIE(CompilationUnit* unit, CfaContext& context,
off_t cieOffset)
{ {
if (cieOffset < 0 || cieOffset >= fDebugFrameSection->Size()) if (cieOffset < 0 || cieOffset >= fDebugFrameSection->Size())
return B_BAD_DATA; return B_BAD_DATA;
DataReader dataReader((uint8*)fDebugFrameSection->Data() + cieOffset, DataReader dataReader((uint8*)fDebugFrameSection->Data() + cieOffset,
fDebugFrameSection->Size() - cieOffset); fDebugFrameSection->Size() - cieOffset, unit->AddressSize());
// length // length
bool dwarf64; bool dwarf64;
@ -962,20 +966,21 @@ context.ReturnAddressRegister());
if (remaining < 0) if (remaining < 0)
return B_BAD_DATA; return B_BAD_DATA;
return _ParseFrameInfoInstructions(context, dataReader.Offset(), remaining); return _ParseFrameInfoInstructions(unit, context, dataReader.Offset(),
remaining);
} }
status_t status_t
DwarfFile::_ParseFrameInfoInstructions(CfaContext& context, DwarfFile::_ParseFrameInfoInstructions(CompilationUnit* unit,
dwarf_off_t instructionOffset, dwarf_off_t instructionSize) CfaContext& context, off_t instructionOffset, off_t instructionSize)
{ {
if (instructionSize <= 0) if (instructionSize <= 0)
return B_OK; return B_OK;
DataReader dataReader( DataReader dataReader(
(uint8*)fDebugFrameSection->Data() + instructionOffset, (uint8*)fDebugFrameSection->Data() + instructionOffset,
instructionSize); instructionSize, unit->AddressSize());
while (dataReader.BytesRemaining() > 0) { while (dataReader.BytesRemaining() > 0) {
printf(" [%2lld]", dataReader.BytesRemaining()); printf(" [%2lld]", dataReader.BytesRemaining());
@ -987,7 +992,7 @@ printf(" [%2lld]", dataReader.BytesRemaining());
case DW_CFA_advance_loc: case DW_CFA_advance_loc:
{ {
printf(" DW_CFA_advance_loc: %#lx\n", operand); printf(" DW_CFA_advance_loc: %#lx\n", operand);
dwarf_addr_t location = context.Location() target_addr_t location = context.Location()
+ operand * context.CodeAlignment(); + operand * context.CodeAlignment();
if (location > context.TargetLocation()) if (location > context.TargetLocation())
return B_OK; return B_OK;
@ -1020,8 +1025,8 @@ printf(" DW_CFA_restore: %#lx\n", operand);
} }
case DW_CFA_set_loc: case DW_CFA_set_loc:
{ {
dwarf_addr_t location = dataReader.Read<dwarf_addr_t>(0); target_addr_t location = dataReader.ReadAddress(0);
printf(" DW_CFA_set_loc: %#lx\n", location); printf(" DW_CFA_set_loc: %#llx\n", location);
if (location < context.Location()) if (location < context.Location())
return B_BAD_VALUE; return B_BAD_VALUE;
if (location > context.TargetLocation()) if (location > context.TargetLocation())
@ -1033,7 +1038,7 @@ printf(" DW_CFA_set_loc: %#lx\n", location);
{ {
uint32 delta = dataReader.Read<uint8>(0); uint32 delta = dataReader.Read<uint8>(0);
printf(" DW_CFA_advance_loc1: %#lx\n", delta); printf(" DW_CFA_advance_loc1: %#lx\n", delta);
dwarf_addr_t location = context.Location() target_addr_t location = context.Location()
+ delta * context.CodeAlignment(); + delta * context.CodeAlignment();
if (location > context.TargetLocation()) if (location > context.TargetLocation())
return B_OK; return B_OK;
@ -1044,7 +1049,7 @@ printf(" DW_CFA_advance_loc1: %#lx\n", delta);
{ {
uint32 delta = dataReader.Read<uint16>(0); uint32 delta = dataReader.Read<uint16>(0);
printf(" DW_CFA_advance_loc2: %#lx\n", delta); printf(" DW_CFA_advance_loc2: %#lx\n", delta);
dwarf_addr_t location = context.Location() target_addr_t location = context.Location()
+ delta * context.CodeAlignment(); + delta * context.CodeAlignment();
if (location > context.TargetLocation()) if (location > context.TargetLocation())
return B_OK; return B_OK;
@ -1055,7 +1060,7 @@ printf(" DW_CFA_advance_loc2: %#lx\n", delta);
{ {
uint32 delta = dataReader.Read<uint32>(0); uint32 delta = dataReader.Read<uint32>(0);
printf(" DW_CFA_advance_loc4: %#lx\n", delta); printf(" DW_CFA_advance_loc4: %#lx\n", delta);
dwarf_addr_t location = context.Location() target_addr_t location = context.Location()
+ delta * context.CodeAlignment(); + delta * context.CodeAlignment();
if (location > context.TargetLocation()) if (location > context.TargetLocation())
return B_OK; return B_OK;
@ -1243,7 +1248,7 @@ printf(" DW_CFA_val_expression: reg: %lu, block: %p, %llu\n", reg, block, blo
{ {
uint64 delta = dataReader.Read<uint64>(0); uint64 delta = dataReader.Read<uint64>(0);
printf(" DW_CFA_MIPS_advance_loc8: %#llx\n", delta); printf(" DW_CFA_MIPS_advance_loc8: %#llx\n", delta);
dwarf_addr_t location = context.Location() target_addr_t location = context.Location()
+ delta * context.CodeAlignment(); + delta * context.CodeAlignment();
if (location > context.TargetLocation()) if (location > context.TargetLocation())
return B_OK; return B_OK;
@ -1347,20 +1352,22 @@ DwarfFile::_ResolveRangeList(uint64 offset)
} }
Reference<TargetAddressRangeList> rangesReference(ranges); Reference<TargetAddressRangeList> rangesReference(ranges);
dwarf_addr_t baseAddress target_addr_t baseAddress
= fCurrentCompilationUnit->UnitEntry()->AddressRangeBase(); = fCurrentCompilationUnit->UnitEntry()->AddressRangeBase();
target_addr_t maxAddress = fCurrentCompilationUnit->MaxAddress();
DataReader dataReader((uint8*)fDebugRangesSection->Data() + offset, DataReader dataReader((uint8*)fDebugRangesSection->Data() + offset,
fDebugRangesSection->Size() - offset); fDebugRangesSection->Size() - offset,
fCurrentCompilationUnit->AddressSize());
while (true) { while (true) {
dwarf_addr_t start = dataReader.Read<dwarf_addr_t>(0); target_addr_t start = dataReader.ReadAddress(0);
dwarf_addr_t end = dataReader.Read<dwarf_addr_t>(0); target_addr_t end = dataReader.ReadAddress(0);
if (dataReader.HasOverflow()) if (dataReader.HasOverflow())
return NULL; return NULL;
if (start == 0 && end == 0) if (start == 0 && end == 0)
break; break;
if (start == DWARF_ADDRESS_MAX) { if (start == maxAddress) {
baseAddress = end; baseAddress = end;
continue; continue;
} }

View File

@ -39,7 +39,8 @@ public:
CompilationUnit* CompilationUnitForDIE( CompilationUnit* CompilationUnitForDIE(
const DebugInfoEntry* entry) const; const DebugInfoEntry* entry) const;
status_t UnwindCallFrame(target_addr_t location, status_t UnwindCallFrame(CompilationUnit* unit,
target_addr_t location,
const DwarfTargetInterface* inputInterface, const DwarfTargetInterface* inputInterface,
DwarfTargetInterface* outputInterface, DwarfTargetInterface* outputInterface,
target_addr_t& _framePointer); target_addr_t& _framePointer);
@ -61,11 +62,12 @@ private:
status_t _ParseLineInfo(CompilationUnit* unit); status_t _ParseLineInfo(CompilationUnit* unit);
status_t _ParseCIE(CfaContext& context, status_t _ParseCIE(CompilationUnit* unit,
dwarf_off_t cieOffset); CfaContext& context, off_t cieOffset);
status_t _ParseFrameInfoInstructions(CfaContext& context, status_t _ParseFrameInfoInstructions(
dwarf_off_t instructionOffset, CompilationUnit* unit, CfaContext& context,
dwarf_off_t instructionSize); off_t instructionOffset,
off_t instructionSize);
status_t _GetAbbreviationTable(off_t offset, status_t _GetAbbreviationTable(off_t offset,
AbbreviationTable*& _table); AbbreviationTable*& _table);

View File

@ -1,22 +0,0 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef DWARF_TYPES_H
#define DWARF_TYPES_H
#include <SupportDefs.h>
// target address type
typedef uint32 dwarf_addr_t;
// DWARF 32 or 64 offset/size types
typedef uint32 dwarf_off_t;
typedef uint32 dwarf_size_t;
#define DWARF_ADDRESS_MAX 0xffffffff
#endif // DWARF_TYPES_H

View File

@ -18,7 +18,7 @@ static const uint8 kLineNumberStandardOpcodeOperands[]
static const uint32 kLineNumberStandardOpcodeCount = 12; static const uint32 kLineNumberStandardOpcodeCount = 12;
LineNumberProgram::LineNumberProgram() LineNumberProgram::LineNumberProgram(uint8 addressSize)
: :
fProgram(NULL), fProgram(NULL),
fProgramSize(0), fProgramSize(0),
@ -27,6 +27,7 @@ LineNumberProgram::LineNumberProgram()
fLineBase(0), fLineBase(0),
fLineRange(0), fLineRange(0),
fOpcodeBase(0), fOpcodeBase(0),
fAddressSize(addressSize),
fStandardOpcodeLengths(NULL) fStandardOpcodeLengths(NULL)
{ {
} }
@ -72,7 +73,7 @@ LineNumberProgram::GetInitialState(State& state) const
return; return;
_SetToInitial(state); _SetToInitial(state);
state.dataReader.SetTo(fProgram, fProgramSize); state.dataReader.SetTo(fProgram, fProgramSize, fAddressSize);
} }
@ -160,7 +161,7 @@ printf("unsupported standard opcode %u\n", opcode);
appendRow = true; appendRow = true;
break; break;
case DW_LNE_set_address: case DW_LNE_set_address:
state.address = dataReader.Read<dwarf_addr_t>(0); state.address = dataReader.ReadAddress(0);
break; break;
case DW_LNE_define_file: case DW_LNE_define_file:
{ {

View File

@ -6,7 +6,7 @@
#define LINE_NUMBER_PROGRAM_H #define LINE_NUMBER_PROGRAM_H
#include "DataReader.h" #include "DataReader.h"
#include "DwarfTypes.h" #include "Types.h"
class LineNumberProgram { class LineNumberProgram {
@ -14,7 +14,7 @@ public:
struct State; struct State;
public: public:
LineNumberProgram(); LineNumberProgram(uint8 addressSize);
~LineNumberProgram(); ~LineNumberProgram();
status_t Init(const void* program, size_t programSize, status_t Init(const void* program, size_t programSize,
@ -38,12 +38,13 @@ private:
int8 fLineBase; int8 fLineBase;
uint8 fLineRange; uint8 fLineRange;
uint8 fOpcodeBase; uint8 fOpcodeBase;
uint8 fAddressSize;
const uint8* fStandardOpcodeLengths; const uint8* fStandardOpcodeLengths;
}; };
struct LineNumberProgram::State { struct LineNumberProgram::State {
dwarf_addr_t address; target_addr_t address;
int32 file; int32 file;
int32 line; int32 line;
int32 column; int32 column;