diff --git a/src/apps/debugger/arch/Architecture.cpp b/src/apps/debugger/arch/Architecture.cpp index 4da06410f2..c1724f78ec 100644 --- a/src/apps/debugger/arch/Architecture.cpp +++ b/src/apps/debugger/arch/Architecture.cpp @@ -94,8 +94,8 @@ Architecture::InitRegisterRules(CfaContext& context) const status_t Architecture::CreateStackTrace(Team* team, ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState, - StackTrace*& _stackTrace, bool getReturnValue, int32 maxStackDepth, - bool useExistingTrace, bool getFullFrameInfo) + StackTrace*& _stackTrace, target_addr_t returnFunctionAddress, + int32 maxStackDepth, bool useExistingTrace, bool getFullFrameInfo) { BReference cpuStateReference(cpuState); @@ -163,7 +163,7 @@ Architecture::CreateStackTrace(Team* team, if (function != NULL) { status_t error = functionDebugInfo->GetSpecificImageDebugInfo() ->CreateFrame(image, function, cpuState, getFullFrameInfo, - nextFrame == NULL ? getReturnValue : false, frame, + nextFrame == NULL ? returnFunctionAddress : 0, frame, previousCpuState); if (error != B_OK && error != B_UNSUPPORTED) break; diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h index 3ab3f7daa4..d9610ba77f 100644 --- a/src/apps/debugger/arch/Architecture.h +++ b/src/apps/debugger/arch/Architecture.h @@ -103,13 +103,14 @@ public: target_addr_t address, Statement*& _statement) = 0; virtual status_t GetInstructionInfo(target_addr_t address, - InstructionInfo& _info) = 0; + InstructionInfo& _info, + CpuState* state) = 0; status_t CreateStackTrace(Team* team, ImageDebugInfoProvider* imageInfoProvider, CpuState* cpuState, StackTrace*& _stackTrace, - bool getReturnValue, + target_addr_t returnFunctionAddress, int32 maxStackDepth = -1, bool useExistingTrace = false, bool getFullFrameInfo = true); diff --git a/src/apps/debugger/arch/InstructionInfo.h b/src/apps/debugger/arch/InstructionInfo.h index f130080fb6..25e9e365cd 100644 --- a/src/apps/debugger/arch/InstructionInfo.h +++ b/src/apps/debugger/arch/InstructionInfo.h @@ -12,6 +12,7 @@ enum instruction_type { INSTRUCTION_TYPE_SUBROUTINE_CALL, + INSTRUCTION_TYPE_JUMP, INSTRUCTION_TYPE_OTHER }; diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp index c7995d5193..39e5c7f71b 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.cpp +++ b/src/apps/debugger/arch/x86/ArchitectureX86.cpp @@ -561,7 +561,7 @@ ArchitectureX86::GetStatement(FunctionDebugInfo* function, // TODO: This is not architecture dependent anymore! // get the instruction info InstructionInfo info; - status_t error = GetInstructionInfo(address, info); + status_t error = GetInstructionInfo(address, info, NULL); if (error != B_OK) return error; @@ -578,7 +578,7 @@ ArchitectureX86::GetStatement(FunctionDebugInfo* function, status_t ArchitectureX86::GetInstructionInfo(target_addr_t address, - InstructionInfo& _info) + InstructionInfo& _info, CpuState* state) { // read the code - maximum x86{-64} instruction size = 15 bytes uint8 buffer[16]; @@ -593,40 +593,7 @@ ArchitectureX86::GetInstructionInfo(target_addr_t address, if (error != B_OK) return error; - // disassemble the instruction - BString line; - target_addr_t instructionAddress; - target_addr_t targetAddress = 0; - target_size_t instructionSize; - bool breakpointAllowed; - error = disassembler.GetNextInstruction(line, instructionAddress, - instructionSize, breakpointAllowed); - if (error != B_OK) - return error; - - instruction_type instructionType = INSTRUCTION_TYPE_OTHER; - if (buffer[0] == 0xff && (buffer[1] & 0x34) == 0x10) { - // absolute call with r/m32 - instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL; - // TODO: retrieve target address (might be in a register) - } else if (buffer[0] == 0xe8 && instructionSize == 5) { - // relative call with rel32 -- don't categorize the call with 0 as - // subroutine call, since it is only used to get the address of the GOT - if (buffer[1] != 0 || buffer[2] != 0 || buffer[3] != 0 - || buffer[4] != 0) { - instructionType = INSTRUCTION_TYPE_SUBROUTINE_CALL; - int32 offset; - memcpy(&offset, &buffer[1], 4); - targetAddress = instructionAddress + instructionSize + offset; - } - } - - if (!_info.SetTo(instructionAddress, targetAddress, instructionSize, - instructionType, breakpointAllowed, line)) { - return B_NO_MEMORY; - } - - return B_OK; + return disassembler.GetNextInstructionInfo(_info, state); } diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.h b/src/apps/debugger/arch/x86/ArchitectureX86.h index 1549f9bd65..1a6120cfa2 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.h +++ b/src/apps/debugger/arch/x86/ArchitectureX86.h @@ -59,7 +59,7 @@ public: target_addr_t address, Statement*& _statement); virtual status_t GetInstructionInfo(target_addr_t address, - InstructionInfo& _info); + InstructionInfo& _info, CpuState* state); virtual status_t GetWatchpointDebugCapabilities( int32& _maxRegisterCount, diff --git a/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp b/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp index f20838e31e..e686d7e7f8 100644 --- a/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp +++ b/src/apps/debugger/arch/x86/disasm/DisassemblerX86.cpp @@ -12,6 +12,36 @@ #include +#include "CpuStateX86.h" +#include "InstructionInfo.h" + + +static uint8 RegisterNumberFromUdisIndex(int32 udisIndex) +{ + switch (udisIndex) { + case UD_R_RIP: return X86_REGISTER_EIP; + case UD_R_ESP: return X86_REGISTER_ESP; + case UD_R_EBP: return X86_REGISTER_EBP; + + case UD_R_EAX: return X86_REGISTER_EAX; + case UD_R_EBX: return X86_REGISTER_EBX; + case UD_R_ECX: return X86_REGISTER_ECX; + case UD_R_EDX: return X86_REGISTER_EDX; + + case UD_R_ESI: return X86_REGISTER_ESI; + case UD_R_EDI: return X86_REGISTER_EDI; + + case UD_R_CS: return X86_REGISTER_CS; + case UD_R_DS: return X86_REGISTER_DS; + case UD_R_ES: return X86_REGISTER_ES; + case UD_R_FS: return X86_REGISTER_FS; + case UD_R_GS: return X86_REGISTER_GS; + case UD_R_SS: return X86_REGISTER_SS; + } + + return X86_INT_REGISTER_END; +} + struct DisassemblerX86::UdisData : ud_t { }; @@ -108,3 +138,85 @@ DisassemblerX86::GetPreviousInstruction(target_addr_t nextAddress, } } } + + +status_t +DisassemblerX86::GetNextInstructionInfo(InstructionInfo& _info, + CpuState* state) +{ + unsigned int size = ud_disassemble(fUdisData); + if (size < 1) + return B_ENTRY_NOT_FOUND; + + uint32 address = (uint32)ud_insn_off(fUdisData); + + instruction_type type = INSTRUCTION_TYPE_OTHER; + target_addr_t targetAddress = 0; + + if (fUdisData->mnemonic == UD_Icall) + type = INSTRUCTION_TYPE_SUBROUTINE_CALL; + else if (fUdisData->mnemonic == UD_Ijmp) + type = INSTRUCTION_TYPE_JUMP; + if (state != NULL) + targetAddress = GetInstructionTargetAddress(state); + + char buffer[256]; + snprintf(buffer, sizeof(buffer), "0x%08" B_PRIx32 ": %16.16s %s", address, + ud_insn_hex(fUdisData), ud_insn_asm(fUdisData)); + // TODO: Resolve symbols! + + if (!_info.SetTo(address, targetAddress, size, type, true, buffer)) + return B_NO_MEMORY; + + return B_OK; +} + + +target_addr_t +DisassemblerX86::GetInstructionTargetAddress(CpuState* state) const +{ + if (fUdisData->mnemonic != UD_Icall && fUdisData->mnemonic != UD_Ijmp) + return 0; + + CpuStateX86* x86State = dynamic_cast(state); + if (x86State == NULL) + return 0; + + target_addr_t targetAddress = 0; + switch (fUdisData->operand[0].type) { + case UD_OP_REG: + { + targetAddress = x86State->IntRegisterValue( + RegisterNumberFromUdisIndex(fUdisData->operand[0].base)); + targetAddress += fUdisData->operand[0].offset; + } + break; + case UD_OP_MEM: + { + targetAddress = x86State->IntRegisterValue( + RegisterNumberFromUdisIndex(fUdisData->operand[0].base)); + targetAddress += x86State->IntRegisterValue( + RegisterNumberFromUdisIndex(fUdisData->operand[0].index)) + * fUdisData->operand[0].scale; + } + break; + case UD_OP_JIMM: + { + targetAddress = ud_insn_off(fUdisData) + + fUdisData->operand[0].lval.sdword + ud_insn_len(fUdisData); + } + break; + + case UD_OP_IMM: + case UD_OP_CONST: + { + targetAddress = fUdisData->operand[0].lval.udword; + } + break; + + default: + break; + } + + return targetAddress; +} diff --git a/src/apps/debugger/arch/x86/disasm/DisassemblerX86.h b/src/apps/debugger/arch/x86/disasm/DisassemblerX86.h index b66a0adbcd..9d4952560d 100644 --- a/src/apps/debugger/arch/x86/disasm/DisassemblerX86.h +++ b/src/apps/debugger/arch/x86/disasm/DisassemblerX86.h @@ -10,6 +10,10 @@ #include "Types.h" +class CpuState; +class InstructionInfo; + + class DisassemblerX86 { public: DisassemblerX86(); @@ -27,6 +31,14 @@ public: target_addr_t& _address, target_size_t& _size); + virtual status_t GetNextInstructionInfo( + InstructionInfo& _info, + CpuState* state); + + +private: + target_addr_t GetInstructionTargetAddress( + CpuState* state) const; private: struct UdisData; diff --git a/src/apps/debugger/arch/x86/disasm/Jamfile b/src/apps/debugger/arch/x86/disasm/Jamfile index a916ab0144..0b40f9f7e0 100644 --- a/src/apps/debugger/arch/x86/disasm/Jamfile +++ b/src/apps/debugger/arch/x86/disasm/Jamfile @@ -3,9 +3,12 @@ SubDir HAIKU_TOP src apps debugger arch x86 disasm ; CCFLAGS += -Werror ; C++FLAGS += -Werror ; +UsePrivateHeaders shared ; + UseHeaders [ LibraryHeaders udis86 ] ; UseHeaders [ LibraryHeaders [ FDirName udis86 libudis86 ] ] ; +SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) ] ; SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) $(DOTDOT) $(DOTDOT) types ] ; diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp index acf2f93d31..05ba2a4315 100644 --- a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp +++ b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp @@ -451,7 +451,7 @@ ArchitectureX8664::GetStatement(FunctionDebugInfo* function, // TODO: This is not architecture dependent anymore! // get the instruction info InstructionInfo info; - status_t error = GetInstructionInfo(address, info); + status_t error = GetInstructionInfo(address, info, NULL); if (error != B_OK) return error; @@ -468,7 +468,7 @@ ArchitectureX8664::GetStatement(FunctionDebugInfo* function, status_t ArchitectureX8664::GetInstructionInfo(target_addr_t address, - InstructionInfo& _info) + InstructionInfo& _info, CpuState* state) { // read the code uint8 buffer[16]; diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.h b/src/apps/debugger/arch/x86_64/ArchitectureX8664.h index f61b8f38b1..2ff90bedec 100644 --- a/src/apps/debugger/arch/x86_64/ArchitectureX8664.h +++ b/src/apps/debugger/arch/x86_64/ArchitectureX8664.h @@ -60,7 +60,7 @@ public: target_addr_t address, Statement*& _statement); virtual status_t GetInstructionInfo(target_addr_t address, - InstructionInfo& _info); + InstructionInfo& _info, CpuState* state); virtual status_t GetWatchpointDebugCapabilities( int32& _maxRegisterCount, diff --git a/src/apps/debugger/controllers/ThreadHandler.cpp b/src/apps/debugger/controllers/ThreadHandler.cpp index 7913da930f..6a2fe948fb 100644 --- a/src/apps/debugger/controllers/ThreadHandler.cpp +++ b/src/apps/debugger/controllers/ThreadHandler.cpp @@ -253,7 +253,7 @@ ThreadHandler::HandleThreadAction(uint32 action) if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace, false, 1, + fThread->GetTeam(), this, cpuState, stackTrace, 0, 1, false, false) == B_OK) { stackTraceReference.SetTo(stackTrace, true); } @@ -469,7 +469,7 @@ ThreadHandler::_DoStepOver(CpuState* cpuState) // just single-step, otherwise we set a breakpoint after the instruction. InstructionInfo info; if (fDebuggerInterface->GetArchitecture()->GetInstructionInfo( - cpuState->InstructionPointer(), info) != B_OK) { + cpuState->InstructionPointer(), info, cpuState) != B_OK) { TRACE_CONTROL(" failed to get instruction info\n"); return false; } @@ -484,7 +484,7 @@ ThreadHandler::_DoStepOver(CpuState* cpuState) TRACE_CONTROL(" subroutine call -- installing breakpoint at address " "%#" B_PRIx64 "\n", info.Address() + info.Size()); - fThread->SetExecutedSubroutine(); + fThread->SetExecutedSubroutine(info.TargetAddress()); if (_InstallTemporaryBreakpoint(info.Address() + info.Size()) != B_OK) return false; @@ -566,8 +566,8 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState) if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace, false, - 1, false, false) == B_OK) { + fThread->GetTeam(), this, cpuState, stackTrace, 0, 1, + false, false) == B_OK) { stackTraceReference.SetTo(stackTrace, true); } } @@ -608,7 +608,7 @@ ThreadHandler::_HandleBreakpointHitStep(CpuState* cpuState) // That's the return address, so we're done in theory, // unless we're a recursive function. Check if we've actually // exited the previous stack frame or not. - fThread->SetExecutedSubroutine(); + fThread->SetExecutedSubroutine(cpuState->InstructionPointer()); target_addr_t framePointer = cpuState->StackFramePointer(); bool hasExitedFrame = fDebuggerInterface->GetArchitecture() ->StackGrowthDirection() == STACK_GROWTH_DIRECTION_POSITIVE @@ -653,8 +653,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState) if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace, false, - 1, false, false) == B_OK) { + fThread->GetTeam(), this, cpuState, stackTrace, 0, 1, + false, false) == B_OK) { stackTraceReference.SetTo(stackTrace, true); } } @@ -685,7 +685,7 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState) BReference stackTraceReference(stackTrace); if (stackTrace == NULL && cpuState != NULL) { if (fDebuggerInterface->GetArchitecture()->CreateStackTrace( - fThread->GetTeam(), this, cpuState, stackTrace, false, + fThread->GetTeam(), this, cpuState, stackTrace, 0, 1, false, false) == B_OK) { stackTraceReference.SetTo(stackTrace, true); } @@ -693,7 +693,8 @@ ThreadHandler::_HandleSingleStepStep(CpuState* cpuState) if (stackTrace != NULL && stackTrace->FrameAt(0) ->FrameAddress() != fPreviousFrameAddress) { - fThread->SetExecutedSubroutine(); + fThread->SetExecutedSubroutine( + cpuState->InstructionPointer()); } return false; diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp index 1ff7ac88e0..b40e08c998 100644 --- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.cpp @@ -68,8 +68,8 @@ DebuggerImageDebugInfo::GetAddressSectionType(target_addr_t address) status_t DebuggerImageDebugInfo::CreateFrame(Image* image, FunctionInstance* functionInstance, CpuState* cpuState, - bool getFullFrameInfo, bool getReturnValue, StackFrame*& _previousFrame, - CpuState*& _previousCpuState) + bool getFullFrameInfo, target_addr_t returnFunctionAddress, + StackFrame*& _previousFrame, CpuState*& _previousCpuState) { return B_UNSUPPORTED; } diff --git a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h index 981dbd8f46..bcafebc0f3 100644 --- a/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DebuggerImageDebugInfo.h @@ -36,7 +36,7 @@ public: FunctionInstance* functionInstance, CpuState* cpuState, bool getFullFrameInfo, - bool getReturnValue, + target_addr_t returnFunctionAddress, StackFrame*& _previousFrame, CpuState*& _previousCpuState); virtual status_t GetStatement(FunctionDebugInfo* function, diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp index c7448e05e8..6d60b1b8e8 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.cpp @@ -522,8 +522,8 @@ DwarfImageDebugInfo::GetAddressSectionType(target_addr_t address) status_t DwarfImageDebugInfo::CreateFrame(Image* image, FunctionInstance* functionInstance, CpuState* cpuState, - bool getFullFrameInfo, bool getReturnValue, StackFrame*& _frame, - CpuState*& _previousCpuState) + bool getFullFrameInfo, target_addr_t returnFunctionAddress, + StackFrame*& _frame, CpuState*& _previousCpuState) { DwarfFunctionDebugInfo* function = dynamic_cast( functionInstance->GetFunctionDebugInfo()); @@ -673,9 +673,9 @@ DwarfImageDebugInfo::CreateFrame(Image* image, instructionPointer, functionInstance->Address() - fRelocationDelta, subprogramEntry->Variables(), subprogramEntry->Blocks()); - if (getReturnValue) { - _CreateReturnValue(functionInstance, image, function, frame, - *stackFrameDebugInfo, instructionPointer); + if (returnFunctionAddress != 0) { + _CreateReturnValue(returnFunctionAddress, image, frame, + *stackFrameDebugInfo); } } @@ -1086,75 +1086,28 @@ DwarfImageDebugInfo::_CreateLocalVariables(CompilationUnit* unit, status_t -DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance, - Image* image, DwarfFunctionDebugInfo* function, StackFrame* frame, - DwarfStackFrameDebugInfo& factory, target_addr_t instructionPointer) +DwarfImageDebugInfo::_CreateReturnValue(target_addr_t returnFunctionAddress, + Image* image, StackFrame* frame, DwarfStackFrameDebugInfo& factory) { - // the thread just executed a subroutine, look for the last call - // instruction. - 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; - - InstructionInfo info; - do { - TargetAddressRange range = statement->CoveringAddressRange(); - result = fArchitecture->GetInstructionInfo(range.Start(), info); - if (result != B_OK) - return result; - - if (info.Type() == INSTRUCTION_TYPE_SUBROUTINE_CALL) - break; - - previousStatementAddress = statement->CoveringAddressRange().Start() - 1; - statement = sourceCode->StatementAtAddress( - previousStatementAddress); - } while (statement != NULL); - - // we weren't able to find a subroutine call by stepping back - // so we can't retrieve a return value - if (info.Type() != INSTRUCTION_TYPE_SUBROUTINE_CALL) - return B_OK; - - target_addr_t targetAddress = info.TargetAddress(); - if (targetAddress == 0) - return B_BAD_VALUE; - - if (!image->ContainsAddress(targetAddress)) { + if (!image->ContainsAddress(returnFunctionAddress)) { // our current image doesn't contain the target function, // locate the one which does. - image = image->GetTeam()->ImageByAddress(targetAddress); + image = image->GetTeam()->ImageByAddress(returnFunctionAddress); if (image == NULL) return B_BAD_VALUE; } + status_t result = B_OK; FunctionInstance* targetFunction; - if (targetAddress >= fPLTSectionStart && targetAddress < fPLTSectionEnd) { - // TODO: resolve actual target address in the PIC case - // and adjust targetAddress accordingly + if (returnFunctionAddress >= fPLTSectionStart + && returnFunctionAddress < fPLTSectionEnd) { + // TODO: handle resolving PLT entries + // to their target function + return B_UNSUPPORTED; } + ImageDebugInfo* imageInfo = image->GetImageDebugInfo(); - targetFunction = imageInfo->FunctionAtAddress(targetAddress); + targetFunction = imageInfo->FunctionAtAddress(returnFunctionAddress); if (targetFunction != NULL) { DwarfFunctionDebugInfo* targetInfo = dynamic_cast( @@ -1163,15 +1116,30 @@ DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance, DIESubprogram* subProgram = targetInfo->SubprogramEntry(); DIEType* returnType = subProgram->ReturnType(); if (returnType == NULL) { + // check if we have a specification, and if so, if that has + // a return type + subProgram = dynamic_cast(subProgram->Specification()); + if (subProgram != NULL) + returnType = subProgram->ReturnType(); + // function doesn't return a value, we're done. - return B_OK; + if (returnType == NULL) + return B_OK; } + uint32 byteSize = 0; + if (returnType->ByteSize() == NULL) { + if (dynamic_cast(returnType) != NULL) + byteSize = fArchitecture->AddressSize(); + } else + byteSize = returnType->ByteSize()->constant; + ValueLocation* location; result = fArchitecture->GetReturnAddressLocation(frame, - returnType->ByteSize()->constant, location); + byteSize, location); if (result != B_OK) return result; + BReference locationReference(location, true); Variable* variable = NULL; BReference idReference( @@ -1180,6 +1148,7 @@ DwarfImageDebugInfo::_CreateReturnValue(FunctionInstance* functionInstance, location, variable); if (result != B_OK) return result; + BReference variableReference(variable, true); if (!frame->AddLocalVariable(variable)) return B_NO_MEMORY; diff --git a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h index 56cd1c13a6..203920b11a 100644 --- a/src/apps/debugger/debug_info/DwarfImageDebugInfo.h +++ b/src/apps/debugger/debug_info/DwarfImageDebugInfo.h @@ -64,7 +64,7 @@ public: FunctionInstance* functionInstance, CpuState* cpuState, bool getFullFrameInfo, - bool getReturnValue, + target_addr_t returnFunctionAddress, StackFrame*& _frame, CpuState*& _previousCpuState); virtual status_t GetStatement(FunctionDebugInfo* function, @@ -104,12 +104,11 @@ private: const EntryListWrapper& variableEntries, const EntryListWrapper& blockEntries); - status_t _CreateReturnValue(FunctionInstance* instance, + status_t _CreateReturnValue( + target_addr_t returnFunctionAddress, Image* image, - DwarfFunctionDebugInfo* info, StackFrame* frame, - DwarfStackFrameDebugInfo& factory, - target_addr_t instructionPointer); + DwarfStackFrameDebugInfo& factory); bool _EvaluateBaseTypeConstraints(DIEType* type, const TypeLookupConstraints& constraints); diff --git a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h index 4d424638f5..ac655cdf16 100644 --- a/src/apps/debugger/debug_info/SpecificImageDebugInfo.h +++ b/src/apps/debugger/debug_info/SpecificImageDebugInfo.h @@ -56,7 +56,7 @@ public: FunctionInstance* functionInstance, CpuState* cpuState, bool getFullFrameInfo, - bool getReturnValue, + target_addr_t returnFunctionAddress, StackFrame*& _Frame, CpuState*& _previousCpuState) = 0; // returns reference to previous frame diff --git a/src/apps/debugger/jobs/GetStackTraceJob.cpp b/src/apps/debugger/jobs/GetStackTraceJob.cpp index 2f08190f99..23ce2fc102 100644 --- a/src/apps/debugger/jobs/GetStackTraceJob.cpp +++ b/src/apps/debugger/jobs/GetStackTraceJob.cpp @@ -58,7 +58,8 @@ GetStackTraceJob::Do() // get the stack trace StackTrace* stackTrace; status_t error = fArchitecture->CreateStackTrace(fThread->GetTeam(), this, - fCpuState, stackTrace, fThread->ExecutedSubroutine()); + fCpuState, stackTrace, fThread->ExecutedSubroutine() + ? fThread->SubroutineAddress() : 0); if (error != B_OK) return error; BReference stackTraceReference(stackTrace, true);