/* * Copyright 2002-2019 Intel Corporation. * * This software is provided to you as Sample Source Code as defined in the accompanying * End User License Agreement for the Intel(R) Software Development Products ("Agreement") * section 1.L. * * This software and the related documents are provided as is, with no express or implied * warranties, other than those that are expressly stated in the License. */ /* * This is a test of the PIN_RaiseException() API and is closely connected to the * "faultcheck" test. The "faultcheck" test has a series of assembly functions * that raise each type of exception and the application establishes a signal * handler to catch and print each exception. * * This tool is meant to run only on the "faultcheck" test application. The tool * uses INS_Delete() to delete each of the faulty instructions and replaces each * with a call to an analysis routine that uses PIN_RaiseException() to raise * exactly the same exception. We then run the "faultcheck" test twice, once * natively and once with this tool, and compare the output from the two runs. * This ensures that Pin's emulated exceptions exactly match the exceptions raised * by the real O/S. */ #include #include #include "pin.H" #include "raise-exception-addrs.h" KNOB KnobUseIargConstContext(KNOB_MODE_WRITEONCE, "pintool", "const_context", "0", "use IARG_CONST_CONTEXT"); /* * Bit positions in the MXCSR and x87 status registers that correspond to * each exception condition. */ enum { EXCBIT_IE = (1<<0), EXCBIT_DE = (1<<1), EXCBIT_ZE = (1<<2), EXCBIT_OE = (1<<3), EXCBIT_UE = (1<<4), EXCBIT_PE = (1<<5) }; static VOID OnImage(IMG, VOID *); static VOID OnInstruction(INS, VOID *); static void OnFini(INT32, VOID *); static void AtSetLabels(RAISE_EXCEPTION_ADDRS *); static void DoUnmappedRead(CONTEXT *, THREADID, ADDRINT); static void DoUnmappedWrite(CONTEXT *, THREADID, ADDRINT); static void DoInaccessibleRead(CONTEXT *, THREADID, ADDRINT); static void DoInaccessibleWrite(CONTEXT *, THREADID, ADDRINT); static void DoMisalignedRead(CONTEXT *, THREADID); static void DoMisalignedWrite(CONTEXT *, THREADID); static void DoIllegalInstruction(CONTEXT *, THREADID); static void DoPrivilegedInstruction(CONTEXT *, THREADID); static void DoIntegerDivideByZero(CONTEXT *, THREADID); static void DoIntegerOverflowTrap(CONTEXT *, THREADID, UINT32); static void DoBoundTrap(CONTEXT *, THREADID, UINT32); static void DoX87DivideByZero(CONTEXT *, THREADID); static void DoX87Overflow(CONTEXT *, THREADID); static void DoX87Underflow(CONTEXT *, THREADID); static void DoX87Precision(CONTEXT *, THREADID); static void DoX87InvalidOperation(CONTEXT *, THREADID); static void DoX87DenormalizedOperand(CONTEXT *, THREADID); static void DoX87StackUnderflow(CONTEXT *, THREADID); static void DoX87StackOverflow(CONTEXT *, THREADID); static void DoSIMDDivideByZero(CONTEXT *, THREADID); static void DoSIMDOverflow(CONTEXT *, THREADID); static void DoSIMDUnderflow(CONTEXT *, THREADID); static void DoSIMDPrecision(CONTEXT *, THREADID); static void DoSIMDInvalidOperation(CONTEXT *, THREADID); static void DoSIMDDenormalizedOperand(CONTEXT *, THREADID); static void DoBreakpointTrap(CONTEXT *, THREADID, UINT32); BOOL HaveExceptionAddrs = FALSE; BOOL ExpectUnmappedRead = FALSE; BOOL ExpectUnmappedWrite = FALSE; BOOL ExpectInaccessibleRead = FALSE; BOOL ExpectInaccessibleWrite = FALSE; BOOL ExpectMisalignedRead = FALSE; BOOL ExpectMisalignedWrite = FALSE; BOOL ExpectIllegalInstruction = FALSE; BOOL ExpectPrivilegedInstruction = FALSE; BOOL ExpectIntegerDivideByZero = FALSE; BOOL ExpectIntegerOverflowTrap = FALSE; BOOL ExpectBoundTrap = FALSE; BOOL ExpectX87DivideByZero = FALSE; BOOL ExpectX87Overflow = FALSE; BOOL ExpectX87Underflow = FALSE; BOOL ExpectX87Precision = FALSE; BOOL ExpectX87InvalidOperation = FALSE; BOOL ExpectX87DenormalizedOperand = FALSE; BOOL ExpectX87StackUnderflow = FALSE; BOOL ExpectX87StackOverflow = FALSE; BOOL ExpectSimdDivideByZero = FALSE; BOOL ExpectSimdOverflow = FALSE; BOOL ExpectSimdUnderflow = FALSE; BOOL ExpectSimdPrecision = FALSE; BOOL ExpectSimdInvalidOperation = FALSE; BOOL ExpectSimdDenormalizedOperand = FALSE; BOOL ExpectBreakpointTrap = FALSE; RAISE_EXCEPTION_ADDRS ExceptionAddrs; int main(int argc, char * argv[]) { PIN_Init(argc, argv); PIN_InitSymbols(); IMG_AddInstrumentFunction(OnImage, 0); INS_AddInstrumentFunction(OnInstruction, 0); PIN_AddFiniFunction(OnFini, 0); PIN_StartProgram(); return 0; } static VOID OnImage(IMG img, VOID *) { RTN rtn = RTN_FindByName(img, "SetLabelsForPinTool"); if (RTN_Valid(rtn)) { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(AtSetLabels), IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END); RTN_Close(rtn); } } static VOID OnInstruction(INS ins, VOID *) { if (!HaveExceptionAddrs) return; char *insAddr = reinterpret_cast(INS_Address(ins)); if (insAddr == ExceptionAddrs._unmappedRead) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoUnmappedRead), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_ADDRINT, ExceptionAddrs._unmappedReadAddr, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._unmappedWrite) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoUnmappedWrite), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_ADDRINT, ExceptionAddrs._unmappedWriteAddr, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._inaccessibleRead) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoInaccessibleRead), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_ADDRINT, ExceptionAddrs._inaccessibleReadAddr, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._inaccessibleWrite) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoInaccessibleWrite), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_ADDRINT, ExceptionAddrs._inaccessibleWriteAddr, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._misalignedRead) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoMisalignedRead), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._misalignedWrite) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoMisalignedWrite), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._illegalInstruction) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoIllegalInstruction), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._privilegedInstruction) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoPrivilegedInstruction), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._integerDivideByZero) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoIntegerDivideByZero), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._integerOverflowTrap) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoIntegerOverflowTrap), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_UINT32, static_cast(INS_Size(ins)), IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._boundTrap) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoBoundTrap), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_UINT32, static_cast(INS_Size(ins)), IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._x87DivideByZero) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoX87DivideByZero), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._x87Overflow) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoX87Overflow), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._x87Underflow) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoX87Underflow), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._x87Precision) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoX87Precision), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._x87InvalidOperation) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoX87InvalidOperation), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._x87DenormalizedOperand) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoX87DenormalizedOperand), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._x87StackUnderflow) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoX87StackUnderflow), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._x87StackOverflow) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoX87StackOverflow), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._simdDivideByZero) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoSIMDDivideByZero), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._simdOverflow) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoSIMDOverflow), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._simdUnderflow) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoSIMDUnderflow), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._simdPrecision) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoSIMDPrecision), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._simdInvalidOperation) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoSIMDInvalidOperation), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._simdDenormalizedOperand) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoSIMDDenormalizedOperand), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_END); INS_Delete(ins); } if (insAddr == ExceptionAddrs._breakpointTrap) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoBreakpointTrap), (KnobUseIargConstContext)?IARG_CONST_CONTEXT:IARG_CONTEXT, IARG_THREAD_ID, IARG_UINT32, static_cast(INS_Size(ins)), IARG_END); INS_Delete(ins); } } static void OnFini(INT32, VOID *) { if (!HaveExceptionAddrs) { std::cerr << "Did not get exception lables\n"; std::exit(1); } if (ExpectUnmappedRead) { std::cerr << "Did not emulate unmapped read\n"; std::exit(1); } if (ExpectUnmappedWrite) { std::cerr << "Did not emulate unmapped write\n"; std::exit(1); } if (ExpectInaccessibleRead) { std::cerr << "Did not emulate inaccessible read\n"; std::exit(1); } if (ExpectInaccessibleWrite) { std::cerr << "Did not emulate inaccessible write\n"; std::exit(1); } if (ExpectMisalignedRead) { std::cerr << "Did not emulate misaligned read\n"; std::exit(1); } if (ExpectMisalignedWrite) { std::cerr << "Did not emulate misaligned write\n"; std::exit(1); } if (ExpectIllegalInstruction) { std::cerr << "Did not emulate illegal instruction\n"; std::exit(1); } if (ExpectPrivilegedInstruction) { std::cerr << "Did not emulate privileged instruction\n"; std::exit(1); } if (ExpectIntegerDivideByZero) { std::cerr << "Did not emulate integer divide by zero\n"; std::exit(1); } if (ExpectIntegerOverflowTrap) { std::cerr << "Did not emulate integer overflow trap\n"; std::exit(1); } if (ExpectBoundTrap) { std::cerr << "Did not emulate bound trap\n"; std::exit(1); } if (ExpectX87DivideByZero) { std::cerr << "Did not emulate x87 divide by zero\n"; std::exit(1); } if (ExpectX87Overflow) { std::cerr << "Did not emulate x87 overflow\n"; std::exit(1); } if (ExpectX87Underflow) { std::cerr << "Did not emulate x87 underflow\n"; std::exit(1); } if (ExpectX87Precision) { std::cerr << "Did not emulate x87 precision\n"; std::exit(1); } if (ExpectX87InvalidOperation) { std::cerr << "Did not emulate x87 invalid operation\n"; std::exit(1); } if (ExpectX87DenormalizedOperand) { std::cerr << "Did not emulate x87 denormalized operand\n"; std::exit(1); } if (ExpectX87StackUnderflow) { std::cerr << "Did not emulate x87 stack underflow\n"; std::exit(1); } if (ExpectX87StackOverflow) { std::cerr << "Did not emulate x87 stack overflow\n"; std::exit(1); } if (ExpectSimdDivideByZero) { std::cerr << "Did not emulate simd divide by zero\n"; std::exit(1); } if (ExpectSimdOverflow) { std::cerr << "Did not emulate simd overflow\n"; std::exit(1); } if (ExpectSimdUnderflow) { std::cerr << "Did not emulate simd underflow\n"; std::exit(1); } if (ExpectSimdPrecision) { std::cerr << "Did not emulate simd precision\n"; std::exit(1); } if (ExpectSimdInvalidOperation) { std::cerr << "Did not emulate simd invalid operation\n"; std::exit(1); } if (ExpectSimdDenormalizedOperand) { std::cerr << "Did not emulate simd denormalized operand\n"; std::exit(1); } if (ExpectBreakpointTrap) { std::cerr << "Did not emulate breakpoint trap\n"; std::exit(1); } } static void AtSetLabels(RAISE_EXCEPTION_ADDRS *exceptionAddrs) { size_t sz = PIN_SafeCopy(&ExceptionAddrs, exceptionAddrs, sizeof(ExceptionAddrs)); if (sz != sizeof(ExceptionAddrs)) { std::cerr << "Unable to copy RAISE_EXCEPTION_ADDRS\n"; std::exit(1); } HaveExceptionAddrs = TRUE; ExpectUnmappedRead = (ExceptionAddrs._unmappedRead != 0); ExpectUnmappedWrite = (ExceptionAddrs._unmappedWrite != 0); ExpectInaccessibleRead = (ExceptionAddrs._inaccessibleRead != 0); ExpectInaccessibleWrite = (ExceptionAddrs._inaccessibleWrite != 0); ExpectMisalignedRead = (ExceptionAddrs._misalignedRead != 0); ExpectMisalignedWrite = (ExceptionAddrs._misalignedWrite != 0); ExpectIllegalInstruction = (ExceptionAddrs._illegalInstruction != 0); ExpectPrivilegedInstruction = (ExceptionAddrs._privilegedInstruction != 0); ExpectIntegerDivideByZero = (ExceptionAddrs._integerDivideByZero != 0); ExpectIntegerOverflowTrap = (ExceptionAddrs._integerOverflowTrap != 0); ExpectBoundTrap = (ExceptionAddrs._boundTrap != 0); ExpectX87DivideByZero = (ExceptionAddrs._x87DivideByZero != 0); ExpectX87Overflow = (ExceptionAddrs._x87Overflow != 0); ExpectX87Underflow = (ExceptionAddrs._x87Underflow != 0); ExpectX87Precision = (ExceptionAddrs._x87Precision != 0); ExpectX87InvalidOperation = (ExceptionAddrs._x87InvalidOperation != 0); ExpectX87DenormalizedOperand = (ExceptionAddrs._x87DenormalizedOperand != 0); ExpectX87StackUnderflow = (ExceptionAddrs._x87StackUnderflow != 0); ExpectX87StackOverflow = (ExceptionAddrs._x87StackOverflow != 0); ExpectSimdDivideByZero = (ExceptionAddrs._simdDivideByZero != 0); ExpectSimdOverflow = (ExceptionAddrs._simdOverflow != 0); ExpectSimdUnderflow = (ExceptionAddrs._simdUnderflow != 0); ExpectSimdPrecision = (ExceptionAddrs._simdPrecision != 0); ExpectSimdInvalidOperation = (ExceptionAddrs._simdInvalidOperation != 0); ExpectSimdDenormalizedOperand = (ExceptionAddrs._simdDenormalizedOperand != 0); ExpectBreakpointTrap = (ExceptionAddrs._breakpointTrap != 0); PIN_RemoveInstrumentation(); } static void DoUnmappedRead(CONTEXT *ctxt, THREADID tid, ADDRINT accessAddr) { ExpectUnmappedRead = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitAccessFaultInfo(&exc, EXCEPTCODE_ACCESS_INVALID_ADDRESS, pc, accessAddr, FAULTY_ACCESS_READ); PIN_RaiseException(ctxt, tid, &exc); } static void DoUnmappedWrite(CONTEXT *ctxt, THREADID tid, ADDRINT accessAddr) { ExpectUnmappedWrite= FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitAccessFaultInfo(&exc, EXCEPTCODE_ACCESS_INVALID_ADDRESS, pc, accessAddr, FAULTY_ACCESS_WRITE); PIN_RaiseException(ctxt, tid, &exc); } static void DoInaccessibleRead(CONTEXT *ctxt, THREADID tid, ADDRINT accessAddr) { ExpectInaccessibleRead = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitAccessFaultInfo(&exc, EXCEPTCODE_ACCESS_DENIED, pc, accessAddr, FAULTY_ACCESS_READ); PIN_RaiseException(ctxt, tid, &exc); } static void DoInaccessibleWrite(CONTEXT *ctxt, THREADID tid, ADDRINT accessAddr) { ExpectInaccessibleWrite = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitAccessFaultInfo(&exc, EXCEPTCODE_ACCESS_DENIED, pc, accessAddr, FAULTY_ACCESS_WRITE); PIN_RaiseException(ctxt, tid, &exc); } static void DoMisalignedRead(CONTEXT *ctxt, THREADID tid) { ExpectMisalignedRead = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_ACCESS_MISALIGNED, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoMisalignedWrite(CONTEXT *ctxt, THREADID tid) { ExpectMisalignedWrite = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_ACCESS_MISALIGNED, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoIllegalInstruction(CONTEXT *ctxt, THREADID tid) { ExpectIllegalInstruction = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_ILLEGAL_INS, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoPrivilegedInstruction(CONTEXT *ctxt, THREADID tid) { ExpectPrivilegedInstruction = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_PRIVILEGED_INS, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoIntegerDivideByZero(CONTEXT *ctxt, THREADID tid) { ExpectIntegerDivideByZero = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_INT_DIVIDE_BY_ZERO, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoIntegerOverflowTrap(CONTEXT *context, THREADID tid, UINT32 instSize) { ExpectIntegerOverflowTrap = FALSE; ADDRINT pc = PIN_GetContextReg(context, REG_INST_PTR); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } PIN_SetContextReg(ctxt, REG_INST_PTR, pc+instSize); // The fault is reported on the PC after the trap instruction. EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_INT_OVERFLOW_TRAP, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoBoundTrap(CONTEXT *ctxt, THREADID tid, UINT32 instSize) { ExpectBoundTrap = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_INT_BOUNDS_EXCEEDED, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoX87DivideByZero(CONTEXT *ctxt, THREADID tid) { ExpectX87DivideByZero = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_X87_DIVIDE_BY_ZERO, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoX87Overflow(CONTEXT *ctxt, THREADID tid) { ExpectX87Overflow = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_X87_OVERFLOW, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoX87Underflow(CONTEXT *ctxt, THREADID tid) { ExpectX87Underflow = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_X87_UNDERFLOW, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoX87Precision(CONTEXT *ctxt, THREADID tid) { ExpectX87Precision = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_X87_INEXACT_RESULT, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoX87InvalidOperation(CONTEXT *ctxt, THREADID tid) { ExpectX87InvalidOperation = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_X87_INVALID_OPERATION, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoX87DenormalizedOperand(CONTEXT *ctxt, THREADID tid) { ExpectX87DenormalizedOperand = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_X87_DENORMAL_OPERAND, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoX87StackUnderflow(CONTEXT *ctxt, THREADID tid) { ExpectX87StackUnderflow = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_X87_STACK_ERROR, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoX87StackOverflow(CONTEXT *ctxt, THREADID tid) { ExpectX87StackOverflow = FALSE; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_X87_STACK_ERROR, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoSIMDDivideByZero(CONTEXT *context, THREADID tid) { ExpectSimdDivideByZero = FALSE; ADDRINT pc = PIN_GetContextReg(context, REG_INST_PTR); ADDRINT mxcsr = PIN_GetContextReg(context, REG_MXCSR); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } PIN_SetContextReg(ctxt, REG_MXCSR, mxcsr | EXCBIT_ZE); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_SIMD_DIVIDE_BY_ZERO, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoSIMDOverflow(CONTEXT *context, THREADID tid) { ExpectSimdOverflow = FALSE; ADDRINT pc = PIN_GetContextReg(context, REG_INST_PTR); ADDRINT mxcsr = PIN_GetContextReg(context, REG_MXCSR); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } PIN_SetContextReg(ctxt, REG_MXCSR, mxcsr | (EXCBIT_OE | EXCBIT_PE)); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_SIMD_OVERFLOW, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoSIMDUnderflow(CONTEXT *context, THREADID tid) { ExpectSimdUnderflow = FALSE; ADDRINT pc = PIN_GetContextReg(context, REG_INST_PTR); ADDRINT mxcsr = PIN_GetContextReg(context, REG_MXCSR); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } PIN_SetContextReg(ctxt, REG_MXCSR, mxcsr | (EXCBIT_UE | EXCBIT_PE)); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_SIMD_UNDERFLOW, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoSIMDPrecision(CONTEXT *context, THREADID tid) { ExpectSimdPrecision = FALSE; ADDRINT pc = PIN_GetContextReg(context, REG_INST_PTR); ADDRINT mxcsr = PIN_GetContextReg(context, REG_MXCSR); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } PIN_SetContextReg(ctxt, REG_MXCSR, mxcsr | EXCBIT_PE); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_SIMD_INEXACT_RESULT, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoSIMDInvalidOperation(CONTEXT *context, THREADID tid) { ExpectSimdInvalidOperation = FALSE; ADDRINT pc = PIN_GetContextReg(context, REG_INST_PTR); ADDRINT mxcsr = PIN_GetContextReg(context, REG_MXCSR); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } PIN_SetContextReg(ctxt, REG_MXCSR, mxcsr | EXCBIT_IE); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_SIMD_INVALID_OPERATION, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoSIMDDenormalizedOperand(CONTEXT *context, THREADID tid) { ExpectSimdDenormalizedOperand = FALSE; ADDRINT pc = PIN_GetContextReg(context, REG_INST_PTR); ADDRINT mxcsr = PIN_GetContextReg(context, REG_MXCSR); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } PIN_SetContextReg(ctxt, REG_MXCSR, mxcsr | EXCBIT_DE); EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_SIMD_DENORMAL_OPERAND, pc); PIN_RaiseException(ctxt, tid, &exc); } static void DoBreakpointTrap(CONTEXT *context, THREADID tid, UINT32 instSize) { ExpectBreakpointTrap = FALSE; ADDRINT pc = PIN_GetContextReg(context, REG_INST_PTR); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } PIN_SetContextReg(ctxt, REG_INST_PTR, pc+instSize); // The fault is reported on the PC after the trap instruction. EXCEPTION_INFO exc; PIN_InitExceptionInfo(&exc, EXCEPTCODE_DBG_BREAKPOINT_TRAP, pc); PIN_RaiseException(ctxt, tid, &exc); }