/* * 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. */ // features initializes the system's state, including the state of __USE_GNU #include // If __USE_GNU is defined, we don't need to do anything. // If we defined it ourselves, we need to undefine it later. #ifndef __USE_GNU #define __USE_GNU #define APP_UNDEF_USE_GNU #endif #include // If we defined __USE_GNU ourselves, we need to undefine it here. #ifdef APP_UNDEF_USE_GNU #undef __USE_GNU #undef APP_UNDEF_USE_GNU #endif #include #include #include #ifdef TARGET_IA32 # define REG_IP REG_EIP #else # define REG_IP REG_RIP #endif void *DivideByZeroRetPoint; int DivideByZero() { unsigned int i; volatile unsigned int zero = 0; fprintf(stderr, "Going to divide by zero\n"); i = 1 / zero; return i/i; } #define DIV_OPCODE 0xf7 #define MODRM_REG 0xc0 #define MODRM_DISP8 0x40 #define MODRM_DISP32 0x80 #define IS_REG_MODE(modrmByte) ((modrmByte & MODRM_REG) == MODRM_REG) #define IS_DISP8_MODE(modrmByte) ((modrmByte & MODRM_DISP8) == MODRM_DISP8) #define IS_DISP32_MODE(modrmByte) ((modrmByte & MODRM_DISP32) == MODRM_DISP32) void div0_signal_handler(int signum, siginfo_t *siginfo, void *uctxt) { printf("Inside div0 handler\n"); ucontext_t *frameContext = (ucontext_t *)uctxt; unsigned char *bytes = (unsigned char *)frameContext->uc_mcontext.gregs[REG_IP]; if (bytes[0] == DIV_OPCODE) { if (IS_REG_MODE(bytes[1])) { printf("div %reg instruction\n"); // set IP pointing to the next instruction frameContext->uc_mcontext.gregs[REG_IP] += 2; return; } if (IS_DISP8_MODE(bytes[1])) { printf("div mem8 instruction\n"); // set IP pointing to the next instruction frameContext->uc_mcontext.gregs[REG_IP] += 3; return; } if (IS_DISP32_MODE(bytes[1])) { printf("div mem32 instruction\n"); // set IP pointing to the next instruction frameContext->uc_mcontext.gregs[REG_IP] += 6; return; } } printf("Unexpected instruction at address 0x%lx\n", (unsigned long)frameContext->uc_mcontext.gregs[REG_IP]); exit(-1); } int main() { int ret; struct sigaction sSigaction; /* Register the signal hander using the siginfo interface*/ sSigaction.sa_sigaction = div0_signal_handler; sSigaction.sa_flags = SA_SIGINFO; /* mask all other signals */ sigfillset(&sSigaction.sa_mask); ret = sigaction(SIGFPE, &sSigaction, NULL); if(ret) { perror("ERROR, sigaction failed"); exit(-1); } if(DivideByZero() != 1) { exit (-1); } return 0; }