MaskRay created this revision.
MaskRay added reviewers: Sanitizers, nickdesaulniers.
Herald added subscribers: dexonsmith, hiraditya.
MaskRay requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.

The Linux kernel objtool diagnostic `call without frame pointer save/setup`
arise in multiple instrumentation passes (asan/tsan/gcov). With the mechanism
introduced in D100251 <https://reviews.llvm.org/D100251>, it's trivial to 
respect the command line
-m[no-]omit-leaf-frame-pointer/-f[no-]omit-frame-pointer, so let's do it.

Fix: https://github.com/ClangBuiltLinux/linux/issues/1236 (tsan)
Fix: https://github.com/ClangBuiltLinux/linux/issues/1238 (asan)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D101016

Files:
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/asan-frame-pointer.cpp
  llvm/include/llvm/IR/Module.h
  llvm/lib/IR/Function.cpp
  llvm/lib/IR/Module.cpp
  llvm/test/Instrumentation/AddressSanitizer/module-flags.ll
  llvm/test/Instrumentation/AddressSanitizer/uwtable.ll

Index: llvm/test/Instrumentation/AddressSanitizer/module-flags.ll
===================================================================
--- llvm/test/Instrumentation/AddressSanitizer/module-flags.ll
+++ llvm/test/Instrumentation/AddressSanitizer/module-flags.ll
@@ -10,12 +10,15 @@
   ret i32 %tmp
 }
 
-!llvm.module.flags = !{!0}
+!llvm.module.flags = !{!0, !1}
 
 ;; Due to -fasynchronous-unwind-tables.
 !0 = !{i32 7, !"uwtable", i32 1}
 
+;; Due to -fno-omit-frame-pointer.
+!1 = !{i32 7, !"frame-pointer", i32 2}
+
 ;; Set the uwtable attribute on ctor/dtor.
 ; CHECK: define internal void @asan.module_ctor() #[[#ATTR:]]
 ; CHECK: define internal void @asan.module_dtor() #[[#ATTR]]
-; CHECK: attributes #[[#ATTR]] = { nounwind uwtable }
+; CHECK: attributes #[[#ATTR]] = { nounwind uwtable "frame-pointer"="all" }
Index: llvm/lib/IR/Module.cpp
===================================================================
--- llvm/lib/IR/Module.cpp
+++ llvm/lib/IR/Module.cpp
@@ -676,6 +676,15 @@
 
 void Module::setUwtable() { addModuleFlag(ModFlagBehavior::Max, "uwtable", 1); }
 
+int Module::getFramePointer() const {
+  auto *Val = cast_or_null<ConstantAsMetadata>(getModuleFlag("frame-pointer"));
+  return Val ? cast<ConstantInt>(Val->getValue())->getZExtValue() : 0;
+}
+
+void Module::setFramePointer(int V) {
+  addModuleFlag(ModFlagBehavior::Max, "frame-pointer", V);
+}
+
 void Module::setSDKVersion(const VersionTuple &V) {
   SmallVector<unsigned, 3> Entries;
   Entries.push_back(V.getMajor());
Index: llvm/lib/IR/Function.cpp
===================================================================
--- llvm/lib/IR/Function.cpp
+++ llvm/lib/IR/Function.cpp
@@ -335,8 +335,23 @@
                                           unsigned AddrSpace, const Twine &N,
                                           Module *M) {
   auto *F = new Function(Ty, Linkage, AddrSpace, N, M);
+  AttrBuilder B;
   if (M->getUwtable())
-    F->addAttribute(AttributeList::FunctionIndex, Attribute::UWTable);
+    B.addAttribute(Attribute::UWTable);
+  switch (M->getFramePointer()) {
+  case 0:
+    // 0 ("none") is the default.
+    break;
+  case 1:
+    B.addAttribute("frame-pointer", "non-leaf");
+    break;
+  case 2:
+    B.addAttribute("frame-pointer", "all");
+    break;
+  default:
+    llvm_unreachable("unknown \"frame-pointer\" value");
+  }
+  F->addAttributes(AttributeList::FunctionIndex, B);
   return F;
 }
 
Index: llvm/include/llvm/IR/Module.h
===================================================================
--- llvm/include/llvm/IR/Module.h
+++ llvm/include/llvm/IR/Module.h
@@ -890,6 +890,11 @@
   bool getUwtable() const;
   void setUwtable();
 
+  /// Get/set whether synthesized functions should get the "frame-pointer"
+  /// attribute.
+  int getFramePointer() const;
+  void setFramePointer(int V);
+
   /// @name Utility functions for querying and setting the build SDK version
   /// @{
 
Index: clang/test/CodeGen/asan-frame-pointer.cpp
===================================================================
--- /dev/null
+++ clang/test/CodeGen/asan-frame-pointer.cpp
@@ -0,0 +1,19 @@
+/// -mframe-pointer=none sets the module flag "frame-pointer" (merge behavior: max).
+/// asan synthesized ctor/dtor get the "frame-pointer" function attribute if not zero (default).
+// RUN: %clang_cc1 -emit-llvm -fsanitize=address -mframe-pointer=none %s -o - | FileCheck %s --check-prefix=NONE
+// RUN: %clang_cc1 -emit-llvm -fsanitize=address -mframe-pointer=non-leaf %s -o - | FileCheck %s --check-prefix=NONLEAF
+// RUN: %clang_cc1 -emit-llvm -fsanitize=address -mframe-pointer=all %s -o - | FileCheck %s --check-prefix=ALL
+
+int global;
+
+// NONE: define internal void @asan.module_ctor() #[[#ATTR:]] {
+// NONE: define internal void @asan.module_dtor() #[[#ATTR]] {
+// NONE: attributes #[[#ATTR]] = { nounwind }
+
+// NONLEAF: define internal void @asan.module_ctor() #[[#ATTR:]] {
+// NONLEAF: define internal void @asan.module_dtor() #[[#ATTR]] {
+// NONLEAF: attributes #[[#ATTR]] = { nounwind "frame-pointer"="non-leaf" }
+
+// ALL: define internal void @asan.module_ctor() #[[#ATTR:]] {
+// ALL: define internal void @asan.module_dtor() #[[#ATTR]] {
+// ALL: attributes #[[#ATTR]] = { nounwind "frame-pointer"="all" }
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -744,6 +744,18 @@
   if (CodeGenOpts.UnwindTables)
     getModule().setUwtable();
 
+  switch (CodeGenOpts.getFramePointer()) {
+  case CodeGenOptions::FramePointerKind::None:
+    // 0 is the default.
+    break;
+  case CodeGenOptions::FramePointerKind::NonLeaf:
+    getModule().setFramePointer(1);
+    break;
+  case CodeGenOptions::FramePointerKind::All:
+    getModule().setFramePointer(2);
+    break;
+  }
+
   SimplifyPersonality();
 
   if (getCodeGenOpts().EmitDeclMetadata)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to