diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -5644,6 +5644,14 @@ } return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty); } + + llvm::Constant * + getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override { + unsigned Sig = getABIInfo().getDataLayout().isBigEndian() + ? 0x02000014 + : 0x14000002; // b .+8 + return llvm::ConstantInt::get(CGM.Int32Ty, Sig); + } }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { 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,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; 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,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) 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 --check-prefix=AARCH64 +// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefix=AARCH64_BE // CHECK: @[[PROXY:.*]] = private unnamed_addr constant ptr @_ZTIFvvE // CHECK: define{{.*}} void @_Z3funv() #0 !func_sanitize ![[FUNCSAN:.*]] { @@ -23,3 +25,8 @@ void caller(void (*f)()) { f(); } // CHECK: ![[FUNCSAN]] = !{i32 846595819, ptr @[[PROXY]]} + +/// .word 0x14000002 # b .+8 +// AARCH64: ![[#]] = !{i32 335544322, ptr @__llvm_rtti_proxy} +/// .word 0x02000014 # b .+8 +// AARCH64_BE: ![[#]] = !{i32 33554452, ptr @__llvm_rtti_proxy} 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/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1027,8 +1027,7 @@ // Emit the function prologue data for the indirect call sanitizer. if (const MDNode *MD = F.getMetadata(LLVMContext::MD_func_sanitize)) { - assert(TM.getTargetTriple().getArch() == Triple::x86 || - TM.getTargetTriple().getArch() == Triple::x86_64); + assert(TM.getTargetTriple().isAArch64() || TM.getTargetTriple().isX86()); assert(MD->getNumOperands() == 2); auto *PrologueSig = mdconst::extract(MD->getOperand(0)); 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,20 @@ +; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s + +; CHECK-LABEL: _Z3funv: +; CHECK-NEXT: .word 335544322 // 0x14000002 +; CHECK-NEXT: .word .L__llvm_rtti_proxy-_Z3funv +; CHECK-NEXT: // %bb.0: + +; 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}