From bc1ec2ec41d1ea3454e76eab1b9d5f8256b63c81 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Wed, 26 Dec 2012 00:21:06 -0500 Subject: [PATCH] Initial work towards retrieving function return values. - When creating a stack frame, we now look at the current function's state to determine if the last executed statement was a function call. Still need to determine the call destination in order to look up the latter function, retrieve its return type, and then request retrieval of the actual return value if applicable. --- .../debug_info/DwarfImageDebugInfo.cpp | 54 +++++++++++++++++++ .../debugger/debug_info/DwarfImageDebugInfo.h | 8 +++ 2 files changed, 62 insertions(+) diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index d64f823034..c6aa3ca4ac 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -26,6 +26,7 @@ #include "DebuggerInterface.h" #include "DebugInfoEntries.h" #include "Demangler.h" +#include "DisassembledCode.h" #include "Dwarf.h" #include "DwarfFile.h" #include "DwarfFunctionDebugInfo.h" @@ -40,6 +41,7 @@ #include "FunctionID.h" #include "FunctionInstance.h" #include "GlobalTypeLookup.h" +#include "InstructionInfo.h" #include "LocatableFile.h" #include "Register.h" #include "RegisterMap.h" @@ -665,6 +667,14 @@ DwarfImageDebugInfo::CreateFrame(Image* image, _CreateLocalVariables(unit, frame, functionID, *stackFrameDebugInfo, instructionPointer, functionInstance->Address() - fRelocationDelta, subprogramEntry->Variables(), subprogramEntry->Blocks()); + + // determine if the previously executed instruction was a function + // call to see if we need to potentially retrieve a return value + // as well + if (instructionPointer > functionInstance->Address() - fRelocationDelta) { + _CreateReturnValue(functionInstance, function, frame, + *stackFrameDebugInfo, instructionPointer); + } } _frame = frameReference.Detach(); @@ -1073,6 +1083,50 @@ DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit, } +status_t +DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance, + DwarfFunctionDebugInfo* function, StackFrame* frame, + DwarfStackFrameDebugInfo& factory, target_addr_t instructionPointer) +{ + DisassembledCode* sourceCode = NULL; + target_size_t bufferSize = std::min(functionInstance->Size(), + (target_size_t)64 * 1024); + void* buffer = malloc(bufferSize); + if (buffer == NULL) + return B_NO_MEMORY; + MemoryDeleter bufferDeleter(buffer); + ssize_t bytesRead = function->GetSpecificImageDebugInfo() + ->ReadCode(functionInstance->Address(), buffer, bufferSize); + if (bytesRead < 0) + return bytesRead; + + status_t result = fArchitecture->DisassembleCode(function, buffer, + bytesRead, sourceCode); + if (result != B_OK) + return result; + + BReference sourceCodeReference(sourceCode, true); + target_addr_t previousStatementAddress = instructionPointer + fRelocationDelta - 1; + Statement* 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). + } + + return B_OK; +} + + bool DwarfImageDebugInfo::_EvaluateBaseTypeConstraints(DIEType* type, const TypeLookupConstraints& constraints) diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h index a79a58bb51..c03370fdea 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h @@ -21,12 +21,14 @@ class Architecture; class CompilationUnit; class DebuggerInterface; class DIEType; +class DwarfFunctionDebugInfo; class DwarfStackFrameDebugInfo; class DwarfFile; class ElfSegment; class FileManager; class FileSourceCode; class FunctionID; +class FunctionInstance; class GlobalTypeCache; class GlobalTypeLookup; class LocatableFile; @@ -101,6 +103,12 @@ private: const EntryListWrapper& variableEntries, const EntryListWrapper& blockEntries); + status_t _CreateReturnValue(FunctionInstance* instance, + DwarfFunctionDebugInfo* info, + StackFrame* frame, + DwarfStackFrameDebugInfo& factory, + target_addr_t instructionPointer); + bool _EvaluateBaseTypeConstraints(DIEType* type, const TypeLookupConstraints& constraints);