1#include <stdlib.h> 2#include <signal.h> 3#include "syscall.h" 4#include "pthread_impl.h" 5#include "atomic.h" 6#include "lock.h" 7#include "ksigaction.h" 8#if defined(MUSL_AARCH64_ARCH) 9#include <stdint.h> 10#include <stdio.h> 11#include <inttypes.h> 12#include <info/fatal_message.h> 13 14#define MESSAGE_BUFFER_SIZE 512 15 16/** 17 * @brief Retrieves the current value of the x1 register on AArch64. 18 * 19 * This function is used in CFI checks to obtain the function address 20 * stored in the x1 register during calls involving function pointers, 21 * virtual calls (vcall), and non-virtual calls (nvcall) using vtable addresses. 22 * 23 * @return Value of the x1 register. 24 */ 25uint64_t fetch_function_address() 26{ 27 uint64_t val; 28 __asm__ __volatile__( 29 "mov %0, x1" 30 : "=r" (val) 31 : 32 : "memory" 33 ); 34 return val; 35} 36#endif 37 38_Noreturn void __cfi_fail_report(void) 39{ 40#if defined(MUSL_AARCH64_ARCH) 41 uint64_t function_address = fetch_function_address(); 42 char message[MESSAGE_BUFFER_SIZE]; 43 snprintf(message, sizeof(message), 44 " CFI check failed. Function Address: 0x%" PRIx64, function_address); 45 set_fatal_message(message); 46#endif 47 abort(); 48} 49 50_Noreturn void abort(void) 51{ 52#ifdef __LITEOS_A__ 53 sigset_t set, pending; 54 sigemptyset(&set); 55 sigaddset(&set, SIGABRT); 56 57 sigpending(&pending); 58 __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, &set, 0, _NSIG / 8); 59 if (!sigismember(&pending, SIGABRT)) { 60 raise(SIGABRT); 61 } 62#else 63 raise(SIGABRT); 64#endif 65 66 /* If there was a SIGABRT handler installed and it returned, or if 67 * SIGABRT was blocked or ignored, take an AS-safe lock to prevent 68 * sigaction from installing a new SIGABRT handler, uninstall any 69 * handler that may be present, and re-raise the signal to generate 70 * the default action of abnormal termination. */ 71 __block_all_sigs(0); 72 LOCK(__abort_lock); 73#ifdef __LITEOS_A__ 74 signal(SIGABRT, SIG_DFL); 75#else 76 __syscall(SYS_rt_sigaction, SIGABRT, 77 &(struct k_sigaction){.handler = SIG_DFL}, 0, _NSIG/8); 78#endif 79 __syscall(SYS_tkill, __pthread_self()->tid, SIGABRT); 80 __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, 81 &(long[_NSIG/(8*sizeof(long))]){1UL<<(SIGABRT-1)}, 0, _NSIG/8); 82 83 /* Beyond this point should be unreachable. */ 84 a_crash(); 85 raise(SIGKILL); 86 _Exit(127); 87} 88