1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * check_initial_reg_state.c - check that execve sets the correct state
4  * Copyright (c) 2014-2016 Andrew Lutomirski
5  */
6 
7 #define _GNU_SOURCE
8 
9 #include <stdio.h>
10 
11 unsigned long ax, bx, cx, dx, si, di, bp, sp, flags;
12 unsigned long r8, r9, r10, r11, r12, r13, r14, r15;
13 
14 asm (
15 	".pushsection .text\n\t"
16 	".type real_start, @function\n\t"
17 	".global real_start\n\t"
18 	"real_start:\n\t"
19 #ifdef __x86_64__
20 	"mov %rax, ax\n\t"
21 	"mov %rbx, bx\n\t"
22 	"mov %rcx, cx\n\t"
23 	"mov %rdx, dx\n\t"
24 	"mov %rsi, si\n\t"
25 	"mov %rdi, di\n\t"
26 	"mov %rbp, bp\n\t"
27 	"mov %rsp, sp\n\t"
28 	"mov %r8, r8\n\t"
29 	"mov %r9, r9\n\t"
30 	"mov %r10, r10\n\t"
31 	"mov %r11, r11\n\t"
32 	"mov %r12, r12\n\t"
33 	"mov %r13, r13\n\t"
34 	"mov %r14, r14\n\t"
35 	"mov %r15, r15\n\t"
36 	"pushfq\n\t"
37 	"popq flags\n\t"
38 #else
39 	"mov %eax, ax\n\t"
40 	"mov %ebx, bx\n\t"
41 	"mov %ecx, cx\n\t"
42 	"mov %edx, dx\n\t"
43 	"mov %esi, si\n\t"
44 	"mov %edi, di\n\t"
45 	"mov %ebp, bp\n\t"
46 	"mov %esp, sp\n\t"
47 	"pushfl\n\t"
48 	"popl flags\n\t"
49 #endif
50 	"jmp _start\n\t"
51 	".size real_start, . - real_start\n\t"
52 	".popsection");
53 
54 int main()
55 {
56 	int nerrs = 0;
57 
58 	if (sp == 0) {
59 		printf("[FAIL]\tTest was built incorrectly\n");
60 		return 1;
61 	}
62 
63 	if (ax || bx || cx || dx || si || di || bp
64 #ifdef __x86_64__
65 	    || r8 || r9 || r10 || r11 || r12 || r13 || r14 || r15
66 #endif
67 		) {
68 		printf("[FAIL]\tAll GPRs except SP should be 0\n");
69 #define SHOW(x) printf("\t" #x " = 0x%lx\n", x);
70 		SHOW(ax);
71 		SHOW(bx);
72 		SHOW(cx);
73 		SHOW(dx);
74 		SHOW(si);
75 		SHOW(di);
76 		SHOW(bp);
77 		SHOW(sp);
78 #ifdef __x86_64__
79 		SHOW(r8);
80 		SHOW(r9);
81 		SHOW(r10);
82 		SHOW(r11);
83 		SHOW(r12);
84 		SHOW(r13);
85 		SHOW(r14);
86 		SHOW(r15);
87 #endif
88 		nerrs++;
89 	} else {
90 		printf("[OK]\tAll GPRs except SP are 0\n");
91 	}
92 
93 	if (flags != 0x202) {
94 		printf("[FAIL]\tFLAGS is 0x%lx, but it should be 0x202\n", flags);
95 		nerrs++;
96 	} else {
97 		printf("[OK]\tFLAGS is 0x202\n");
98 	}
99 
100 	return nerrs ? 1 : 0;
101 }
102