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.
Unified · Split
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | # define _GNU_SOURCE // for syscall (performance monitoring API), strsignal() | 27 | # define _GNU_SOURCE // for syscall (performance monitoring API), strsignal() |
| 28 | #endif | 28 | #endif |
| 29 | 29 | ||
| 30 | #include <signal.h> | ||
| 30 | #include <stdarg.h> | 31 | #include <stdarg.h> |
| 31 | #include <stdio.h> | 32 | #include <stdio.h> |
| 32 | #include <stdlib.h> | 33 | #include <stdlib.h> |
| @@ -734,6 +735,14 @@ int main(int argc, char *argv[]) · 701 unmodified lines | |||
| 734 | if (have_vfp(av_get_cpu_flags()) || have_neon(av_get_cpu_flags())) | 735 | if (have_vfp(av_get_cpu_flags()) || have_neon(av_get_cpu_flags())) |
| 735 | checkasm_checked_call = checkasm_checked_call_vfp; | 736 | checkasm_checked_call = checkasm_checked_call_vfp; |
| 736 | #endif | 737 | #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 | ||
| 737 | 746 | ||
| 738 | if (!tests[0].func || !cpus[0].flag) { | 747 | if (!tests[0].func || !cpus[0].flag) { |
| 739 | fprintf(stderr, "checkasm: no tests to perform\n"); | 748 | fprintf(stderr, "checkasm: no tests to perform\n"); |
| @@ -23,6 +23,7 @@ · 22 unmodified lines | |||
| 23 | #ifndef TESTS_CHECKASM_CHECKASM_H | 23 | #ifndef TESTS_CHECKASM_CHECKASM_H |
| 24 | #define TESTS_CHECKASM_CHECKASM_H | 24 | #define TESTS_CHECKASM_CHECKASM_H |
| 25 | 25 | ||
| 26 | #include <setjmp.h> | ||
| 26 | #include <stdint.h> | 27 | #include <stdint.h> |
| 27 | #include "config.h" | 28 | #include "config.h" |
| 28 | 29 | ||
| @@ -211,14 +212,20 @@ void checkasm_checked_call(void *func, ...); · 182 unmodified lines | |||
| 211 | checked_call(func_new, 0, 0, 0, 0, 0, 0, 0, __VA_ARGS__,\ | 212 | checked_call(func_new, 0, 0, 0, 0, 0, 0, 0, __VA_ARGS__,\ |
| 212 | 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0)) | 213 | 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0)) |
| 213 | #elif ARCH_RISCV | 214 | #elif ARCH_RISCV |
| 214 | void checkasm_set_function(void *); | 215 | void checkasm_set_function(void *, sigjmp_buf); |
| 215 | void *checkasm_get_wrapper(void); | 216 | void *checkasm_get_wrapper(void); |
| 217 | void checkasm_handle_signal(int signum); | ||
| 216 | 218 | ||
| 217 | #if (__riscv_xlen == 64) && defined (__riscv_d) | 219 | #if (__riscv_xlen == 64) && defined (__riscv_d) |
| 218 | #define declare_new(ret, ...) \ | 220 | #define declare_new(ret, ...) \ |
| 221 | int checked_call_signum = 0; \ | ||
| 222 | sigjmp_buf checked_call_jb; \ | ||
| 219 | ret (*checked_call)(__VA_ARGS__) = checkasm_get_wrapper(); | 223 | ret (*checked_call)(__VA_ARGS__) = checkasm_get_wrapper(); |
| 220 | #define call_new(...) \ | 224 | #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)) | ||
| 222 | #endif | 229 | #endif |
| 223 | #else | 230 | #else |
| 224 | #define declare_new(ret, ...) | 231 | #define declare_new(ret, ...) |
| @@ -41,6 +41,7 @@ endconst · 40 unmodified lines | |||
| 41 | 41 | ||
| 42 | checked_func: | 42 | checked_func: |
| 43 | .quad 0 | 43 | .quad 0 |
| 44 | .quad 0 | ||
| 44 | 45 | ||
| 45 | saved_regs: | 46 | saved_regs: |
| 46 | /* Space to spill RA, SP, GP, TP, S0-S11 and FS0-FS11 */ | 47 | /* Space to spill RA, SP, GP, TP, S0-S11 and FS0-FS11 */ |
| @@ -52,6 +53,7 @@ func checkasm_set_function · 5 unmodified lines | |||
| 52 | la.tls.ie t0, checked_func | 53 | la.tls.ie t0, checked_func |
| 53 | add t0, tp, t0 | 54 | add t0, tp, t0 |
| 54 | sd a0, (t0) | 55 | sd a0, (t0) |
| 56 | sd a1, 8(t0) | ||
| 55 | ret | 57 | ret |
| 56 | endfunc | 58 | endfunc |
| 57 | 59 | ||
| @@ -175,4 +177,14 @@ func checkasm_get_wrapper, v · 117 unmodified lines | |||
| 175 | call checkasm_fail_func | 177 | call checkasm_fail_func |
| 176 | j 4b | 178 | j 4b |
| 177 | endfunc | 179 | 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 | ||
| 178 | #endif | 190 | #endif |