MaskRay updated this revision to Diff 514768. MaskRay edited the summary of this revision. MaskRay added a comment.
Make -mbranch-protection=bti -fsanitize=function work. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D148573/new/ https://reviews.llvm.org/D148573 Files: clang/docs/UndefinedBehaviorSanitizer.rst clang/lib/CodeGen/TargetInfo.cpp clang/lib/Driver/ToolChains/FreeBSD.cpp clang/lib/Driver/ToolChains/Linux.cpp clang/test/CodeGen/ubsan-function.cpp clang/test/Driver/fsanitize.c compiler-rt/test/ubsan/TestCases/TypeCheck/Function/lit.local.cfg.py llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp llvm/test/CodeGen/AArch64/func-sanitizer.ll llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll
Index: llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll =================================================================== --- llvm/test/CodeGen/AArch64/patchable-function-entry-bti.ll +++ 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 335544322 // 0x14000002 +; 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 335544322, ptr @__llvm_rtti_proxy} Index: llvm/test/CodeGen/AArch64/func-sanitizer.ll =================================================================== --- /dev/null +++ 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 335544322 // 0x14000002 +; 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 335544322, ptr @__llvm_rtti_proxy} Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -972,7 +972,7 @@ // Emit the function prologue data for the indirect call sanitizer. if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) { - assert(TM.getTargetTriple().isX86()); + assert(TM.getTargetTriple().isAArch64() || TM.getTargetTriple().isX86()); assert(MD->getNumOperands() == 2); auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0)); Index: compiler-rt/test/ubsan/TestCases/TypeCheck/Function/lit.local.cfg.py =================================================================== --- compiler-rt/test/ubsan/TestCases/TypeCheck/Function/lit.local.cfg.py +++ 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 Index: clang/test/Driver/fsanitize.c =================================================================== --- clang/test/Driver/fsanitize.c +++ 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' Index: clang/test/CodeGen/ubsan-function.cpp =================================================================== --- clang/test/CodeGen/ubsan-function.cpp +++ 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 x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,X86 +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,AARCH64 +// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,AARCH64 // CHECK: @[[PROXY:.*]] = private unnamed_addr constant ptr @_ZTIFvvE // CHECK: define{{.*}} void @_Z3funv() #0 !func_sanitize ![[FUNCSAN:.*]] { @@ -7,7 +9,8 @@ // CHECK-LABEL: define{{.*}} void @_Z6callerPFvvE(ptr noundef %f) // CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize // CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize -// CHECK: icmp eq i32 {{.*}}, 846595819, !nosanitize +// X86-NEXT: icmp eq i32 {{.*}}, 846595819, !nosanitize +// AARCH64-NEXT: icmp eq i32 {{.*}}, 335544322, !nosanitize // CHECK: br i1 {{.*}}, label %[[LABEL1:.*]], label %[[LABEL4:.*]], !nosanitize // CHECK: [[LABEL1]]: // CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 1, !nosanitize @@ -22,4 +25,7 @@ // CHECK: br label %[[LABEL4]], !nosanitize void caller(void (*f)()) { f(); } -// CHECK: ![[FUNCSAN]] = !{i32 846595819, ptr @[[PROXY]]} +// X86: ![[FUNCSAN]] = !{i32 846595819, ptr @[[PROXY]]} + +/// .word 0x14000002 # b .+8 +// AARCH64: ![[FUNCSAN]] = !{i32 335544322, ptr @[[PROXY]]} Index: clang/lib/Driver/ToolChains/Linux.cpp =================================================================== --- clang/lib/Driver/ToolChains/Linux.cpp +++ clang/lib/Driver/ToolChains/Linux.cpp @@ -771,7 +771,7 @@ Res |= SanitizerKind::Thread; if (IsX86_64) Res |= SanitizerKind::KernelMemory; - if (IsX86 || IsX86_64) + if (IsAArch64 || IsX86 || IsX86_64) Res |= SanitizerKind::Function; if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsMIPS || IsArmArch || IsPowerPC64 || IsHexagon || IsLoongArch64 || IsRISCV64) Index: clang/lib/Driver/ToolChains/FreeBSD.cpp =================================================================== --- clang/lib/Driver/ToolChains/FreeBSD.cpp +++ clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -483,9 +483,8 @@ Res |= SanitizerKind::Leak; Res |= SanitizerKind::Thread; } - if (IsX86 || IsX86_64) { + if (IsAArch64 || IsX86 || IsX86_64) Res |= SanitizerKind::Function; - } if (IsAArch64 || IsX86 || IsX86_64) { Res |= SanitizerKind::SafeStack; Res |= SanitizerKind::Fuzzer; Index: clang/lib/CodeGen/TargetInfo.cpp =================================================================== --- clang/lib/CodeGen/TargetInfo.cpp +++ clang/lib/CodeGen/TargetInfo.cpp @@ -5644,6 +5644,12 @@ } return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + + llvm::Constant * + getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override { + // b .+8 + return llvm::ConstantInt::get(CGM.Int32Ty, 0x14000002); + } }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { Index: clang/docs/UndefinedBehaviorSanitizer.rst =================================================================== --- clang/docs/UndefinedBehaviorSanitizer.rst +++ clang/docs/UndefinedBehaviorSanitizer.rst @@ -100,8 +100,8 @@ 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 (Darwin/Linux, C++ and + AArch64/x86-32/x86-64 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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits