[haiku-commits] haiku: hrev45055 - src/apps/debugger/dwarf

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 22 Dec 2012 05:33:03 +0100 (CET)

hrev45055 adds 2 changesets to branch 'master'
old head: 268177055e889e53b8fdf80ed7a33f484662f8c7
new head: 96a4619b92d32c9a068d32e60aba9d02f230fac7
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=96a4619+%5E2681770

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

54531e9: Allow CfaContext to be initialized lazily.

96a4619: Make use of augmentation if available.
  
  - Pull out a _ParseCIEAugmentation() from _ParseCIE().
  
  - If .eh_frame is being used, do a quick parse of the CIE up front
    in order to determine the augmentation (if any), and use it to
    retrieve addresses in the appropriate format. This fixes stack
    unwinding on x86-64, and possibly other cases where the address
    encoding didn't correspond to architectural target size in absolute
    address format.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

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

4 files changed, 96 insertions(+), 32 deletions(-)
src/apps/debugger/dwarf/CfaContext.cpp | 16 +++--
src/apps/debugger/dwarf/CfaContext.h   |  6 +-
src/apps/debugger/dwarf/DwarfFile.cpp  | 96 ++++++++++++++++++++++--------
src/apps/debugger/dwarf/DwarfFile.h    | 10 ++++

############################################################################

Commit:      54531e9f97d78a52610ec486828543a9abb2ab69
URL:         http://cgit.haiku-os.org/haiku/commit/?id=54531e9
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Sat Dec 22 04:24:51 2012 UTC

Allow CfaContext to be initialized lazily.

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

diff --git a/src/apps/debugger/dwarf/CfaContext.cpp 
b/src/apps/debugger/dwarf/CfaContext.cpp
index 6205ad0..d4d13a1 100644
--- a/src/apps/debugger/dwarf/CfaContext.cpp
+++ b/src/apps/debugger/dwarf/CfaContext.cpp
@@ -9,11 +9,10 @@
 #include "CfaContext.h"
 
 
-CfaContext::CfaContext(target_addr_t targetLocation,
-       target_addr_t initialLocation)
+CfaContext::CfaContext()
        :
-       fTargetLocation(targetLocation),
-       fLocation(initialLocation),
+       fTargetLocation(0),
+       fLocation(0),
        fCodeAlignment(0),
        fDataAlignment(0),
        fReturnAddressRegister(0),
@@ -31,6 +30,15 @@ CfaContext::~CfaContext()
 }
 
 
+void
+CfaContext::SetLocation(target_addr_t targetLocation,
+       target_addr_t initialLocation)
+{
+       fTargetLocation = targetLocation;
+       fLocation = initialLocation;
+}
+
+
 status_t
 CfaContext::Init(uint32 registerCount)
 {
diff --git a/src/apps/debugger/dwarf/CfaContext.h 
b/src/apps/debugger/dwarf/CfaContext.h
index b652e01..78d224c 100644
--- a/src/apps/debugger/dwarf/CfaContext.h
+++ b/src/apps/debugger/dwarf/CfaContext.h
@@ -14,10 +14,12 @@
 
 class CfaContext {
 public:
-                                                               
CfaContext(target_addr_t targetLocation,
-                                                                       
target_addr_t initialLocation);
+                                                               CfaContext();
                                                                ~CfaContext();
 
+                       void                            
SetLocation(target_addr_t targetLocation,
+                                                                       
target_addr_t initialLocation);
+
                        status_t                        Init(uint32 
registerCount);
                        status_t                        SaveInitialRuleSet();
 

############################################################################

Revision:    hrev45055
Commit:      96a4619b92d32c9a068d32e60aba9d02f230fac7
URL:         http://cgit.haiku-os.org/haiku/commit/?id=96a4619
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Sat Dec 22 04:26:34 2012 UTC

Make use of augmentation if available.

- Pull out a _ParseCIEAugmentation() from _ParseCIE().

- If .eh_frame is being used, do a quick parse of the CIE up front
  in order to determine the augmentation (if any), and use it to
  retrieve addresses in the appropriate format. This fixes stack
  unwinding on x86-64, and possibly other cases where the address
  encoding didn't correspond to architectural target size in absolute
  address format.

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

diff --git a/src/apps/debugger/dwarf/DwarfFile.cpp 
b/src/apps/debugger/dwarf/DwarfFile.cpp
index e858ceb..69187c5 100644
--- a/src/apps/debugger/dwarf/DwarfFile.cpp
+++ b/src/apps/debugger/dwarf/DwarfFile.cpp
@@ -335,17 +335,15 @@ struct DwarfFile::CIEAugmentation {
                return (fFlags & CFI_AUGMENTATION_ADDRESS_POINTER_FORMAT) != 0;
        }
 
-       target_addr_t FDEAddressOffset(CompilationUnit* unit,
-               ElfFile* file) const
+       target_addr_t FDEAddressOffset(ElfFile* file) const
        {
                switch (FDEAddressType()) {
                        // function relative is currently equivalent to absolute
                        // in all the cases in which it gets generated
                        case CFI_ADDRESS_FORMAT_ABSOLUTE:
+                       case CFI_ADDRESS_TYPE_PC_RELATIVE:
                        case CFI_ADDRESS_TYPE_FUNCTION_RELATIVE:
                                return 0;
-                       case CFI_ADDRESS_TYPE_PC_RELATIVE:
-                               return unit->AddressRangeBase();
                        case CFI_ADDRESS_TYPE_TEXT_RELATIVE:
                                return file->TextSegment()->LoadAddress();
                        case CFI_ADDRESS_TYPE_DATA_RELATIVE:
@@ -384,9 +382,9 @@ struct DwarfFile::CIEAugmentation {
        }
 
        target_addr_t ReadEncodedAddress(DataReader &reader,
-               CompilationUnit* unit, ElfFile* file) const
+               ElfFile* file) const
        {
-               target_addr_t address = FDEAddressOffset(unit, file);
+               target_addr_t address = FDEAddressOffset(file);
                switch (fAddressEncoding & 0x0f) {
                        case CFI_ADDRESS_FORMAT_ABSOLUTE:
                                address += reader.ReadAddress(0);
@@ -1512,8 +1510,44 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, 
CompilationUnit* unit,
                } else {
                        // this is a FDE
                        uint64 initialLocationOffset = dataReader.Offset();
-                       target_addr_t initialLocation = 
dataReader.ReadAddress(0);
-                       target_size_t addressRange = dataReader.ReadAddress(0);
+                       // In .eh_frame the CIE offset is a relative back 
offset.
+                       if (usingEHFrameSection) {
+                               if (cieID > (uint64)lengthOffset) {
+                                       TRACE_CFI("Invalid CIE offset: %" 
B_PRIu64 ", max "
+                                               "possible: %" B_PRIu64 "\n", 
cieID, lengthOffset);
+                                       break;
+                               }
+                               // convert to a section relative offset
+                               cieID = lengthOffset - cieID;
+                       }
+
+
+                       CfaContext context;
+                       CIEAugmentation cieAugmentation;
+                       // when using .eh_frame format, we need to parse the 
CIE's
+                       // augmentation up front in order to know how the FDE's 
addresses
+                       //  will be represented
+                       if (usingEHFrameSection) {
+                               // TODO: this isn't so ideal since it means we 
parse
+                               // the CIE twice, once here in order to get the 
augmentation
+                               // data for address parsing, and again later 
when we perform
+                               // the full CIE parse to get its initial Cfa 
ruleset. In the
+                               // long term, we should probably
+                               // shift to parsing the CIEs as we hit them and 
caching
+                               // their information so it can simply be 
retrieved directly
+                               // later.
+                               DataReader cieReader;
+                               status_t error = 
_ParseCIEAugmentation(currentFrameSection,
+                                       usingEHFrameSection, unit, addressSize, 
context, cieID,
+                                       cieAugmentation, cieReader);
+                               if (error != B_OK)
+                                       return error;
+                       }
+
+                       target_addr_t initialLocation = 
cieAugmentation.ReadEncodedAddress(
+                               dataReader,     fElfFile);
+                       target_size_t addressRange = 
cieAugmentation.ReadEncodedAddress(
+                               dataReader,     fElfFile);
 
                        if (dataReader.HasOverflow())
                                return B_BAD_DATA;
@@ -1552,23 +1586,12 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, 
CompilationUnit* unit,
                                if (remaining < 0)
                                        return B_BAD_DATA;
 
-                               // In .eh_frame the CIE offset is a relative 
back offset.
-                               if (usingEHFrameSection) {
-                                       if (cieID > (uint64)lengthOffset) {
-                                               TRACE_CFI("Invalid CIE offset: 
%" B_PRIu64 ", max "
-                                                       "possible: %" B_PRIu64 
"\n", cieID, lengthOffset);
-                                               break;
-                                       }
-                                       // convert to a section relative offset
-                                       cieID = lengthOffset - cieID;
-                               }
-
                                TRACE_CFI("  found fde: length: %" B_PRIu64 " 
(%" B_PRIdOFF
                                        "), CIE offset: %#" B_PRIx64 ", 
location: %#" B_PRIx64 ", "
                                        "range: %#" B_PRIx64 "\n", length, 
remaining, cieID,
                                        initialLocation, addressRange);
 
-                               CfaContext context(location, initialLocation);
+                               context.SetLocation(location, initialLocation);
                                uint32 registerCount = 
outputInterface->CountRegisters();
                                status_t error = context.Init(registerCount);
                                if (error != B_OK)
@@ -1579,7 +1602,6 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, 
CompilationUnit* unit,
                                        return error;
 
                                // process the CIE
-                               CIEAugmentation cieAugmentation;
                                error = _ParseCIE(currentFrameSection, 
usingEHFrameSection,
                                        unit, addressSize, context, cieID, 
cieAugmentation);
                                if (error != B_OK)
@@ -1750,14 +1772,15 @@ DwarfFile::_UnwindCallFrame(bool usingEHFrameSection, 
CompilationUnit* unit,
 
 
 status_t
-DwarfFile::_ParseCIE(ElfSection* debugFrameSection, bool usingEHFrameSection,
-       CompilationUnit* unit, uint8 addressSize, CfaContext& context,
-       off_t cieOffset, CIEAugmentation& cieAugmentation)
+DwarfFile::_ParseCIEAugmentation(ElfSection* debugFrameSection,
+       bool usingEHFrameSection, CompilationUnit* unit, uint8 addressSize,
+       CfaContext& context, off_t cieOffset, CIEAugmentation& cieAugmentation,
+       DataReader& dataReader, off_t* _length, off_t* _lengthOffset)
 {
        if (cieOffset < 0 || cieOffset >= debugFrameSection->Size())
                return B_BAD_DATA;
 
-       DataReader dataReader((uint8*)debugFrameSection->Data() + cieOffset,
+       dataReader.SetTo((uint8*)debugFrameSection->Data() + cieOffset,
                debugFrameSection->Size() - cieOffset, unit != NULL
                        ? unit->AddressSize() : addressSize);
 
@@ -1767,7 +1790,11 @@ DwarfFile::_ParseCIE(ElfSection* debugFrameSection, bool 
usingEHFrameSection,
        if (length > (uint64)dataReader.BytesRemaining())
                return B_BAD_DATA;
 
-       off_t lengthOffset = dataReader.Offset();
+       if (_length != NULL)
+               *_length = length;
+
+       if (_lengthOffset != NULL)
+               *_lengthOffset = dataReader.Offset();
 
        // CIE ID/CIE pointer
        uint64 cieID = dwarf64
@@ -1815,6 +1842,23 @@ DwarfFile::_ParseCIE(ElfSection* debugFrameSection, bool 
usingEHFrameSection,
                return error;
        }
 
+       return B_OK;
+}
+
+
+status_t
+DwarfFile::_ParseCIE(ElfSection* debugFrameSection, bool usingEHFrameSection,
+       CompilationUnit* unit, uint8 addressSize, CfaContext& context,
+       off_t cieOffset, CIEAugmentation& cieAugmentation)
+{
+       DataReader dataReader;
+       off_t length;
+       off_t lengthOffset;
+       status_t result = _ParseCIEAugmentation(debugFrameSection,
+               usingEHFrameSection, unit, addressSize, context, cieOffset,
+               cieAugmentation, dataReader, &length, &lengthOffset);
+       if (result != B_OK)
+               return result;
        if (dataReader.HasOverflow())
                return B_BAD_DATA;
        off_t remaining = (off_t)length
diff --git a/src/apps/debugger/dwarf/DwarfFile.h 
b/src/apps/debugger/dwarf/DwarfFile.h
index 429e98d..35159c9 100644
--- a/src/apps/debugger/dwarf/DwarfFile.h
+++ b/src/apps/debugger/dwarf/DwarfFile.h
@@ -123,6 +123,16 @@ private:
                                                                        
DwarfTargetInterface* outputInterface,
                                                                        
target_addr_t& _framePointer);
 
+                       status_t                        _ParseCIEAugmentation(
+                                                                       
ElfSection* debugFrameSection,
+                                                                       bool 
usingEHFrameSection,
+                                                                       
CompilationUnit* unit,
+                                                                       uint8 
addressSize,
+                                                                       
CfaContext& context, off_t cieOffset,
+                                                                       
CIEAugmentation& cieAugmentation,
+                                                                       
DataReader& reader,
+                                                                       off_t* 
length = NULL,
+                                                                       off_t* 
lengthOffset = NULL);
                        status_t                        _ParseCIE(ElfSection* 
debugFrameSection,
                                                                        bool 
usingEHFrameSection,
                                                                        
CompilationUnit* unit,


Other related posts: