History

checkasm/riscv: report an error upon SIGILL

Terminating the whole checkasm process is not very helpful. This will report if an illegal instruction occurs while executing a tested function. This is a common occurrence whilst developping RISC-V assembler, due to the compatibility between vector configuration and instruction done at run-time.

Rémi Denis-Courmont committed 3 years ago

Commit 72124661 parent 286d6743 files · +30 −2Browse files

Unified · Split

3 files
  1. tests/checkasm/checkasm.c +9 −0
  2. tests/checkasm/checkasm.h +9 −2
  3. tests/checkasm/riscv/checkasm.S +12 −0
tests/checkasm/checkasm.c+9−0
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 # define _GNU_SOURCE // for syscall (performance monitoring API), strsignal()
2828 #endif
2929
30+#include <signal.h>
3031 #include <stdarg.h>
3132 #include <stdio.h>
3233 #include <stdlib.h>
@@ -734,6 +735,14 @@ int main(int argc, char *argv[]) · 701 unmodified lines
734735 if (have_vfp(av_get_cpu_flags()) || have_neon(av_get_cpu_flags()))
735736 checkasm_checked_call = checkasm_checked_call_vfp;
736737 #endif
738+#if ARCH_RISCV
739+ struct sigaction act = {
740+ .sa_handler = checkasm_handle_signal,
741+ .sa_flags = 0,
742+ };
743+
744+ sigaction(SIGILL, &act, NULL);
745+#endif
737746
738747 if (!tests[0].func || !cpus[0].flag) {
739748 fprintf(stderr, "checkasm: no tests to perform\n");
tests/checkasm/checkasm.h+9−2
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323 #ifndef TESTS_CHECKASM_CHECKASM_H
2424 #define TESTS_CHECKASM_CHECKASM_H
2525
26+#include <setjmp.h>
2627 #include <stdint.h>
2728 #include "config.h"
2829
@@ -211,14 +212,20 @@ void checkasm_checked_call(void *func, ...); · 182 unmodified lines
211212 checked_call(func_new, 0, 0, 0, 0, 0, 0, 0, __VA_ARGS__,\
212213 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0))
213214 #elif ARCH_RISCV
214−void checkasm_set_function(void *);
215+void checkasm_set_function(void *, sigjmp_buf);
215216 void *checkasm_get_wrapper(void);
217+void checkasm_handle_signal(int signum);
216218
217219 #if (__riscv_xlen == 64) && defined (__riscv_d)
218220 #define declare_new(ret, ...) \
221+ int checked_call_signum = 0; \
222+ sigjmp_buf checked_call_jb; \
219223 ret (*checked_call)(__VA_ARGS__) = checkasm_get_wrapper();
220224 #define call_new(...) \
221− (checkasm_set_function(func_new), checked_call(__VA_ARGS__))
225+ (checkasm_set_function(func_new, checked_call_jb), \
226+ (checked_call_signum = sigsetjmp(checked_call_jb, 1)) == 0 \
227+ ? checked_call(__VA_ARGS__) \
228+ : (checkasm_fail_signal(checked_call_signum), 0))
222229 #endif
223230 #else
224231 #define declare_new(ret, ...)
tests/checkasm/riscv/checkasm.S+12−0
@@ -41,6 +41,7 @@ endconst · 40 unmodified lines
4141
4242 checked_func:
4343 .quad 0
44+ .quad 0
4445
4546 saved_regs:
4647 /* Space to spill RA, SP, GP, TP, S0-S11 and FS0-FS11 */
@@ -52,6 +53,7 @@ func checkasm_set_function · 5 unmodified lines
5253 la.tls.ie t0, checked_func
5354 add t0, tp, t0
5455 sd a0, (t0)
56+ sd a1, 8(t0)
5557 ret
5658 endfunc
5759
@@ -175,4 +177,14 @@ func checkasm_get_wrapper, v · 117 unmodified lines
175177 call checkasm_fail_func
176178 j 4b
177179 endfunc
180+
181+func checkasm_handle_signal
182+ mv a1, a0
183+ la.tls.ie a0, checked_func
184+ add a0, tp, a0
185+ ld a0, 8(a0)
186+ beqz a0, 8f
187+ tail siglongjmp
188+8: tail abort /* No jump buffer to go to */
189+endfunc
178190 #endif

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t