MaskRay created this revision.
MaskRay added reviewers: dmgreen, lenary, pcc, peter.smith.
Herald added subscribers: Enna1, hiraditya, kristof.beyls, emaste.
Herald added a project: All.
MaskRay requested review of this revision.
Herald added projects: clang, Sanitizers, LLVM.
Herald added subscribers: llvm-commits, Sanitizers, cfe-commits.

-fsanitize=function instrumented functions have two words preceding at the
function label: a signature and an indirect RTTI object.
The signature also serves as a branch instruction skipping the two words.

With this patch, clang -fsanitize=function correctly instrument aarch64
and aarch64_be target triples.

  _Z3funv:
    .word   335544322                    // signature
    .word   .L__llvm_rtti_proxy-_Z3funv  // indirect RTTI
  
  _Z6callerPFvvE:
    if the first word loaded from the function pointer is not 335544322, skip
    load the second word and dereference the indirect RTTI object, if not the 
expected typeinfo object, fail


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D148573

Files:
  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

Index: llvm/test/CodeGen/AArch64/func-sanitizer.ll
===================================================================
--- /dev/null
+++ 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}
Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ 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<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 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}
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,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 {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to