diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index 5daff70c33..78faee2d22 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -232,6 +232,97 @@ struct DwarfImageDebugInfo::EntryListWrapper { }; +// #pragma mark - DwarfImageDebugInfo::TypeNameKey + + +struct DwarfImageDebugInfo::TypeNameKey { + BString typeName; + + TypeNameKey(const BString& typeName) + : + typeName(typeName) + { + } + + uint32 HashValue() const + { + return StringUtils::HashValue(typeName); + } + + bool operator==(const TypeNameKey& other) const + { + return typeName == other.typeName; + } +}; + + +// #pragma mark - DwarfImageDebugInfo::TypeNameEntry + + +struct DwarfImageDebugInfo::TypeNameEntry : TypeNameKey { + TypeNameEntry* next; + TypeEntryList types; + + TypeNameEntry(const BString& name) + : + TypeNameKey(name), + types(10, false) + { + } + + ~TypeNameEntry() + { + } + +}; + + +// #pragma mark - DwarfImageDebugInfo::TypeNameEntryHashDefinition + + +struct DwarfImageDebugInfo::TypeNameEntryHashDefinition { + typedef TypeNameKey KeyType; + typedef TypeNameEntry ValueType; + + size_t HashKey(const TypeNameKey& key) const + { + return key.HashValue(); + } + + size_t Hash(const TypeNameEntry* value) const + { + return value->HashValue(); + } + + bool Compare(const TypeNameKey& key, + const TypeNameEntry* value) const + { + return key == *value; + } + + TypeNameEntry*& GetLink(TypeNameEntry* value) const + { + return value->next; + } +}; + + +// #pragma mark - DwarfImageDebugInfo::TypeEntryInfo + + +struct DwarfImageDebugInfo::TypeEntryInfo { + DIEType* type; + CompilationUnit* unit; + + TypeEntryInfo(DIEType* type, CompilationUnit* unit) + : + type(type), + unit(unit) + { + } +}; + + // #pragma mark - DwarfImageDebugInfo @@ -247,6 +338,7 @@ DwarfImageDebugInfo::DwarfImageDebugInfo(const ImageInfo& imageInfo, fFileManager(fileManager), fTypeLookup(typeLookup), fTypeCache(typeCache), + fTypeNameTable(NULL), fFile(file), fTextSegment(NULL), fRelocationDelta(0), @@ -266,6 +358,8 @@ DwarfImageDebugInfo::~DwarfImageDebugInfo() fDebuggerInterface->ReleaseReference(); fFile->ReleaseReference(); fTypeCache->ReleaseReference(); + + delete fTypeNameTable; } @@ -294,7 +388,7 @@ DwarfImageDebugInfo::Init() fPLTSectionEnd = fPLTSectionStart + section->Size(); } - return B_OK; + return _BuildTypeNameTable(); } @@ -426,64 +520,47 @@ DwarfImageDebugInfo::GetFunctions(const BObjectList& symbols, status_t -DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, - const BString& name, const TypeLookupConstraints& constraints, - Type*& _type) +DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name, + const TypeLookupConstraints& constraints, Type*& _type) { - // iterate through all compilation units - for (int32 i = 0; CompilationUnit* unit = fFile->CompilationUnitAt(i); - i++) { - DwarfTypeContext* typeContext = NULL; - BReference typeContextReference; + TypeNameEntry* entry = fTypeNameTable->Lookup(name); + if (entry == NULL) + return B_ENTRY_NOT_FOUND; - // iterate through all types of the compilation unit - for (DebugInfoEntryList::ConstIterator it - = unit->UnitEntry()->Types().GetIterator(); - DIEType* typeEntry = dynamic_cast(it.Next());) { - if (typeEntry->IsDeclaration()) + for (int32 i = 0; TypeEntryInfo* info = entry->types.ItemAt(i); i++) { + DIEType* typeEntry = info->type; + if (constraints.HasTypeKind()) { + if (dwarf_tag_to_type_kind(typeEntry->Tag()) + != constraints.TypeKind()) { continue; - - if (constraints.HasTypeKind()) { - if (dwarf_tag_to_type_kind(typeEntry->Tag()) - != constraints.TypeKind()) - continue; - - if (!_EvaluateBaseTypeConstraints(typeEntry, - constraints)) - continue; } - if (constraints.HasSubtypeKind() - && dwarf_tag_to_subtype_kind(typeEntry->Tag()) - != constraints.SubtypeKind()) + if (!_EvaluateBaseTypeConstraints(typeEntry, constraints)) continue; - - BString typeEntryName; - DwarfUtils::GetFullyQualifiedDIEName(typeEntry, typeEntryName); - if (typeEntryName != name) - continue; - - // The name matches and the entry is not just a declaration -- - // create the type. First create the type context lazily. - if (typeContext == NULL) { - typeContext = new(std::nothrow) - DwarfTypeContext(fArchitecture, fImageInfo.ImageID(), fFile, - unit, NULL, 0, 0, fRelocationDelta, NULL, NULL); - if (typeContext == NULL) - return B_NO_MEMORY; - typeContextReference.SetTo(typeContext, true); - } - - // create the type - DwarfType* type; - DwarfTypeFactory typeFactory(typeContext, fTypeLookup, cache); - status_t error = typeFactory.CreateType(typeEntry, type); - if (error != B_OK) - continue; - - _type = type; - return B_OK; } + + if (constraints.HasSubtypeKind() + && dwarf_tag_to_subtype_kind(typeEntry->Tag()) + != constraints.SubtypeKind()) { + continue; + } + + DwarfTypeContext* typeContext = new(std::nothrow) + DwarfTypeContext(fArchitecture, fImageInfo.ImageID(), fFile, + info->unit, NULL, 0, 0, fRelocationDelta, NULL, NULL); + if (typeContext == NULL) + return B_NO_MEMORY; + BReference typeContextReference(typeContext, true); + + // create the type + DwarfType* type; + DwarfTypeFactory typeFactory(typeContext, fTypeLookup, cache); + status_t error = typeFactory.CreateType(typeEntry, type); + if (error != B_OK) + continue; + + _type = type; + return B_OK; } return B_ENTRY_NOT_FOUND; @@ -1162,7 +1239,7 @@ DwarfImageDebugInfo::_CreateReturnValues(ReturnValueInfoList* returnValueInfos, bool DwarfImageDebugInfo::_EvaluateBaseTypeConstraints(DIEType* type, - const TypeLookupConstraints& constraints) + const TypeLookupConstraints& constraints) const { if (constraints.HasBaseTypeName()) { BString baseEntryName; @@ -1204,3 +1281,55 @@ DwarfImageDebugInfo::_EvaluateBaseTypeConstraints(DIEType* type, return true; } + + +status_t +DwarfImageDebugInfo::_BuildTypeNameTable() +{ + fTypeNameTable = new(std::nothrow) TypeNameTable; + if (fTypeNameTable == NULL) + return B_NO_MEMORY; + + status_t error = fTypeNameTable->Init(); + if (error != B_OK) + return error; + + // iterate through all compilation units + for (int32 i = 0; CompilationUnit* unit = fFile->CompilationUnitAt(i); + i++) { + + // iterate through all types of the compilation unit + for (DebugInfoEntryList::ConstIterator it + = unit->UnitEntry()->Types().GetIterator(); + DIEType* typeEntry = dynamic_cast(it.Next());) { + if (typeEntry->IsDeclaration()) + continue; + + BString typeEntryName; + DwarfUtils::GetFullyQualifiedDIEName(typeEntry, typeEntryName); + + TypeNameEntry* entry = fTypeNameTable->Lookup(typeEntryName); + if (entry == NULL) { + entry = new(std::nothrow) TypeNameEntry(typeEntryName); + if (entry == NULL) + return B_NO_MEMORY; + + error = fTypeNameTable->Insert(entry); + if (error != B_OK) + return error; + } + + TypeEntryInfo* info = new(std::nothrow) TypeEntryInfo(typeEntry, + unit); + if (info == NULL) + return B_NO_MEMORY; + + if (!entry->types.AddItem(info)) { + delete info; + return B_NO_MEMORY; + } + } + } + + return B_OK; +} diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h index 0a2daf2e48..41f1198156 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010-2013, Rene Gollent, rene@gollent.com. + * Copyright 2010-2014, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_IMAGE_DEBUG_INFO_H @@ -90,6 +90,16 @@ private: struct UnwindTargetInterface; struct EntryListWrapper; + struct TypeNameKey; + struct TypeNameEntry; + struct TypeNameEntryHashDefinition; + + typedef BOpenHashTable + TypeNameTable; + + struct TypeEntryInfo; + typedef BObjectList TypeEntryList; + private: status_t _AddSourceCodeInfo(CompilationUnit* unit, FileSourceCode* sourceCode, @@ -112,7 +122,10 @@ private: DwarfStackFrameDebugInfo& factory); bool _EvaluateBaseTypeConstraints(DIEType* type, - const TypeLookupConstraints& constraints); + const TypeLookupConstraints& constraints) + const; + + status_t _BuildTypeNameTable(); private: BLocker fLock; @@ -122,6 +135,7 @@ private: FileManager* fFileManager; GlobalTypeLookup* fTypeLookup; GlobalTypeCache* fTypeCache; + TypeNameTable* fTypeNameTable; DwarfFile* fFile; ElfSegment* fTextSegment; target_addr_t fRelocationDelta;