From f733c6031a76256d7b6652267b649892a9a849f7 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Fri, 28 Dec 2012 22:31:52 -0500 Subject: [PATCH] Initial implementation of _GetReturnValue(). - Look at the destination of the subroutine instruction and try to resolve it to a function. Currently only handles functions whose destination are within the same image. - If found, look up debug info for the target function. If available, determine if it returns a value. If so, construct an appropriate placeholder variable and add it to the frame's variable list. --- .../debug_info/DwarfImageDebugInfo.cpp | 61 ++++++++++++++++--- .../debugger/debug_info/DwarfImageDebugInfo.h | 1 + 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index c6aa3ca4ac..d8942ffe0f 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -41,6 +41,8 @@ #include "FunctionID.h" #include "FunctionInstance.h" #include "GlobalTypeLookup.h" +#include "Image.h" +#include "ImageDebugInfo.h" #include "InstructionInfo.h" #include "LocatableFile.h" #include "Register.h" @@ -56,6 +58,7 @@ #include "TypeLookupConstraints.h" #include "UnsupportedLanguage.h" #include "Variable.h" +#include "ValueLocation.h" namespace { @@ -672,7 +675,7 @@ DwarfImageDebugInfo::CreateFrame(Image* image, // call to see if we need to potentially retrieve a return value // as well if (instructionPointer > functionInstance->Address() - fRelocationDelta) { - _CreateReturnValue(functionInstance, function, frame, + _CreateReturnValue(functionInstance, image, function, frame, *stackFrameDebugInfo, instructionPointer); } } @@ -1085,7 +1088,7 @@ DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit, status_t DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance, - DwarfFunctionDebugInfo* function, StackFrame* frame, + Image* image, DwarfFunctionDebugInfo* function, StackFrame* frame, DwarfStackFrameDebugInfo& factory, target_addr_t instructionPointer) { DisassembledCode* sourceCode = NULL; @@ -1111,16 +1114,60 @@ DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance, previousStatementAddress); if (statement == NULL) return B_BAD_VALUE; + previousStatementAddress = statement->CoveringAddressRange().Start() - 1; + statement = sourceCode->StatementAtAddress( + previousStatementAddress); + if (statement == NULL) + return B_BAD_VALUE; TargetAddressRange range = statement->CoveringAddressRange(); InstructionInfo info; if (fArchitecture->GetInstructionInfo(range.Start(), info) == B_OK && info.Type() == INSTRUCTION_TYPE_SUBROUTINE_CALL) { - // TODO: determine where the previous instruction actually jumps to, - // retrieve that function (could potentially be in another image), - // and use its return type to retrieve the return value (will need - // architecture support since function return value passing convention - // is arch-dependent). + target_addr_t targetAddress = info.TargetAddress(); + if (targetAddress == 0) + return B_BAD_VALUE; + + if (image->ContainsAddress(targetAddress)) { + FunctionInstance* targetFunction; + if (targetAddress >= fPLTSectionStart && targetAddress < fPLTSectionEnd) { + // TODO: resolve actual target address in the PIC case + // and adjust targetAddress accordingly + } + ImageDebugInfo* imageInfo = image->GetImageDebugInfo(); + targetFunction = imageInfo->FunctionAtAddress(targetAddress); + if (targetFunction != NULL) { + DwarfFunctionDebugInfo* targetInfo = + dynamic_cast( + targetFunction->GetFunctionDebugInfo()); + if (targetInfo != NULL) { + DIESubprogram* subProgram = targetInfo->SubprogramEntry(); + DIEType* returnType = subProgram->ReturnType(); + if (returnType == NULL) { + // function doesn't return a value, we're done. + return B_OK; + } + + ValueLocation* location; + result = fArchitecture->GetReturnAddressLocation(frame, + returnType->ByteSize()->constant, location); + if (result != B_OK) + return result; + BReference locationReference(location, + true); + Variable* variable = NULL; + BReference idReference( + targetFunction->GetFunctionID(), true); + result = factory.CreateReturnValue(idReference, + returnType, location, variable); + if (result != B_OK) + return result; + BReference variableReference(variable, true); + if (!frame->AddLocalVariable(variable)) + return B_NO_MEMORY; + } + } + } } return B_OK; diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h index c03370fdea..4c9b0c1db8 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h @@ -104,6 +104,7 @@ private: const EntryListWrapper& blockEntries); status_t _CreateReturnValue(FunctionInstance* instance, + Image* image, DwarfFunctionDebugInfo* info, StackFrame* frame, DwarfStackFrameDebugInfo& factory,