[prev in list] [next in list] [prev in thread] [next in thread] 

List:       haiku-commits
Subject:    [haiku-commits] haiku: hrev45419 - in src/apps/debugger: debug_info model controllers arch
From:       anevilyak () gmail ! com
Date:       2013-03-28 3:29:39
Message-ID: 20130328032939.71FC25C07D8 () vmrepo ! haiku-os ! org
[Download RAW message or body]

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@gmail.com> ]

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

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@gmail.com>
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@gollent.com.
+ * 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@gollent.com.
+ * 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@gmail.com>
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;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic