From dc693e9265707e9e0c470c2ec00106795424b6dc Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Fri, 28 Dec 2012 22:27:30 -0500 Subject: [PATCH] Extend Architecture to help retrieve return values. - Architecture now has a new function to retrieve the location where a return value can be found. Added implementation for x86 and stub for x86-64. --- src/apps/debugger/arch/Architecture.h | 5 ++ .../debugger/arch/x86/ArchitectureX86.cpp | 50 ++++++++++++++++++- src/apps/debugger/arch/x86/ArchitectureX86.h | 5 ++ .../arch/x86_64/ArchitectureX8664.cpp | 7 +++ .../debugger/arch/x86_64/ArchitectureX8664.h | 4 ++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/apps/debugger/arch/Architecture.h b/src/apps/debugger/arch/Architecture.h index 38409d0a3a..748e9dc63a 100644 --- a/src/apps/debugger/arch/Architecture.h +++ b/src/apps/debugger/arch/Architecture.h @@ -30,6 +30,7 @@ class StackTrace; class Statement; class Team; class TeamMemory; +class ValueLocation; enum { @@ -118,6 +119,10 @@ public: int32& _maxBytesPerRegister, uint8& _watchpointCapabilityFlags) = 0; + virtual status_t GetReturnAddressLocation( + StackFrame* frame, target_size_t valueSize, + ValueLocation*& _location) = 0; + protected: TeamMemory* fTeamMemory; diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.cpp b/src/apps/debugger/arch/x86/ArchitectureX86.cpp index 5eccb064c8..c7995d5193 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.cpp +++ b/src/apps/debugger/arch/x86/ArchitectureX86.cpp @@ -23,6 +23,7 @@ #include "StackFrame.h" #include "Statement.h" #include "TeamMemory.h" +#include "ValueLocation.h" #include "X86AssemblyLanguage.h" #include "disasm/DisassemblerX86.h" @@ -579,9 +580,8 @@ status_t ArchitectureX86::GetInstructionInfo(target_addr_t address, InstructionInfo& _info) { - // read the code + // read the code - maximum x86{-64} instruction size = 15 bytes uint8 buffer[16]; - // TODO: What's the maximum instruction size? ssize_t bytesRead = fTeamMemory->ReadMemory(address, buffer, sizeof(buffer)); if (bytesRead < 0) @@ -648,6 +648,52 @@ ArchitectureX86::GetWatchpointDebugCapabilities(int32& _maxRegisterCount, } +status_t +ArchitectureX86::GetReturnAddressLocation(StackFrame* frame, + target_size_t valueSize, ValueLocation*& _location) +{ + // for the calling conventions currently in use on Haiku, + // the x86 rules for how values are returned are as follows: + // + // - 32 bits or smaller values are returned directly in EAX. + // - 32-64 bit values are returned across EAX:EDX. + // - > 64 bit values are returned on the stack. + ValueLocation* location = new(std::nothrow) ValueLocation( + IsBigEndian()); + if (location == NULL) + return B_NO_MEMORY; + BReference locationReference(location, + true); + + if (valueSize <= 4) { + ValuePieceLocation piece; + piece.SetSize(valueSize); + piece.SetToRegister(X86_REGISTER_EAX); + if (!location->AddPiece(piece)) + return B_NO_MEMORY; + } else if (valueSize <= 8) { + ValuePieceLocation piece; + piece.SetSize(4); + piece.SetToRegister(X86_REGISTER_EAX); + if (!location->AddPiece(piece)) + return B_NO_MEMORY; + piece.SetToRegister(X86_REGISTER_EDX); + piece.SetSize(valueSize - 4); + if (!location->AddPiece(piece)) + return B_NO_MEMORY; + } else { + ValuePieceLocation piece; + piece.SetToMemory(frame->GetCpuState()->StackPointer()); + piece.SetSize(valueSize); + if (!location->AddPiece(piece)) + return B_NO_MEMORY; + } + + _location = locationReference.Detach(); + return B_OK; +} + + void ArchitectureX86::_AddRegister(int32 index, const char* name, uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved) diff --git a/src/apps/debugger/arch/x86/ArchitectureX86.h b/src/apps/debugger/arch/x86/ArchitectureX86.h index 48e849c502..1549f9bd65 100644 --- a/src/apps/debugger/arch/x86/ArchitectureX86.h +++ b/src/apps/debugger/arch/x86/ArchitectureX86.h @@ -66,6 +66,11 @@ public: int32& _maxBytesPerRegister, uint8& _watchpointCapabilityFlags); + virtual status_t GetReturnAddressLocation( + StackFrame* frame, target_size_t valueSize, + ValueLocation*& _location); + + private: struct ToDwarfRegisterMap; struct FromDwarfRegisterMap; diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp index f32b82055f..acf2f93d31 100644 --- a/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp +++ b/src/apps/debugger/arch/x86_64/ArchitectureX8664.cpp @@ -535,6 +535,13 @@ ArchitectureX8664::GetWatchpointDebugCapabilities(int32& _maxRegisterCount, } +status_t +ArchitectureX8664::GetReturnAddressLocation(StackFrame* frame, + target_size_t valueSize, ValueLocation*& _location) { + return B_NOT_SUPPORTED; +} + + void ArchitectureX8664::_AddRegister(int32 index, const char* name, uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved) diff --git a/src/apps/debugger/arch/x86_64/ArchitectureX8664.h b/src/apps/debugger/arch/x86_64/ArchitectureX8664.h index ec814483f0..f61b8f38b1 100644 --- a/src/apps/debugger/arch/x86_64/ArchitectureX8664.h +++ b/src/apps/debugger/arch/x86_64/ArchitectureX8664.h @@ -67,6 +67,10 @@ public: int32& _maxBytesPerRegister, uint8& _watchpointCapabilityFlags); + virtual status_t GetReturnAddressLocation( + StackFrame* frame, target_size_t valueSize, + ValueLocation*& _location); + private: struct ToDwarfRegisterMap; struct FromDwarfRegisterMap;