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:
Rene Gollent 2012-12-28 22:27:30 -05:00
parent 84ea02a0f4
commit dc693e9265
5 changed files with 69 additions and 2 deletions

View File

@ -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;

View File

@ -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<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
ArchitectureX86::_AddRegister(int32 index, const char* name,
uint32 bitSize, uint32 valueType, register_type type, bool calleePreserved)

View File

@ -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;

View File

@ -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)

View File

@ -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;