1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <stdlib.h>
28#include <stdio.h>
29#include <unistd.h>
30#include <sys/types.h>
31#include <fcntl.h>
32#include <setjmp.h>
33#include <signal.h>
34
35typedef unsigned char uint8_t;
36
37int err;
38int segv_caught;
39
40#define SHOULD_NOT_CHANGE_VAL 5
41int should_not_change = SHOULD_NOT_CHANGE_VAL;
42
43#define BUF_SIZE 300
44unsigned char buf[BUF_SIZE];
45
46
47static void __check(const char *filename, int line, int x, int expect)
48{
49 if (x != expect) {
50 printf("ERROR %s:%d - %d != %d\n",
51 filename, line, x, expect);
52 err++;
53 }
54}
55
56#define check(x, expect) __check(__FILE__, __LINE__, (x), (expect))
57
58static void __chk_error(const char *filename, int line, int ret)
59{
60 if (ret < 0) {
61 printf("ERROR %s:%d - %d\n", filename, line, ret);
62 err++;
63 }
64}
65
66#define chk_error(ret) __chk_error(__FILE__, __LINE__, (ret))
67
68jmp_buf jmp_env;
69
70static void sig_segv(int sig, siginfo_t *info, void *puc)
71{
72 check(sig, SIGSEGV);
73 segv_caught = 1;
74 longjmp(jmp_env, 1);
75}
76
77int main()
78{
79 struct sigaction act;
80
81
82 act.sa_sigaction = sig_segv;
83 sigemptyset(&act.sa_mask);
84 act.sa_flags = SA_SIGINFO;
85 chk_error(sigaction(SIGSEGV, &act, NULL));
86 if (setjmp(jmp_env) == 0) {
87 asm volatile("r18 = ##should_not_change\n\t"
88 "r19 = #0\n\t"
89 "{\n\t"
90 " memw(r18) = #7\n\t"
91 " memw(r19) = #0\n\t"
92 "}\n\t"
93 : : : "r18", "r19", "memory");
94 }
95
96 act.sa_handler = SIG_DFL;
97 sigemptyset(&act.sa_mask);
98 act.sa_flags = 0;
99 chk_error(sigaction(SIGSEGV, &act, NULL));
100
101 check(segv_caught, 1);
102 check(should_not_change, SHOULD_NOT_CHANGE_VAL);
103
104 puts(err ? "FAIL" : "PASS");
105 return err ? EXIT_FAILURE : EXIT_SUCCESS;
106}
107