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
This commit is contained in:
@@ -646,8 +646,23 @@ void AsmPrinter::EmitFunctionHeader() {
|
||||
}
|
||||
|
||||
// Emit the prefix data.
|
||||
if (F->hasPrefixData())
|
||||
EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
// Emit the CurrentFnSym. This is a virtual function to allow targets to
|
||||
// do their wild and crazy things as required.
|
||||
|
||||
29
llvm/test/CodeGen/AArch64/prefixdata.ll
Normal file
29
llvm/test/CodeGen/AArch64/prefixdata.ll
Normal file
@@ -0,0 +1,29 @@
|
||||
; RUN: llc < %s -mtriple=aarch64-apple-darwin | FileCheck --check-prefix=MACHO %s
|
||||
; RUN: llc < %s -mtriple=aarch64-pc-linux | FileCheck --check-prefix=ELF %s
|
||||
|
||||
@i = linkonce_odr global i32 1
|
||||
|
||||
; MACHO: ltmp0:
|
||||
; MACHO-NEXT: .long 1
|
||||
; MACHO-NEXT: .alt_entry _f
|
||||
; MACHO-NEXT: _f:
|
||||
; ELF: .type f,@function
|
||||
; ELF-NEXT: .word 1
|
||||
; ELF-NEXT: // 0x1
|
||||
; ELF-NEXT: f:
|
||||
define void @f() prefix i32 1 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; MACHO: ltmp1:
|
||||
; MACHO-NEXT: .quad _i
|
||||
; MACHO-NEXT: .alt_entry _g
|
||||
; MACHO-NEXT: _g:
|
||||
; ELF: .type g,@function
|
||||
; ELF-NEXT: .xword i
|
||||
; ELF-NEXT: g:
|
||||
define void @g() prefix i32* @i {
|
||||
ret void
|
||||
}
|
||||
|
||||
; MACHO: .subsections_via_symbols
|
||||
@@ -1,18 +1,29 @@
|
||||
; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck --check-prefix=MACHO %s
|
||||
; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck --check-prefix=ELF %s
|
||||
|
||||
@i = linkonce_odr global i32 1
|
||||
|
||||
; CHECK: .type f,@function
|
||||
; CHECK-NEXT: .long 1
|
||||
; CHECK-NEXT: # 0x1
|
||||
; CHECK-NEXT: f:
|
||||
; MACHO: ltmp0:
|
||||
; MACHO-NEXT: .long 1
|
||||
; MACHO-NEXT: .alt_entry _f
|
||||
; MACHO-NEXT: _f:
|
||||
; ELF: .type f,@function
|
||||
; ELF-NEXT: .long 1
|
||||
; ELF-NEXT: # 0x1
|
||||
; ELF-NEXT: f:
|
||||
define void @f() prefix i32 1 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: .type g,@function
|
||||
; CHECK-NEXT: .quad i
|
||||
; CHECK-NEXT: g:
|
||||
; MACHO: ltmp1:
|
||||
; MACHO-NEXT: .quad _i
|
||||
; MACHO-NEXT: .alt_entry _g
|
||||
; MACHO-NEXT: _g:
|
||||
; ELF: .type g,@function
|
||||
; ELF-NEXT: .quad i
|
||||
; ELF-NEXT: g:
|
||||
define void @g() prefix i32* @i {
|
||||
ret void
|
||||
}
|
||||
|
||||
; MACHO: .subsections_via_symbols
|
||||
|
||||
Reference in New Issue
Block a user