Skip to content

Commit 7f6e2c9

Browse files
committed
Ensure that prefix data is preserved with subsections-via-symbols
On MachO platforms that use subsections-via-symbols dead code stripping will drop prefix data. Unfortunately there is no great way to convey the relationship between a function and its prefix data to the linker. We are forced to use a bit of a hack: we give the prefix data it’s own symbol, and mark the actual function entry an .alt_entry. Patch by Moritz Angermann! Differential Revision: https://reviews.llvm.org/D30770 llvm-svn: 297804
1 parent 3b4e29b commit 7f6e2c9

File tree

3 files changed

+65
-10
lines changed

3 files changed

+65
-10
lines changed

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,8 +646,23 @@ void AsmPrinter::EmitFunctionHeader() {
646646
}
647647

648648
// Emit the prefix data.
649-
if (F->hasPrefixData())
650-
EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData());
649+
if (F->hasPrefixData()) {
650+
if (MAI->hasSubsectionsViaSymbols()) {
651+
// Preserving prefix data on platforms which use subsections-via-symbols
652+
// is a bit tricky. Here we introduce a symbol for the prefix data
653+
// and use the .alt_entry attribute to mark the function's real entry point
654+
// as an alternative entry point to the prefix-data symbol.
655+
MCSymbol *PrefixSym = OutContext.createLinkerPrivateTempSymbol();
656+
OutStreamer->EmitLabel(PrefixSym);
657+
658+
EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData());
659+
660+
// Emit an .alt_entry directive for the actual function symbol.
661+
OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);
662+
} else {
663+
EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData());
664+
}
665+
}
651666

652667
// Emit the CurrentFnSym. This is a virtual function to allow targets to
653668
// do their wild and crazy things as required.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
; RUN: llc < %s -mtriple=aarch64-apple-darwin | FileCheck --check-prefix=MACHO %s
2+
; RUN: llc < %s -mtriple=aarch64-pc-linux | FileCheck --check-prefix=ELF %s
3+
4+
@i = linkonce_odr global i32 1
5+
6+
; MACHO: ltmp0:
7+
; MACHO-NEXT: .long 1
8+
; MACHO-NEXT: .alt_entry _f
9+
; MACHO-NEXT: _f:
10+
; ELF: .type f,@function
11+
; ELF-NEXT: .word 1
12+
; ELF-NEXT: // 0x1
13+
; ELF-NEXT: f:
14+
define void @f() prefix i32 1 {
15+
ret void
16+
}
17+
18+
; MACHO: ltmp1:
19+
; MACHO-NEXT: .quad _i
20+
; MACHO-NEXT: .alt_entry _g
21+
; MACHO-NEXT: _g:
22+
; ELF: .type g,@function
23+
; ELF-NEXT: .xword i
24+
; ELF-NEXT: g:
25+
define void @g() prefix i32* @i {
26+
ret void
27+
}
28+
29+
; MACHO: .subsections_via_symbols

llvm/test/CodeGen/X86/prefixdata.ll

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,29 @@
1-
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
1+
; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck --check-prefix=MACHO %s
2+
; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck --check-prefix=ELF %s
23

34
@i = linkonce_odr global i32 1
45

5-
; CHECK: .type f,@function
6-
; CHECK-NEXT: .long 1
7-
; CHECK-NEXT: # 0x1
8-
; CHECK-NEXT: f:
6+
; MACHO: ltmp0:
7+
; MACHO-NEXT: .long 1
8+
; MACHO-NEXT: .alt_entry _f
9+
; MACHO-NEXT: _f:
10+
; ELF: .type f,@function
11+
; ELF-NEXT: .long 1
12+
; ELF-NEXT: # 0x1
13+
; ELF-NEXT: f:
914
define void @f() prefix i32 1 {
1015
ret void
1116
}
1217

13-
; CHECK: .type g,@function
14-
; CHECK-NEXT: .quad i
15-
; CHECK-NEXT: g:
18+
; MACHO: ltmp1:
19+
; MACHO-NEXT: .quad _i
20+
; MACHO-NEXT: .alt_entry _g
21+
; MACHO-NEXT: _g:
22+
; ELF: .type g,@function
23+
; ELF-NEXT: .quad i
24+
; ELF-NEXT: g:
1625
define void @g() prefix i32* @i {
1726
ret void
1827
}
28+
29+
; MACHO: .subsections_via_symbols

0 commit comments

Comments
 (0)