[compiler-rt] Reapply "[UBSan] [compiler-rt] add preservecc variants of handlers" (#168973) (PR #169091)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 21 12:45:47 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Florian Mayer (fmayer)
<details>
<summary>Changes</summary>
This reverts commit 418204d9c108351340fe21194ace0e31157b7189.
---
Full diff: https://github.com/llvm/llvm-project/pull/169091.diff
2 Files Affected:
- (modified) compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp (+40-9)
- (modified) compiler-rt/test/ubsan_minimal/TestCases/test-darwin-interface.c (+1)
``````````diff
diff --git a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
index ebc36a8583e05..034071f527362 100644
--- a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
+++ b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp
@@ -12,6 +12,22 @@ static void message(const char *msg) { ubsan_message(msg); }
static void message(const char *msg) { (void)write(2, msg, strlen(msg)); }
#endif
+// If for some reason we cannot build the runtime with preserve_all, don't
+// emit any symbol. Programs that need them will fail to link, but that is
+// better than randomly corrupted registers.
+// Some architectures don't support preserve_all (but clang still has the)
+// attribute. For now, only support x86-64 and aarch64.
+#if defined(__clang__) && defined(__has_cpp_attribute) && \
+ (defined(__x86_64__) || defined(__aarch64__))
+#if __has_cpp_attribute(clang::preserve_all)
+#define PRESERVE_HANDLERS true
+#else
+#define PRESERVE_HANDLERS false
+#endif
+#else
+#define PRESERVE_HANDLERS false
+#endif
+
static const int kMaxCallerPcs = 20;
static __sanitizer::atomic_uintptr_t caller_pcs[kMaxCallerPcs];
// Number of elements in caller_pcs. A special value of kMaxCallerPcs + 1 means
@@ -85,6 +101,18 @@ SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error, const char *kind,
}
}
+#if PRESERVE_HANDLERS
+SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error_preserve,
+ const char *kind, uintptr_t caller)
+[[clang::preserve_all]] {
+ // Additional indirecton so the user can override this with their own
+ // preserve_all function. This would allow, e.g., a function that reports the
+ // first error only, so for all subsequent calls we can skip the register save
+ // / restore.
+ __ubsan_report_error(kind, caller);
+}
+#endif
+
SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error_fatal, const char *kind,
uintptr_t caller) {
// Use another handlers, in case it's already overriden.
@@ -119,6 +147,16 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) {
#define INTERFACE extern "C" __attribute__((visibility("default")))
+#if PRESERVE_HANDLERS
+#define HANDLER_PRESERVE(name, kind) \
+ INTERFACE void __ubsan_handle_##name##_minimal_preserve() \
+ [[clang::preserve_all]] { \
+ __ubsan_report_error_preserve(kind, GET_CALLER_PC()); \
+ }
+#else
+#define HANDLER_PRESERVE(name, kind)
+#endif
+
#define HANDLER_RECOVER(name, kind) \
INTERFACE void __ubsan_handle_##name##_minimal() { \
__ubsan_report_error(kind, GET_CALLER_PC()); \
@@ -133,17 +171,10 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) {
#define HANDLER(name, kind) \
HANDLER_RECOVER(name, kind) \
- HANDLER_NORECOVER(name, kind)
+ HANDLER_NORECOVER(name, kind) \
+ HANDLER_PRESERVE(name, kind)
HANDLER(type_mismatch, "type-mismatch")
-HANDLER(alignment_assumption, "alignment-assumption")
-HANDLER(add_overflow, "add-overflow")
-HANDLER(sub_overflow, "sub-overflow")
-HANDLER(mul_overflow, "mul-overflow")
-HANDLER(negate_overflow, "negate-overflow")
-HANDLER(divrem_overflow, "divrem-overflow")
-HANDLER(shift_out_of_bounds, "shift-out-of-bounds")
-HANDLER(out_of_bounds, "out-of-bounds")
HANDLER(local_out_of_bounds, "local-out-of-bounds")
HANDLER_RECOVER(builtin_unreachable, "builtin-unreachable")
HANDLER_RECOVER(missing_return, "missing-return")
diff --git a/compiler-rt/test/ubsan_minimal/TestCases/test-darwin-interface.c b/compiler-rt/test/ubsan_minimal/TestCases/test-darwin-interface.c
index abc1073e02073..3c76e5aadc087 100644
--- a/compiler-rt/test/ubsan_minimal/TestCases/test-darwin-interface.c
+++ b/compiler-rt/test/ubsan_minimal/TestCases/test-darwin-interface.c
@@ -4,6 +4,7 @@
// REQUIRES: x86_64-darwin
// RUN: nm -jgU `%clangxx_min_runtime -fsanitize-minimal-runtime -fsanitize=undefined %s -o %t '-###' 2>&1 | grep "libclang_rt.ubsan_minimal_osx_dynamic.dylib" | sed -e 's/.*"\(.*libclang_rt.ubsan_minimal_osx_dynamic.dylib\)".*/\1/'` | grep "^___ubsan_handle" \
+// RUN: | grep -vE "_minimal_preserve" \
// RUN: | sed 's/_minimal//g' \
// RUN: > %t.minimal.symlist
//
``````````
</details>
https://github.com/llvm/llvm-project/pull/169091
More information about the llvm-commits
mailing list