[haiku-commits] haiku: hrev44316 - in src/apps/debugger: dwarf debug_info

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 12 Jul 2012 01:13:18 +0200 (CEST)

hrev44316 adds 1 changeset to branch 'master'
old head: 2218c029a5ab7260d03036b43c68475e0b35b449
new head: dfa21dfeabe22cd7df5de50e21bf1ad3678454b8

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

dfa21df: Fix #8508.
  
  - When attempting to unwind the call frame, we now search for the appropriate
    FDE in both .debug_frame and .eh_frame. This mirrors gdb's behavior and
    works around the ever-changing whims of the gcc developers as to which
    section the requisite FDE/CIE resides in.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

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

Revision:    hrev44316
Commit:      dfa21dfeabe22cd7df5de50e21bf1ad3678454b8
URL:         http://cgit.haiku-os.org/haiku/commit/?id=dfa21df
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Wed Jul 11 23:10:32 2012 UTC

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

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

3 files changed, 68 insertions(+), 46 deletions(-)
.../debugger/debug_info/DwarfImageDebugInfo.cpp    |   19 +++-
src/apps/debugger/dwarf/DwarfFile.cpp              |   77 ++++++++--------
src/apps/debugger/dwarf/DwarfFile.h                |   18 +++-

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

diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp 
b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
index 7731e5a..f24f9b1 100644
--- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  */
 
@@ -554,8 +555,22 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
                = cpuState->InstructionPointer() - fRelocationDelta;
        target_addr_t framePointer;
        CompilationUnit* unit = function->GetCompilationUnit();
-       error = fFile->UnwindCallFrame(unit, function->SubprogramEntry(),
-               instructionPointer, inputInterface, outputInterface, 
framePointer);
+       // first try .debug_frame
+       if (fFile->HasDebugFrameSection()) {
+               error = fFile->UnwindCallFrame(false, unit,
+                       function->SubprogramEntry(), instructionPointer, 
inputInterface,
+                       outputInterface, framePointer);
+       } else
+               error = B_ENTRY_NOT_FOUND;
+
+       // if that section isn't present, or we couldn't find a match,
+       // try .eh_frame if possible.
+       if (error == B_ENTRY_NOT_FOUND && fFile->HasEHFrameSection()) {
+               error = fFile->UnwindCallFrame(true, unit,
+                       function->SubprogramEntry(), instructionPointer, 
inputInterface,
+                       outputInterface, framePointer);
+       }
+
        if (error != B_OK) {
                TRACE_CFI("Failed to unwind call frame: %s\n", strerror(error));
                return B_UNSUPPORTED;
diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp 
b/src/apps/debugger/dwarf/DwarfFile.cpp
index 49b5a9c..aee71b4 100644
--- a/src/apps/debugger/dwarf/DwarfFile.cpp
+++ b/src/apps/debugger/dwarf/DwarfFile.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  */
 
@@ -287,12 +288,11 @@ DwarfFile::DwarfFile()
        fDebugRangesSection(NULL),
        fDebugLineSection(NULL),
        fDebugFrameSection(NULL),
+       fEHFrameSection(NULL),
        fDebugLocationSection(NULL),
        fDebugPublicTypesSection(NULL),
        fCompilationUnits(20, true),
        fCurrentCompilationUnit(NULL),
-       fUsingEHFrameSection(false),
-       fGCC4EHFrameSection(false),
        fFinished(false),
        fFinishError(B_OK)
 {
@@ -311,6 +311,7 @@ DwarfFile::~DwarfFile()
                fElfFile->PutSection(fDebugRangesSection);
                fElfFile->PutSection(fDebugLineSection);
                fElfFile->PutSection(fDebugFrameSection);
+               fElfFile->PutSection(fEHFrameSection);
                fElfFile->PutSection(fDebugLocationSection);
                fElfFile->PutSection(fDebugPublicTypesSection);
                delete fElfFile;
@@ -350,26 +351,7 @@ DwarfFile::Load(const char* fileName)
        fDebugRangesSection = fElfFile->GetSection(".debug_ranges");
        fDebugLineSection = fElfFile->GetSection(".debug_line");
        fDebugFrameSection = fElfFile->GetSection(".debug_frame");
-       ElfSection* ehFrameSection = fElfFile->GetSection(".eh_frame");
-       if (fDebugFrameSection != NULL && ehFrameSection != NULL) {
-               if (ehFrameSection->Size() > fDebugFrameSection->Size()) {
-                       fElfFile->PutSection(fDebugFrameSection);
-                       fDebugFrameSection = ehFrameSection;
-                       fUsingEHFrameSection = true;
-               } else
-                       fElfFile->PutSection(ehFrameSection);
-       } else if (ehFrameSection != NULL) {
-               fDebugFrameSection = ehFrameSection;
-               fUsingEHFrameSection = true;
-       }
-
-       if (fUsingEHFrameSection) {
-               fGCC4EHFrameSection = !fDebugFrameSection->IsWritable();
-                       // Crude heuristic for recognizing GCC 4 (Itanium ABI) 
style
-                       // .eh_frame sections. The ones generated by GCC 2 are 
writable,
-                       // the ones generated by GCC 4 aren't.
-       }
-
+       fEHFrameSection = fElfFile->GetSection(".eh_frame");
        fDebugLocationSection = fElfFile->GetSection(".debug_loc");
        fDebugPublicTypesSection = fElfFile->GetSection(".debug_pubtypes");
 
@@ -553,18 +535,31 @@ DwarfFile::ResolveRangeList(CompilationUnit* unit, uint64 
offset) const
 
 
 status_t
-DwarfFile::UnwindCallFrame(CompilationUnit* unit,
+DwarfFile::UnwindCallFrame(bool usingEHFrameSection, CompilationUnit* unit,
        DIESubprogram* subprogramEntry, target_addr_t location,
        const DwarfTargetInterface* inputInterface,
        DwarfTargetInterface* outputInterface, target_addr_t& _framePointer)
 {
-       if (fDebugFrameSection == NULL)
+       ElfSection* currentFrameSection = (usingEHFrameSection)
+               ? fEHFrameSection : fDebugFrameSection;
+
+       if (currentFrameSection == NULL)
                return B_ENTRY_NOT_FOUND;
 
+       bool gcc4EHFrameSection = false;
+       if (usingEHFrameSection) {
+               gcc4EHFrameSection = !currentFrameSection->IsWritable();
+                       // Crude heuristic for recognizing GCC 4 (Itanium ABI) 
style
+                       // .eh_frame sections. The ones generated by GCC 2 are 
writable,
+                       // the ones generated by GCC 4 aren't.
+       }
+
+
+
        TRACE_CFI("DwarfFile::UnwindCallFrame(%#llx)\n", location);
 
-       DataReader dataReader((uint8*)fDebugFrameSection->Data(),
-               fDebugFrameSection->Size(), unit->AddressSize());
+       DataReader dataReader((uint8*)currentFrameSection->Data(),
+               currentFrameSection->Size(), unit->AddressSize());
 
        while (dataReader.BytesRemaining() > 0) {
                // length
@@ -584,7 +579,7 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
                        ? dataReader.Read<uint64>(0) : 
dataReader.Read<uint32>(0);
 
                // In .debug_frame ~0 indicates a CIE, in .eh_frame 0 does.
-               if (fUsingEHFrameSection
+               if (usingEHFrameSection
                        ? cieID == 0
                        : (dwarf64
                                ? cieID == 0xffffffffffffffffULL
@@ -601,16 +596,16 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
 
                        // In the GCC 4 .eh_frame initialLocation is relative 
to the offset
                        // of the address.
-                       if (fUsingEHFrameSection && fGCC4EHFrameSection) {
+                       if (usingEHFrameSection && gcc4EHFrameSection) {
                                // Note: We need to cast to the exact address 
width, since the
                                // initialLocation value can be (and likely is) 
negative.
                                if (dwarf64) {
-                                       initialLocation = 
(uint64)fDebugFrameSection->LoadAddress()
-                                               + (uint64)initialLocationOffset
+                                       initialLocation = 
(uint64)currentFrameSection
+                                               ->LoadAddress() + 
(uint64)initialLocationOffset
                                                + (uint64)initialLocation;
                                } else {
-                                       initialLocation = 
(uint32)fDebugFrameSection->LoadAddress()
-                                               + (uint32)initialLocationOffset
+                                       initialLocation = 
(uint32)currentFrameSection
+                                               ->LoadAddress() + 
(uint32)initialLocationOffset
                                                + (uint32)initialLocation;
                                }
                        }
@@ -634,7 +629,7 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
                                        return B_BAD_DATA;
 
                                // In .eh_frame the CIE offset is a relative 
back offset.
-                               if (fUsingEHFrameSection) {
+                               if (usingEHFrameSection) {
                                        if (cieID > (uint64)lengthOffset) {
                                                TRACE_CFI("Invalid CIE offset: 
%" B_PRIu64 ", max "
                                                        "possible: %" B_PRIu64 
"\n", cieID, lengthOffset);
@@ -660,7 +655,8 @@ DwarfFile::UnwindCallFrame(CompilationUnit* unit,
 
                                // process the CIE
                                CIEAugmentation cieAugmentation;
-                               error = _ParseCIE(unit, context, cieID, 
cieAugmentation);
+                               error = _ParseCIE(currentFrameSection, 
usingEHFrameSection,
+                                       unit, context, cieID, cieAugmentation);
                                if (error != B_OK)
                                        return error;
 
@@ -1554,14 +1550,15 @@ DwarfFile::_ParseLineInfo(CompilationUnit* unit)
 
 
 status_t
-DwarfFile::_ParseCIE(CompilationUnit* unit, CfaContext& context,
-       off_t cieOffset, CIEAugmentation& cieAugmentation)
+DwarfFile::_ParseCIE(ElfSection* debugFrameSection, bool usingEHFrameSection,
+       CompilationUnit* unit, CfaContext& context,     off_t cieOffset,
+       CIEAugmentation& cieAugmentation)
 {
-       if (cieOffset < 0 || cieOffset >= fDebugFrameSection->Size())
+       if (cieOffset < 0 || cieOffset >= debugFrameSection->Size())
                return B_BAD_DATA;
 
-       DataReader dataReader((uint8*)fDebugFrameSection->Data() + cieOffset,
-               fDebugFrameSection->Size() - cieOffset, unit->AddressSize());
+       DataReader dataReader((uint8*)debugFrameSection->Data() + cieOffset,
+               debugFrameSection->Size() - cieOffset, unit->AddressSize());
 
        // length
        bool dwarf64;
@@ -1573,7 +1570,7 @@ DwarfFile::_ParseCIE(CompilationUnit* unit, CfaContext& 
context,
        // CIE ID/CIE pointer
        uint64 cieID = dwarf64
                ? dataReader.Read<uint64>(0) : dataReader.Read<uint32>(0);
-       if (fUsingEHFrameSection) {
+       if (usingEHFrameSection) {
                if (cieID != 0)
                        return B_BAD_DATA;
        } else {
diff --git a/src/apps/debugger/dwarf/DwarfFile.h 
b/src/apps/debugger/dwarf/DwarfFile.h
index f4d5281..a7afede 100644
--- a/src/apps/debugger/dwarf/DwarfFile.h
+++ b/src/apps/debugger/dwarf/DwarfFile.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Copyright 2012, Rene Gollent, rene@xxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  */
 #ifndef DWARF_FILE_H
@@ -38,6 +39,13 @@ public:
                        const char*                     Name() const            
{ return fName; }
                        ElfFile*                        GetElfFile() const      
{ return fElfFile; }
 
+                       bool                            HasDebugFrameSection() 
const {
+                                                                       return 
fDebugFrameSection != NULL;
+                                                               }
+                       bool                            HasEHFrameSection() 
const {
+                                                                       return 
fEHFrameSection != NULL;
+                                                               }
+
                        int32                           CountCompilationUnits() 
const;
                        CompilationUnit*        CompilationUnitAt(int32 index) 
const;
                        CompilationUnit*        CompilationUnitForDIE(
@@ -46,7 +54,8 @@ public:
                        TargetAddressRangeList* 
ResolveRangeList(CompilationUnit* unit,
                                                                        uint64 
offset) const;
 
-                       status_t                        
UnwindCallFrame(CompilationUnit* unit,
+                       status_t                        UnwindCallFrame(bool 
usingEHFrameSection,
+                                                                       
CompilationUnit* unit,
                                                                        
DIESubprogram* subprogramEntry,
                                                                        
target_addr_t location,
                                                                        const 
DwarfTargetInterface* inputInterface,
@@ -112,7 +121,9 @@ private:
 
                        status_t                        
_ParseLineInfo(CompilationUnit* unit);
 
-                       status_t                        
_ParseCIE(CompilationUnit* unit,
+                       status_t                        _ParseCIE(ElfSection* 
debugFrameSection,
+                                                                       bool 
usingEHFrameSection,
+                                                                       
CompilationUnit* unit,
                                                                        
CfaContext& context, off_t cieOffset,
                                                                        
CIEAugmentation& cieAugmentation);
                        status_t                        
_ParseFrameInfoInstructions(
@@ -151,14 +162,13 @@ private:
                        ElfSection*                     fDebugRangesSection;
                        ElfSection*                     fDebugLineSection;
                        ElfSection*                     fDebugFrameSection;
+                       ElfSection*                     fEHFrameSection;
                        ElfSection*                     fDebugLocationSection;
                        ElfSection*                     
fDebugPublicTypesSection;
                        AbbreviationTableList fAbbreviationTables;
                        DebugInfoEntryFactory fDebugInfoFactory;
                        CompilationUnitList     fCompilationUnits;
                        CompilationUnit*        fCurrentCompilationUnit;
-                       bool                            fUsingEHFrameSection;
-                       bool                            fGCC4EHFrameSection;
                        bool                            fFinished;
                        status_t                        fFinishError;
 };


Other related posts:

  • » [haiku-commits] haiku: hrev44316 - in src/apps/debugger: dwarf debug_info - anevilyak