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

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 28 Mar 2013 04:29:39 +0100 (CET)

hrev45419 adds 2 changesets to branch 'master'
old head: 5a6b854033916abf2f924f11d6ce8d52c14153bd
new head: 76ed6d72a535697c54305bc36c946e13dc5ed28c
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=76ed6d7+%5E5a6b854

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

3fa4297: Add ReturnValueInfo class for storing function return information.

76ed6d7: Refactoring to handle multiple return values.
  
  - Replace use of address + CpuState pair in Thread,
    SpecificImageDebugInfo::CreateStackTrace() with a ReturnValueInfoList.
    Adjust all implementing subclasses and callers accordingly.
  
  - DwarfImageDebugInfo::CreateReturnValue() -> CreateReturnValues().
    Now processes a list of return value information structures rather
    than just a single one. This means we can now handle multiple return
    values in a single statement. This still isn't entirely correct though,
    since, e.g. for functions whose return types fit in a register we need
    to either retrieve them immediately after function return, or store the
    CPU state at that point in time for later use in value retrieval,
    otherwise the return values will all be those of the last called function.

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

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

14 files changed, 253 insertions(+), 141 deletions(-)
src/apps/debugger/Jamfile                        |   3 +-
src/apps/debugger/arch/Architecture.cpp          |  12 +-
src/apps/debugger/arch/Architecture.h            |   4 +-
src/apps/debugger/controllers/ThreadHandler.cpp  |  48 ++++--
.../debug_info/DebuggerImageDebugInfo.cpp        |   5 +-
.../debugger/debug_info/DebuggerImageDebugInfo.h |   3 +-
.../debugger/debug_info/DwarfImageDebugInfo.cpp  | 167 ++++++++++---------
.../debugger/debug_info/DwarfImageDebugInfo.h    |   8 +-
.../debugger/debug_info/SpecificImageDebugInfo.h |   4 +-
src/apps/debugger/jobs/GetStackTraceJob.cpp      |   4 +-
src/apps/debugger/model/ReturnValueInfo.cpp      |  47 ++++++
src/apps/debugger/model/ReturnValueInfo.h        |  38 +++++
src/apps/debugger/model/Thread.cpp               |  33 ++--
src/apps/debugger/model/Thread.h                 |  18 +-

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

Commit:      3fa429781c54a21dd23f1ac128b4e2b79b7e1b82
URL:         http://cgit.haiku-os.org/haiku/commit/?id=3fa4297
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Thu Mar 28 03:27:03 2013 UTC

Add ReturnValueInfo class for storing function return information.

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

diff --git a/src/apps/debugger/model/ReturnValueInfo.cpp 
b/src/apps/debugger/model/ReturnValueInfo.cpp
new file mode 100644
index 0000000..e44da35
--- /dev/null
+++ b/src/apps/debugger/model/ReturnValueInfo.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+
+#include "ReturnValueInfo.h"
+
+#include "CpuState.h"
+
+
+ReturnValueInfo::ReturnValueInfo()
+       :
+       BReferenceable(),
+       fAddress(0),
+       fState(NULL)
+{
+}
+
+
+ReturnValueInfo::ReturnValueInfo(target_addr_t address, CpuState* state)
+       :
+       BReferenceable(),
+       fAddress(address),
+       fState(state)
+{
+       state->AcquireReference();
+}
+
+
+ReturnValueInfo::~ReturnValueInfo()
+{
+       if (fState != NULL)
+               fState->ReleaseReference();
+}
+
+
+void
+ReturnValueInfo::SetTo(target_addr_t address, CpuState* state)
+{
+       fAddress = address;
+
+       if (fState != NULL)
+               fState->ReleaseReference();
+
+       fState = state;
+       fState->AcquireReference();
+}
diff --git a/src/apps/debugger/model/ReturnValueInfo.h 
b/src/apps/debugger/model/ReturnValueInfo.h
new file mode 100644
index 0000000..693da13
--- /dev/null
+++ b/src/apps/debugger/model/ReturnValueInfo.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx.
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef RETURN_VALUE_INFO_H
+#define RETURN_VALUE_INFO_H
+
+#include "ObjectList.h"
+#include "Referenceable.h"
+#include "Types.h"
+
+
+class CpuState;
+
+
+class ReturnValueInfo : public BReferenceable {
+public:
+                                                               
ReturnValueInfo();
+                                                               
ReturnValueInfo(target_addr_t address,
+                                                                       
CpuState* state);
+                                                               
~ReturnValueInfo();
+
+                       void                            SetTo(target_addr_t 
address, CpuState* state);
+
+                       target_addr_t           SubroutineAddress() const
+                                                                       { 
return fAddress; }
+                       CpuState*                       State() const   { 
return fState; }
+
+private:
+                       target_addr_t           fAddress;
+                       CpuState*                       fState;
+};
+
+
+typedef BObjectList<ReturnValueInfo> ReturnValueInfoList;
+
+
+#endif // RETURN_VALUE_INFO_H

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

Revision:    hrev45419
Commit:      76ed6d72a535697c54305bc36c946e13dc5ed28c
URL:         http://cgit.haiku-os.org/haiku/commit/?id=76ed6d7
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Thu Mar 28 03:21:42 2013 UTC

Refactoring to handle multiple return values.

- Replace use of address + CpuState pair in Thread,
  SpecificImageDebugInfo::CreateStackTrace() with a ReturnValueInfoList.
  Adjust all implementing subclasses and callers accordingly.

- DwarfImageDebugInfo::CreateReturnValue() -> CreateReturnValues().
  Now processes a list of return value information structures rather
  than just a single one. This means we can now handle multiple return
  values in a single statement. This still isn't entirely correct though,
  since, e.g. for functions whose return types fit in a register we need
  to either retrieve them immediately after function return, or store the
  CPU state at that point in time for later use in value retrieval,
  otherwise the return values will all be those of the last called function.

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

diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index c2aaa66..053121c 100644
--- a/src/apps/debugger/Jamfile
+++ b/src/apps/debugger/Jamfile
@@ -144,6 +144,7 @@ Application Debugger :
        FileSourceCode.cpp
        Image.cpp
        ImageInfo.cpp
+       ReturnValueInfo.cpp
        SourceCode.cpp
        StackFrame.cpp
        StackFrameValues.cpp
@@ -151,7 +152,6 @@ Application Debugger :
        StackTrace.cpp
        Statement.cpp
        SymbolInfo.cpp
-       UserBreakpoint.cpp
        Team.cpp
        TeamMemory.cpp
        TeamMemoryBlock.cpp
@@ -161,6 +161,7 @@ Application Debugger :
        Type.cpp
        TypeComponentPath.cpp
        TypeLookupConstraints.cpp
+       UserBreakpoint.cpp
        Variable.cpp
        Watchpoint.cpp
 
diff --git a/src/apps/debugger/arch/Architecture.cpp 
b/src/apps/debugger/arch/Architecture.cpp
index ecae506..1620024 100644
--- a/src/apps/debugger/arch/Architecture.cpp
+++ b/src/apps/debugger/arch/Architecture.cpp
@@ -94,9 +94,8 @@ Architecture::InitRegisterRules(CfaContext& context) const
 status_t
 Architecture::CreateStackTrace(Team* team,
        ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState,
-       StackTrace*& _stackTrace, target_addr_t returnFunctionAddress,
-       CpuState* returnFunctionState, int32 maxStackDepth, bool 
useExistingTrace,
-       bool getFullFrameInfo)
+       StackTrace*& _stackTrace, ReturnValueInfoList* returnValueInfos,
+       int32 maxStackDepth, bool useExistingTrace, bool getFullFrameInfo)
 {
        BReference<CpuState> cpuStateReference(cpuState);
 
@@ -164,8 +163,8 @@ Architecture::CreateStackTrace(Team* team,
                if (function != NULL) {
                        status_t error = 
functionDebugInfo->GetSpecificImageDebugInfo()
                                ->CreateFrame(image, function, cpuState, 
getFullFrameInfo,
-                                       nextFrame == NULL ? 
returnFunctionAddress : 0,
-                                       nextFrame == NULL ? returnFunctionState 
: 0, frame,
+                                       nextFrame == NULL
+                                               ? returnValueInfos : NULL, 
frame,
                                        previousCpuState);
                        if (error != B_OK && error != B_UNSUPPORTED)
                                break;
@@ -174,8 +173,7 @@ Architecture::CreateStackTrace(Team* team,
                // If we have no frame yet, let the architecture create it.
                if (frame == NULL) {
                        status_t error = CreateStackFrame(image, 
functionDebugInfo,
-                               cpuState, nextFrame == NULL, frame,
-                               previousCpuState);
+                               cpuState, nextFrame == NULL, frame, 
previousCpuState);
                        if (error != B_OK)
                                break;
                }
diff --git a/src/apps/debugger/arch/Architecture.h 
b/src/apps/debugger/arch/Architecture.h
index e390774..76d553b 100644
--- a/src/apps/debugger/arch/Architecture.h
+++ b/src/apps/debugger/arch/Architecture.h
@@ -13,6 +13,7 @@
 #include <Referenceable.h>
 #include <Variant.h>
 
+#include "ReturnValueInfo.h"
 #include "Types.h"
 
 
@@ -110,8 +111,7 @@ public:
                                                                        
ImageDebugInfoProvider* imageInfoProvider,
                                                                        
CpuState* cpuState,
                                                                        
StackTrace*& _stackTrace,
-                                                                       
target_addr_t returnFunctionAddress,
-                                                                       
CpuState* returnFunctionState,
+                                                                       
ReturnValueInfoList* returnValueInfos,
                                                                        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 af647cb..b40aa35 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, NULL, 1,
+                               fThread->GetTeam(), this, cpuState, stackTrace, 
NULL, 1,
                                false, false) == B_OK) {
                        stackTraceReference.SetTo(stackTrace, true);
                }
@@ -484,11 +484,20 @@ ThreadHandler::_DoStepOver(CpuState* cpuState)
        TRACE_CONTROL("  subroutine call -- installing breakpoint at address "
                "%#" B_PRIx64 "\n", info.Address() + info.Size());
 
-       fThread->SetExecutedSubroutine(info.TargetAddress());
-       fThread->SetSubroutineCpuState(cpuState);
        if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK)
                return false;
 
+       ReturnValueInfo* returnInfo = new(std::nothrow) ReturnValueInfo(
+               info.TargetAddress(), cpuState);
+       if (returnInfo == NULL)
+               return false;
+
+       BReference<ReturnValueInfo> returnInfoReference(returnInfo, true);
+
+       if (fThread->AddReturnValueInfo(returnInfo) != B_OK)
+               return false;
+
+       returnInfoReference.Detach();
        _RunThread(cpuState->InstructionPointer());
        return true;
 }
@@ -567,8 +576,8 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
 
                        if (stackTrace == NULL && cpuState != NULL) {
                                if 
(fDebuggerInterface->GetArchitecture()->CreateStackTrace(
-                                               fThread->GetTeam(), this, 
cpuState, stackTrace, 0,
-                                               NULL, 1, false, false) == B_OK) 
{
+                                               fThread->GetTeam(), this, 
cpuState, stackTrace, NULL,
+                                               1, false, false) == B_OK) {
                                        stackTraceReference.SetTo(stackTrace, 
true);
                                }
                        }
@@ -608,8 +617,16 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState)
                {
                        // That's the return address, so we're done in theory,
                        // unless we're a recursive function. Check if we've 
actually
-                       // exited the previous stack frame or not.
-                       
fThread->SetExecutedSubroutine(cpuState->InstructionPointer());
+                       // exited the previous stack frame or not
+                       ReturnValueInfo* info = new(std::nothrow) 
ReturnValueInfo(
+                               cpuState->InstructionPointer(), cpuState);
+                       if (info == NULL)
+                               return false;
+                       BReference<ReturnValueInfo> infoReference(info, true);
+                       if (fThread->AddReturnValueInfo(info) != B_OK)
+                               return false;
+
+                       infoReference.Detach();
                        target_addr_t framePointer = 
cpuState->StackFramePointer();
                        bool hasExitedFrame = 
fDebuggerInterface->GetArchitecture()
                                ->StackGrowthDirection() == 
STACK_GROWTH_DIRECTION_POSITIVE
@@ -654,8 +671,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
 
                        if (stackTrace == NULL && cpuState != NULL) {
                                if 
(fDebuggerInterface->GetArchitecture()->CreateStackTrace(
-                                               fThread->GetTeam(), this, 
cpuState, stackTrace, 0,
-                                               NULL, 1, false, false) == B_OK) 
{
+                                               fThread->GetTeam(), this, 
cpuState, stackTrace, NULL,
+                                               1, false, false) == B_OK) {
                                        stackTraceReference.SetTo(stackTrace, 
true);
                                }
                        }
@@ -686,7 +703,7 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
                                BReference<StackTrace> 
stackTraceReference(stackTrace);
                                if (stackTrace == NULL && cpuState != NULL) {
                                        if 
(fDebuggerInterface->GetArchitecture()->CreateStackTrace(
-                                                       fThread->GetTeam(), 
this, cpuState, stackTrace, 0,
+                                                       fThread->GetTeam(), 
this, cpuState, stackTrace,
                                                        NULL, 1, false, false) 
== B_OK) {
                                                
stackTraceReference.SetTo(stackTrace, true);
                                        }
@@ -694,8 +711,15 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState)
 
                                if (stackTrace != NULL && stackTrace->FrameAt(0)
                                                ->FrameAddress() != 
fPreviousFrameAddress) {
-                                       fThread->SetExecutedSubroutine(
-                                               cpuState->InstructionPointer());
+                                       ReturnValueInfo* info = 
new(std::nothrow) ReturnValueInfo(
+                                               cpuState->InstructionPointer(), 
cpuState);
+                                       if (info == NULL)
+                                               return false;
+                                       BReference<ReturnValueInfo> 
infoReference(info, true);
+                                       if (fThread->AddReturnValueInfo(info) 
!= B_OK)
+                                               return false;
+
+                                       infoReference.Detach();
                                }
 
                                return false;
diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp 
b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp
index c7a77e1..8aa49b4 100644
--- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp
@@ -68,9 +68,8 @@ DebuggerImageDebugInfo::GetAddressSectionType(target_addr_t 
address)
 status_t
 DebuggerImageDebugInfo::CreateFrame(Image* image,
        FunctionInstance* functionInstance, CpuState* cpuState,
-       bool getFullFrameInfo, target_addr_t returnFunctionAddress,
-       CpuState* returnFunctionState, StackFrame*& _previousFrame,
-       CpuState*& _previousCpuState)
+       bool getFullFrameInfo, ReturnValueInfoList* returnValueInfos,
+       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 91d0c1b..efe5816 100644
--- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h
+++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h
@@ -36,8 +36,7 @@ public:
                                                                        
FunctionInstance* functionInstance,
                                                                        
CpuState* cpuState,
                                                                        bool 
getFullFrameInfo,
-                                                                       
target_addr_t returnFunctionAddress,
-                                                                       
CpuState* returnFunctionState,
+                                                                       
ReturnValueInfoList* returnValueInfos,
                                                                        
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 5c58ed3..b467cd1 100644
--- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
+++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp
@@ -522,9 +522,8 @@ DwarfImageDebugInfo::GetAddressSectionType(target_addr_t 
address)
 status_t
 DwarfImageDebugInfo::CreateFrame(Image* image,
        FunctionInstance* functionInstance, CpuState* cpuState,
-       bool getFullFrameInfo, target_addr_t returnFunctionAddress,
-       CpuState* returnFunctionState, StackFrame*& _frame,
-       CpuState*& _previousCpuState)
+       bool getFullFrameInfo, ReturnValueInfoList* returnValueInfos,
+       StackFrame*& _frame, CpuState*& _previousCpuState)
 {
        DwarfFunctionDebugInfo* function = 
dynamic_cast<DwarfFunctionDebugInfo*>(
                functionInstance->GetFunctionDebugInfo());
@@ -674,9 +673,9 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
                        instructionPointer, functionInstance->Address() - 
fRelocationDelta,
                        subprogramEntry->Variables(), 
subprogramEntry->Blocks());
 
-               if (returnFunctionAddress != 0) {
-                       _CreateReturnValue(returnFunctionAddress, 
returnFunctionState,
-                               image, frame, *stackFrameDebugInfo);
+               if (!returnValueInfos->IsEmpty()) {
+                       _CreateReturnValues(returnValueInfos, image, frame,
+                               *stackFrameDebugInfo);
                }
        }
 
@@ -1087,88 +1086,94 @@ 
DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit,
 
 
 status_t
-DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress,
-       CpuState* returnFunctionState, Image* image, StackFrame* frame,
-       DwarfStackFrameDebugInfo& factory)
+DwarfImageDebugInfo::_CreateReturnValues(ReturnValueInfoList* returnValueInfos,
+       Image* image, StackFrame* frame, DwarfStackFrameDebugInfo& factory)
 {
-       if (!image->ContainsAddress(returnFunctionAddress)) {
-               // our current image doesn't contain the target function,
-               // locate the one which does.
-               image = image->GetTeam()->ImageByAddress(returnFunctionAddress);
-               if (image == NULL)
-                       return B_BAD_VALUE;
-       }
-
-       status_t result = B_OK;
-       ImageDebugInfo* imageInfo = image->GetImageDebugInfo();
-       FunctionInstance* targetFunction;
-       if (returnFunctionAddress >= fPLTSectionStart
-               && returnFunctionAddress < fPLTSectionEnd) {
-               // 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;
+       for (int32 i = 0; i < returnValueInfos->CountItems(); i++) {
+               ReturnValueInfo* valueInfo = returnValueInfos->ItemAt(i);
+               target_addr_t subroutineAddress = 
valueInfo->SubroutineAddress();
+               CpuState* subroutineState = valueInfo->State();
+               if (!image->ContainsAddress(subroutineAddress)) {
+                       // our current image doesn't contain the target 
function,
+                       // locate the one which does.
+                       image = 
image->GetTeam()->ImageByAddress(subroutineAddress);
+                       if (image == NULL) {
+                               // nothing we can do, try the next entry (if 
any)
+                               continue;
+                       }
                }
 
-               target_size_t addressSize = 
fDebuggerInterface->GetArchitecture()
-                       ->AddressSize();
-               ssize_t bytesRead = 
fDebuggerInterface->ReadMemory(info.TargetAddress(),
-                       &returnFunctionAddress, addressSize);
+               status_t result = B_OK;
+               ImageDebugInfo* imageInfo = image->GetImageDebugInfo();
+               FunctionInstance* targetFunction;
+               if (subroutineAddress >= fPLTSectionStart
+                       && subroutineAddress < fPLTSectionEnd) {
+                       // 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(
+                               subroutineAddress, info, subroutineState) != 
B_OK) {
+                               return B_BAD_VALUE;
+                       }
 
-               if (bytesRead != (ssize_t)addressSize)
-                       return B_BAD_VALUE;
-       }
+                       target_size_t addressSize = 
fDebuggerInterface->GetArchitecture()
+                               ->AddressSize();
+                       ssize_t bytesRead = fDebuggerInterface->ReadMemory(
+                               info.TargetAddress(), &subroutineAddress, 
addressSize);
 
+                       if (bytesRead != (ssize_t)addressSize)
+                               return B_BAD_VALUE;
+               }
 
-       targetFunction = imageInfo->FunctionAtAddress(returnFunctionAddress);
-       if (targetFunction != NULL) {
-               DwarfFunctionDebugInfo* targetInfo =
-                       dynamic_cast<DwarfFunctionDebugInfo*>(
-                               targetFunction->GetFunctionDebugInfo());
-               if (targetInfo != NULL) {
-                       DIESubprogram* subProgram = 
targetInfo->SubprogramEntry();
-                       DIEType* returnType = subProgram->ReturnType();
-                       if (returnType == NULL) {
-                               // check if we have a specification, and if so, 
if that has
-                               // a return type
-                               subProgram = 
dynamic_cast<DIESubprogram*>(subProgram->Specification());
-                               if (subProgram != NULL)
-                                       returnType = subProgram->ReturnType();
-
-                               // function doesn't return a value, we're done.
-                               if (returnType == NULL)
-                                       return B_OK;
-                       }
+               targetFunction = 
imageInfo->FunctionAtAddress(subroutineAddress);
+               if (targetFunction != NULL) {
+                       DwarfFunctionDebugInfo* targetInfo =
+                               dynamic_cast<DwarfFunctionDebugInfo*>(
+                                       targetFunction->GetFunctionDebugInfo());
+                       if (targetInfo != NULL) {
+                               DIESubprogram* subProgram = 
targetInfo->SubprogramEntry();
+                               DIEType* returnType = subProgram->ReturnType();
+                               if (returnType == NULL) {
+                                       // check if we have a specification, 
and if so, if that has
+                                       // a return type
+                                       subProgram = 
dynamic_cast<DIESubprogram*>(
+                                               subProgram->Specification());
+                                       if (subProgram != NULL)
+                                               returnType = 
subProgram->ReturnType();
+
+                                       // function doesn't return a value, 
we're done.
+                                       if (returnType == NULL)
+                                               return B_OK;
+                               }
 
-                       uint32 byteSize = 0;
-                       if (returnType->ByteSize() == NULL) {
-                               if 
(dynamic_cast<DIEAddressingType*>(returnType) != NULL)
-                                       byteSize = fArchitecture->AddressSize();
-                       } else
-                               byteSize = returnType->ByteSize()->constant;
-
-                       ValueLocation* location;
-                       result = fArchitecture->GetReturnAddressLocation(frame,
-                               byteSize, location);
-                       if (result != B_OK)
-                               return result;
-
-                       BReference<ValueLocation> locationReference(location, 
true);
-                       Variable* variable = NULL;
-                       BReference<FunctionID> idReference(
-                               targetFunction->GetFunctionID(), true);
-                       result = factory.CreateReturnValue(idReference, 
returnType,
-                               location, variable);
-                       if (result != B_OK)
-                               return result;
-
-                       BReference<Variable> variableReference(variable, true);
-                       if (!frame->AddLocalVariable(variable))
-                               return B_NO_MEMORY;
+                               uint32 byteSize = 0;
+                               if (returnType->ByteSize() == NULL) {
+                                       if 
(dynamic_cast<DIEAddressingType*>(returnType) != NULL)
+                                               byteSize = 
fArchitecture->AddressSize();
+                               } else
+                                       byteSize = 
returnType->ByteSize()->constant;
+
+                               ValueLocation* location;
+                               result = 
fArchitecture->GetReturnAddressLocation(frame,
+                                       byteSize, location);
+                               if (result != B_OK)
+                                       return result;
+
+                               BReference<ValueLocation> 
locationReference(location, true);
+                               Variable* variable = NULL;
+                               BReference<FunctionID> idReference(
+                                       targetFunction->GetFunctionID(), true);
+                               result = factory.CreateReturnValue(idReference, 
returnType,
+                                       location, variable);
+                               if (result != B_OK)
+                                       return result;
+
+                               BReference<Variable> 
variableReference(variable, true);
+                               if (!frame->AddLocalVariable(variable))
+                                       return B_NO_MEMORY;
+                       }
                }
        }
 
diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h 
b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h
index 7dab0fb..422925a 100644
--- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h
+++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h
@@ -64,8 +64,7 @@ public:
                                                                        
FunctionInstance* functionInstance,
                                                                        
CpuState* cpuState,
                                                                        bool 
getFullFrameInfo,
-                                                                       
target_addr_t returnFunctionAddress,
-                                                                       
CpuState* returnFunctionState,
+                                                                       
ReturnValueInfoList* returnValueInfos,
                                                                        
StackFrame*& _frame,
                                                                        
CpuState*& _previousCpuState);
        virtual status_t                        GetStatement(FunctionDebugInfo* 
function,
@@ -105,9 +104,8 @@ private:
                                                                        const 
EntryListWrapper& variableEntries,
                                                                        const 
EntryListWrapper& blockEntries);
 
-                       status_t                        _CreateReturnValue(
-                                                                       
target_addr_t returnFunctionAddress,
-                                                                       
CpuState* returnFunctionState,
+                       status_t                        _CreateReturnValues(
+                                                                       
ReturnValueInfoList* returnValueInfos,
                                                                        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 595d238..02a1fa9 100644
--- a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h
+++ b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h
@@ -10,6 +10,7 @@
 #include <Referenceable.h>
 
 #include "AddressSectionTypes.h"
+#include "ReturnValueInfo.h"
 #include "Types.h"
 
 
@@ -56,8 +57,7 @@ public:
                                                                        
FunctionInstance* functionInstance,
                                                                        
CpuState* cpuState,
                                                                        bool 
getFullFrameInfo,
-                                                                       
target_addr_t returnFunctionAddress,
-                                                                       
CpuState* returnFunctionState,
+                                                                       
ReturnValueInfoList* returnValueInfos,
                                                                        
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 c3a2316..0bc286e 100644
--- a/src/apps/debugger/jobs/GetStackTraceJob.cpp
+++ b/src/apps/debugger/jobs/GetStackTraceJob.cpp
@@ -58,9 +58,7 @@ GetStackTraceJob::Do()
        // get the stack trace
        StackTrace* stackTrace;
        status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), 
this,
-               fCpuState, stackTrace, fThread->ExecutedSubroutine()
-                       ? fThread->SubroutineAddress() : 0, 
fThread->ExecutedSubroutine()
-                       ? fThread->SubroutineCpuState() : NULL);
+               fCpuState, stackTrace, fThread->ReturnValueInfos());
        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 e32424c..0dc319f 100644
--- a/src/apps/debugger/model/Thread.cpp
+++ b/src/apps/debugger/model/Thread.cpp
@@ -18,8 +18,7 @@ Thread::Thread(Team* team, thread_id threadID)
        fID(threadID),
        fState(THREAD_STATE_UNKNOWN),
        fExecutedSubroutine(false),
-       fSubroutineAddress(0),
-       fSubroutineState(NULL),
+       fReturnValueInfos(NULL),
        fStoppedReason(THREAD_STOPPED_UNKNOWN),
        fCpuState(NULL),
        fStackTrace(NULL)
@@ -33,14 +32,19 @@ Thread::~Thread()
                fCpuState->ReleaseReference();
        if (fStackTrace != NULL)
                fStackTrace->ReleaseReference();
-       if (fSubroutineState != NULL)
-               fSubroutineState->ReleaseReference();
+
+       ClearReturnValueInfos();
+       delete fReturnValueInfos;
 }
 
 
 status_t
 Thread::Init()
 {
+       fReturnValueInfos = new(std::nothrow) ReturnValueInfoList;
+       if (fReturnValueInfos == NULL)
+               return B_NO_MEMORY;
+
        return B_OK;
 }
 
@@ -74,7 +78,7 @@ Thread::SetState(uint32 state, uint32 reason, const BString& 
info)
                SetCpuState(NULL);
                SetStackTrace(NULL);
                fExecutedSubroutine = false;
-               fSubroutineAddress = 0;
+               ClearReturnValueInfos();
        }
 
        fTeam->NotifyThreadStateChanged(this);
@@ -117,20 +121,23 @@ Thread::SetStackTrace(StackTrace* trace)
 }
 
 
-void
-Thread::SetExecutedSubroutine(target_addr_t address)
+status_t
+Thread::AddReturnValueInfo(ReturnValueInfo* info)
 {
+       if (!fReturnValueInfos->AddItem(info))
+               return B_NO_MEMORY;
+
+       info->AcquireReference();
        fExecutedSubroutine = true;
-       fSubroutineAddress = address;
+       return B_OK;
 }
 
 
 void
-Thread::SetSubroutineCpuState(CpuState* state)
+Thread::ClearReturnValueInfos()
 {
-       if (fSubroutineState != NULL)
-               fSubroutineState->ReleaseReference();
+       for (int32 i = 0; i < fReturnValueInfos->CountItems(); i++)
+               fReturnValueInfos->ItemAt(i)->ReleaseReference();
 
-       fSubroutineState = state;
-       fSubroutineState->AcquireReference();
+       fReturnValueInfos->MakeEmpty();
 }
diff --git a/src/apps/debugger/model/Thread.h b/src/apps/debugger/model/Thread.h
index 17aa330..e25a6c7 100644
--- a/src/apps/debugger/model/Thread.h
+++ b/src/apps/debugger/model/Thread.h
@@ -11,6 +11,7 @@
 #include <Referenceable.h>
 #include <util/DoublyLinkedList.h>
 
+#include "ReturnValueInfo.h"
 #include "types/Types.h"
 
 
@@ -69,14 +70,11 @@ public:
                        StackTrace*                     GetStackTrace() const   
{ return fStackTrace; }
                        void                            
SetStackTrace(StackTrace* trace);
 
-                       bool                            ExecutedSubroutine() 
const
-                                                                       { 
return fExecutedSubroutine; }
-                       target_addr_t           SubroutineAddress() const
-                                                                       { 
return fSubroutineAddress; }
-                       void                            
SetExecutedSubroutine(target_addr_t address);
-                       CpuState*                       SubroutineCpuState() 
const
-                                                                       { 
return fSubroutineState; }
-                       void                            
SetSubroutineCpuState(CpuState* state);
+                       ReturnValueInfoList*
+                                                               
ReturnValueInfos() const
+                                                               { return 
fReturnValueInfos; }
+                       status_t                        
AddReturnValueInfo(ReturnValueInfo* info);
+                       void                            ClearReturnValueInfos();
 
 private:
                        Team*                           fTeam;
@@ -84,8 +82,8 @@ private:
                        BString                         fName;
                        uint32                          fState;
                        bool                            fExecutedSubroutine;
-                       target_addr_t           fSubroutineAddress;
-                       CpuState*                       fSubroutineState;
+                       ReturnValueInfoList*
+                                                               
fReturnValueInfos;
                        uint32                          fStoppedReason;
                        BString                         fStoppedReasonInfo;
                        CpuState*                       fCpuState;


Other related posts: