xref: /qemu/tests/tcg/i386/test-flags.c (revision 05470c3979d5485003e129ff4b0c2ef98af91d86)
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