]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/memcheck/tests/amd64/int3-amd64.c
3a0fb0c8b0ff4f85a8f6b278ed621d8d873b44e7
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / memcheck / tests / amd64 / int3-amd64.c
1
2 #undef _GNU_SOURCE
3 #define _GNU_SOURCE 1
4
5 #include <signal.h>
6 #include <stdio.h>
7 #include <sys/ucontext.h>
8
9 static char* rip_at_sig = NULL;
10
11 static void int_handler(int signum, siginfo_t *si, void *uc_arg)
12 {
13    ucontext_t *uc = (ucontext_t *)uc_arg;
14    /* Note that uc->uc_mcontext is an embedded struct, not a pointer */
15    mcontext_t *mc = &(uc->uc_mcontext);
16    void *pc = (void*)mc->gregs[REG_RIP];
17    printf("in int_handler, RIP is ...\n");
18    rip_at_sig = pc;
19 }
20
21 static void register_handler(int sig, void *handler)
22 {
23    struct sigaction sa;
24    sa.sa_flags = SA_RESTART | SA_SIGINFO;
25    sigfillset(&sa.sa_mask);
26    sa.sa_sigaction = handler;
27    sigaction(sig, &sa, NULL);
28 }
29
30 int main(void) {
31    char *intaddr = NULL;
32    puts("main");
33    register_handler(SIGTRAP, int_handler);
34    asm volatile(
35       "movabsq $zz_int, %%rdx\n"
36       "mov %%rdx, %0\n"
37       "zz_int:\n"
38       "int $3\n"
39       : /* no outputs */
40       : "m" (intaddr) /* input: address of var to store target addr to */
41       : /* clobbers */ "rdx"
42       );
43    /* intaddr is the address of the int 3 insn.  rip_at_sig is the PC
44       after the exception, which should be the next insn along.
45       Hence: */
46    if (intaddr != NULL && rip_at_sig != NULL
47        && rip_at_sig == intaddr+1)
48      printf("PASS\n");
49    else
50      printf("FAIL\n");
51    return 0;
52 }