eugenis created this revision.
Herald added subscribers: hiraditya, kristof.beyls, srhines, aemerson.

Set target_cpu and target_features attributes on __cfi_check_fail and
__cfi_check. Make cfi_check use Thumb encoding on ARM target.


https://reviews.llvm.org/D37656

Files:
  clang/lib/CodeGen/CGExpr.cpp
  clang/test/CodeGen/cfi-check-thumb.c
  llvm/lib/Transforms/IPO/CrossDSOCFI.cpp
  llvm/test/Transforms/CrossDSOCFI/thumb.ll

Index: llvm/test/Transforms/CrossDSOCFI/thumb.ll
===================================================================
--- llvm/test/Transforms/CrossDSOCFI/thumb.ll
+++ /dev/null
@@ -1,22 +0,0 @@
-; RUN: opt -mtriple=armv7-linux-android -S -cross-dso-cfi < %s | FileCheck --check-prefix=THUMB %s
-; RUN: opt -mtriple=thumbv7-linux-android -S -cross-dso-cfi < %s | FileCheck --check-prefix=THUMB %s
-; RUN: opt -mtriple=i386-linux -S -cross-dso-cfi < %s | FileCheck --check-prefix=NOTHUMB %s
-; RUN: opt -mtriple=x86_64-linux -S -cross-dso-cfi < %s | FileCheck --check-prefix=NOTHUMB %s
-
-target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
-
-define signext i8 @f() !type !0 !type !1 {
-entry:
-  ret i8 1
-}
-
-!llvm.module.flags = !{!2}
-
-!0 = !{i64 0, !"_ZTSFcvE"}
-!1 = !{i64 0, i64 111}
-!2 = !{i32 4, !"Cross-DSO CFI", i32 1}
-
-; THUMB: define void @__cfi_check({{.*}} #[[A:.*]] align 4096
-; THUMB: attributes #[[A]] = { {{.*}}"target-features"="+thumb-mode"
-
-; NOTHUMB: define void @__cfi_check({{.*}} align 4096
Index: llvm/lib/Transforms/IPO/CrossDSOCFI.cpp
===================================================================
--- llvm/lib/Transforms/IPO/CrossDSOCFI.cpp
+++ llvm/lib/Transforms/IPO/CrossDSOCFI.cpp
@@ -117,10 +117,6 @@
   F->deleteBody();
   F->setAlignment(4096);
 
-  Triple T(M.getTargetTriple());
-  if (T.isARM() || T.isThumb())
-    F->addFnAttr("target-features", "+thumb-mode");
-
   auto args = F->arg_begin();
   Value &CallSiteTypeId = *(args++);
   CallSiteTypeId.setName("CallSiteTypeId");
Index: clang/test/CodeGen/cfi-check-thumb.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/cfi-check-thumb.c
@@ -0,0 +1,18 @@
+// Test that __cfi_check and __cfi_check_fail have common attributes and calling convention.
+// Also __cfi_check is always using Thumb encoding.
+// RUN: %clang_cc1 -triple arm-unknown-linux -O0 -fsanitize-cfi-cross-dso \
+// RUN:     -fsanitize=cfi-vcall \
+// RUN:     -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,CHECK-ARM %s
+//
+// RUN: %clang_cc1 -triple thumb-unknown-linux -O0 -fsanitize-cfi-cross-dso \
+// RUN:     -fsanitize=cfi-vcall \
+// RUN:     -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,CHECK-THUMB %s
+//
+// REQUIRES: arm-registered-target
+
+// CHECK-ARM: define weak_odr hidden void @__cfi_check_fail(i8*, i8*) #[[ARM:.*]] {
+// CHECK-THUMB: define weak_odr hidden void @__cfi_check_fail(i8*, i8*) #[[THUMB:.*]] {
+// CHECK: define weak void @__cfi_check(i64, i8*, i8*) #[[THUMB:.*]] {
+
+// CHECK-ARM: attributes #[[ARM]] = {{.*}}"target-features"="{{.*}}-thumb-mode
+// CHECK: attributes #[[THUMB]] = {{.*}}"target-features"="{{.*}}+thumb-mode
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -2912,6 +2912,33 @@
   EmitBlock(Cont);
 }
 
+static void AddTargetAttributes(llvm::AttrBuilder &Builder,
+                                CodeGenFunction &CGF, llvm::Function *F,
+                                bool ForceThumb) {
+  StringRef TargetCPU = CGF.getTarget().getTargetOpts().CPU;
+  if (TargetCPU != "")
+    Builder.addAttribute("target-cpu", TargetCPU);
+
+  std::vector<std::string> &DefaultFeatures =
+      CGF.getTarget().getTargetOpts().Features;
+  const auto &Triple = CGF.getTarget().getTriple();
+  SmallVector<StringRef, 6> Features;
+  Features.reserve(DefaultFeatures.size() + ForceThumb);
+  if (ForceThumb && (Triple.isARM() || Triple.isThumb())) {
+    for (auto &S : DefaultFeatures)
+      if (S != "-thumb-mode" && S != "+thumb-mode")
+        Features.push_back(S);
+    Features.push_back("+thumb-mode");
+  } else {
+    for (auto &S : DefaultFeatures)
+      Features.push_back(S);
+  }
+
+  std::sort(Features.begin(), Features.end());
+  Builder.addAttribute("target-features",
+                       llvm::join(Features.begin(), Features.end(), ","));
+}
+
 // Emit a stub for __cfi_check function so that the linker knows about this
 // symbol in LTO mode.
 void CodeGenFunction::EmitCfiCheckStub() {
@@ -2928,6 +2955,15 @@
   llvm::CallInst::Create(
       llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::trap), "", BB);
   llvm::ReturnInst::Create(Ctx, nullptr, BB);
+
+  // Set default target-cpu and target-features, but force thumb encoding if
+  // applicable. Note that we don't want the whole set of default function
+  // attributes as SetLLVMFunctionAttributes sets. In particular, __cfi_check
+  // must use the default calling convention for the platform. ABI-changing
+  // flags like -mhard-float should not affect __cfi_check.
+  llvm::AttrBuilder FuncAttrs;
+  AddTargetAttributes(FuncAttrs, *this, F, /*ForceThumb*/ true);
+  F->addAttributes(llvm::AttributeList::FunctionIndex, FuncAttrs);
 }
 
 // This function is basically a switch over the CFI failure kind, which is
@@ -3011,6 +3047,11 @@
   }
 
   FinishFunction();
+
+  llvm::AttrBuilder FuncAttrs;
+  AddTargetAttributes(FuncAttrs, *this, F, /*ForceThumb*/ false);
+  F->addAttributes(llvm::AttributeList::FunctionIndex, FuncAttrs);
+
   // The only reference to this function will be created during LTO link.
   // Make sure it survives until then.
   CGM.addUsedGlobal(F);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to