xref: /llvm-project/lldb/test/API/linux/aarch64/unwind_signal/main.c (revision 9db2541d4c30100d7ccc6cc9db717df102b302d9)
1 #include <signal.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 
handler(int sig)5 void handler(int sig) {
6   // The kernel only changes a few registers so set them all to something other
7   // than the values in sigill() so that we can't fall back to real registers
8   // and still pass the test.
9 #define SETREG(N) "mov x" N ", #" N "+1\n\t"
10   asm volatile(
11       /* clang-format off */
12       /* x0 is used for a parameter */
13                    SETREG("1")  SETREG("2")  SETREG("3")
14       SETREG("4")  SETREG("5")  SETREG("6")  SETREG("7")
15       SETREG("8")  SETREG("9")  SETREG("10") SETREG("11")
16       SETREG("12") SETREG("13") SETREG("14") SETREG("15")
17       SETREG("16") SETREG("17") SETREG("18") SETREG("19")
18       SETREG("20") SETREG("21") SETREG("22") SETREG("23")
19       SETREG("24") SETREG("25") SETREG("26") SETREG("27")
20       SETREG("28") // fp/x29 needed for unwiding
21       SETREG("30") // 31 is xzr/sp
22       /* clang-format on */
23       ::
24           : /* skipped x0 */ "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8",
25             "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18",
26             "x19", "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27",
27             "x28",
28             /* skipped fp/x29 */ "x30");
29   printf("Set a breakpoint here.\n");
30   exit(0);
31 }
32 
sigill()33 static void sigill() {
34   // Set all general registers to known values to check
35   // that the signal unwind plan sets their locations correctly.
36 #define SETREG(N) "mov x" N ", #" N "\n\t"
37   asm volatile(
38       /* clang-format off */
39       SETREG("0")  SETREG("1")  SETREG("2")  SETREG("3")
40       SETREG("4")  SETREG("5")  SETREG("6")  SETREG("7")
41       SETREG("8")  SETREG("9")  SETREG("10") SETREG("11")
42       SETREG("12") SETREG("13") SETREG("14") SETREG("15")
43       SETREG("16") SETREG("17") SETREG("18") SETREG("19")
44       SETREG("20") SETREG("21") SETREG("22") SETREG("23")
45       SETREG("24") SETREG("25") SETREG("26") SETREG("27")
46       SETREG("28") SETREG("29") SETREG("30") /* 31 is xzr/sp */
47       /* clang-format on */
48       ".inst   0x00000000\n\t" // udf #0 (old binutils don't support udf)
49       ::
50           : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10",
51             "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19",
52             "x20", "x21", "x22", "x23", "x24", "x25", "x26", "x27", "x28",
53             "x29", "x30");
54 }
55 
main()56 int main() {
57   if (signal(SIGILL, handler) == SIG_ERR) {
58     perror("signal");
59     return 1;
60   }
61 
62   sigill();
63   return 2;
64 }
65