File: int3-amd64.c

package info (click to toggle)
valgrind 1%3A3.12.0~svn20160714-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 120,428 kB
  • ctags: 70,855
  • sloc: ansic: 674,645; exp: 26,134; xml: 21,574; asm: 7,570; cpp: 7,567; makefile: 7,380; sh: 6,188; perl: 5,855; haskell: 195
file content (52 lines) | stat: -rw-r--r-- 1,329 bytes parent folder | download | duplicates (12)
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

#undef _GNU_SOURCE
#define _GNU_SOURCE 1

#include <signal.h>
#include <stdio.h>
#include <sys/ucontext.h>

static char* rip_at_sig = NULL;

static void int_handler(int signum, siginfo_t *si, void *uc_arg)
{
   ucontext_t *uc = (ucontext_t *)uc_arg;
   /* Note that uc->uc_mcontext is an embedded struct, not a pointer */
   mcontext_t *mc = &(uc->uc_mcontext);
   void *pc = (void*)mc->gregs[REG_RIP];
   printf("in int_handler, RIP is ...\n");
   rip_at_sig = pc;
}

static void register_handler(int sig, void *handler)
{
   struct sigaction sa;
   sa.sa_flags = SA_RESTART | SA_SIGINFO;
   sigfillset(&sa.sa_mask);
   sa.sa_sigaction = handler;
   sigaction(sig, &sa, NULL);
}

int main(void) {
   char *intaddr = NULL;
   puts("main");
   register_handler(SIGTRAP, int_handler);
   asm volatile(
      "movabsq $zz_int, %%rdx\n"
      "mov %%rdx, %0\n"
      "zz_int:\n"
      "int $3\n"
      : /* no outputs */
      : "m" (intaddr) /* input: address of var to store target addr to */
      : /* clobbers */ "rdx"
      );
   /* intaddr is the address of the int 3 insn.  rip_at_sig is the PC
      after the exception, which should be the next insn along.
      Hence: */
   if (intaddr != NULL && rip_at_sig != NULL
       && rip_at_sig == intaddr+1)
     printf("PASS\n");
   else
     printf("FAIL\n");
   return 0;
}