1/* 2 * Minimal user-environment for testing BTI. 3 * 4 * Normal libc is not (yet) built with BTI support enabled, 5 * and so could generate a BTI TRAP before ever reaching main. 6 */ 7 8#include <stdlib.h> 9#include <signal.h> 10#include <ucontext.h> 11#include <asm/unistd.h> 12 13int main(void); 14 15void _start(void) 16{ 17 exit(main()); 18} 19 20void exit(int ret) 21{ 22 register int x0 __asm__("x0") = ret; 23 register int x8 __asm__("x8") = __NR_exit; 24 25 asm volatile("svc #0" : : "r"(x0), "r"(x8)); 26 __builtin_unreachable(); 27} 28 29/* 30 * Irritatingly, the user API struct sigaction does not match the 31 * kernel API struct sigaction. So for simplicity, isolate the 32 * kernel ABI here, and make this act like signal. 33 */ 34void signal_info(int sig, void (*fn)(int, siginfo_t *, ucontext_t *)) 35{ 36 struct kernel_sigaction { 37 void (*handler)(int, siginfo_t *, ucontext_t *); 38 unsigned long flags; 39 unsigned long restorer; 40 unsigned long mask; 41 } sa = { fn, SA_SIGINFO, 0, 0 }; 42 43 register int x0 __asm__("x0") = sig; 44 register void *x1 __asm__("x1") = &sa; 45 register void *x2 __asm__("x2") = 0; 46 register int x3 __asm__("x3") = sizeof(unsigned long); 47 register int x8 __asm__("x8") = __NR_rt_sigaction; 48 49 asm volatile("svc #0" 50 : : "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x8) : "memory"); 51} 52