10b2d8bd6SPhilippe Mathieu-Daudé/* 20b2d8bd6SPhilippe Mathieu-Daudé * Minimal user-environment for testing BTI. 30b2d8bd6SPhilippe Mathieu-Daudé * 40b2d8bd6SPhilippe Mathieu-Daudé * Normal libc is not (yet) built with BTI support enabled, 50b2d8bd6SPhilippe Mathieu-Daudé * and so could generate a BTI TRAP before ever reaching main. 60b2d8bd6SPhilippe Mathieu-Daudé */ 70b2d8bd6SPhilippe Mathieu-Daudé 80b2d8bd6SPhilippe Mathieu-Daudé#include <stdlib.h> 90b2d8bd6SPhilippe Mathieu-Daudé#include <signal.h> 100b2d8bd6SPhilippe Mathieu-Daudé#include <ucontext.h> 110b2d8bd6SPhilippe Mathieu-Daudé#include <asm/unistd.h> 120b2d8bd6SPhilippe Mathieu-Daudé 130b2d8bd6SPhilippe Mathieu-Daudéint main(void); 140b2d8bd6SPhilippe Mathieu-Daudé 150b2d8bd6SPhilippe Mathieu-Daudévoid _start(void) 160b2d8bd6SPhilippe Mathieu-Daudé{ 170b2d8bd6SPhilippe Mathieu-Daudé exit(main()); 180b2d8bd6SPhilippe Mathieu-Daudé} 190b2d8bd6SPhilippe Mathieu-Daudé 200b2d8bd6SPhilippe Mathieu-Daudévoid exit(int ret) 210b2d8bd6SPhilippe Mathieu-Daudé{ 220b2d8bd6SPhilippe Mathieu-Daudé register int x0 __asm__("x0") = ret; 230b2d8bd6SPhilippe Mathieu-Daudé register int x8 __asm__("x8") = __NR_exit; 240b2d8bd6SPhilippe Mathieu-Daudé 250b2d8bd6SPhilippe Mathieu-Daudé asm volatile("svc #0" : : "r"(x0), "r"(x8)); 260b2d8bd6SPhilippe Mathieu-Daudé __builtin_unreachable(); 270b2d8bd6SPhilippe Mathieu-Daudé} 280b2d8bd6SPhilippe Mathieu-Daudé 290b2d8bd6SPhilippe Mathieu-Daudé/* 300b2d8bd6SPhilippe Mathieu-Daudé * Irritatingly, the user API struct sigaction does not match the 310b2d8bd6SPhilippe Mathieu-Daudé * kernel API struct sigaction. So for simplicity, isolate the 320b2d8bd6SPhilippe Mathieu-Daudé * kernel ABI here, and make this act like signal. 330b2d8bd6SPhilippe Mathieu-Daudé */ 340b2d8bd6SPhilippe Mathieu-Daudévoid signal_info(int sig, void (*fn)(int, siginfo_t *, ucontext_t *)) 350b2d8bd6SPhilippe Mathieu-Daudé{ 360b2d8bd6SPhilippe Mathieu-Daudé struct kernel_sigaction { 370b2d8bd6SPhilippe Mathieu-Daudé void (*handler)(int, siginfo_t *, ucontext_t *); 380b2d8bd6SPhilippe Mathieu-Daudé unsigned long flags; 390b2d8bd6SPhilippe Mathieu-Daudé unsigned long restorer; 400b2d8bd6SPhilippe Mathieu-Daudé unsigned long mask; 410b2d8bd6SPhilippe Mathieu-Daudé } sa = { fn, SA_SIGINFO, 0, 0 }; 420b2d8bd6SPhilippe Mathieu-Daudé 430b2d8bd6SPhilippe Mathieu-Daudé register int x0 __asm__("x0") = sig; 440b2d8bd6SPhilippe Mathieu-Daudé register void *x1 __asm__("x1") = &sa; 450b2d8bd6SPhilippe Mathieu-Daudé register void *x2 __asm__("x2") = 0; 460b2d8bd6SPhilippe Mathieu-Daudé register int x3 __asm__("x3") = sizeof(unsigned long); 470b2d8bd6SPhilippe Mathieu-Daudé register int x8 __asm__("x8") = __NR_rt_sigaction; 480b2d8bd6SPhilippe Mathieu-Daudé 490b2d8bd6SPhilippe Mathieu-Daudé asm volatile("svc #0" 500b2d8bd6SPhilippe Mathieu-Daudé : : "r"(x0), "r"(x1), "r"(x2), "r"(x3), "r"(x8) : "memory"); 510b2d8bd6SPhilippe Mathieu-Daudé} 52