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.
This commit is contained in:
@@ -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<DisassembledCode> 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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user