You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

881 lines
29 KiB

/*
* 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 <iostream>
#include <cstdlib>
#include "pin.H"
#include "raise-exception-addrs.h"
KNOB<BOOL> 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<char *>(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<UINT32>(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<UINT32>(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<UINT32>(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);
}