[haiku-commits] haiku: hrev52188 - in src/kits/debugger: debug_info dwarf

  • From: Rene Gollent <rene@xxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 7 Aug 2018 22:28:42 -0400 (EDT)

hrev52188 adds 1 changeset to branch 'master'
old head: 8d1f13817f33276a94a48396dbd3aa9f5634118d
new head: 57893202f1849d6e49e3ae88ca6202c18713b775
overview: 
https://git.haiku-os.org/haiku/log/?qt=range&q=57893202f184+%5E8d1f13817f33

----------------------------------------------------------------------------

57893202f184: Debugger: Fix #14321.
  
  DIESubprogram:
  - Adjust to inherit from DIENamespace, as gcc can and will use it as a
    container in some circumstances.
  
  DIEClassBaseType:
  - Add accessor for member functions.
  
  DwarfImageDebugInfo:
  - Adjust recursive walking for types to take into account any DIENamespace,
    not just DW_TAG_namespace specifically.
  - Factor out adding function to list into a helper.
  - When retrieving the list of functions, perform a similar recursive walk as 
is
    done when building the types table, as some subprograms are apparently not
    always added to the root compilation unit entry. Curiously, this behavior
    seems to be relatively specific to a struct/class type declared inside a
    function in GCC's case, but based on the DWARF spec, there does not appear 
to
    be any specific restriction as far as where these can be nested, so be a bit
    more paranoid to ensure we don't encounter similar cases in the future.

                                         [ Rene Gollent <rene@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev52188
Commit:      57893202f1849d6e49e3ae88ca6202c18713b775
URL:         https://git.haiku-os.org/haiku/commit/?id=57893202f184
Author:      Rene Gollent <rene@xxxxxxxxxxx>
Date:        Wed Aug  8 02:15:02 2018 UTC

Ticket:      https://dev.haiku-os.org/ticket/14321

----------------------------------------------------------------------------

4 files changed, 210 insertions(+), 151 deletions(-)
.../debugger/debug_info/DwarfImageDebugInfo.cpp  | 241 +++++++++++--------
.../debugger/debug_info/DwarfImageDebugInfo.h    |   9 +
src/kits/debugger/dwarf/DebugInfoEntries.cpp     |  63 ++---
src/kits/debugger/dwarf/DebugInfoEntries.h       |  48 ++--

----------------------------------------------------------------------------

diff --git a/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp 
b/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp
index 084cf2ac5c..46d515c070 100644
--- a/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp
+++ b/src/kits/debugger/debug_info/DwarfImageDebugInfo.cpp
@@ -409,6 +409,7 @@ DwarfImageDebugInfo::GetFunctions(const 
BObjectList<SymbolInfo>& symbols,
        TRACE_IMAGES("  %" B_PRId32 " compilation units\n",
                fFile->CountCompilationUnits());
 
+       status_t error = B_OK;
        for (int32 i = 0; CompilationUnit* unit = fFile->CompilationUnitAt(i);
                        i++) {
                DIECompileUnitBase* unitEntry = unit->UnitEntry();
@@ -430,86 +431,21 @@ DwarfImageDebugInfo::GetFunctions(const 
BObjectList<SymbolInfo>& symbols,
                for (DebugInfoEntryList::ConstIterator it
                                        = 
unitEntry->OtherChildren().GetIterator();
                                DebugInfoEntry* entry = it.Next();) {
-                       if (entry->Tag() != DW_TAG_subprogram)
-                               continue;
-
-                       DIESubprogram* subprogramEntry = 
static_cast<DIESubprogram*>(entry);
-
-                       // ignore declarations and inlined functions
-                       if (subprogramEntry->IsDeclaration()
-                               || subprogramEntry->Inline() == DW_INL_inlined
-                               || subprogramEntry->Inline() == 
DW_INL_declared_inlined) {
-                               continue;
-                       }
-
-                       // get the name
-                       BString name;
-                       DwarfUtils::GetFullyQualifiedDIEName(subprogramEntry, 
name);
-                       if (name.Length() == 0)
-                               continue;
-
-                       // get the address ranges
-                       TargetAddressRangeList* rangeList = 
fFile->ResolveRangeList(unit,
-                               subprogramEntry->AddressRangesOffset());
-                       if (rangeList == NULL) {
-                               target_addr_t lowPC = subprogramEntry->LowPC();
-                               target_addr_t highPC = 
subprogramEntry->HighPC();
-                               if (highPC <= lowPC)
-                                       continue;
-
-                               rangeList = new(std::nothrow) 
TargetAddressRangeList(
-                                       TargetAddressRange(lowPC, highPC - 
lowPC));
-                               if (rangeList == NULL)
-                                       return B_NO_MEMORY;
-                                               // TODO: Clean up already added 
functions!
-                       }
-                       BReference<TargetAddressRangeList> 
rangeListReference(rangeList,
-                               true);
-
-                       // get the source location
-                       const char* directoryPath = NULL;
-                       const char* fileName = NULL;
-                       int32 line = -1;
-                       int32 column = -1;
-                       DwarfUtils::GetDeclarationLocation(fFile, 
subprogramEntry,
-                               directoryPath, fileName, line, column);
-
-                       LocatableFile* file = NULL;
-                       if (fileName != NULL) {
-                               file = 
fFileManager->GetSourceFile(directoryPath,
-                                       fileName);
+                       if (entry->Tag() == DW_TAG_subprogram) {
+                               DIESubprogram* subprogramEntry
+                                       = static_cast<DIESubprogram*>(entry);
+                               error = _AddFunction(subprogramEntry, unit, 
functions);
+                               if (error != B_OK)
+                                       return error;
                        }
-                       BReference<LocatableFile> fileReference(file, true);
 
-                       // create and add the functions
-                       DwarfFunctionDebugInfo* function
-                               = new(std::nothrow) 
DwarfFunctionDebugInfo(this, unit,
-                                       subprogramEntry, rangeList, name, file,
-                                       SourceLocation(line, std::max(column, 
(int32)0)));
-                       if (function == NULL || !functions.AddItem(function)) {
-                               delete function;
-                               return B_NO_MEMORY;
-                                       // TODO: Clean up already added 
functions!
+                       DIENamespace* nsEntry = 
dynamic_cast<DIENamespace*>(entry);
+                       if (nsEntry != NULL) {
+                               error = 
_RecursiveTraverseNamespaceForFunctions(nsEntry, unit,
+                                       functions);
+                               if (error != B_OK)
+                                       return error;
                        }
-
-//                     BString name;
-//                     DwarfUtils::GetFullyQualifiedDIEName(subprogramEntry, 
name);
-//                     printf("      subprogram entry: %p, name: %s, 
declaration: %d\n",
-//                             subprogramEntry, name.String(),
-//                             subprogramEntry->IsDeclaration());
-//
-//                     rangeList = subprogramEntry->AddressRanges();
-//                     if (rangeList != NULL) {
-//                             int32 count = rangeList->CountRanges();
-//                             for (int32 i = 0; i < count; i++) {
-//                                     TargetAddressRange range = 
rangeList->RangeAt(i);
-//                                     printf("        %#llx - %#llx\n", 
range.Start(), range.End());
-//                             }
-//                     } else {
-//                             printf("        %#llx - %#llx\n",
-//                                     (target_addr_t)subprogramEntry->LowPC(),
-//                                     
(target_addr_t)subprogramEntry->HighPC());
-//                     }
                }
        }
 
@@ -1383,6 +1319,114 @@ 
DwarfImageDebugInfo::_EvaluateBaseTypeConstraints(DIEType* type,
 }
 
 
+status_t
+DwarfImageDebugInfo::_RecursiveTraverseNamespaceForFunctions(
+       DIENamespace* nsEntry, CompilationUnit* unit,
+       BObjectList<FunctionDebugInfo>& functions)
+{
+       status_t error = B_OK;
+       for (DebugInfoEntryList::ConstIterator it
+                               = nsEntry->Children().GetIterator();
+                       DebugInfoEntry* entry = it.Next();) {
+               if (entry->Tag() == DW_TAG_subprogram) {
+                       DIESubprogram* subprogramEntry
+                               = static_cast<DIESubprogram*>(entry);
+                       error = _AddFunction(subprogramEntry, unit, functions);
+                       if (error != B_OK)
+                               return error;
+               }
+
+               DIENamespace* nsEntry = dynamic_cast<DIENamespace*>(entry);
+               if (nsEntry != NULL) {
+                       error = 
_RecursiveTraverseNamespaceForFunctions(nsEntry, unit,
+                               functions);
+                       if (error != B_OK)
+                               return error;
+                       continue;
+               }
+
+               DIEClassBaseType* classEntry = 
dynamic_cast<DIEClassBaseType*>(entry);
+               if (classEntry != NULL) {
+                       for (DebugInfoEntryList::ConstIterator it
+                                               = 
classEntry->MemberFunctions().GetIterator();
+                                       DebugInfoEntry* memberEntry = 
it.Next();) {
+                               error = 
_AddFunction(static_cast<DIESubprogram*>(memberEntry),
+                                       unit, functions);
+                               if (error != B_OK)
+                                       return error;
+                       }
+               }
+       }
+
+       return B_OK;
+}
+
+
+status_t
+DwarfImageDebugInfo::_AddFunction(DIESubprogram* subprogramEntry,
+       CompilationUnit* unit, BObjectList<FunctionDebugInfo>& functions)
+{
+       // ignore declarations and inlined functions
+       if (subprogramEntry->IsDeclaration()
+               || subprogramEntry->Inline() == DW_INL_inlined
+               || subprogramEntry->Inline() == DW_INL_declared_inlined) {
+               return B_OK;
+       }
+
+       // get the name
+       BString name;
+       DwarfUtils::GetFullyQualifiedDIEName(subprogramEntry, name);
+       if (name.Length() == 0)
+               return B_OK;
+
+       // get the address ranges
+       TargetAddressRangeList* rangeList = fFile->ResolveRangeList(unit,
+               subprogramEntry->AddressRangesOffset());
+       if (rangeList == NULL) {
+               target_addr_t lowPC = subprogramEntry->LowPC();
+               target_addr_t highPC = subprogramEntry->HighPC();
+               if (highPC <= lowPC)
+                       return B_OK;
+
+               rangeList = new(std::nothrow) TargetAddressRangeList(
+                       TargetAddressRange(lowPC, highPC - lowPC));
+               if (rangeList == NULL)
+                       return B_NO_MEMORY;
+                               // TODO: Clean up already added functions!
+       }
+       BReference<TargetAddressRangeList> rangeListReference(rangeList,
+               true);
+
+       // get the source location
+       const char* directoryPath = NULL;
+       const char* fileName = NULL;
+       int32 line = -1;
+       int32 column = -1;
+       DwarfUtils::GetDeclarationLocation(fFile, subprogramEntry,
+               directoryPath, fileName, line, column);
+
+       LocatableFile* file = NULL;
+       if (fileName != NULL) {
+               file = fFileManager->GetSourceFile(directoryPath,
+                       fileName);
+       }
+       BReference<LocatableFile> fileReference(file, true);
+
+       // create and add the functions
+       DwarfFunctionDebugInfo* function
+               = new(std::nothrow) DwarfFunctionDebugInfo(this, unit,
+                       subprogramEntry, rangeList, name, file,
+                       SourceLocation(line, std::max(column, (int32)0)));
+       if (function == NULL || !functions.AddItem(function)) {
+               delete function;
+               return B_NO_MEMORY;
+                       // TODO: Clean up already added functions!
+       }
+
+       return B_OK;
+}
+
+
 status_t
 DwarfImageDebugInfo::_BuildTypeNameTable()
 {
@@ -1409,10 +1453,10 @@ DwarfImageDebugInfo::_BuildTypeNameTable()
                for (DebugInfoEntryList::ConstIterator it
                        = unit->UnitEntry()->OtherChildren().GetIterator();
                        DebugInfoEntry* child = it.Next();) {
-                       if (child->Tag() != DW_TAG_namespace)
+                       DIENamespace* namespaceEntry = 
dynamic_cast<DIENamespace*>(child);
+                       if (namespaceEntry == NULL)
                                continue;
 
-                       DIENamespace* namespaceEntry = 
dynamic_cast<DIENamespace*>(child);
                        if (_RecursiveTraverseNamespaceForTypes(namespaceEntry, 
unit)
                                        != B_OK) {
                                return B_NO_MEMORY;
@@ -1455,14 +1499,15 @@ DwarfImageDebugInfo::_RecursiveAddTypeNames(DIEType* 
type, CompilationUnit* unit
        }
 
        DIEClassBaseType* classType = dynamic_cast<DIEClassBaseType*>(type);
-       if (classType != NULL) {
-               for (DebugInfoEntryList::ConstIterator it
-                               = classType->InnerTypes().GetIterator();
-                       DIEType* innerType = 
dynamic_cast<DIEType*>(it.Next());) {
-                       error = _RecursiveAddTypeNames(innerType, unit);
-                       if (error != B_OK)
-                               return error;
-               }
+       if (classType == NULL)
+               return B_OK;
+
+       for (DebugInfoEntryList::ConstIterator it
+                       = classType->InnerTypes().GetIterator();
+               DIEType* innerType = dynamic_cast<DIEType*>(it.Next());) {
+               error = _RecursiveAddTypeNames(innerType, unit);
+               if (error != B_OK)
+                       return error;
        }
 
        return B_OK;
@@ -1476,20 +1521,22 @@ 
DwarfImageDebugInfo::_RecursiveTraverseNamespaceForTypes(DIENamespace* nsEntry,
        for (DebugInfoEntryList::ConstIterator it
                                = nsEntry->Children().GetIterator();
                        DebugInfoEntry* child = it.Next();) {
-               if (child->Tag() == DW_TAG_namespace) {
-                       DIENamespace* entry = 
dynamic_cast<DIENamespace*>(child);
-                       status_t error = 
_RecursiveTraverseNamespaceForTypes(entry, unit);
+
+               if (child->IsType()) {
+                       DIEType* type = dynamic_cast<DIEType*>(child);
+                       if (_RecursiveAddTypeNames(type, unit) != B_OK)
+                               return B_NO_MEMORY;
+               } else {
+                       DIENamespace* nameSpace = 
dynamic_cast<DIENamespace*>(child);
+                       if (nameSpace == NULL)
+                               continue;
+
+                       status_t error = 
_RecursiveTraverseNamespaceForTypes(nameSpace,
+                               unit);
                        if (error != B_OK)
                                return error;
                        continue;
                }
-
-               if (!child->IsType())
-                       continue;
-
-               DIEType* type = dynamic_cast<DIEType*>(child);
-               if (_RecursiveAddTypeNames(type, unit) != B_OK)
-                       return B_NO_MEMORY;
        }
 
        return B_OK;
diff --git a/src/kits/debugger/debug_info/DwarfImageDebugInfo.h 
b/src/kits/debugger/debug_info/DwarfImageDebugInfo.h
index 7e5c92ddba..66d481154f 100644
--- a/src/kits/debugger/debug_info/DwarfImageDebugInfo.h
+++ b/src/kits/debugger/debug_info/DwarfImageDebugInfo.h
@@ -21,6 +21,7 @@ class Architecture;
 class CompilationUnit;
 class DebuggerInterface;
 class DIENamespace;
+class DIESubprogram;
 class DIEType;
 class DwarfFunctionDebugInfo;
 class DwarfStackFrameDebugInfo;
@@ -131,6 +132,14 @@ private:
                                                                        const 
TypeLookupConstraints& constraints)
                                                                        const;
 
+                       status_t                        
_RecursiveTraverseNamespaceForFunctions(
+                                                                       
DIENamespace* nsEntry,
+                                                                       
CompilationUnit* unit,
+                                                                       
BObjectList<FunctionDebugInfo>& functions);
+                       status_t                        
_AddFunction(DIESubprogram* subprogramEntry,
+                                                                       
CompilationUnit* unit,
+                                                                       
BObjectList<FunctionDebugInfo>& functions);
+
                        status_t                        _BuildTypeNameTable();
                        status_t                        
_RecursiveAddTypeNames(DIEType* type,
                                                                        
CompilationUnit* unit);
diff --git a/src/kits/debugger/dwarf/DebugInfoEntries.cpp 
b/src/kits/debugger/dwarf/DebugInfoEntries.cpp
index 64c8eadd96..9ddf148117 100644
--- a/src/kits/debugger/dwarf/DebugInfoEntries.cpp
+++ b/src/kits/debugger/dwarf/DebugInfoEntries.cpp
@@ -1865,6 +1865,36 @@ DIENameListItem::Tag() const
 }
 
 
+// #pragma mark - DIENamespace
+
+
+DIENamespace::DIENamespace()
+{
+}
+
+
+uint16
+DIENamespace::Tag() const
+{
+       return DW_TAG_namespace;
+}
+
+
+bool
+DIENamespace::IsNamespace() const
+{
+       return true;
+}
+
+
+status_t
+DIENamespace::AddChild(DebugInfoEntry* child)
+{
+       fChildren.Add(child);
+       return B_OK;
+}
+
+
 // #pragma mark - DIEPackedType
 
 
@@ -1952,11 +1982,12 @@ DIESubprogram::AddChild(DebugInfoEntry* child)
                        fCallSites.Add(child);
                        return B_OK;
                default:
-                       return DIEDeclaredNamedBase::AddChild(child);
+                       return DIENamespace::AddChild(child);
        }
 }
 
 
+
 status_t
 DIESubprogram::AddAttribute_low_pc(uint16 attributeName,
        const AttributeValue& value)
@@ -2410,36 +2441,6 @@ DIEInterfaceType::Tag() const
 }
 
 
-// #pragma mark - DIENamespace
-
-
-DIENamespace::DIENamespace()
-{
-}
-
-
-uint16
-DIENamespace::Tag() const
-{
-       return DW_TAG_namespace;
-}
-
-
-bool
-DIENamespace::IsNamespace() const
-{
-       return true;
-}
-
-
-status_t
-DIENamespace::AddChild(DebugInfoEntry* child)
-{
-       fChildren.Add(child);
-       return B_OK;
-}
-
-
 // #pragma mark - DIEImportedModule
 
 
diff --git a/src/kits/debugger/dwarf/DebugInfoEntries.h 
b/src/kits/debugger/dwarf/DebugInfoEntries.h
index 4789eefe6a..fb078c85f2 100644
--- a/src/kits/debugger/dwarf/DebugInfoEntries.h
+++ b/src/kits/debugger/dwarf/DebugInfoEntries.h
@@ -366,6 +366,8 @@ public:
 
                        const DebugInfoEntryList& BaseTypes() const
                                                                        { 
return fBaseTypes; }
+                       const DebugInfoEntryList& MemberFunctions() const
+                                                                       { 
return fMemberFunctions; }
                        const DebugInfoEntryList& InnerTypes() const
                                                                        { 
return fInnerTypes; }
                        const DebugInfoEntryList& TemplateParameters() const
@@ -1218,6 +1220,28 @@ public:
 };
 
 
+class DIENamespace : public DIEDeclaredNamedBase {
+public:
+                                                               DIENamespace();
+
+       virtual uint16                          Tag() const;
+
+       virtual bool                            IsNamespace() const;
+
+                       const DebugInfoEntryList& Children() const
+                                                                               
{ return fChildren; }
+
+       virtual status_t                        AddChild(DebugInfoEntry* child);
+
+private:
+                       DebugInfoEntryList      fChildren;
+
+// TODO:
+// DW_AT_extension
+// DW_AT_start_scope
+};
+
+
 class DIEPackedType : public DIEModifiedType {
 public:
                                                                DIEPackedType();
@@ -1226,7 +1250,7 @@ public:
 };
 
 
-class DIESubprogram : public DIEDeclaredNamedBase {
+class DIESubprogram : public DIENamespace {
 public:
                                                                DIESubprogram();
                                                                
~DIESubprogram();
@@ -1531,28 +1555,6 @@ public:
 };
 
 
-class DIENamespace : public DIEDeclaredNamedBase {
-public:
-                                                               DIENamespace();
-
-       virtual uint16                          Tag() const;
-
-       virtual bool                            IsNamespace() const;
-
-                       const DebugInfoEntryList& Children() const
-                                                                               
{ return fChildren; }
-
-       virtual status_t                        AddChild(DebugInfoEntry* child);
-
-private:
-                       DebugInfoEntryList      fChildren;
-
-// TODO:
-// DW_AT_extension
-// DW_AT_start_scope
-};
-
-
 class DIEImportedModule : public DIEDeclaredBase {
 public:
                                                                
DIEImportedModule();


Other related posts:

  • » [haiku-commits] haiku: hrev52188 - in src/kits/debugger: debug_info dwarf - Rene Gollent