ARM: Add vfpv3 support to native trace.
This commit is contained in:
parent
632cf8dd80
commit
48f7fda706
4 changed files with 77 additions and 13 deletions
|
@ -54,7 +54,11 @@ namespace Trace {
|
||||||
static const char *regNames[] = {
|
static const char *regNames[] = {
|
||||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||||
"r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc",
|
"r8", "r9", "r10", "fp", "r12", "sp", "lr", "pc",
|
||||||
"cpsr"
|
"cpsr", "f0", "f1", "f2", "f3", "f4", "f5", "f6",
|
||||||
|
"f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14",
|
||||||
|
"f15", "f16", "f17", "f18", "f19", "f20", "f21", "f22",
|
||||||
|
"f23", "f24", "f25", "f26", "f27", "f28", "f29", "f30",
|
||||||
|
"f31", "fpscr"
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -67,7 +71,7 @@ Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent)
|
||||||
|
|
||||||
memcpy(newState, oldState, sizeof(state[0]));
|
memcpy(newState, oldState, sizeof(state[0]));
|
||||||
|
|
||||||
uint32_t diffVector;
|
uint64_t diffVector;
|
||||||
parent->read(&diffVector, sizeof(diffVector));
|
parent->read(&diffVector, sizeof(diffVector));
|
||||||
diffVector = ArmISA::gtoh(diffVector);
|
diffVector = ArmISA::gtoh(diffVector);
|
||||||
|
|
||||||
|
@ -82,7 +86,7 @@ Trace::ArmNativeTrace::ThreadState::update(NativeTrace *parent)
|
||||||
diffVector >>= 1;
|
diffVector >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t values[changes];
|
uint64_t values[changes];
|
||||||
parent->read(values, sizeof(values));
|
parent->read(values, sizeof(values));
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
for (int i = 0; i < STATE_NUMVALS; i++) {
|
for (int i = 0; i < STATE_NUMVALS; i++) {
|
||||||
|
@ -114,6 +118,14 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
|
||||||
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
|
newState[STATE_CPSR] = tc->readMiscReg(MISCREG_CPSR) |
|
||||||
tc->readIntReg(INTREG_CONDCODES);
|
tc->readIntReg(INTREG_CONDCODES);
|
||||||
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
|
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
|
||||||
|
|
||||||
|
for (int i = 0; i < NumFloatArchRegs; i += 2) {
|
||||||
|
newState[STATE_F0 + (i >> 1)] =
|
||||||
|
static_cast<uint64_t>(tc->readFloatRegBits(i + 1)) << 32 |
|
||||||
|
tc->readFloatRegBits(i);
|
||||||
|
}
|
||||||
|
newState[STATE_FPSCR] = tc->readMiscRegNoEffect(MISCREG_FPSCR) |
|
||||||
|
tc->readIntReg(INTREG_FPCONDCODES);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -62,15 +62,21 @@ class ArmNativeTrace : public NativeTrace
|
||||||
STATE_R15,
|
STATE_R15,
|
||||||
STATE_PC = STATE_R15,
|
STATE_PC = STATE_R15,
|
||||||
STATE_CPSR,
|
STATE_CPSR,
|
||||||
|
STATE_F0, STATE_F1, STATE_F2, STATE_F3, STATE_F4, STATE_F5, STATE_F6,
|
||||||
|
STATE_F7, STATE_F8, STATE_F9, STATE_F10, STATE_F11, STATE_F12,
|
||||||
|
STATE_F13, STATE_F14, STATE_F15, STATE_F16, STATE_F17, STATE_F18,
|
||||||
|
STATE_F19, STATE_F20, STATE_F21, STATE_F22, STATE_F23, STATE_F24,
|
||||||
|
STATE_F25, STATE_F26, STATE_F27, STATE_F28, STATE_F29, STATE_F30,
|
||||||
|
STATE_F31, STATE_FPSCR,
|
||||||
STATE_NUMVALS
|
STATE_NUMVALS
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct ThreadState {
|
struct ThreadState {
|
||||||
bool changed[STATE_NUMVALS];
|
bool changed[STATE_NUMVALS];
|
||||||
uint32_t state[2][STATE_NUMVALS];
|
uint64_t state[2][STATE_NUMVALS];
|
||||||
uint32_t *newState;
|
uint64_t *newState;
|
||||||
uint32_t *oldState;
|
uint64_t *oldState;
|
||||||
int current;
|
int current;
|
||||||
void update(NativeTrace *parent);
|
void update(NativeTrace *parent);
|
||||||
void update(ThreadContext *tc);
|
void update(ThreadContext *tc);
|
||||||
|
|
|
@ -56,23 +56,28 @@ ARMTraceChild::ARMTraceChild()
|
||||||
{
|
{
|
||||||
foundMvn = false;
|
foundMvn = false;
|
||||||
|
|
||||||
|
memset(®s, 0, sizeof(regs));
|
||||||
|
memset(&oldregs, 0, sizeof(regs));
|
||||||
|
memset(&fpregs, 0, sizeof(vfp_regs));
|
||||||
|
memset(&oldfpregs, 0, sizeof(vfp_regs));
|
||||||
|
|
||||||
for (int x = 0; x < numregs; x++) {
|
for (int x = 0; x < numregs; x++) {
|
||||||
memset(®s, 0, sizeof(regs));
|
|
||||||
memset(&oldregs, 0, sizeof(regs));
|
|
||||||
regDiffSinceUpdate[x] = false;
|
regDiffSinceUpdate[x] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(sizeof(regs.uregs)/sizeof(regs.uregs[0]) > CPSR);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ARMTraceChild::sendState(int socket)
|
ARMTraceChild::sendState(int socket)
|
||||||
{
|
{
|
||||||
uint32_t regVal = 0;
|
uint32_t regVal = 0;
|
||||||
uint32_t message[numregs + 1];
|
uint64_t message[numregs + 1];
|
||||||
int pos = 1;
|
int pos = 1;
|
||||||
message[0] = 0;
|
message[0] = 0;
|
||||||
for (int x = 0; x < numregs; x++) {
|
for (int x = 0; x < numregs; x++) {
|
||||||
if (regDiffSinceUpdate[x]) {
|
if (regDiffSinceUpdate[x]) {
|
||||||
message[0] = message[0] | (1 << x);
|
message[0] = message[0] | (1ULL << x);
|
||||||
message[pos++] = getRegVal(x);
|
message[pos++] = getRegVal(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,10 +102,21 @@ ARMTraceChild::sendState(int socket)
|
||||||
uint32_t
|
uint32_t
|
||||||
ARMTraceChild::getRegs(user_regs &myregs, int num)
|
ARMTraceChild::getRegs(user_regs &myregs, int num)
|
||||||
{
|
{
|
||||||
assert(num < numregs && num >= 0);
|
assert(num <= CPSR && num >= 0);
|
||||||
return myregs.uregs[num];
|
return myregs.uregs[num];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
ARMTraceChild::getFpRegs(vfp_regs &my_fp_regs, int num)
|
||||||
|
{
|
||||||
|
assert(num >= F0 && num < numregs);
|
||||||
|
if (num == FPSCR)
|
||||||
|
return my_fp_regs.fpscr;
|
||||||
|
|
||||||
|
num -= F0;
|
||||||
|
return my_fp_regs.fpregs[num];
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ARMTraceChild::update(int pid)
|
ARMTraceChild::update(int pid)
|
||||||
{
|
{
|
||||||
|
@ -110,21 +126,36 @@ ARMTraceChild::update(int pid)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint32_t get_vfp_regs = 32;
|
||||||
|
|
||||||
|
oldfpregs = fpregs;
|
||||||
|
if (ptrace((__ptrace_request)get_vfp_regs, pid, 0, &fpregs) != 0) {
|
||||||
|
cerr << "update: " << strerror(errno) << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int x = 0; x < numregs; x++)
|
for (unsigned int x = 0; x < numregs; x++)
|
||||||
regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
|
regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
ARMTraceChild::getRegVal(int num)
|
ARMTraceChild::getRegVal(int num)
|
||||||
{
|
{
|
||||||
return getRegs(regs, num);
|
if (num <= CPSR)
|
||||||
|
return getRegs(regs, num);
|
||||||
|
else
|
||||||
|
return (int64_t)getFpRegs(fpregs, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
ARMTraceChild::getOldRegVal(int num)
|
ARMTraceChild::getOldRegVal(int num)
|
||||||
{
|
{
|
||||||
return getRegs(oldregs, num);
|
if (num <= CPSR)
|
||||||
|
return getRegs(oldregs, num);
|
||||||
|
else
|
||||||
|
return (int64_t)getFpRegs(oldfpregs, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
ostream &
|
ostream &
|
||||||
|
|
|
@ -67,12 +67,27 @@ class ARMTraceChild : public TraceChild
|
||||||
R0, R1, R2, R3, R4, R5, R6, R7,
|
R0, R1, R2, R3, R4, R5, R6, R7,
|
||||||
R8, R9, R10, FP, R12, SP, LR, PC,
|
R8, R9, R10, FP, R12, SP, LR, PC,
|
||||||
CPSR,
|
CPSR,
|
||||||
|
F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15,
|
||||||
|
F16, F17, F18, F19, F20, F21, F22, F23, F24, F25, F26, F27, F28, F29,
|
||||||
|
F30, F31, FPSCR,
|
||||||
numregs
|
numregs
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct vfp_regs {
|
||||||
|
uint64_t fpregs[32];
|
||||||
|
uint32_t fpscr;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t getRegs(user_regs& myregs, int num);
|
uint32_t getRegs(user_regs& myregs, int num);
|
||||||
|
uint64_t getFpRegs(vfp_regs &myfpregs, int num);
|
||||||
|
|
||||||
user_regs regs;
|
user_regs regs;
|
||||||
user_regs oldregs;
|
user_regs oldregs;
|
||||||
|
|
||||||
|
vfp_regs fpregs;
|
||||||
|
vfp_regs oldfpregs;
|
||||||
|
|
||||||
bool regDiffSinceUpdate[numregs];
|
bool regDiffSinceUpdate[numregs];
|
||||||
bool foundMvn;
|
bool foundMvn;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue