diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index d64f823034a..c6aa3ca4ac8 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 a79a58bb51c..c03370fdea8 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 @@ class DwarfImageDebugInfo : public SpecificImageDebugInfo { 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);