[llvm] -fsanitize=function: fix .subsections_via_symbols (PR #87527)

Leonard Grey via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 8 08:17:00 PDT 2024


https://github.com/speednoisemovement updated https://github.com/llvm/llvm-project/pull/87527

>From 283891886112fffed91cffd0fcf34d16e75f01dd Mon Sep 17 00:00:00 2001
From: Leonard Grey <lgrey at chromium.org>
Date: Tue, 2 Apr 2024 16:31:02 -0400
Subject: [PATCH 1/2] -fsanitize=function: fix .subsections_via_symbols

---
 llvm/include/llvm/CodeGen/AsmPrinter.h      |  3 ++
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp  | 43 +++++++++++++--------
 llvm/test/CodeGen/AArch64/func-sanitizer.ll |  9 +++++
 llvm/test/CodeGen/X86/func-sanitizer.ll     | 10 +++++
 4 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index a7fbf4aeb74494..f5abea8342d587 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -868,6 +868,9 @@ class AsmPrinter : public MachineFunctionPass {
   /// This method emits a comment next to header for the current function.
   virtual void emitFunctionHeaderComment();
 
+  /// This method emits prefix-like data before the current function.
+  void emitFunctionPrefix(const SmallVector<const Constant *, 1> &Prefix);
+
   /// Emit a blob of inline asm to the output streamer.
   void
   emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 293bb5a3c6f6eb..bb6994b96288ed 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -927,6 +927,30 @@ void AsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {
 
 void AsmPrinter::emitFunctionHeaderComment() {}
 
+void AsmPrinter::emitFunctionPrefix(
+    const SmallVector<const Constant *, 1> &Prefix) {
+  const Function &F = MF->getFunction();
+  if (!MAI->hasSubsectionsViaSymbols()) {
+    for (auto &C : Prefix) {
+      emitGlobalConstant(F.getParent()->getDataLayout(), C);
+    }
+    return;
+  }
+  // Preserving prefix data on platforms which use subsections-via-symbols
+  // is a bit tricky. Here we introduce a symbol for the prefix data
+  // and use the .alt_entry attribute to mark the function's real entry point
+  // as an alternative entry point to the prefix-data symbol.
+  MCSymbol *PrefixSym = OutContext.createLinkerPrivateTempSymbol();
+  OutStreamer->emitLabel(PrefixSym);
+
+  for (auto &C : Prefix) {
+    emitGlobalConstant(F.getParent()->getDataLayout(), C);
+  }
+
+  // Emit an .alt_entry directive for the actual function symbol.
+  OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);
+}
+
 /// EmitFunctionHeader - This method emits the header for the current
 /// function.
 void AsmPrinter::emitFunctionHeader() {
@@ -967,21 +991,7 @@ void AsmPrinter::emitFunctionHeader() {
 
   // Emit the prefix data.
   if (F.hasPrefixData()) {
-    if (MAI->hasSubsectionsViaSymbols()) {
-      // Preserving prefix data on platforms which use subsections-via-symbols
-      // is a bit tricky. Here we introduce a symbol for the prefix data
-      // and use the .alt_entry attribute to mark the function's real entry point
-      // as an alternative entry point to the prefix-data symbol.
-      MCSymbol *PrefixSym = OutContext.createLinkerPrivateTempSymbol();
-      OutStreamer->emitLabel(PrefixSym);
-
-      emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
-
-      // Emit an .alt_entry directive for the actual function symbol.
-      OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);
-    } else {
-      emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
-    }
+    emitFunctionPrefix({F.getPrefixData()});
   }
 
   // Emit KCFI type information before patchable-function-prefix nops.
@@ -1014,8 +1024,7 @@ void AsmPrinter::emitFunctionHeader() {
 
     auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));
     auto *TypeHash = mdconst::extract<Constant>(MD->getOperand(1));
-    emitGlobalConstant(F.getParent()->getDataLayout(), PrologueSig);
-    emitGlobalConstant(F.getParent()->getDataLayout(), TypeHash);
+    emitFunctionPrefix({PrologueSig, TypeHash});
   }
 
   if (isVerbose()) {
diff --git a/llvm/test/CodeGen/AArch64/func-sanitizer.ll b/llvm/test/CodeGen/AArch64/func-sanitizer.ll
index 89f23e7ed80e88..eb059a7d36b44c 100644
--- a/llvm/test/CodeGen/AArch64/func-sanitizer.ll
+++ b/llvm/test/CodeGen/AArch64/func-sanitizer.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: llc -mtriple=arm64-apple-darwin < %s | FileCheck %s --check-prefix=MACHO
 
 ; CHECK-LABEL: .type _Z3funv, at function
 ; CHECK-NEXT:    .word   3238382334  // 0xc105cafe
@@ -7,6 +8,14 @@
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ret
 
+; MACHO: ltmp0
+; MACHO-NEXT:   .long 3238382334 ; 0xc105cafe
+; MACHO-NEXT:   .long 42 ; 0x2a
+; MACHO-NEXT:   .alt_entry __Z3funv
+; MACHO-NEXT:   __Z3funv:
+; MACHO-NEXT:   ; %bb.0:
+; MACHO-NEXT:   ret
+
 define dso_local void @_Z3funv() nounwind !func_sanitize !0 {
   ret void
 }
diff --git a/llvm/test/CodeGen/X86/func-sanitizer.ll b/llvm/test/CodeGen/X86/func-sanitizer.ll
index b421cb53ddfecf..016cc0f07db796 100644
--- a/llvm/test/CodeGen/X86/func-sanitizer.ll
+++ b/llvm/test/CodeGen/X86/func-sanitizer.ll
@@ -1,4 +1,5 @@
 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-apple-darwin < %s | FileCheck %s --check-prefix=MACHO
 
 ; CHECK:      .type _Z3funv, at function
 ; CHECK-NEXT:   .long   3238382334  # 0xc105cafe
@@ -8,6 +9,15 @@
 ; CHECK-NEXT:   # %bb.0:
 ; CHECK-NEXT:   retq
 
+; MACHO:      ltmp0
+; MACHO-NEXT:  .long 3238382334 ## 0xc105cafe
+; MACHO-NEXT:  .long 42 ## 0x2a
+; MACHO-NEXT:  .alt_entry __Z3funv
+; MACHO-NEXT: __Z3funv:
+; MACHO-NEXT:  .cfi_startproc
+; MACHO-NEXT:  # %bb.0:
+; MACHO-NEXT:  retq
+
 define dso_local void @_Z3funv() !func_sanitize !0 {
   ret void
 }

>From 90db989814f94a4da8f34bd09c3838c91a0d0679 Mon Sep 17 00:00:00 2001
From: Leonard Grey <lgrey at chromium.org>
Date: Mon, 8 Apr 2024 10:50:55 -0400
Subject: [PATCH 2/2] Use ArrayRef; style

---
 llvm/include/llvm/CodeGen/AsmPrinter.h      |  2 +-
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp  | 18 +++++++-----------
 llvm/test/CodeGen/AArch64/func-sanitizer.ll |  2 +-
 llvm/test/CodeGen/X86/func-sanitizer.ll     |  2 +-
 4 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index f5abea8342d587..81c3e4be95e9ff 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -869,7 +869,7 @@ class AsmPrinter : public MachineFunctionPass {
   virtual void emitFunctionHeaderComment();
 
   /// This method emits prefix-like data before the current function.
-  void emitFunctionPrefix(const SmallVector<const Constant *, 1> &Prefix);
+  void emitFunctionPrefix(ArrayRef<const Constant *> Prefix);
 
   /// Emit a blob of inline asm to the output streamer.
   void
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index bb6994b96288ed..721d144d7f4c67 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -927,21 +927,18 @@ void AsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {
 
 void AsmPrinter::emitFunctionHeaderComment() {}
 
-void AsmPrinter::emitFunctionPrefix(
-    const SmallVector<const Constant *, 1> &Prefix) {
+void AsmPrinter::emitFunctionPrefix(ArrayRef<const Constant *> Prefix) {
   const Function &F = MF->getFunction();
   if (!MAI->hasSubsectionsViaSymbols()) {
-    for (auto &C : Prefix) {
+    for (auto &C : Prefix)
       emitGlobalConstant(F.getParent()->getDataLayout(), C);
-    }
     return;
   }
-  // Preserving prefix data on platforms which use subsections-via-symbols
-  // is a bit tricky. Here we introduce a symbol for the prefix data
+  // Preserving prefix-like data on platforms which use subsections-via-symbols
+  // is a bit tricky. Here we introduce a symbol for the prefix-like data
   // and use the .alt_entry attribute to mark the function's real entry point
-  // as an alternative entry point to the prefix-data symbol.
-  MCSymbol *PrefixSym = OutContext.createLinkerPrivateTempSymbol();
-  OutStreamer->emitLabel(PrefixSym);
+  // as an alternative entry point to the symbol that precedes the function..
+  OutStreamer->emitLabel(OutContext.createLinkerPrivateTempSymbol());
 
   for (auto &C : Prefix) {
     emitGlobalConstant(F.getParent()->getDataLayout(), C);
@@ -990,9 +987,8 @@ void AsmPrinter::emitFunctionHeader() {
     OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Cold);
 
   // Emit the prefix data.
-  if (F.hasPrefixData()) {
+  if (F.hasPrefixData())
     emitFunctionPrefix({F.getPrefixData()});
-  }
 
   // Emit KCFI type information before patchable-function-prefix nops.
   emitKCFITypeId(*MF);
diff --git a/llvm/test/CodeGen/AArch64/func-sanitizer.ll b/llvm/test/CodeGen/AArch64/func-sanitizer.ll
index eb059a7d36b44c..de83d70a5784ab 100644
--- a/llvm/test/CodeGen/AArch64/func-sanitizer.ll
+++ b/llvm/test/CodeGen/AArch64/func-sanitizer.ll
@@ -8,7 +8,7 @@
 ; CHECK-NEXT:  // %bb.0:
 ; CHECK-NEXT:    ret
 
-; MACHO: ltmp0
+; MACHO:      ltmp0:
 ; MACHO-NEXT:   .long 3238382334 ; 0xc105cafe
 ; MACHO-NEXT:   .long 42 ; 0x2a
 ; MACHO-NEXT:   .alt_entry __Z3funv
diff --git a/llvm/test/CodeGen/X86/func-sanitizer.ll b/llvm/test/CodeGen/X86/func-sanitizer.ll
index 016cc0f07db796..71f062ae2f8cd9 100644
--- a/llvm/test/CodeGen/X86/func-sanitizer.ll
+++ b/llvm/test/CodeGen/X86/func-sanitizer.ll
@@ -9,7 +9,7 @@
 ; CHECK-NEXT:   # %bb.0:
 ; CHECK-NEXT:   retq
 
-; MACHO:      ltmp0
+; MACHO:      ltmp0:
 ; MACHO-NEXT:  .long 3238382334 ## 0xc105cafe
 ; MACHO-NEXT:  .long 42 ## 0x2a
 ; MACHO-NEXT:  .alt_entry __Z3funv



More information about the llvm-commits mailing list