INT32 RecordRegisters(BBL bbl, UINT16 * stats) { INT32 count = 0; for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { const UINT32 max_r = INS_MaxNumRRegs(ins); for( UINT32 i=0; i < max_r; i++ ) { const REG reg = INS_RegR(ins, i ); if( REG_is_gr(reg) ) { stats[count++] = REG_GetStatsIndex(reg,FALSE); } #if 0 // This is for arm else if( REG_is_aggregate(reg) ) { REGSET regset = INS_RegAggregateR(ins); for( REG reg = REGSET_PopNext(regset); REG_valid(reg); reg = REGSET_PopNext(regset) ) { stats[count++] = REG_GetStatsIndex(reg,FALSE); } } #endif } const UINT32 max_w = INS_MaxNumWRegs(ins); for( UINT32 i=0; i < max_w; i++ ) { const REG reg = INS_RegW(ins, i ); if( REG_is_gr(reg) ) { stats[count++] = REG_GetStatsIndex(reg,TRUE); } #if 0 else if( REG_is_aggregate(reg) ) { REGSET regset = INS_RegAggregateW(ins); for( REG reg = REGSET_PopNext(regset); REG_valid(reg); reg = REGSET_PopNext(regset) ) { stats[count++] = REG_GetStatsIndex(reg,TRUE); } } #endif } } stats[count++] = 0; return count; }
PyObject* Python_REG_is_gr(PyObject* self, PyObject* args) { PyObject* reg; PyArg_ParseTuple(args, "L", ®); REG reg_object = *(REG*) reg; if (REG_is_gr(reg_object)) { return Py_BuildValue("O", Py_True); } else { return Py_BuildValue("O", Py_False); } }
VOID instrument_reg(INS ins, ins_buffer_entry* e){ UINT32 i, maxNumRegsProd, maxNumRegsCons, regReadCnt, regWriteCnt, opCnt, regOpCnt; REG reg; if(!e->setRead){ maxNumRegsCons = INS_MaxNumRRegs(ins); // maximum number of register consumations (reads) regReadCnt = 0; for(i = 0; i < maxNumRegsCons; i++){ // finding all register operands which are read reg = INS_RegR(ins,i); //assert(((UINT32)reg) < MAX_NUM_REGS); /* only consider valid general-purpose registers (any bit-width) and floating-point registers, * i.e. exlude branch, segment and pin registers, among others */ if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){ regReadCnt++; } } e->regReadCnt = regReadCnt; e->regsRead = (REG*) checked_malloc(regReadCnt*sizeof(REG)); regReadCnt = 0; for(i = 0; i < maxNumRegsCons; i++){ // finding all register operands which are read reg = INS_RegR(ins,i); //assert(((UINT32)reg) < MAX_NUM_REGS); /* only consider valid general-purpose registers (any bit-width) and floating-point registers, * i.e. exlude branch, segment and pin registers, among others */ if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){ e->regsRead[regReadCnt++] = reg; } } e->setRead = true; } if(!e->setWritten){ maxNumRegsProd = INS_MaxNumWRegs(ins); regWriteCnt = 0; for(i=0; i < maxNumRegsProd; i++){ reg = INS_RegW(ins, i); //assert(((UINT32)reg) < MAX_NUM_REGS); /* only consider valid general-purpose registers (any bit-width) and floating-point registers, * i.e. exlude branch, segment and pin registers, among others */ if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){ regWriteCnt++; } } e->regWriteCnt = regWriteCnt; e->regsWritten = (REG*)checked_malloc(regWriteCnt*sizeof(REG)); regWriteCnt = 0; for(i=0; i < maxNumRegsProd; i++){ reg = INS_RegW(ins, i); //assert(((UINT32)reg) < MAX_NUM_REGS); /* only consider valid general-purpose registers (any bit-width) and floating-point registers, * i.e. exlude branch, segment and pin registers, among others */ if(REG_valid(reg) && (REG_is_fr(reg) || REG_is_mm(reg) || REG_is_xmm(reg) || REG_is_gr(reg) || REG_is_gr8(reg) || REG_is_gr16(reg) || REG_is_gr32(reg) || REG_is_gr64(reg))){ e->regsWritten[regWriteCnt++] = reg; } } e->setWritten = true; } if(!e->setRegOpCnt){ regOpCnt = 0; opCnt = INS_OperandCount(ins); for(i = 0; i < opCnt; i++){ if(INS_OperandIsReg(ins,i)) regOpCnt++; } /*if(regOpCnt >= MAX_NUM_OPER){ cerr << "BOOM! -> MAX_NUM_OPER is exceeded! (" << regOpCnt << ")" << endl; exit(1); }*/ e->regOpCnt = regOpCnt; e->setRegOpCnt = true; } if(interval_size == -1){ INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)reg_instr_full, IARG_PTR, (void*)e, IARG_END); } else{ INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)reg_instr_intervals, IARG_PTR, (void*)e, IARG_END); /* only called if interval is full */ INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)reg_instr_interval, IARG_END); } }
VOID Emulate2Address(OPCODE opcode, INS ins, ADDRINT (*OpRM)(ADDRINT,ADDRINT*), ADDRINT (*OpRV)(ADDRINT,ADDRINT), VOID (*OpMV)(ADDRINT*,ADDRINT)) { if (INS_Opcode(ins) != opcode) return; if (INS_OperandIsMemory(ins, 0) // This will filter out segment overrides && INS_IsMemoryWrite(ins)) { if (INS_OperandIsReg(ins, 1) && REG_is_gr(INS_OperandReg(ins, 1))) { // Source register, dst memory INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(OpMV), IARG_MEMORYWRITE_EA, IARG_REG_VALUE, INS_OperandReg(ins, 1), IARG_END); INS_Delete(ins); } else { ASSERTX(!INS_OperandIsMemory(ins, 1)); } } else if (INS_OperandIsReg(ins, 0)) { REG dst = INS_OperandReg(ins, 0); if ((dst == REG_SEG_GS) || (dst == REG_SEG_FS)) return; if (INS_OperandIsReg(ins, 1)) { // Source register, dst register INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(OpRV), IARG_REG_VALUE, INS_OperandReg(ins, 0), IARG_REG_VALUE, INS_OperandReg(ins, 1), IARG_RETURN_REGS, INS_OperandReg(ins, 0), IARG_END); INS_Delete(ins); } else if (INS_OperandIsMemory(ins, 1) // This will filter out segment overrides && INS_IsMemoryRead(ins)) { // Source register, dst register INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(OpRM), IARG_REG_VALUE, INS_OperandReg(ins, 0), IARG_MEMORYREAD_EA, IARG_RETURN_REGS, INS_OperandReg(ins, 0), IARG_END); INS_Delete(ins); } } #if 0 if (KnobCount == icount) fprintf(stderr,"Last one %s\n",INS_Disassemble(ins).c_str()); else if (icount > KnobCount) return; icount++; #endif }