1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
#include <features.h>
#include <fpu_control.h>
#include <signal.h>
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include <unistd.h>
/* Circumvent bad assembly in system header, so Clang doesn't complain */
#undef _FPU_SETCW
#define _FPU_SETCW(cw) __asm__ __volatile__ ("sfpc %0" : : "d" (cw))
#undef _FPU_GETCW
#define _FPU_GETCW(cw) __asm__ __volatile__ ("efpc %0" : "=d" (cw))
void handle_SIG(int sig)
{
double d;
_FPU_SETCW(0);
d = 7;
asm volatile ("":: "f" (d));
printf("Got signal %d\n", sig);
if (sig == SIGSEGV) {
printf("SIGSEGV, exiting...\n");
exit(0);
}
}
void handle_rt_SIG(int sig, siginfo_t *info, void *uc)
{
double d;
_FPU_SETCW(0);
d = 8;
asm volatile ("":: "f" (d));
printf("Got signal %d\n", sig);
printf("si_signo: %d\n", info->si_signo);
printf("si_errno: %d\n", info->si_errno);
printf("si_code: %d\n", info->si_code);
if (sig == SIGSEGV) {
printf("SIGSEGV, exiting...\n");
exit(0);
}
}
int main(void)
{
// char *a;
struct sigaction sa;
double d1,d2,d3,d4,d5;
_FPU_SETCW(1);
d1 = d2 = d3 = d4 = d5 = 1;
sa.sa_sigaction=handle_rt_SIG;
sa.sa_flags =SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sigaction(SIGALRM, &sa, NULL);
signal(SIGUSR1, handle_SIG);
signal(SIGSEGV, handle_SIG);
kill(getpid(), SIGALRM);
printf("One!\n");
kill(getpid(), SIGUSR1);
printf("floating point is now: %f %f %f %f %f\n", d1, d2, d3, d4, d5);
{
int fpc;
_FPU_GETCW(fpc);
printf("fpc= %d\n", fpc);
}
printf("Good Bye!\n");
// a = (char *) 0x12345678;
// *a = 1;
exit(0);
}
|