diff --git a/clang/docs/UndefinedBehaviorSanitizer.rst b/clang/docs/UndefinedBehaviorSanitizer.rst --- a/clang/docs/UndefinedBehaviorSanitizer.rst +++ b/clang/docs/UndefinedBehaviorSanitizer.rst @@ -100,8 +100,7 @@ by Clang (and by ISO/IEC/IEEE 60559 / IEEE 754) as producing either an infinity or NaN value, so is not included in ``-fsanitize=undefined``. - ``-fsanitize=function``: Indirect call of a function through a - function pointer of the wrong type (Darwin/Linux, C++ and x86/x86_64 - only). + function pointer of the wrong type (C++ only). - ``-fsanitize=implicit-unsigned-integer-truncation``, ``-fsanitize=implicit-signed-integer-truncation``: Implicit conversion from integer of larger bit width to smaller bit width, if that results in data diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1156,8 +1156,7 @@ // platform dependent. SanitizerMask Res = - (SanitizerKind::Undefined & ~SanitizerKind::Vptr & - ~SanitizerKind::Function) | + (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | (SanitizerKind::CFI & ~SanitizerKind::CFIICall) | SanitizerKind::CFICastStrict | SanitizerKind::FloatDivideByZero | SanitizerKind::KCFI | SanitizerKind::UnsignedIntegerOverflow | diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -3262,7 +3262,6 @@ Res |= SanitizerKind::Leak; Res |= SanitizerKind::Fuzzer; Res |= SanitizerKind::FuzzerNoLink; - Res |= SanitizerKind::Function; Res |= SanitizerKind::ObjCCast; // Prior to 10.9, macOS shipped a version of the C++ standard library without diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -483,9 +483,6 @@ Res |= SanitizerKind::Leak; Res |= SanitizerKind::Thread; } - if (IsX86 || IsX86_64) { - Res |= SanitizerKind::Function; - } if (IsAArch64 || IsX86 || IsX86_64) { Res |= SanitizerKind::SafeStack; Res |= SanitizerKind::Fuzzer; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -771,8 +771,6 @@ Res |= SanitizerKind::Thread; if (IsX86_64) Res |= SanitizerKind::KernelMemory; - if (IsX86 || IsX86_64) - Res |= SanitizerKind::Function; if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch || IsPowerPC64 || IsHexagon || IsLoongArch64 || IsRISCV64) Res |= SanitizerKind::Scudo; diff --git a/clang/lib/Driver/ToolChains/NetBSD.cpp b/clang/lib/Driver/ToolChains/NetBSD.cpp --- a/clang/lib/Driver/ToolChains/NetBSD.cpp +++ b/clang/lib/Driver/ToolChains/NetBSD.cpp @@ -508,7 +508,6 @@ Res |= SanitizerKind::Address; Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; - Res |= SanitizerKind::Function; Res |= SanitizerKind::Leak; Res |= SanitizerKind::SafeStack; Res |= SanitizerKind::Scudo; diff --git a/clang/lib/Driver/ToolChains/Solaris.cpp b/clang/lib/Driver/ToolChains/Solaris.cpp --- a/clang/lib/Driver/ToolChains/Solaris.cpp +++ b/clang/lib/Driver/ToolChains/Solaris.cpp @@ -225,7 +225,6 @@ SanitizerMask Solaris::getSupportedSanitizers() const { const bool IsX86 = getTriple().getArch() == llvm::Triple::x86; - const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64; SanitizerMask Res = ToolChain::getSupportedSanitizers(); // FIXME: Omit X86_64 until 64-bit support is figured out. if (IsX86) { @@ -233,8 +232,6 @@ Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; } - if (IsX86 || IsX86_64) - Res |= SanitizerKind::Function; Res |= SanitizerKind::Vptr; return Res; } diff --git a/clang/test/CodeGen/ubsan-function.cpp b/clang/test/CodeGen/ubsan-function.cpp --- a/clang/test/CodeGen/ubsan-function.cpp +++ b/clang/test/CodeGen/ubsan-function.cpp @@ -1,4 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s +// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s // CHECK: @[[PROXY:.*]] = private unnamed_addr constant ptr @_ZTIFvvE // CHECK: define{{.*}} void @_Z3funv() #0 !func_sanitize ![[FUNCSAN:.*]] { diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -525,9 +525,10 @@ // RUN: %clang --target=x86_64-linux-gnu -fsanitize=thread -fsanitize-thread-atomics -fno-sanitize-thread-atomics %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ATOMICS-BOTH-OFF // CHECK-TSAN-ATOMICS-BOTH-OFF: -cc1{{.*}}tsan-instrument-atomics=0 -// RUN: %clang --target=x86_64-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-DARWIN -// RUN: %clang --target=i386-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-DARWIN -// CHECK-FSAN-DARWIN: -cc1{{.*}}"-fsanitize=function" "-fsanitize-recover=function" +// RUN: %clang --target=x86_64-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FUNCTION +// RUN: %clang --target=i386-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FUNCTION +// RUN: %clang --target=aarch64-unknown-linux-gnu -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FUNCTION +// CHECK-FUNCTION: -cc1{{.*}}"-fsanitize=function" "-fsanitize-recover=function" // RUN: %clang --target=x86_64-apple-darwin10 -mmacosx-version-min=10.8 -fsanitize=vptr %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-DARWIN-OLD // CHECK-VPTR-DARWIN-OLD: unsupported option '-fsanitize=vptr' for target 'x86_64-apple-darwin10' diff --git a/compiler-rt/test/ubsan/TestCases/TypeCheck/Function/lit.local.cfg.py b/compiler-rt/test/ubsan/TestCases/TypeCheck/Function/lit.local.cfg.py --- a/compiler-rt/test/ubsan/TestCases/TypeCheck/Function/lit.local.cfg.py +++ b/compiler-rt/test/ubsan/TestCases/TypeCheck/Function/lit.local.cfg.py @@ -1,3 +1,3 @@ -# The function type checker is only supported on x86 and x86_64 for now. -if config.target_arch not in ['x86', 'x86_64']: +# The function type checker is only supported on aarch64 and x86 for now. +if config.target_arch not in ['aarch64', 'x86', 'x86_64']: config.unsupported = True diff --git a/llvm/test/CodeGen/AArch64/func-sanitizer.ll b/llvm/test/CodeGen/AArch64/func-sanitizer.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/func-sanitizer.ll @@ -0,0 +1,22 @@ +; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s + +; CHECK-LABEL: .type _Z3funv,@function +; CHECK-NEXT: .word 3238382334 // 0xc105cafe +; CHECK-NEXT: .word .L__llvm_rtti_proxy-_Z3funv +; CHECK-NEXT: _Z3funv: +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: ret + +; CHECK: .section .rodata,"a",@progbits +; CHECK-LABEL: .L__llvm_rtti_proxy: +; CHECK-NEXT: .xword _ZTIFvvE +; CHECK-NEXT: .size .L__llvm_rtti_proxy, 8 + +@_ZTIFvvE = linkonce_odr constant i32 1 +@__llvm_rtti_proxy = private unnamed_addr constant ptr @_ZTIFvvE + +define dso_local void @_Z3funv() nounwind !func_sanitize !0 { + ret void +} + +!0 = !{i32 3238382334, ptr @__llvm_rtti_proxy} diff --git a/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll b/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll --- a/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll +++ b/llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll @@ -1,5 +1,8 @@ ; RUN: llc -mtriple=aarch64 %s -o - | FileCheck %s +@_ZTIFvvE = linkonce_odr constant i32 2 +@__llvm_rtti_proxy = private unnamed_addr constant ptr @_ZTIFvvE + define void @f0() "patchable-function-entry"="0" "branch-target-enforcement"="true" { ; CHECK-LABEL: f0: ; CHECK-NEXT: .Lfunc_begin0: @@ -85,3 +88,22 @@ call void asm sideeffect "", ""() ret void } + +;; Test the interaction with -fsanitize=function. +; CHECK: .type sanitize_function,@function +; CHECK-NEXT: .Ltmp{{.*}}: +; CHECK-NEXT: nop +; CHECK-NEXT: .word 3238382334 // 0xc105cafe +; CHECK-NEXT: .word .L__llvm_rtti_proxy-sanitize_function +; CHECK-NEXT: sanitize_function: +; CHECK-NEXT: .Lfunc_begin{{.*}}: +; CHECK-NEXT: .cfi_startproc +; CHECK-NEXT: // %bb.0: +; CHECK-NEXT: hint #34 +; CHECK-NEXT: nop +; CHECK-NEXT: ret +define void @sanitize_function(ptr noundef %x) "patchable-function-prefix"="1" "patchable-function-entry"="1" "branch-target-enforcement"="true" !func_sanitize !0 { + ret void +} + +!0 = !{i32 3238382334, ptr @__llvm_rtti_proxy}