1*e7bbb7cbSPaolo Bonzini #define _GNU_SOURCE
2*e7bbb7cbSPaolo Bonzini #include <sys/mman.h>
3*e7bbb7cbSPaolo Bonzini #include <signal.h>
4*e7bbb7cbSPaolo Bonzini #include <stdio.h>
5*e7bbb7cbSPaolo Bonzini #include <assert.h>
6*e7bbb7cbSPaolo Bonzini
7*e7bbb7cbSPaolo Bonzini volatile unsigned long flags;
8*e7bbb7cbSPaolo Bonzini volatile unsigned long flags_after;
9*e7bbb7cbSPaolo Bonzini int *addr;
10*e7bbb7cbSPaolo Bonzini
sigsegv(int sig,siginfo_t * info,ucontext_t * uc)11*e7bbb7cbSPaolo Bonzini void sigsegv(int sig, siginfo_t *info, ucontext_t *uc)
12*e7bbb7cbSPaolo Bonzini {
13*e7bbb7cbSPaolo Bonzini flags = uc->uc_mcontext.gregs[REG_EFL];
14*e7bbb7cbSPaolo Bonzini mprotect(addr, 4096, PROT_READ|PROT_WRITE);
15*e7bbb7cbSPaolo Bonzini }
16*e7bbb7cbSPaolo Bonzini
main()17*e7bbb7cbSPaolo Bonzini int main()
18*e7bbb7cbSPaolo Bonzini {
19*e7bbb7cbSPaolo Bonzini struct sigaction sa = { .sa_handler = (void *)sigsegv, .sa_flags = SA_SIGINFO };
20*e7bbb7cbSPaolo Bonzini sigaction(SIGSEGV, &sa, NULL);
21*e7bbb7cbSPaolo Bonzini
22*e7bbb7cbSPaolo Bonzini /* fault in the page then protect it */
23*e7bbb7cbSPaolo Bonzini addr = mmap (NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
24*e7bbb7cbSPaolo Bonzini *addr = 0x1234;
25*e7bbb7cbSPaolo Bonzini mprotect(addr, 4096, PROT_READ);
26*e7bbb7cbSPaolo Bonzini
27*e7bbb7cbSPaolo Bonzini asm("# set flags to all ones \n"
28*e7bbb7cbSPaolo Bonzini "mov $-1, %%eax \n"
29*e7bbb7cbSPaolo Bonzini "movq addr, %%rdi \n"
30*e7bbb7cbSPaolo Bonzini "sahf \n"
31*e7bbb7cbSPaolo Bonzini "sub %%eax, (%%rdi) \n"
32*e7bbb7cbSPaolo Bonzini "pushf \n"
33*e7bbb7cbSPaolo Bonzini "pop flags_after(%%rip) \n" : : : "eax", "edi", "memory");
34*e7bbb7cbSPaolo Bonzini
35*e7bbb7cbSPaolo Bonzini /* OF can have any value before the SUB instruction. */
36*e7bbb7cbSPaolo Bonzini assert((flags & 0xff) == 0xd7 && (flags_after & 0x8ff) == 0x17);
37*e7bbb7cbSPaolo Bonzini }
38