diff options
Diffstat (limited to 'util/statetrace/arch/tracechild_sparc.cc')
-rw-r--r-- | util/statetrace/arch/tracechild_sparc.cc | 331 |
1 files changed, 155 insertions, 176 deletions
diff --git a/util/statetrace/arch/tracechild_sparc.cc b/util/statetrace/arch/tracechild_sparc.cc index f60f9916b..405c36cd7 100644 --- a/util/statetrace/arch/tracechild_sparc.cc +++ b/util/statetrace/arch/tracechild_sparc.cc @@ -54,36 +54,32 @@ string SparcTraceChild::regNames[numregs] = { //Miscelaneous "fsr", "fprs", "pc", "npc", "y", "cwp", "pstate", "asi", "ccr"}; -bool SparcTraceChild::sendState(int socket) +bool +SparcTraceChild::sendState(int socket) { uint64_t regVal = 0; - for(int x = 0; x <= I7; x++) - { + for (int x = 0; x <= I7; x++) { regVal = getRegVal(x); - if(write(socket, ®Val, sizeof(regVal)) == -1) - { + if (write(socket, ®Val, sizeof(regVal)) == -1) { cerr << "Write failed! " << strerror(errno) << endl; tracing = false; return false; } } regVal = getRegVal(PC); - if(write(socket, ®Val, sizeof(regVal)) == -1) - { + if (write(socket, ®Val, sizeof(regVal)) == -1) { cerr << "Write failed! " << strerror(errno) << endl; tracing = false; return false; } regVal = getRegVal(NPC); - if(write(socket, ®Val, sizeof(regVal)) == -1) - { + if (write(socket, ®Val, sizeof(regVal)) == -1) { cerr << "Write failed! " << strerror(errno) << endl; tracing = false; return false; } regVal = getRegVal(CCR); - if(write(socket, ®Val, sizeof(regVal)) == -1) - { + if (write(socket, ®Val, sizeof(regVal)) == -1) { cerr << "Write failed! " << strerror(errno) << endl; tracing = false; return false; @@ -91,141 +87,141 @@ bool SparcTraceChild::sendState(int socket) return true; } -int64_t getRegs(regs & myregs, fpu & myfpu, - uint64_t * locals, uint64_t * inputs, int num) +int64_t +getRegs(regs & myregs, fpu & myfpu, uint64_t * locals, + uint64_t * inputs, int num) { assert(num < SparcTraceChild::numregs && num >= 0); - switch(num) - { - //Global registers - case SparcTraceChild::G0: return 0; - case SparcTraceChild::G1: return myregs.r_g1; - case SparcTraceChild::G2: return myregs.r_g2; - case SparcTraceChild::G3: return myregs.r_g3; - case SparcTraceChild::G4: return myregs.r_g4; - case SparcTraceChild::G5: return myregs.r_g5; - case SparcTraceChild::G6: return myregs.r_g6; - case SparcTraceChild::G7: return myregs.r_g7; - //Output registers - case SparcTraceChild::O0: return myregs.r_o0; - case SparcTraceChild::O1: return myregs.r_o1; - case SparcTraceChild::O2: return myregs.r_o2; - case SparcTraceChild::O3: return myregs.r_o3; - case SparcTraceChild::O4: return myregs.r_o4; - case SparcTraceChild::O5: return myregs.r_o5; - case SparcTraceChild::O6: return myregs.r_o6; - case SparcTraceChild::O7: return myregs.r_o7; - //Local registers - case SparcTraceChild::L0: return locals[0]; - case SparcTraceChild::L1: return locals[1]; - case SparcTraceChild::L2: return locals[2]; - case SparcTraceChild::L3: return locals[3]; - case SparcTraceChild::L4: return locals[4]; - case SparcTraceChild::L5: return locals[5]; - case SparcTraceChild::L6: return locals[6]; - case SparcTraceChild::L7: return locals[7]; - //Input registers - case SparcTraceChild::I0: return inputs[0]; - case SparcTraceChild::I1: return inputs[1]; - case SparcTraceChild::I2: return inputs[2]; - case SparcTraceChild::I3: return inputs[3]; - case SparcTraceChild::I4: return inputs[4]; - case SparcTraceChild::I5: return inputs[5]; - case SparcTraceChild::I6: return inputs[6]; - case SparcTraceChild::I7: return inputs[7]; - //Floating point - case SparcTraceChild::F0: return myfpu.f_fpstatus.fpu_fr[0]; - case SparcTraceChild::F2: return myfpu.f_fpstatus.fpu_fr[1]; - case SparcTraceChild::F4: return myfpu.f_fpstatus.fpu_fr[2]; - case SparcTraceChild::F6: return myfpu.f_fpstatus.fpu_fr[3]; - case SparcTraceChild::F8: return myfpu.f_fpstatus.fpu_fr[4]; - case SparcTraceChild::F10: return myfpu.f_fpstatus.fpu_fr[5]; - case SparcTraceChild::F12: return myfpu.f_fpstatus.fpu_fr[6]; - case SparcTraceChild::F14: return myfpu.f_fpstatus.fpu_fr[7]; - case SparcTraceChild::F16: return myfpu.f_fpstatus.fpu_fr[8]; - case SparcTraceChild::F18: return myfpu.f_fpstatus.fpu_fr[9]; - case SparcTraceChild::F20: return myfpu.f_fpstatus.fpu_fr[10]; - case SparcTraceChild::F22: return myfpu.f_fpstatus.fpu_fr[11]; - case SparcTraceChild::F24: return myfpu.f_fpstatus.fpu_fr[12]; - case SparcTraceChild::F26: return myfpu.f_fpstatus.fpu_fr[13]; - case SparcTraceChild::F28: return myfpu.f_fpstatus.fpu_fr[14]; - case SparcTraceChild::F30: return myfpu.f_fpstatus.fpu_fr[15]; - case SparcTraceChild::F32: return myfpu.f_fpstatus.fpu_fr[16]; - case SparcTraceChild::F34: return myfpu.f_fpstatus.fpu_fr[17]; - case SparcTraceChild::F36: return myfpu.f_fpstatus.fpu_fr[18]; - case SparcTraceChild::F38: return myfpu.f_fpstatus.fpu_fr[19]; - case SparcTraceChild::F40: return myfpu.f_fpstatus.fpu_fr[20]; - case SparcTraceChild::F42: return myfpu.f_fpstatus.fpu_fr[21]; - case SparcTraceChild::F44: return myfpu.f_fpstatus.fpu_fr[22]; - case SparcTraceChild::F46: return myfpu.f_fpstatus.fpu_fr[23]; - case SparcTraceChild::F48: return myfpu.f_fpstatus.fpu_fr[24]; - case SparcTraceChild::F50: return myfpu.f_fpstatus.fpu_fr[25]; - case SparcTraceChild::F52: return myfpu.f_fpstatus.fpu_fr[26]; - case SparcTraceChild::F54: return myfpu.f_fpstatus.fpu_fr[27]; - case SparcTraceChild::F56: return myfpu.f_fpstatus.fpu_fr[28]; - case SparcTraceChild::F58: return myfpu.f_fpstatus.fpu_fr[29]; - case SparcTraceChild::F60: return myfpu.f_fpstatus.fpu_fr[30]; - case SparcTraceChild::F62: return myfpu.f_fpstatus.fpu_fr[31]; - //Miscelaneous - case SparcTraceChild::FSR: return myfpu.f_fpstatus.Fpu_fsr; - case SparcTraceChild::FPRS: return myregs.r_fprs; - case SparcTraceChild::PC: return myregs.r_tpc; - case SparcTraceChild::NPC: return myregs.r_tnpc; - case SparcTraceChild::Y: return myregs.r_y; - case SparcTraceChild::CWP: - return (myregs.r_tstate >> 0) & ((1 << 5) - 1); - case SparcTraceChild::PSTATE: - return (myregs.r_tstate >> 8) & ((1 << 13) - 1); - case SparcTraceChild::ASI: - return (myregs.r_tstate >> 24) & ((1 << 8) - 1); - case SparcTraceChild::CCR: - return (myregs.r_tstate >> 32) & ((1 << 8) - 1); - default: - assert(0); - return 0; + switch (num) { + //Global registers + case SparcTraceChild::G0: return 0; + case SparcTraceChild::G1: return myregs.r_g1; + case SparcTraceChild::G2: return myregs.r_g2; + case SparcTraceChild::G3: return myregs.r_g3; + case SparcTraceChild::G4: return myregs.r_g4; + case SparcTraceChild::G5: return myregs.r_g5; + case SparcTraceChild::G6: return myregs.r_g6; + case SparcTraceChild::G7: return myregs.r_g7; + //Output registers + case SparcTraceChild::O0: return myregs.r_o0; + case SparcTraceChild::O1: return myregs.r_o1; + case SparcTraceChild::O2: return myregs.r_o2; + case SparcTraceChild::O3: return myregs.r_o3; + case SparcTraceChild::O4: return myregs.r_o4; + case SparcTraceChild::O5: return myregs.r_o5; + case SparcTraceChild::O6: return myregs.r_o6; + case SparcTraceChild::O7: return myregs.r_o7; + //Local registers + case SparcTraceChild::L0: return locals[0]; + case SparcTraceChild::L1: return locals[1]; + case SparcTraceChild::L2: return locals[2]; + case SparcTraceChild::L3: return locals[3]; + case SparcTraceChild::L4: return locals[4]; + case SparcTraceChild::L5: return locals[5]; + case SparcTraceChild::L6: return locals[6]; + case SparcTraceChild::L7: return locals[7]; + //Input registers + case SparcTraceChild::I0: return inputs[0]; + case SparcTraceChild::I1: return inputs[1]; + case SparcTraceChild::I2: return inputs[2]; + case SparcTraceChild::I3: return inputs[3]; + case SparcTraceChild::I4: return inputs[4]; + case SparcTraceChild::I5: return inputs[5]; + case SparcTraceChild::I6: return inputs[6]; + case SparcTraceChild::I7: return inputs[7]; + //Floating point + case SparcTraceChild::F0: return myfpu.f_fpstatus.fpu_fr[0]; + case SparcTraceChild::F2: return myfpu.f_fpstatus.fpu_fr[1]; + case SparcTraceChild::F4: return myfpu.f_fpstatus.fpu_fr[2]; + case SparcTraceChild::F6: return myfpu.f_fpstatus.fpu_fr[3]; + case SparcTraceChild::F8: return myfpu.f_fpstatus.fpu_fr[4]; + case SparcTraceChild::F10: return myfpu.f_fpstatus.fpu_fr[5]; + case SparcTraceChild::F12: return myfpu.f_fpstatus.fpu_fr[6]; + case SparcTraceChild::F14: return myfpu.f_fpstatus.fpu_fr[7]; + case SparcTraceChild::F16: return myfpu.f_fpstatus.fpu_fr[8]; + case SparcTraceChild::F18: return myfpu.f_fpstatus.fpu_fr[9]; + case SparcTraceChild::F20: return myfpu.f_fpstatus.fpu_fr[10]; + case SparcTraceChild::F22: return myfpu.f_fpstatus.fpu_fr[11]; + case SparcTraceChild::F24: return myfpu.f_fpstatus.fpu_fr[12]; + case SparcTraceChild::F26: return myfpu.f_fpstatus.fpu_fr[13]; + case SparcTraceChild::F28: return myfpu.f_fpstatus.fpu_fr[14]; + case SparcTraceChild::F30: return myfpu.f_fpstatus.fpu_fr[15]; + case SparcTraceChild::F32: return myfpu.f_fpstatus.fpu_fr[16]; + case SparcTraceChild::F34: return myfpu.f_fpstatus.fpu_fr[17]; + case SparcTraceChild::F36: return myfpu.f_fpstatus.fpu_fr[18]; + case SparcTraceChild::F38: return myfpu.f_fpstatus.fpu_fr[19]; + case SparcTraceChild::F40: return myfpu.f_fpstatus.fpu_fr[20]; + case SparcTraceChild::F42: return myfpu.f_fpstatus.fpu_fr[21]; + case SparcTraceChild::F44: return myfpu.f_fpstatus.fpu_fr[22]; + case SparcTraceChild::F46: return myfpu.f_fpstatus.fpu_fr[23]; + case SparcTraceChild::F48: return myfpu.f_fpstatus.fpu_fr[24]; + case SparcTraceChild::F50: return myfpu.f_fpstatus.fpu_fr[25]; + case SparcTraceChild::F52: return myfpu.f_fpstatus.fpu_fr[26]; + case SparcTraceChild::F54: return myfpu.f_fpstatus.fpu_fr[27]; + case SparcTraceChild::F56: return myfpu.f_fpstatus.fpu_fr[28]; + case SparcTraceChild::F58: return myfpu.f_fpstatus.fpu_fr[29]; + case SparcTraceChild::F60: return myfpu.f_fpstatus.fpu_fr[30]; + case SparcTraceChild::F62: return myfpu.f_fpstatus.fpu_fr[31]; + //Miscelaneous + case SparcTraceChild::FSR: return myfpu.f_fpstatus.Fpu_fsr; + case SparcTraceChild::FPRS: return myregs.r_fprs; + case SparcTraceChild::PC: return myregs.r_tpc; + case SparcTraceChild::NPC: return myregs.r_tnpc; + case SparcTraceChild::Y: return myregs.r_y; + case SparcTraceChild::CWP: + return (myregs.r_tstate >> 0) & ((1 << 5) - 1); + case SparcTraceChild::PSTATE: + return (myregs.r_tstate >> 8) & ((1 << 13) - 1); + case SparcTraceChild::ASI: + return (myregs.r_tstate >> 24) & ((1 << 8) - 1); + case SparcTraceChild::CCR: + return (myregs.r_tstate >> 32) & ((1 << 8) - 1); + default: + assert(0); + return 0; } } -bool SparcTraceChild::update(int pid) +bool +SparcTraceChild::update(int pid) { memcpy(&oldregs, &theregs, sizeof(regs)); memcpy(&oldfpregs, &thefpregs, sizeof(fpu)); memcpy(oldLocals, locals, 8 * sizeof(uint64_t)); memcpy(oldInputs, inputs, 8 * sizeof(uint64_t)); - if(ptrace(PTRACE_GETREGS, pid, &theregs, 0) != 0) - { + if (ptrace(PTRACE_GETREGS, pid, &theregs, 0) != 0) { cerr << "Update failed" << endl; return false; } uint64_t stackPointer = getSP(); uint64_t stackBias = 2047; bool v9 = stackPointer % 2; - for(unsigned int x = 0; x < 8; x++) - { + for (unsigned int x = 0; x < 8; x++) { uint64_t localAddr = stackPointer + (v9 ? (stackBias + x * 8) : (x * 4)); locals[x] = ptrace(PTRACE_PEEKTEXT, pid, localAddr, 0); - if(!v9) locals[x] >>= 32; + if (!v9) locals[x] >>= 32; uint64_t inputAddr = stackPointer + (v9 ? (stackBias + x * 8 + (8 * 8)) : (x * 4 + 8 * 4)); inputs[x] = ptrace(PTRACE_PEEKTEXT, pid, inputAddr, 0); - if(!v9) inputs[x] >>= 32; + if (!v9) inputs[x] >>= 32; } - if(ptrace(PTRACE_GETFPREGS, pid, &thefpregs, 0) != 0) + if (ptrace(PTRACE_GETFPREGS, pid, &thefpregs, 0) != 0) return false; - for(unsigned int x = 0; x < numregs; x++) + for (unsigned int x = 0; x < numregs; x++) regDiffSinceUpdate[x] = (getRegVal(x) != getOldRegVal(x)); return true; } SparcTraceChild::SparcTraceChild() { - for(unsigned int x = 0; x < numregs; x++) + for (unsigned int x = 0; x < numregs; x++) regDiffSinceUpdate[x] = false; } -int SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc, - uint64_t &target1, uint64_t &target2) +int +SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc, + uint64_t &target1, uint64_t &target2) { //We can identify the instruction categories we care about using the top //10 bits of the instruction, excluding the annul bit in the 3rd most @@ -245,28 +241,21 @@ int SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc, bool bcc = (cond & 0x7) && (sig == 0x1 || sig == 0x2 || sig == 0x3 || sig == 0x5 || sig == 0x6); - if(annul) - { - if(bcc) - { + if (annul) { + if (bcc) { target1 = npc; target2 = npc + 4; return 2; - } - else if(ba) - { + } else if(ba) { //This branches immediately to the effective address of the branch //which we'll have to calculate. uint64_t disp = 0; int64_t extender = 0; //Figure out how big the displacement field is, and grab the bits - if(sig == 0x1 || sig == 0x5) - { + if (sig == 0x1 || sig == 0x5) { disp = inst & ((1 << 19) - 1); extender = 1 << 18; - } - else - { + } else { disp = inst & ((1 << 22) - 1); extender = 1 << 21; } @@ -276,21 +265,19 @@ int SparcTraceChild::getTargets(uint32_t inst, uint64_t pc, uint64_t npc, //smart enough to turn this into a shift. disp *= 4; target1 = pc + disp; - } - else if(bn) + } else if(bn) target1 = npc + 4; else target1 = npc; return 1; - } - else - { + } else { target1 = npc; return 1; } } -bool SparcTraceChild::step() +bool +SparcTraceChild::step() { //Increment the count of the number of instructions executed instructions++; @@ -345,18 +332,17 @@ bool SparcTraceChild::step() uint64_t newBp1 = origBp1; newBp1 &= unalignedBp1 ? highMask : lowMask; newBp1 |= unalignedBp1 ? lowBreakInst : highBreakInst; - if(ptrace(PTRACE_POKETEXT, pid, alignedBp1, newBp1) != 0) + if (ptrace(PTRACE_POKETEXT, pid, alignedBp1, newBp1) != 0) cerr << "Poke failed" << endl; /* * Set the second breakpoint if necessary */ - if(numTargets == 2) - { + if (numTargets == 2) { origBp2 = ptrace(PTRACE_PEEKTEXT, pid, alignedBp2, 0); uint64_t newBp2 = origBp2; newBp2 &= unalignedBp2 ? highMask : lowMask; newBp2 |= unalignedBp2 ? lowBreakInst : highBreakInst; - if(ptrace(PTRACE_POKETEXT, pid, alignedBp2, newBp2) != 0) + if (ptrace(PTRACE_POKETEXT, pid, alignedBp2, newBp2) != 0) cerr << "Poke failed" << endl; } @@ -366,7 +352,7 @@ bool SparcTraceChild::step() //Note that the "addr" parameter is supposed to be ignored, but in at //least one version of the kernel, it must be 1 or it will set what //pc to continue from - if(ptrace(PTRACE_CONT, pid, 1, 0) != 0) + if (ptrace(PTRACE_CONT, pid, 1, 0) != 0) cerr << "Cont failed" << endl; doWait(); @@ -379,42 +365,42 @@ bool SparcTraceChild::step() * Put back the original contents of the childs address space in the * reverse order. */ - if(numTargets == 2) - { - if(ptrace(PTRACE_POKETEXT, pid, alignedBp2, origBp2) != 0) + if (numTargets == 2) { + if (ptrace(PTRACE_POKETEXT, pid, alignedBp2, origBp2) != 0) cerr << "Poke failed" << endl; } - if(ptrace(PTRACE_POKETEXT, pid, alignedBp1, origBp1) != 0) + if (ptrace(PTRACE_POKETEXT, pid, alignedBp1, origBp1) != 0) cerr << "Poke failed" << endl; } -int64_t SparcTraceChild::getRegVal(int num) +int64_t +SparcTraceChild::getRegVal(int num) { return getRegs(theregs, thefpregs, locals, inputs, num); } -int64_t SparcTraceChild::getOldRegVal(int num) +int64_t +SparcTraceChild::getOldRegVal(int num) { return getRegs(oldregs, oldfpregs, oldLocals, oldInputs, num); } -char * SparcTraceChild::printReg(int num) +char * +SparcTraceChild::printReg(int num) { sprintf(printBuffer, "0x%016llx", getRegVal(num)); return printBuffer; } -ostream & SparcTraceChild::outputStartState(ostream & os) +ostream & +SparcTraceChild::outputStartState(ostream & os) { bool v8 = false; uint64_t sp = getSP(); - if(sp % 2) - { + if (sp % 2) { os << "Detected a 64 bit executable.\n"; v8 = false; - } - else - { + } else { os << "Detected a 32 bit executable.\n"; v8 = true; } @@ -424,16 +410,14 @@ ostream & SparcTraceChild::outputStartState(ostream & os) os << obuf; sprintf(obuf, "Initial program counter = 0x%016llx\n", pc); os << obuf; - if(!v8) - { + if (!v8) { //Take out the stack bias sp += 2047; } //Output the window save area - for(unsigned int x = 0; x < 16; x++) - { + for (unsigned int x = 0; x < 16; x++) { uint64_t regspot = ptrace(PTRACE_PEEKDATA, pid, sp, 0); - if(v8) regspot = regspot >> 32; + if (v8) regspot = regspot >> 32; sprintf(obuf, "0x%016llx: Window save %d = 0x%016llx\n", sp, x+1, regspot); os << obuf; @@ -441,17 +425,16 @@ ostream & SparcTraceChild::outputStartState(ostream & os) } //Output the argument count uint64_t cargc = ptrace(PTRACE_PEEKDATA, pid, sp, 0); - if(v8) cargc = cargc >> 32; + if (v8) cargc = cargc >> 32; sprintf(obuf, "0x%016llx: Argc = 0x%016llx\n", sp, cargc); os << obuf; sp += v8 ? 4 : 8; //Output argv pointers int argCount = 0; uint64_t cargv; - do - { + do { cargv = ptrace(PTRACE_PEEKDATA, pid, sp, 0); - if(v8) cargv = cargv >> 32; + if (v8) cargv = cargv >> 32; sprintf(obuf, "0x%016llx: argv[%d] = 0x%016llx\n", sp, argCount++, cargv); os << obuf; @@ -460,43 +443,38 @@ ostream & SparcTraceChild::outputStartState(ostream & os) //Output the envp pointers int envCount = 0; uint64_t cenvp; - do - { + do { cenvp = ptrace(PTRACE_PEEKDATA, pid, sp, 0); - if(v8) cenvp = cenvp >> 32; + if (v8) cenvp = cenvp >> 32; sprintf(obuf, "0x%016llx: envp[%d] = 0x%016llx\n", sp, envCount++, cenvp); os << obuf; sp += v8 ? 4 : 8; - } while(cenvp); + } while (cenvp); uint64_t auxType, auxVal; - do - { + do { auxType = ptrace(PTRACE_PEEKDATA, pid, sp, 0); - if(v8) auxType = auxType >> 32; + if (v8) auxType = auxType >> 32; sp += (v8 ? 4 : 8); auxVal = ptrace(PTRACE_PEEKDATA, pid, sp, 0); - if(v8) auxVal = auxVal >> 32; + if (v8) auxVal = auxVal >> 32; sp += (v8 ? 4 : 8); sprintf(obuf, "0x%016llx: Auxiliary vector = {0x%016llx, 0x%016llx}\n", sp - 8, auxType, auxVal); os << obuf; - } while(auxType != 0 || auxVal != 0); + } while (auxType != 0 || auxVal != 0); //Print out the argument strings, environment strings, and file name. string current; uint64_t buf; uint64_t currentStart = sp; bool clearedInitialPadding = false; - do - { + do { buf = ptrace(PTRACE_PEEKDATA, pid, sp, 0); char * cbuf = (char *)&buf; - for(int x = 0; x < sizeof(uint32_t); x++) - { - if(cbuf[x]) + for (int x = 0; x < sizeof(uint32_t); x++) { + if (cbuf[x]) current += cbuf[x]; - else - { + else { sprintf(obuf, "0x%016llx: \"%s\"\n", currentStart, current.c_str()); os << obuf; @@ -506,11 +484,12 @@ ostream & SparcTraceChild::outputStartState(ostream & os) } sp += (v8 ? 4 : 8); clearedInitialPadding = clearedInitialPadding || buf != 0; - } while(!clearedInitialPadding || buf != 0); + } while (!clearedInitialPadding || buf != 0); return os; } -TraceChild * genTraceChild() +TraceChild * +genTraceChild() { return new SparcTraceChild; } |