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.
This commit is contained in:
@@ -41,6 +41,8 @@
|
|||||||
#include "FunctionID.h"
|
#include "FunctionID.h"
|
||||||
#include "FunctionInstance.h"
|
#include "FunctionInstance.h"
|
||||||
#include "GlobalTypeLookup.h"
|
#include "GlobalTypeLookup.h"
|
||||||
|
#include "Image.h"
|
||||||
|
#include "ImageDebugInfo.h"
|
||||||
#include "InstructionInfo.h"
|
#include "InstructionInfo.h"
|
||||||
#include "LocatableFile.h"
|
#include "LocatableFile.h"
|
||||||
#include "Register.h"
|
#include "Register.h"
|
||||||
@@ -56,6 +58,7 @@
|
|||||||
#include "TypeLookupConstraints.h"
|
#include "TypeLookupConstraints.h"
|
||||||
#include "UnsupportedLanguage.h"
|
#include "UnsupportedLanguage.h"
|
||||||
#include "Variable.h"
|
#include "Variable.h"
|
||||||
|
#include "ValueLocation.h"
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -672,7 +675,7 @@ DwarfImageDebugInfo::CreateFrame(Image* image,
|
|||||||
// call to see if we need to potentially retrieve a return value
|
// call to see if we need to potentially retrieve a return value
|
||||||
// as well
|
// as well
|
||||||
if (instructionPointer > functionInstance->Address() - fRelocationDelta) {
|
if (instructionPointer > functionInstance->Address() - fRelocationDelta) {
|
||||||
_CreateReturnValue(functionInstance, function, frame,
|
_CreateReturnValue(functionInstance, image, function, frame,
|
||||||
*stackFrameDebugInfo, instructionPointer);
|
*stackFrameDebugInfo, instructionPointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1085,7 +1088,7 @@ DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit,
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance,
|
DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance,
|
||||||
DwarfFunctionDebugInfo* function, StackFrame* frame,
|
Image* image, DwarfFunctionDebugInfo* function, StackFrame* frame,
|
||||||
DwarfStackFrameDebugInfo& factory, target_addr_t instructionPointer)
|
DwarfStackFrameDebugInfo& factory, target_addr_t instructionPointer)
|
||||||
{
|
{
|
||||||
DisassembledCode* sourceCode = NULL;
|
DisassembledCode* sourceCode = NULL;
|
||||||
@@ -1111,16 +1114,60 @@ DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance,
|
|||||||
previousStatementAddress);
|
previousStatementAddress);
|
||||||
if (statement == NULL)
|
if (statement == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
previousStatementAddress = statement->CoveringAddressRange().Start() - 1;
|
||||||
|
statement = sourceCode->StatementAtAddress(
|
||||||
|
previousStatementAddress);
|
||||||
|
if (statement == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
TargetAddressRange range = statement->CoveringAddressRange();
|
TargetAddressRange range = statement->CoveringAddressRange();
|
||||||
InstructionInfo info;
|
InstructionInfo info;
|
||||||
if (fArchitecture->GetInstructionInfo(range.Start(), info) == B_OK
|
if (fArchitecture->GetInstructionInfo(range.Start(), info) == B_OK
|
||||||
&& info.Type() == INSTRUCTION_TYPE_SUBROUTINE_CALL) {
|
&& info.Type() == INSTRUCTION_TYPE_SUBROUTINE_CALL) {
|
||||||
// TODO: determine where the previous instruction actually jumps to,
|
target_addr_t targetAddress = info.TargetAddress();
|
||||||
// retrieve that function (could potentially be in another image),
|
if (targetAddress == 0)
|
||||||
// and use its return type to retrieve the return value (will need
|
return B_BAD_VALUE;
|
||||||
// architecture support since function return value passing convention
|
|
||||||
// is arch-dependent).
|
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<DwarfFunctionDebugInfo*>(
|
||||||
|
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<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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ private:
|
|||||||
const EntryListWrapper& blockEntries);
|
const EntryListWrapper& blockEntries);
|
||||||
|
|
||||||
status_t _CreateReturnValue(FunctionInstance* instance,
|
status_t _CreateReturnValue(FunctionInstance* instance,
|
||||||
|
Image* image,
|
||||||
DwarfFunctionDebugInfo* info,
|
DwarfFunctionDebugInfo* info,
|
||||||
StackFrame* frame,
|
StackFrame* frame,
|
||||||
DwarfStackFrameDebugInfo& factory,
|
DwarfStackFrameDebugInfo& factory,
|
||||||
|
|||||||
Reference in New Issue
Block a user