Skip to content

Commit c23135c

Browse files
-fsanitize=function: fix .subsections_via_symbols (#87527)
-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.
1 parent 01d9528 commit c23135c

File tree

4 files changed

+46
-19
lines changed

4 files changed

+46
-19
lines changed

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,9 @@ class AsmPrinter : public MachineFunctionPass {
868868
/// This method emits a comment next to header for the current function.
869869
virtual void emitFunctionHeaderComment();
870870

871+
/// This method emits prefix-like data before the current function.
872+
void emitFunctionPrefix(ArrayRef<const Constant *> Prefix);
873+
871874
/// Emit a blob of inline asm to the output streamer.
872875
void
873876
emitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,27 @@ void AsmPrinter::emitDebugValue(const MCExpr *Value, unsigned Size) const {
927927

928928
void AsmPrinter::emitFunctionHeaderComment() {}
929929

930+
void AsmPrinter::emitFunctionPrefix(ArrayRef<const Constant *> Prefix) {
931+
const Function &F = MF->getFunction();
932+
if (!MAI->hasSubsectionsViaSymbols()) {
933+
for (auto &C : Prefix)
934+
emitGlobalConstant(F.getParent()->getDataLayout(), C);
935+
return;
936+
}
937+
// Preserving prefix-like data on platforms which use subsections-via-symbols
938+
// is a bit tricky. Here we introduce a symbol for the prefix-like data
939+
// and use the .alt_entry attribute to mark the function's real entry point
940+
// as an alternative entry point to the symbol that precedes the function..
941+
OutStreamer->emitLabel(OutContext.createLinkerPrivateTempSymbol());
942+
943+
for (auto &C : Prefix) {
944+
emitGlobalConstant(F.getParent()->getDataLayout(), C);
945+
}
946+
947+
// Emit an .alt_entry directive for the actual function symbol.
948+
OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);
949+
}
950+
930951
/// EmitFunctionHeader - This method emits the header for the current
931952
/// function.
932953
void AsmPrinter::emitFunctionHeader() {
@@ -966,23 +987,8 @@ void AsmPrinter::emitFunctionHeader() {
966987
OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_Cold);
967988

968989
// Emit the prefix data.
969-
if (F.hasPrefixData()) {
970-
if (MAI->hasSubsectionsViaSymbols()) {
971-
// Preserving prefix data on platforms which use subsections-via-symbols
972-
// is a bit tricky. Here we introduce a symbol for the prefix data
973-
// and use the .alt_entry attribute to mark the function's real entry point
974-
// as an alternative entry point to the prefix-data symbol.
975-
MCSymbol *PrefixSym = OutContext.createLinkerPrivateTempSymbol();
976-
OutStreamer->emitLabel(PrefixSym);
977-
978-
emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
979-
980-
// Emit an .alt_entry directive for the actual function symbol.
981-
OutStreamer->emitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);
982-
} else {
983-
emitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
984-
}
985-
}
990+
if (F.hasPrefixData())
991+
emitFunctionPrefix({F.getPrefixData()});
986992

987993
// Emit KCFI type information before patchable-function-prefix nops.
988994
emitKCFITypeId(*MF);
@@ -1014,8 +1020,7 @@ void AsmPrinter::emitFunctionHeader() {
10141020

10151021
auto *PrologueSig = mdconst::extract<Constant>(MD->getOperand(0));
10161022
auto *TypeHash = mdconst::extract<Constant>(MD->getOperand(1));
1017-
emitGlobalConstant(F.getParent()->getDataLayout(), PrologueSig);
1018-
emitGlobalConstant(F.getParent()->getDataLayout(), TypeHash);
1023+
emitFunctionPrefix({PrologueSig, TypeHash});
10191024
}
10201025

10211026
if (isVerbose()) {

llvm/test/CodeGen/AArch64/func-sanitizer.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
2+
; RUN: llc -mtriple=arm64-apple-darwin < %s | FileCheck %s --check-prefix=MACHO
23

34
; CHECK-LABEL: .type _Z3funv,@function
45
; CHECK-NEXT: .word 3238382334 // 0xc105cafe
@@ -7,6 +8,14 @@
78
; CHECK-NEXT: // %bb.0:
89
; CHECK-NEXT: ret
910

11+
; MACHO: ltmp0:
12+
; MACHO-NEXT: .long 3238382334 ; 0xc105cafe
13+
; MACHO-NEXT: .long 42 ; 0x2a
14+
; MACHO-NEXT: .alt_entry __Z3funv
15+
; MACHO-NEXT: __Z3funv:
16+
; MACHO-NEXT: ; %bb.0:
17+
; MACHO-NEXT: ret
18+
1019
define dso_local void @_Z3funv() nounwind !func_sanitize !0 {
1120
ret void
1221
}

llvm/test/CodeGen/X86/func-sanitizer.ll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
2+
; RUN: llc -mtriple=x86_64-apple-darwin < %s | FileCheck %s --check-prefix=MACHO
23

34
; CHECK: .type _Z3funv,@function
45
; CHECK-NEXT: .long 3238382334 # 0xc105cafe
@@ -8,6 +9,15 @@
89
; CHECK-NEXT: # %bb.0:
910
; CHECK-NEXT: retq
1011

12+
; MACHO: ltmp0:
13+
; MACHO-NEXT: .long 3238382334 ## 0xc105cafe
14+
; MACHO-NEXT: .long 42 ## 0x2a
15+
; MACHO-NEXT: .alt_entry __Z3funv
16+
; MACHO-NEXT: __Z3funv:
17+
; MACHO-NEXT: .cfi_startproc
18+
; MACHO-NEXT: # %bb.0:
19+
; MACHO-NEXT: retq
20+
1121
define dso_local void @_Z3funv() !func_sanitize !0 {
1222
ret void
1323
}

0 commit comments

Comments
 (0)