From ac9e464b78d486514f953adafdb5f0b63b8e0203 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Fri, 12 Jan 2018 22:15:11 -0500 Subject: [PATCH] Debugger: Fix various issues in the DWARF subsystem. AttributeClasses: - Fix typo in get_attribute_name_classes which resulted in us not handling DW_AT_linkage_name properly. - Fix incorrect class specification for DW_AT_default_value due to inconsistencies in the DWARF documentation (the table of attribute classes indicates it is only a reference, but the detailed description indicates it also being possible to be a flag or constant, both of which gcc outputs). DebugInfoEntries: - Add accessor for DIEClassBaseType's inner types. DwarfImageDebugInfo: - When looking up types, create a basic target interface to pass on to the type context. Otherwise, type lookups that required DWARF expression evaluation would crash. - When building the type name table, we now recursively walk a class's inner types, and add them to the list as well. This omission would cause the debugger to lack the type description for such classes, and consequently be unable to display their details in the variables view. --- .../debug_info/DwarfImageDebugInfo.cpp | 100 +++++++++++++----- .../debugger/debug_info/DwarfImageDebugInfo.h | 4 +- src/kits/debugger/dwarf/AttributeClasses.cpp | 8 +- src/kits/debugger/dwarf/DebugInfoEntries.h | 4 +- 4 files changed, 83 insertions(+), 33 deletions(-) diff --git a/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp index 1d8f420887..edc3531dbe 100644 --- a/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009-2012, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2012-2016, Rene Gollent, rene@gollent.com. + * Copyright 2012-2018, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -554,9 +554,33 @@ DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name, continue; } + int32 registerCount = fArchitecture->CountRegisters(); + const Register* registers = fArchitecture->Registers(); + + // get the DWARF <-> architecture register maps + RegisterMap* toDwarfMap; + RegisterMap* fromDwarfMap; + status_t error = fArchitecture->GetDwarfRegisterMaps(&toDwarfMap, + &fromDwarfMap); + if (error != B_OK) + return error; + + BReference toDwarfMapReference(toDwarfMap, true); + BReference fromDwarfMapReference(fromDwarfMap, true); + + // create the target interface + BasicTargetInterface* targetInterface + = new(std::nothrow) BasicTargetInterface(registers, registerCount, + fromDwarfMap, fArchitecture, fDebuggerInterface); + if (targetInterface == NULL) + return B_NO_MEMORY; + + BReference targetInterfaceReference( + targetInterface, true); + DwarfTypeContext* typeContext = new(std::nothrow) DwarfTypeContext(fArchitecture, fImageInfo.ImageID(), fFile, - info->unit, NULL, 0, 0, fRelocationDelta, NULL, NULL); + info->unit, NULL, 0, 0, fRelocationDelta, targetInterface, NULL); if (typeContext == NULL) return B_NO_MEMORY; BReference typeContextReference(typeContext, true); @@ -564,7 +588,7 @@ DwarfImageDebugInfo::GetType(GlobalTypeCache* cache, const BString& name, // create the type DwarfType* type; DwarfTypeFactory typeFactory(typeContext, fTypeLookup, cache); - status_t error = typeFactory.CreateType(typeEntry, type); + error = typeFactory.CreateType(typeEntry, type); if (error != B_OK) continue; @@ -1378,32 +1402,54 @@ DwarfImageDebugInfo::_BuildTypeNameTable() 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) + if (_RecursiveAddTypeNames(typeEntry, unit) != B_OK) return B_NO_MEMORY; - - if (!entry->types.AddItem(info)) { - delete info; - return B_NO_MEMORY; - } + } + } + + return B_OK; +} + + +status_t +DwarfImageDebugInfo::_RecursiveAddTypeNames(DIEType* type, CompilationUnit* unit) +{ + if (type->IsDeclaration()) + return B_OK; + + BString typeEntryName; + DwarfUtils::GetFullyQualifiedDIEName(type, typeEntryName); + + status_t error = B_OK; + 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(type, unit); + if (info == NULL) + return B_NO_MEMORY; + + if (!entry->types.AddItem(info)) { + delete info; + return B_NO_MEMORY; + } + + DIEClassBaseType* classType = dynamic_cast(type); + if (classType != NULL) { + for (DebugInfoEntryList::ConstIterator it + = classType->InnerTypes().GetIterator(); + DIEType* innerType = dynamic_cast(it.Next());) { + error = _RecursiveAddTypeNames(innerType, unit); + if (error != B_OK) + return error; } } diff --git a/src/kits/debugger/debug_info/DwarfImageDebugInfo.h b/src/kits/debugger/debug_info/DwarfImageDebugInfo.h index 05c163cea3..be4cfd4807 100644 --- a/src/kits/debugger/debug_info/DwarfImageDebugInfo.h +++ b/src/kits/debugger/debug_info/DwarfImageDebugInfo.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2010-2016, Rene Gollent, rene@gollent.com. + * Copyright 2010-2018, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DWARF_IMAGE_DEBUG_INFO_H @@ -131,6 +131,8 @@ private: const; status_t _BuildTypeNameTable(); + status_t _RecursiveAddTypeNames(DIEType* type, + CompilationUnit* unit); private: BLocker fLock; diff --git a/src/kits/debugger/dwarf/AttributeClasses.cpp b/src/kits/debugger/dwarf/AttributeClasses.cpp index 47123d2b89..f06cb3b127 100644 --- a/src/kits/debugger/dwarf/AttributeClasses.cpp +++ b/src/kits/debugger/dwarf/AttributeClasses.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2013-2014, Rene Gollent, rene@gollent.com. + * Copyright 2013-2018, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ @@ -61,7 +61,7 @@ static const attribute_name_info_entry kAttributeNameInfos[] = { { ENTRY(comp_dir), AC_STRING }, { ENTRY(const_value), AC_BLOCK | AC_CONSTANT | AC_STRING }, { ENTRY(containing_type), AC_REFERENCE }, - { ENTRY(default_value), AC_REFERENCE }, + { ENTRY(default_value), AC_REFERENCE | AC_CONSTANT | AC_FLAG }, { ENTRY(inline), AC_CONSTANT }, { ENTRY(is_optional), AC_FLAG }, { ENTRY(lower_bound), AC_BLOCK | AC_CONSTANT | AC_REFERENCE }, @@ -213,7 +213,7 @@ static struct InitAttributeInfos { uint16 get_attribute_name_classes(uint32 name) { - if (name < DW_AT_linkage_name) + if (name <= DW_AT_linkage_name) return sAttributeNameInfos[name].classes; else if (name >= DW_AT_call_site_value && name <= DW_AT_all_source_call_sites) { @@ -252,7 +252,7 @@ get_attribute_class(uint32 name, uint32 form) const char* get_attribute_name_name(uint32 name) { - if (name < DW_AT_linkage_name) + if (name <= DW_AT_linkage_name) return sAttributeNameInfos[name].name; else if (name >= DW_AT_call_site_value && name <= DW_AT_all_source_call_sites) { diff --git a/src/kits/debugger/dwarf/DebugInfoEntries.h b/src/kits/debugger/dwarf/DebugInfoEntries.h index 71170e0530..4789eefe6a 100644 --- a/src/kits/debugger/dwarf/DebugInfoEntries.h +++ b/src/kits/debugger/dwarf/DebugInfoEntries.h @@ -1,6 +1,6 @@ /* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. - * Copyright 2013-2014, Rene Gollent, rene@gollent.com. + * Copyright 2013-2018, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #ifndef DEBUG_INFO_ENTRIES_H @@ -366,6 +366,8 @@ public: const DebugInfoEntryList& BaseTypes() const { return fBaseTypes; } + const DebugInfoEntryList& InnerTypes() const + { return fInnerTypes; } const DebugInfoEntryList& TemplateParameters() const { return fTemplateParameters; }