From 1dcfa7a4fa35f5bf07e5da04113329189d96e7d1 Mon Sep 17 00:00:00 2001 From: zhengweiwei Date: Fri, 9 Aug 2024 22:06:01 +0800 Subject: [PATCH] [CFI] Implemented failure reporting mechanism for CFI checks Desc: - Added `cfi_fail_report.cpp` to handle CFI check failures on aarch64. - Integrated with build system to create `clang_rt.cfi_fail_report` static library. - Improved error reporting for easier debugging of CFI crashes. Issue: https://gitee.com/openharmony/third_party_llvm-project/issues/IAJ36I Signed-off-by: zhengweiwei --- compiler-rt/lib/cfi/CMakeLists.txt | 10 ++++++ compiler-rt/lib/cfi/cfi_fail_report.cpp | 41 +++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 compiler-rt/lib/cfi/cfi_fail_report.cpp diff --git a/compiler-rt/lib/cfi/CMakeLists.txt b/compiler-rt/lib/cfi/CMakeLists.txt index cf8479d39c25..2a69b455bba9 100644 --- a/compiler-rt/lib/cfi/CMakeLists.txt +++ b/compiler-rt/lib/cfi/CMakeLists.txt @@ -5,6 +5,10 @@ if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetB cfi.cpp ) + set(CFI_FAIL_REPORT_SOURCES + cfi_fail_report.cpp + ) + include_directories(..) set(CFI_CFLAGS @@ -40,6 +44,12 @@ if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetB RTUbsan CFLAGS ${CFI_CFLAGS} ${CFI_DIAG_CFLAGS} PARENT_TARGET cfi) + add_compiler_rt_runtime(clang_rt.cfi_fail_report + STATIC + ARCHS ${arch} + SOURCES ${CFI_FAIL_REPORT_SOURCES} + CFLAGS ${CFI_CFLAGS} + PARENT_TARGET cfi) endforeach() endif() diff --git a/compiler-rt/lib/cfi/cfi_fail_report.cpp b/compiler-rt/lib/cfi/cfi_fail_report.cpp new file mode 100644 index 000000000000..083707da3a24 --- /dev/null +++ b/compiler-rt/lib/cfi/cfi_fail_report.cpp @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#if defined(__aarch64__) && defined(__OHOS__) +#include + +extern "C" _Noreturn void __cfi_fail_report(void); +/** + * @brief Retrieves the current value of the x1 register on AArch64. + * + * This function is used in CFI checks to obtain the function address + * stored in the x1 register during calls involving function pointers, + * virtual calls (vcall), and non-virtual calls (nvcall) using vtable addresses. + * + * @return Value of the x1 register. + */ +uint64_t fetch_function_address(void) { + uint64_t val; + __asm__ __volatile__( + "mov %0, x1" + : "=r" (val) + : + : "memory" + ); + return val; +} + +_Noreturn void __cfi_fail_report(void) { + uint64_t function_address = fetch_function_address(); + char message[512]; + snprintf(message, sizeof(message), + "CFI check failed. Function Address: 0x%" PRIx64, function_address); + set_fatal_message(message); + abort(); +} +#else +extern "C" _Noreturn void __cfi_fail_report(void) { + abort(); +} +#endif -- Gitee