From 4bf83686751337b8cd29e14b6059ea25506bea51 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 16 Jul 2013 22:40:21 -0400 Subject: [PATCH] Add TypeUnit and refactor. - Pull common base class BaseUnit out of CompilationUnit and adjust the latter to inherit. - Add TypeUnit to represent the top level units for .debug_types. --- src/apps/debugger/dwarf/BaseUnit.cpp | 97 +++++++++++++++++++++ src/apps/debugger/dwarf/BaseUnit.h | 84 ++++++++++++++++++ src/apps/debugger/dwarf/CompilationUnit.cpp | 84 +++--------------- src/apps/debugger/dwarf/CompilationUnit.h | 56 ++---------- src/apps/debugger/dwarf/Jamfile | 2 + src/apps/debugger/dwarf/TypeUnit.cpp | 51 +++++++++++ src/apps/debugger/dwarf/TypeUnit.h | 89 +++++++++++++++++++ 7 files changed, 341 insertions(+), 122 deletions(-) create mode 100644 src/apps/debugger/dwarf/BaseUnit.cpp create mode 100644 src/apps/debugger/dwarf/BaseUnit.h create mode 100644 src/apps/debugger/dwarf/TypeUnit.cpp create mode 100644 src/apps/debugger/dwarf/TypeUnit.h diff --git a/src/apps/debugger/dwarf/BaseUnit.cpp b/src/apps/debugger/dwarf/BaseUnit.cpp new file mode 100644 index 0000000000..f0bb2da8cb --- /dev/null +++ b/src/apps/debugger/dwarf/BaseUnit.cpp @@ -0,0 +1,97 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ + + +#include "BaseUnit.h" + +#include + +#include "DebugInfoEntries.h" + + +BaseUnit::BaseUnit(off_t headerOffset, off_t contentOffset, + off_t totalSize, off_t abbreviationOffset, uint8 addressSize, + bool isDwarf64) + : + fHeaderOffset(headerOffset), + fContentOffset(contentOffset), + fTotalSize(totalSize), + fAbbreviationOffset(abbreviationOffset), + fAbbreviationTable(NULL), + fAddressSize(addressSize), + fIsDwarf64(isDwarf64) +{ +} + + +BaseUnit::~BaseUnit() +{ +} + + +void +BaseUnit::SetAbbreviationTable(AbbreviationTable* abbreviationTable) +{ + fAbbreviationTable = abbreviationTable; +} + + +status_t +BaseUnit::AddDebugInfoEntry(DebugInfoEntry* entry, off_t offset) +{ + if (!fEntries.Add(entry)) + return B_NO_MEMORY; + if (!fEntryOffsets.Add(offset)) { + fEntries.Remove(fEntries.Count() - 1); + return B_NO_MEMORY; + } + + return B_OK; +} + + +void +BaseUnit::SetSourceLanguage(const SourceLanguageInfo* language) +{ + fSourceLanguage = language; +} + + +int +BaseUnit::CountEntries() const +{ + return fEntries.Count(); +} + + +void +BaseUnit::GetEntryAt(int index, DebugInfoEntry*& entry, + off_t& offset) const +{ + entry = fEntries[index]; + offset = fEntryOffsets[index]; +} + + +DebugInfoEntry* +BaseUnit::EntryForOffset(off_t offset) const +{ + if (fEntries.IsEmpty()) + return NULL; + + // binary search + int lower = 0; + int upper = fEntries.Count() - 1; + while (lower < upper) { + int mid = (lower + upper + 1) / 2; + if (fEntryOffsets[mid] > offset) + upper = mid - 1; + else + lower = mid; + } + + return fEntryOffsets[lower] == offset ? fEntries[lower] : NULL; +} diff --git a/src/apps/debugger/dwarf/BaseUnit.h b/src/apps/debugger/dwarf/BaseUnit.h new file mode 100644 index 0000000000..985573d4be --- /dev/null +++ b/src/apps/debugger/dwarf/BaseUnit.h @@ -0,0 +1,84 @@ +/* + * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef BASE_UNIT_H +#define BASE_UNIT_H + + +#include + +#include + +#include "Types.h" + + +class AbbreviationTable; +class DebugInfoEntry; +class SourceLanguageInfo; + + +enum dwarf_unit_kind { + dwarf_unit_kind_compilation = 0, + dwarf_unit_kind_type +}; + + +class BaseUnit { +public: + BaseUnit(off_t headerOffset, + off_t contentOffset, + off_t totalSize, + off_t abbreviationOffset, + uint8 addressSize, bool isDwarf64); + virtual ~BaseUnit(); + + off_t HeaderOffset() const { return fHeaderOffset; } + off_t ContentOffset() const { return fContentOffset; } + off_t RelativeContentOffset() const + { return fContentOffset - fHeaderOffset; } + off_t TotalSize() const { return fTotalSize; } + off_t ContentSize() const + { return fTotalSize + - RelativeContentOffset(); } + off_t AbbreviationOffset() const + { return fAbbreviationOffset; } + + uint8 AddressSize() const { return fAddressSize; } + bool IsDwarf64() const { return fIsDwarf64; } + + AbbreviationTable* GetAbbreviationTable() const + { return fAbbreviationTable; } + void SetAbbreviationTable( + AbbreviationTable* abbreviationTable); + + const SourceLanguageInfo* SourceLanguage() const + { return fSourceLanguage; } + void SetSourceLanguage( + const SourceLanguageInfo* language); + + status_t AddDebugInfoEntry(DebugInfoEntry* entry, + off_t offset); + int CountEntries() const; + void GetEntryAt(int index, DebugInfoEntry*& entry, + off_t& offset) const; + DebugInfoEntry* EntryForOffset(off_t offset) const; + + virtual dwarf_unit_kind Kind() const = 0; + +private: + off_t fHeaderOffset; + off_t fContentOffset; + off_t fTotalSize; + off_t fAbbreviationOffset; + AbbreviationTable* fAbbreviationTable; + const SourceLanguageInfo* fSourceLanguage; + Array fEntries; + Array fEntryOffsets; + uint8 fAddressSize; + bool fIsDwarf64; +}; + + +#endif // BASE_UNIT_H diff --git a/src/apps/debugger/dwarf/CompilationUnit.cpp b/src/apps/debugger/dwarf/CompilationUnit.cpp index 08dccaa443..688fdcb941 100644 --- a/src/apps/debugger/dwarf/CompilationUnit.cpp +++ b/src/apps/debugger/dwarf/CompilationUnit.cpp @@ -1,5 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -30,18 +31,13 @@ CompilationUnit::CompilationUnit(off_t headerOffset, off_t contentOffset, off_t totalSize, off_t abbreviationOffset, uint8 addressSize, bool isDwarf64) : - fHeaderOffset(headerOffset), - fContentOffset(contentOffset), - fTotalSize(totalSize), - fAbbreviationOffset(abbreviationOffset), - fAbbreviationTable(NULL), + BaseUnit(headerOffset, contentOffset, totalSize, abbreviationOffset, + addressSize, isDwarf64), fUnitEntry(NULL), fAddressRanges(NULL), fDirectories(10, true), fFiles(10, true), - fLineNumberProgram(addressSize), - fAddressSize(addressSize), - fIsDwarf64(isDwarf64) + fLineNumberProgram(addressSize) { } @@ -52,27 +48,6 @@ CompilationUnit::~CompilationUnit() } -void -CompilationUnit::SetAbbreviationTable(AbbreviationTable* abbreviationTable) -{ - fAbbreviationTable = abbreviationTable; -} - - -status_t -CompilationUnit::AddDebugInfoEntry(DebugInfoEntry* entry, off_t offset) -{ - if (!fEntries.Add(entry)) - return B_NO_MEMORY; - if (!fEntryOffsets.Add(offset)) { - fEntries.Remove(fEntries.Count() - 1); - return B_NO_MEMORY; - } - - return B_OK; -} - - void CompilationUnit::SetUnitEntry(DIECompileUnitBase* entry) { @@ -80,13 +55,6 @@ CompilationUnit::SetUnitEntry(DIECompileUnitBase* entry) } -void -CompilationUnit::SetSourceLanguage(const SourceLanguageInfo* language) -{ - fSourceLanguage = language; -} - - void CompilationUnit::SetAddressRanges(TargetAddressRangeList* ranges) { @@ -107,43 +75,6 @@ CompilationUnit::AddressRangeBase() const } -int -CompilationUnit::CountEntries() const -{ - return fEntries.Count(); -} - - -void -CompilationUnit::GetEntryAt(int index, DebugInfoEntry*& entry, - off_t& offset) const -{ - entry = fEntries[index]; - offset = fEntryOffsets[index]; -} - - -DebugInfoEntry* -CompilationUnit::EntryForOffset(off_t offset) const -{ - if (fEntries.IsEmpty()) - return NULL; - - // binary search - int lower = 0; - int upper = fEntries.Count() - 1; - while (lower < upper) { - int mid = (lower + upper + 1) / 2; - if (fEntryOffsets[mid] > offset) - upper = mid - 1; - else - lower = mid; - } - - return fEntryOffsets[lower] == offset ? fEntries[lower] : NULL; -} - - bool CompilationUnit::AddDirectory(const char* directory) { @@ -204,3 +135,10 @@ CompilationUnit::FileAt(int32 index, const char** _directory) const return NULL; } + + +dwarf_unit_kind +CompilationUnit::Kind() const +{ + return dwarf_unit_kind_compilation; +} diff --git a/src/apps/debugger/dwarf/CompilationUnit.h b/src/apps/debugger/dwarf/CompilationUnit.h index 44d7520a29..dd8c837a71 100644 --- a/src/apps/debugger/dwarf/CompilationUnit.h +++ b/src/apps/debugger/dwarf/CompilationUnit.h @@ -1,64 +1,37 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2013, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef COMPILATION_UNIT_H #define COMPILATION_UNIT_H - #include #include -#include - +#include "BaseUnit.h" #include "LineNumberProgram.h" #include "Types.h" -class AbbreviationTable; -class DebugInfoEntry; class DIECompileUnitBase; -class SourceLanguageInfo; class TargetAddressRangeList; -class CompilationUnit { +class CompilationUnit : public BaseUnit { public: CompilationUnit(off_t headerOffset, off_t contentOffset, off_t totalSize, off_t abbreviationOffset, uint8 addressSize, bool isDwarf64); - ~CompilationUnit(); + virtual ~CompilationUnit(); - off_t HeaderOffset() const { return fHeaderOffset; } - off_t ContentOffset() const { return fContentOffset; } - off_t RelativeContentOffset() const - { return fContentOffset - fHeaderOffset; } - off_t TotalSize() const { return fTotalSize; } - off_t ContentSize() const - { return fTotalSize - - RelativeContentOffset(); } - off_t AbbreviationOffset() const - { return fAbbreviationOffset; } - - uint8 AddressSize() const { return fAddressSize; } inline target_addr_t MaxAddress() const; - bool IsDwarf64() const { return fIsDwarf64; } - - AbbreviationTable* GetAbbreviationTable() const - { return fAbbreviationTable; } - void SetAbbreviationTable( - AbbreviationTable* abbreviationTable); DIECompileUnitBase* UnitEntry() const { return fUnitEntry; } void SetUnitEntry(DIECompileUnitBase* entry); - const SourceLanguageInfo* SourceLanguage() const - { return fSourceLanguage; } - void SetSourceLanguage( - const SourceLanguageInfo* language); - TargetAddressRangeList* AddressRanges() const { return fAddressRanges; } void SetAddressRanges( @@ -69,13 +42,6 @@ public: LineNumberProgram& GetLineNumberProgram() { return fLineNumberProgram; } - status_t AddDebugInfoEntry(DebugInfoEntry* entry, - off_t offset); - int CountEntries() const; - void GetEntryAt(int index, DebugInfoEntry*& entry, - off_t& offset) const; - DebugInfoEntry* EntryForOffset(off_t offset) const; - bool AddDirectory(const char* directory); int32 CountDirectories() const; const char* DirectoryAt(int32 index) const; @@ -85,34 +51,26 @@ public: const char* FileAt(int32 index, const char** _directory = NULL) const; + virtual dwarf_unit_kind Kind() const; + private: struct File; typedef BObjectList DirectoryList; typedef BObjectList FileList; private: - off_t fHeaderOffset; - off_t fContentOffset; - off_t fTotalSize; - off_t fAbbreviationOffset; - AbbreviationTable* fAbbreviationTable; DIECompileUnitBase* fUnitEntry; - const SourceLanguageInfo* fSourceLanguage; TargetAddressRangeList* fAddressRanges; - Array fEntries; - Array fEntryOffsets; DirectoryList fDirectories; FileList fFiles; LineNumberProgram fLineNumberProgram; - uint8 fAddressSize; - bool fIsDwarf64; }; target_addr_t CompilationUnit::MaxAddress() const { - return fAddressSize == 4 ? 0xffffffffULL : 0xffffffffffffffffULL; + return AddressSize() == 4 ? 0xffffffffULL : 0xffffffffffffffffULL; } diff --git a/src/apps/debugger/dwarf/Jamfile b/src/apps/debugger/dwarf/Jamfile index 1a0bc505fd..0efb29c52e 100644 --- a/src/apps/debugger/dwarf/Jamfile +++ b/src/apps/debugger/dwarf/Jamfile @@ -17,6 +17,7 @@ MergeObject Debugger_dwarf.o AbbreviationTable.cpp AttributeClasses.cpp AttributeValue.cpp + BaseUnit.cpp CfaContext.cpp CfaRuleSet.cpp CompilationUnit.cpp @@ -29,5 +30,6 @@ MergeObject Debugger_dwarf.o DwarfUtils.cpp LineNumberProgram.cpp SourceLanguageInfo.cpp + TypeUnit.cpp TagNames.cpp ; diff --git a/src/apps/debugger/dwarf/TypeUnit.cpp b/src/apps/debugger/dwarf/TypeUnit.cpp new file mode 100644 index 0000000000..0a3af5d85a --- /dev/null +++ b/src/apps/debugger/dwarf/TypeUnit.cpp @@ -0,0 +1,51 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "TypeUnit.h" + +#include + +#include "DebugInfoEntries.h" + + +TypeUnit::TypeUnit(off_t headerOffset, off_t contentOffset, + off_t totalSize, off_t abbreviationOffset, off_t typeOffset, + uint8 addressSize, uint64 signature, bool isDwarf64) + : + BaseUnit(headerOffset, contentOffset, totalSize, abbreviationOffset, + addressSize, isDwarf64), + fUnitEntry(NULL), + fSignature(signature), + fTypeOffset(typeOffset) +{ +} + + +TypeUnit::~TypeUnit() +{ +} + + +void +TypeUnit::SetUnitEntry(DIETypeUnit* entry) +{ + fUnitEntry = entry; +} + + +DebugInfoEntry* +TypeUnit::TypeEntry() const +{ + if (fUnitEntry != NULL) + return fUnitEntry->GetType(); + + return NULL; +} + + +dwarf_unit_kind +TypeUnit::Kind() const +{ + return dwarf_unit_kind_type; +} diff --git a/src/apps/debugger/dwarf/TypeUnit.h b/src/apps/debugger/dwarf/TypeUnit.h new file mode 100644 index 0000000000..74664e6491 --- /dev/null +++ b/src/apps/debugger/dwarf/TypeUnit.h @@ -0,0 +1,89 @@ +/* + * Copyright 2013, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef TYPE_UNIT_H +#define TYPE_UNIT_H + + +#include +#include + +#include "BaseUnit.h" + + +class DIETypeUnit; + + +class TypeUnit : public BaseUnit { +public: + TypeUnit(off_t headerOffset, + off_t contentOffset, + off_t totalSize, + off_t abbreviationOffset, + off_t typeOffset, + uint8 addressSize, + uint64 typeSignature, + bool isDwarf64); + ~TypeUnit(); + + uint64 Signature() const { return fSignature; } + + off_t TypeOffset() const { return fTypeOffset; } + + + DIETypeUnit* UnitEntry() const { return fUnitEntry; } + void SetUnitEntry(DIETypeUnit* entry); + + DebugInfoEntry* TypeEntry() const; + + virtual dwarf_unit_kind Kind() const; + +private: + DIETypeUnit* fUnitEntry; + uint64 fSignature; + off_t fTypeOffset; +}; + + +struct TypeUnitTableEntry { + uint64 signature; + TypeUnit* unit; + TypeUnitTableEntry* next; + + TypeUnitTableEntry(uint64 signature, TypeUnit* unit) + : + signature(signature), + unit(unit) + { + } +}; + + +struct TypeUnitTableHashDefinition { + typedef uint64 KeyType; + typedef TypeUnitTableEntry ValueType; + + size_t HashKey(uint64 key) const + { + return (size_t)key; + } + + size_t Hash(TypeUnitTableEntry* value) const + { + return HashKey(value->signature); + } + + bool Compare(uint64 key, TypeUnitTableEntry* value) const + { + return value->signature == key; + } + + TypeUnitTableEntry*& GetLink(TypeUnitTableEntry* value) const + { + return value->next; + } +}; + + +#endif // TYPE_UNIT_H