From c7a57cdda643e397720daa35ea3b1c4b7ce42371 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 15 Mar 2017 04:18:16 +0000 Subject: [PATCH] Ensure that prefix data is preserved with subsections-via-symbols MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297804 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 19 ++++++++++++++++-- test/CodeGen/AArch64/prefixdata.ll | 29 +++++++++++++++++++++++++++ test/CodeGen/X86/prefixdata.ll | 27 +++++++++++++++++-------- 3 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 test/CodeGen/AArch64/prefixdata.ll diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 7099065a638..f02062b7377 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -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. diff --git a/test/CodeGen/AArch64/prefixdata.ll b/test/CodeGen/AArch64/prefixdata.ll new file mode 100644 index 00000000000..f62734c16e5 --- /dev/null +++ b/test/CodeGen/AArch64/prefixdata.ll @@ -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 diff --git a/test/CodeGen/X86/prefixdata.ll b/test/CodeGen/X86/prefixdata.ll index 9bb54a2a397..b62f48ddce2 100644 --- a/test/CodeGen/X86/prefixdata.ll +++ b/test/CodeGen/X86/prefixdata.ll @@ -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 -- 2.50.1