Index: lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -636,8 +636,18 @@ if (MAI->hasFunctionAlignment()) EmitAlignment(MF->getAlignment(), F); - if (MAI->hasDotTypeDotSizeDirective()) - OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction); + if (MAI->hasDotTypeDotSizeDirective()) { + // We can't treat symbols with prefix data as functions since these + // will be relocated via trampoline, which will break references to + // prefix data. This can be observed on ELF, and rectified by treating + // the symbol as object rather than function. + // + // For Mach-O, the use of MCSA_AltEntry is used to prevent the + // breaking linker from stripping the prefix data. + MCSymbolAttr attr = F->hasPrefixData() ? MCSA_ELF_TypeObject + : MCSA_ELF_TypeFunction; + OutStreamer->EmitSymbolAttribute(CurrentFnSym, attr); + } if (isVerbose()) { F->printAsOperand(OutStreamer->GetCommentOS(), Index: test/CodeGen/AArch64/prefixdata-symbol-type.ll =================================================================== --- /dev/null +++ test/CodeGen/AArch64/prefixdata-symbol-type.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=aarch64-pc-linux | FileCheck %s + +; functions with prefix data, should be of type +; object to prevent them being relocated through +; the PLT and making the prefix data inaccessable. +; CHECK: .type f,@object +define i32 @f() prefix i32 42 { + ret i32 0; +} + +; CHECK .type g,@function +define i32 @g() { + ret i32 0; +} \ No newline at end of file Index: test/CodeGen/ARM/prefixdata-symbol-type.ll =================================================================== --- /dev/null +++ test/CodeGen/ARM/prefixdata-symbol-type.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=armv7-pc-linux | FileCheck %s + +; functions with prefix data, should be of type +; object to prevent them being relocated through +; the PLT and making the prefix data inaccessable. +; CHECK: .type f,%object +define i32 @f() prefix i32 42 { + ret i32 0; +} + +; CHECK .type g,%function +define i32 @g() { + ret i32 0; +} \ No newline at end of file Index: test/CodeGen/X86/prefixdata-symbol-type.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/prefixdata-symbol-type.ll @@ -0,0 +1,14 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux | FileCheck %s + +; functions with prefix data, should be of type +; object to prevent them being relocated through +; the PLT and making the prefix data inaccessable. +; CHECK: .type f,@object +define i32 @f() prefix i32 42 { + ret i32 0; +} + +; CHECK .type g,@function +define i32 @g() { + ret i32 0; +} \ No newline at end of file