[haiku-commits] haiku: hrev45412 - in src/apps/debugger: debug_info controllers arch model jobs

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 26 Mar 2013 23:51:10 +0100 (CET)

hrev45412 adds 3 changesets to branch 'master'
old head: 469f13fdfe886f0eca9cc9204ad2e3da7377f7ba
new head: 1efa0a42f6a490bfb88cfd928c53d17c3dd62907
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=1efa0a4+%5E469f13f

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

04c919f: Fix incorrect target address calculation for memory operands.

029fcc4: Add CPU state at time of function call to Thread.
  
  - When we detect that we're stepping over a function call, also store
    the CPU state at the time it occurred. This information is needed
    in order to correctly reconstruct target addresses later since some
    operands may be register-based.
  
  - Add the aforementioned CPU state to CreateFrame()'s arguments and
    adjust implementations and callers accordingly.

1efa0a4: Fix return value handling.
  
  - In the case of position independent code, the initial call isn't to
    the function we want, but rather to a PLT slot which resolves the
    function's location. As such, find that slot and use it to determine
    the corresponding GOT offset for the function's real location.
  
  Still need some further refactoring of return value handling to properly
  handle the case of stepping over a single line that makes multiple calls,
  but this fixes the basic case at least.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

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

12 files changed, 64 insertions(+), 22 deletions(-)
src/apps/debugger/arch/Architecture.cpp          |  6 ++--
src/apps/debugger/arch/Architecture.h            |  1 +
.../debugger/arch/x86/disasm/DisassemblerX86.cpp |  2 ++
src/apps/debugger/controllers/ThreadHandler.cpp  | 13 +++----
.../debug_info/DebuggerImageDebugInfo.cpp        |  3 +-
.../debugger/debug_info/DebuggerImageDebugInfo.h |  1 +
.../debugger/debug_info/DwarfImageDebugInfo.cpp  | 37 +++++++++++++-------
.../debugger/debug_info/DwarfImageDebugInfo.h    |  2 ++
.../debugger/debug_info/SpecificImageDebugInfo.h |  1 +
src/apps/debugger/jobs/GetStackTraceJob.cpp      |  3 +-
src/apps/debugger/model/Thread.cpp               | 13 +++++++
src/apps/debugger/model/Thread.h                 |  4 +++

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

Commit:      04c919f9d6a8d94b05b0aa91fa529c1e5ba5475e
URL:         http://cgit.haiku-os.org/haiku/commit/?id=04c919f
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Tue Mar 26 22:42:14 2013 UTC

Fix incorrect target address calculation for memory operands.

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

diff --git a/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp 
b/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp
index e686d7e..a681f23 100644
--- a/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp
+++ b/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp
@@ -198,6 +198,8 @@ DisassemblerX86::GetInstructionTargetAddress(CpuState* 
state) const
                        targetAddress += x86State->IntRegisterValue(
                                
RegisterNumberFromUdisIndex(fUdisData->operand[0].index))
                                * fUdisData->operand[0].scale;
+                       if (fUdisData->operand[0].offset != 0)
+                               targetAddress += 
fUdisData->operand[0].lval.sdword;
                }
                break;
                case UD_OP_JIMM:

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

Commit:      029fcc4ad65d306eadd3ce77b9ea30bec93ba3fe
URL:         http://cgit.haiku-os.org/haiku/commit/?id=029fcc4
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Tue Mar 26 22:44:54 2013 UTC

Add CPU state at time of function call to Thread.

- When we detect that we're stepping over a function call, also store
  the CPU state at the time it occurred. This information is needed
  in order to correctly reconstruct target addresses later since some
  operands may be register-based.

- Add the aforementioned CPU state to CreateFrame()'s arguments and
  adjust implementations and callers accordingly.

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

diff --git a/src/apps/debugger/arch/Architecture.cpp 
b/src/apps/debugger/arch/Architecture.cpp
index 42fd88e..ecae506 100644
--- a/src/apps/debugger/arch/Architecture.cpp
+++ b/src/apps/debugger/arch/Architecture.cpp
@@ -95,7 +95,8 @@ status_t
 Architecture::CreateStackTrace(Team* team,
        ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState,
        StackTrace*& _stackTrace, target_addr_t returnFunctionAddress,
-       int32 maxStackDepth, bool useExistingTrace, bool getFullFrameInfo)
+       CpuState* returnFunctionState, int32 maxStackDepth, bool 
useExistingTrace,
+       bool getFullFrameInfo)
 {
        BReference<CpuState> cpuStateReference(cpuState);
 
@@ -163,7 +164,8 @@ Architecture::CreateStackTrace(Team* team,
                if (function != NULL) {
                        status_t error = 
functionDebugInfo->GetSpecificImageDebugInfo()
                                ->CreateFrame(image, function, cpuState, 
getFullFrameInfo,
-                                       nextFrame == NULL ? 
returnFunctionAddress : 0, frame,
+                                       nextFrame == NULL ? 
returnFunctionAddress : 0,
+                                       nextFrame == NULL ? returnFunctionState 
: 0, frame,
                                        previousCpuState);
                        if (error != B_OK && error != B_UNSUPPORTED)
                                break;
diff --git a/src/apps/debugger/arch/Architecture.h 
b/src/apps/debugger/arch/Architecture.h
index d9610ba..e390774 100644
--- a/src/apps/debugger/arch/Architecture.h
+++ b/src/apps/debugger/arch/Architecture.h
@@ -111,6 +111,7 @@ public:
                                                                        
CpuState* cpuState,
                                                                        
StackTrace*& _stackTrace,
                                                                        
target_addr_t returnFunctionAddress,
+                                                                       
CpuState* returnFunctionState,
                                                                        int32 
maxStackDepth = -1,
                                                                        bool 
useExistingTrace = false,
                                                                        bool 
getFullFrameInfo = true);
diff --git a/src/apps/debugger/controllers/ThreadHandler.cpp 
b/src/apps/debugger/controllers/ThreadHandler.cpp
index 6a2fe94..af647cb 100644
--- a/src/apps/debugger/controllers/ThreadHandler.cpp
+++ b/src/apps/debugger/controllers/ThreadHandler.cpp
@@ -253,7 +253,7 @@ ThreadHandler::HandleThreadAction(uint32 action)
 
        if (stackTrace == NULL && cpuState != NULL) {
                if (fDebuggerInterface->GetArchitecture()->CreateStackTrace(
-                               fThread->GetTeam(), this, cpuState, stackTrace, 
0, 1,
+                               fThread->GetTeam(), this, cpuState, stackTrace, 
0, NULL, 1,
                                false, false) == B_OK) {
                        stackTraceReference.SetTo(stackTrace, true);
                }
@@ -485,6 +485,7 @@ ThreadHandler::_DoStepOver(CpuState* cpuState)
                "%#" B_PRIx64 "\n", info.Address() + info.Size());
 
        fThread->SetExecutedSubroutine(info.TargetAddress());
+       fThread->SetSubroutineCpuState(cpuState);
        if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK)
                return false;
 
@@ -566,8 +567,8 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
 
                        if (stackTrace == NULL && cpuState != NULL) {
                                if 
(fDebuggerInterface->GetArchitecture()->CreateStackTrace(
-                                               fThread->GetTeam(), this, 
cpuState, stackTrace, 0, 1,
-                                               false, false) == B_OK) {
+                                               fThread->GetTeam(), this, 
cpuState, stackTrace, 0,
+                                               NULL, 1, false, false) == B_OK) 
{
                                        stackTraceReference.SetTo(stackTrace, 
true);
                                }
                        }
@@ -653,8 +654,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
 
                        if (stackTrace == NULL && cpuState != NULL) {
                                if 
(fDebuggerInterface->GetArchitecture()->CreateStackTrace(
-                                               fThread->GetTeam(), this, 
cpuState, stackTrace, 0, 1,
-                                               false, false) == B_OK) {
+                                               fThread->GetTeam(), this, 
cpuState, stackTrace, 0,
+                                               NULL, 1, false, false) == B_OK) 
{
                                        stackTraceReference.SetTo(stackTrace, 
true);
                                }
                        }
@@ -686,7 +687,7 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
                                if (stackTrace == NULL && cpuState != NULL) {
                                        if 
(fDebuggerInterface->GetArchitecture()->CreateStackTrace(
                                                        fThread->GetTeam(), 
this, cpuState, stackTrace, 0,
-                                                       1, false, false) == 
B_OK) {
+                                                       NULL, 1, false, false) 
== B_OK) {
                                                
stackTraceReference.SetTo(stackTrace, true);
                                        }
                                }
diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp 
b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp
index b40e08c..c7a77e1 100644
--- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp
@@ -69,7 +69,8 @@ status_t
 DebuggerImageDebugInfo::CreateFrame(Image* image,
        FunctionInstance* functionInstance, CpuState* cpuState,
        bool getFullFrameInfo, target_addr_t returnFunctionAddress,
-       StackFrame*& _previousFrame, CpuState*& _previousCpuState)
+       CpuState* returnFunctionState, StackFrame*& _previousFrame,
+       CpuState*& _previousCpuState)
 {
        return B_UNSUPPORTED;
 }
diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h 
b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h
index bcafebc..91d0c1b 100644
--- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h
+++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h
@@ -37,6 +37,7 @@ public:
                                                                        
CpuState* cpuState,
                                                                        bool 
getFullFrameInfo,
                                                                        
target_addr_t returnFunctionAddress,
+                                                                       
CpuState* returnFunctionState,
                                                                        
StackFrame*& _previousFrame,
                                                                        
CpuState*& _previousCpuState);
        virtual status_t                        GetStatement(FunctionDebugInfo* 
function,
diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp 
b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
index b96814d..4c0247f 100644
--- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
@@ -523,7 +523,8 @@ status_t
 DwarfImageDebugInfo::CreateFrame(Image* image,
        FunctionInstance* functionInstance, CpuState* cpuState,
        bool getFullFrameInfo, target_addr_t returnFunctionAddress,
-       StackFrame*& _frame, CpuState*& _previousCpuState)
+       CpuState* returnFunctionState, StackFrame*& _frame,
+       CpuState*& _previousCpuState)
 {
        DwarfFunctionDebugInfo* function = 
dynamic_cast<DwarfFunctionDebugInfo*>(
                functionInstance->GetFunctionDebugInfo());
@@ -1091,7 +1092,8 @@ 
DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit,
 
 status_t
 DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress,
-       Image* image, StackFrame* frame, DwarfStackFrameDebugInfo& factory)
+       CpuState* returnFunctionState, Image* image, StackFrame* frame,
+       DwarfStackFrameDebugInfo& factory)
 {
        if (!image->ContainsAddress(returnFunctionAddress)) {
                // our current image doesn't contain the target function,
diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h 
b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h
index 203920b..7dab0fb 100644
--- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h
+++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h
@@ -65,6 +65,7 @@ public:
                                                                        
CpuState* cpuState,
                                                                        bool 
getFullFrameInfo,
                                                                        
target_addr_t returnFunctionAddress,
+                                                                       
CpuState* returnFunctionState,
                                                                        
StackFrame*& _frame,
                                                                        
CpuState*& _previousCpuState);
        virtual status_t                        GetStatement(FunctionDebugInfo* 
function,
@@ -106,6 +107,7 @@ private:
 
                        status_t                        _CreateReturnValue(
                                                                        
target_addr_t returnFunctionAddress,
+                                                                       
CpuState* returnFunctionState,
                                                                        Image* 
image,
                                                                        
StackFrame* frame,
                                                                        
DwarfStackFrameDebugInfo& factory);
diff --git a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h 
b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h
index ac655cd..595d238 100644
--- a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h
+++ b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h
@@ -57,6 +57,7 @@ public:
                                                                        
CpuState* cpuState,
                                                                        bool 
getFullFrameInfo,
                                                                        
target_addr_t returnFunctionAddress,
+                                                                       
CpuState* returnFunctionState,
                                                                        
StackFrame*& _Frame,
                                                                        
CpuState*& _previousCpuState) = 0;
                                                                                
// returns reference to previous frame
diff --git a/src/apps/debugger/jobs/GetStackTraceJob.cpp 
b/src/apps/debugger/jobs/GetStackTraceJob.cpp
index 23ce2fc..c3a2316 100644
--- a/src/apps/debugger/jobs/GetStackTraceJob.cpp
+++ b/src/apps/debugger/jobs/GetStackTraceJob.cpp
@@ -59,7 +59,8 @@ GetStackTraceJob::Do()
        StackTrace* stackTrace;
        status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), 
this,
                fCpuState, stackTrace, fThread->ExecutedSubroutine()
-                       ? fThread->SubroutineAddress() : 0);
+                       ? fThread->SubroutineAddress() : 0, 
fThread->ExecutedSubroutine()
+                       ? fThread->SubroutineCpuState() : NULL);
        if (error != B_OK)
                return error;
        BReference<StackTrace> stackTraceReference(stackTrace, true);
diff --git a/src/apps/debugger/model/Thread.cpp 
b/src/apps/debugger/model/Thread.cpp
index 63d21e0..e32424c 100644
--- a/src/apps/debugger/model/Thread.cpp
+++ b/src/apps/debugger/model/Thread.cpp
@@ -19,6 +19,7 @@ Thread::Thread(Team* team, thread_id threadID)
        fState(THREAD_STATE_UNKNOWN),
        fExecutedSubroutine(false),
        fSubroutineAddress(0),
+       fSubroutineState(NULL),
        fStoppedReason(THREAD_STOPPED_UNKNOWN),
        fCpuState(NULL),
        fStackTrace(NULL)
@@ -32,6 +33,8 @@ Thread::~Thread()
                fCpuState->ReleaseReference();
        if (fStackTrace != NULL)
                fStackTrace->ReleaseReference();
+       if (fSubroutineState != NULL)
+               fSubroutineState->ReleaseReference();
 }
 
 
@@ -121,3 +124,13 @@ Thread::SetExecutedSubroutine(target_addr_t address)
        fSubroutineAddress = address;
 }
 
+
+void
+Thread::SetSubroutineCpuState(CpuState* state)
+{
+       if (fSubroutineState != NULL)
+               fSubroutineState->ReleaseReference();
+
+       fSubroutineState = state;
+       fSubroutineState->AcquireReference();
+}
diff --git a/src/apps/debugger/model/Thread.h b/src/apps/debugger/model/Thread.h
index 1cba07f..17aa330 100644
--- a/src/apps/debugger/model/Thread.h
+++ b/src/apps/debugger/model/Thread.h
@@ -74,6 +74,9 @@ public:
                        target_addr_t           SubroutineAddress() const
                                                                        { 
return fSubroutineAddress; }
                        void                            
SetExecutedSubroutine(target_addr_t address);
+                       CpuState*                       SubroutineCpuState() 
const
+                                                                       { 
return fSubroutineState; }
+                       void                            
SetSubroutineCpuState(CpuState* state);
 
 private:
                        Team*                           fTeam;
@@ -82,6 +85,7 @@ private:
                        uint32                          fState;
                        bool                            fExecutedSubroutine;
                        target_addr_t           fSubroutineAddress;
+                       CpuState*                       fSubroutineState;
                        uint32                          fStoppedReason;
                        BString                         fStoppedReasonInfo;
                        CpuState*                       fCpuState;

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

Revision:    hrev45412
Commit:      1efa0a42f6a490bfb88cfd928c53d17c3dd62907
URL:         http://cgit.haiku-os.org/haiku/commit/?id=1efa0a4
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Tue Mar 26 22:48:22 2013 UTC

Fix return value handling.

- In the case of position independent code, the initial call isn't to
  the function we want, but rather to a PLT slot which resolves the
  function's location. As such, find that slot and use it to determine
  the corresponding GOT offset for the function's real location.

Still need some further refactoring of return value handling to properly
handle the case of stepping over a single line that makes multiple calls,
but this fixes the basic case at least.

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

diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp 
b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
index 4c0247f..0195ecc 100644
--- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
@@ -674,14 +674,10 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
                        instructionPointer, functionInstance->Address() - 
fRelocationDelta,
                        subprogramEntry->Variables(), 
subprogramEntry->Blocks());
 
-               // TODO: re-enable once PIC and false positive issues
-               // are properly dealt with
-#if 0
                if (returnFunctionAddress != 0) {
-                       _CreateReturnValue(returnFunctionAddress, image, frame,
-                               *stackFrameDebugInfo);
+                       _CreateReturnValue(returnFunctionAddress, 
returnFunctionState,
+                               image, frame, *stackFrameDebugInfo);
                }
-#endif
        }
 
        _frame = frameReference.Detach();
@@ -1104,15 +1100,30 @@ DwarfImageDebugInfo::_CreateReturnValue(target_addr_t 
returnFunctionAddress,
        }
 
        status_t result = B_OK;
+       ImageDebugInfo* imageInfo = image->GetImageDebugInfo();
        FunctionInstance* targetFunction;
        if (returnFunctionAddress >= fPLTSectionStart
                && returnFunctionAddress < fPLTSectionEnd) {
-               // TODO: handle resolving PLT entries
-               // to their target function
-               return B_UNSUPPORTED;
+               // if the function in question is position-independent, the call
+               // will actually have taken us to its corresponding PLT slot.
+               // in such a case, look at the disassembled jump to determine
+               // where to find the actual function address.
+               InstructionInfo info;
+               if (fDebuggerInterface->GetArchitecture()->GetInstructionInfo(
+                       returnFunctionAddress, info, returnFunctionState) != 
B_OK) {
+                       return B_BAD_VALUE;
+               }
+
+               target_size_t addressSize = 
fDebuggerInterface->GetArchitecture()
+                       ->AddressSize();
+               ssize_t bytesRead = 
fDebuggerInterface->ReadMemory(info.TargetAddress(),
+                       &returnFunctionAddress, addressSize);
+
+               if (bytesRead != addressSize)
+                       return B_BAD_VALUE;
        }
 
-       ImageDebugInfo* imageInfo = image->GetImageDebugInfo();
+
        targetFunction = imageInfo->FunctionAtAddress(returnFunctionAddress);
        if (targetFunction != NULL) {
                DwarfFunctionDebugInfo* targetInfo =


Other related posts:

  • » [haiku-commits] haiku: hrev45412 - in src/apps/debugger: debug_info controllers arch model jobs - anevilyak