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.
This commit is contained in:
@@ -30,6 +30,7 @@ class StackTrace;
|
|||||||
class Statement;
|
class Statement;
|
||||||
class Team;
|
class Team;
|
||||||
class TeamMemory;
|
class TeamMemory;
|
||||||
|
class ValueLocation;
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -118,6 +119,10 @@ public:
|
|||||||
int32& _maxBytesPerRegister,
|
int32& _maxBytesPerRegister,
|
||||||
uint8& _watchpointCapabilityFlags) = 0;
|
uint8& _watchpointCapabilityFlags) = 0;
|
||||||
|
|
||||||
|
virtual status_t GetReturnAddressLocation(
|
||||||
|
StackFrame* frame, target_size_t valueSize,
|
||||||
|
ValueLocation*& _location) = 0;
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TeamMemory* fTeamMemory;
|
TeamMemory* fTeamMemory;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "StackFrame.h"
|
#include "StackFrame.h"
|
||||||
#include "Statement.h"
|
#include "Statement.h"
|
||||||
#include "TeamMemory.h"
|
#include "TeamMemory.h"
|
||||||
|
#include "ValueLocation.h"
|
||||||
#include "X86AssemblyLanguage.h"
|
#include "X86AssemblyLanguage.h"
|
||||||
|
|
||||||
#include "disasm/DisassemblerX86.h"
|
#include "disasm/DisassemblerX86.h"
|
||||||
@@ -579,9 +580,8 @@ status_t
|
|||||||
ArchitectureX86::GetInstructionInfo(target_addr_t address,
|
ArchitectureX86::GetInstructionInfo(target_addr_t address,
|
||||||
InstructionInfo& _info)
|
InstructionInfo& _info)
|
||||||
{
|
{
|
||||||
// read the code
|
// read the code - maximum x86{-64} instruction size = 15 bytes
|
||||||
uint8 buffer[16];
|
uint8 buffer[16];
|
||||||
// TODO: What's the maximum instruction size?
|
|
||||||
ssize_t bytesRead = fTeamMemory->ReadMemory(address, buffer,
|
ssize_t bytesRead = fTeamMemory->ReadMemory(address, buffer,
|
||||||
sizeof(buffer));
|
sizeof(buffer));
|
||||||
if (bytesRead < 0)
|
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<ValueLocation> 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
|
void
|
||||||
ArchitectureX86::_AddRegister(int32 index, const char* name,
|
ArchitectureX86::_AddRegister(int32 index, const char* name,
|
||||||
uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved)
|
uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved)
|
||||||
|
|||||||
@@ -66,6 +66,11 @@ public:
|
|||||||
int32& _maxBytesPerRegister,
|
int32& _maxBytesPerRegister,
|
||||||
uint8& _watchpointCapabilityFlags);
|
uint8& _watchpointCapabilityFlags);
|
||||||
|
|
||||||
|
virtual status_t GetReturnAddressLocation(
|
||||||
|
StackFrame* frame, target_size_t valueSize,
|
||||||
|
ValueLocation*& _location);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ToDwarfRegisterMap;
|
struct ToDwarfRegisterMap;
|
||||||
struct FromDwarfRegisterMap;
|
struct FromDwarfRegisterMap;
|
||||||
|
|||||||
@@ -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
|
void
|
||||||
ArchitectureX8664::_AddRegister(int32 index, const char* name,
|
ArchitectureX8664::_AddRegister(int32 index, const char* name,
|
||||||
uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved)
|
uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved)
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ public:
|
|||||||
int32& _maxBytesPerRegister,
|
int32& _maxBytesPerRegister,
|
||||||
uint8& _watchpointCapabilityFlags);
|
uint8& _watchpointCapabilityFlags);
|
||||||
|
|
||||||
|
virtual status_t GetReturnAddressLocation(
|
||||||
|
StackFrame* frame, target_size_t valueSize,
|
||||||
|
ValueLocation*& _location);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ToDwarfRegisterMap;
|
struct ToDwarfRegisterMap;
|
||||||
struct FromDwarfRegisterMap;
|
struct FromDwarfRegisterMap;
|
||||||
|
|||||||
Reference in New Issue
Block a user