1 /* Test if values in rax, rbx, rcx, rdx, rsi and rdi are correctly propagated
2 into and out of a signal handler and also check that the same applies for
3 uninitialised values and their origins. */
10 #include <sys/regset.h>
11 #include <sys/syscall.h>
16 /* x0 is always zero, but is visible to Valgrind as uninitialised. */
21 static void sighandler(int sig
, siginfo_t
*sip
, void *arg
)
23 ucontext_t
*ucp
= (ucontext_t
*) arg
;
28 ucp
->uc_mcontext
.gregs
[REG_RCX
] = x0
;
30 /* Break out of the endless loop. */
31 *(uintptr_t*)&ucp
->uc_mcontext
.gregs
[REG_RIP
] = (uintptr_t)break_out
;
37 long rax
, rbx
, rcx
, rdx
, rsi
, rdi
;
40 /* Uninitialised, but we know px[0] is 0x0. */
41 long *px
= malloc(sizeof(*px
));
44 /* Uninitialised, but we know py[0] is 0x0. */
45 long *py
= malloc(sizeof(*py
));
48 sa
.sa_sigaction
= sighandler
;
49 sa
.sa_flags
= SA_SIGINFO
;
50 if (sigfillset(&sa
.sa_mask
)) {
54 if (sigaction(SIGALRM
, &sa
, NULL
)) {
62 /* Set values in general purpose registers. */
70 /* Loopity loop, this is where the SIGALRM is triggered. */
75 : "=a" (rax
), "=b" (rbx
), "=c" (rcx
), "=d" (rdx
), "=S" (rsi
),
80 printf("Values in the signal handler:\n");
81 printf(" rax=%#lx, rcx=%#lx, rdx=%#lx, rsi=%#lx, rdi=%#lx\n",
82 uc
.uc_mcontext
.gregs
[REG_RAX
], uc
.uc_mcontext
.gregs
[REG_RCX
],
83 uc
.uc_mcontext
.gregs
[REG_RDX
], uc
.uc_mcontext
.gregs
[REG_RSI
],
84 uc
.uc_mcontext
.gregs
[REG_RDI
]);
85 /* Check that rbx contains an uninitialised value (origin is py[0]). */
86 if (uc
.uc_mcontext
.gregs
[REG_RBX
])
89 printf("Values after the return from the signal handler:\n");
90 printf(" rax=%#lx, rdx=%#lx, rsi=%#lx, rdi=%#lx\n", rax
, rdx
, rsi
, rdi
);
91 /* Check that rbx and rcx contain uninitialised values (origin is py[0]
92 and px[0], respectively). */