[PATCH] D111757: [CFI] Add a module flag to allow custom section on globals with !type metadata when not doing CFI

Kuba (Brecka) Mracek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 13 14:51:00 PDT 2021


kubamracek created this revision.
kubamracek added reviewers: pcc, tejohnson, eugenis, MaskRay, fhahn.
kubamracek added a project: LLVM.
Herald added subscribers: ormris, hiraditya.
kubamracek requested review of this revision.

See the added testcase -- the problem happens when trying to apply VFE during LTO, but without CFI at all, and when having a custom section on a vtable global. In that case LowerTypeTestsPass rejects the IR because it enforces that all !type-having globals must not specify a custom section. However, in a non-CFI compilation, this requirement is too strict, using !type metadata for VFE does not have any such requirement.

This diff adds a module flag, "No CFI Section Enforcement", that allows custom sections on globals with !type metadata, and basically is a way of informing LowerTypeTestsPass that the compilation is not doing CFI. Suggestions for alternative solutions welcome!


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D111757

Files:
  llvm/lib/Transforms/IPO/LowerTypeTests.cpp
  llvm/test/Transforms/GlobalDCE/virtual-functions-sections.ll


Index: llvm/test/Transforms/GlobalDCE/virtual-functions-sections.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/GlobalDCE/virtual-functions-sections.ll
@@ -0,0 +1,32 @@
+; RUN: opt < %s -globaldce -lowertypetests -lowertypetests-summary-action=export -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+declare { i8*, i1 } @llvm.type.checked.load(i8*, i32, metadata)
+
+ at vtable = internal unnamed_addr constant { [2 x i8*] } { [2 x i8*] [
+  i8* bitcast (void ()* @vfunc1_live to i8*),
+  i8* bitcast (void ()* @vfunc2_dead to i8*)
+]}, align 8, !type !0, !type !1, !vcall_visibility !{i64 2}, section "my_custom_section"
+!0 = !{i64 0, !"vfunc1.type"}
+!1 = !{i64 8, !"vfunc2.type"}
+
+define internal void @vfunc1_live() {
+  ; CHECK: define internal void @vfunc1_live(
+  ret void
+}
+
+define internal void @vfunc2_dead() {
+  ; CHECK-NOT: define internal void @vfunc2_dead(
+  ret void
+}
+
+define void @main() {
+  %1 = ptrtoint { [2 x i8*] }* @vtable to i64 ; to keep @vtable alive
+  %2 = tail call { i8*, i1 } @llvm.type.checked.load(i8* null, i32 0, metadata !"vfunc1.type")
+  ret void
+}
+
+!998 = !{i32 1, !"Virtual Function Elim", i32 1}
+!999 = !{i32 1, !"No CFI Section Enforcement", i32 1}
+!llvm.module.flags = !{!998, !999}
Index: llvm/lib/Transforms/IPO/LowerTypeTests.cpp
===================================================================
--- llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -474,7 +474,8 @@
   void createJumpTableEntry(raw_ostream &AsmOS, raw_ostream &ConstraintOS,
                             Triple::ArchType JumpTableArch,
                             SmallVectorImpl<Value *> &AsmArgs, Function *Dest);
-  void verifyTypeMDNode(GlobalObject *GO, MDNode *Type);
+  void verifyTypeMDNode(GlobalObject *GO, MDNode *Type,
+                        bool NoCfiSectionEnforcement);
   void buildBitSetsFromFunctions(ArrayRef<Metadata *> TypeIds,
                                  ArrayRef<GlobalTypeMember *> Functions);
   void buildBitSetsFromFunctionsNative(ArrayRef<Metadata *> TypeIds,
@@ -1186,13 +1187,14 @@
   }
 }
 
-void LowerTypeTestsModule::verifyTypeMDNode(GlobalObject *GO, MDNode *Type) {
+void LowerTypeTestsModule::verifyTypeMDNode(GlobalObject *GO, MDNode *Type,
+                                            bool NoCfiSectionEnforcement) {
   if (Type->getNumOperands() != 2)
     report_fatal_error("All operands of type metadata must have 2 elements");
 
   if (GO->isThreadLocal())
     report_fatal_error("Bit set element may not be thread-local");
-  if (isa<GlobalVariable>(GO) && GO->hasSection())
+  if (isa<GlobalVariable>(GO) && GO->hasSection() && !NoCfiSectionEnforcement)
     report_fatal_error(
         "A member of a type identifier may not have an explicit section");
 
@@ -2007,6 +2009,9 @@
     }
   }
 
+  const bool NoCfiSectionEnforcement =
+      M.getModuleFlag("No CFI Section Enforcement") != nullptr;
+
   DenseMap<GlobalObject *, GlobalTypeMember *> GlobalTypeMembers;
   for (GlobalObject &GO : M.global_objects()) {
     if (isa<GlobalVariable>(GO) && GO.isDeclarationForLinker())
@@ -2037,7 +2042,7 @@
                                          IsExported, Types);
     GlobalTypeMembers[&GO] = GTM;
     for (MDNode *Type : Types) {
-      verifyTypeMDNode(&GO, Type);
+      verifyTypeMDNode(&GO, Type, NoCfiSectionEnforcement);
       auto &Info = TypeIdInfo[Type->getOperand(1)];
       Info.UniqueId = ++CurUniqueId;
       Info.RefGlobals.push_back(GTM);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D111757.379526.patch
Type: text/x-patch
Size: 3588 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20211013/66556c17/attachment.bin>


More information about the llvm-commits mailing list