Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

-fsanitize=function: fix .subsections_via_symbols #87527

Merged
merged 2 commits into from
Apr 8, 2024

Conversation

speednoisemovement
Copy link
Contributor

-fsanitize=function emits a signature and function hash before a function. Similar to 7f6e2c9, these can be sheared off when .subsections_via_symbols is used.

This change uses the same technique 7f6e2c9 introduced for prefixes: emitting a symbol for the metadata, then marking the actual function entry as an .alt_entry symbol.

@llvmbot
Copy link
Collaborator

llvmbot commented Apr 3, 2024

@llvm/pr-subscribers-backend-aarch64

@llvm/pr-subscribers-backend-x86

Author: Leonard Grey (speednoisemovement)

Changes

-fsanitize=function emits a signature and function hash before a function. Similar to 7f6e2c9, these can be sheared off when .subsections_via_symbols is used.

This change uses the same technique 7f6e2c9 introduced for prefixes: emitting a symbol for the metadata, then marking the actual function entry as an .alt_entry symbol.


Full diff: https://github.com/llvm/llvm-project/pull/87527.diff

4 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/AsmPrinter.h (+3)
  • (modified) llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (+26-17)
  • (modified) llvm/test/CodeGen/AArch64/func-sanitizer.ll (+9)
  • (modified) llvm/test/CodeGen/X86/func-sanitizer.ll (+10)
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,@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,@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
 }

@@ -7,6 +8,14 @@
; CHECK-NEXT: // %bb.0:
; CHECK-NEXT: ret

; MACHO: ltmp0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

; MACHO: ltmp0:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -8,6 +9,15 @@
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: retq

; MACHO: ltmp0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

; MACHO: ltmp0:

add a colon to ensure we are testing a label

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

const Function &F = MF->getFunction();
if (!MAI->hasSubsectionsViaSymbols()) {
for (auto &C : Prefix) {
emitGlobalConstant(F.getParent()->getDataLayout(), C);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

OutStreamer->emitLabel(PrefixSym);

for (auto &C : Prefix) {
emitGlobalConstant(F.getParent()->getDataLayout(), C);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

} else {
emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
}
emitFunctionPrefix({F.getPrefixData()});
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove braces

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return;
}
// Preserving prefix data on platforms which use subsections-via-symbols
// is a bit tricky. Here we introduce a symbol for the prefix data
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment about "prefix data" should be adjusted

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// 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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OutStreamer->emitLabel(OutContext.createLinkerPrivateTempSymbol());

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@speednoisemovement speednoisemovement merged commit c23135c into llvm:main Apr 8, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants