master
c 118 lines 2.93 KB
Raw
1 /*
2 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
3 * SPDX-License-Identifier: GPL-2.0-or-later
4 */
5
6 /*
7 * Test that unaligned scalar loads raise SIGBUS.
8 */
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <stdbool.h>
14 #include <setjmp.h>
15 #include <signal.h>
16
17 int err;
18
19 #include "hex_test.h"
20
21 static bool sigbus_caught;
22 static sigjmp_buf jmp_env;
23 static uint64_t buf[2] = { 0, 0 };
24
25 static void sigbus_handler(int sig, siginfo_t *info, void *puc)
26 {
27 check32(sig, SIGBUS);
28 sigbus_caught = true;
29 siglongjmp(jmp_env, 1);
30 }
31
32 static void test_unaligned_load(int size, int offset)
33 {
34 char *p = (char *)buf + offset;
35 uint32_t dummy32;
36 uint64_t dummy64;
37
38 sigbus_caught = false;
39 if (sigsetjmp(jmp_env, 1) == 0) {
40 switch (size) {
41 case 2:
42 asm volatile("%[dst] = memh(%[src])\n\t"
43 : [dst] "=r"(dummy32) : [src] "r"(p) : "memory");
44 break;
45 case 4:
46 asm volatile("%[dst] = memw(%[src])\n\t"
47 : [dst] "=r"(dummy32) : [src] "r"(p) : "memory");
48 break;
49 case 8:
50 asm volatile("%[dst] = memd(%[src])\n\t"
51 : [dst] "=r"(dummy64) : [src] "r"(p) : "memory");
52 break;
53 default:
54 abort();
55 }
56 }
57 check32(sigbus_caught, true);
58 }
59
60 static void test_unaligned_store(int size, int offset)
61 {
62 char *p = (char *)buf + offset;
63 uint32_t val32 = 0x11223344;
64 uint64_t val64 = 0x1122334455667788ULL;
65
66 sigbus_caught = false;
67 if (sigsetjmp(jmp_env, 1) == 0) {
68 switch (size) {
69 case 2:
70 asm volatile("memh(%[addr]) = %[val]\n\t"
71 : : [addr] "r"(p), [val] "r"(val32) : "memory");
72 break;
73 case 4:
74 asm volatile("memw(%[addr]) = %[val]\n\t"
75 : : [addr] "r"(p), [val] "r"(val32) : "memory");
76 break;
77 case 8:
78 asm volatile("memd(%[addr]) = %[val]\n\t"
79 : : [addr] "r"(p), [val] "r"(val64) : "memory");
80 break;
81 default:
82 abort();
83 }
84 }
85 check32(sigbus_caught, true);
86 }
87
88 int main()
89 {
90 struct sigaction act;
91
92 act.sa_sigaction = sigbus_handler;
93 sigemptyset(&act.sa_mask);
94 act.sa_flags = SA_SIGINFO;
95 chk_error(sigaction(SIGBUS, &act, NULL));
96
97 test_unaligned_load(2, 1);
98 test_unaligned_load(4, 1);
99 test_unaligned_load(4, 2);
100 test_unaligned_load(4, 3);
101 test_unaligned_load(8, 1);
102 test_unaligned_load(8, 4);
103
104 test_unaligned_store(2, 1);
105 test_unaligned_store(4, 1);
106 test_unaligned_store(4, 2);
107 test_unaligned_store(4, 3);
108 test_unaligned_store(8, 1);
109 test_unaligned_store(8, 4);
110
111 act.sa_handler = SIG_DFL;
112 sigemptyset(&act.sa_mask);
113 act.sa_flags = 0;
114 chk_error(sigaction(SIGBUS, &act, NULL));
115
116 puts(err ? "FAIL" : "PASS");
117 return err ? EXIT_FAILURE : EXIT_SUCCESS;
118 }