From d5d3e188f068941b8ea43e90c3aacc6ca692ad02 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 29 Apr 2014 10:06:10 +0000 Subject: [PATCH] X86: emit hidden stubs into a proper non_lazy_symbol_pointer section. rdar://problem/16660411 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207518 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86AsmPrinter.cpp | 66 +++++++++++++++-------------- test/CodeGen/X86/indirect-hidden.ll | 43 +++++++++++++++++++ 2 files changed, 78 insertions(+), 31 deletions(-) create mode 100644 test/CodeGen/X86/indirect-hidden.ll diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index c0c6f2148f5..fd2cc7a3dc6 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -527,6 +527,30 @@ void X86AsmPrinter::EmitStartOfAsmFile(Module &M) { } } +static void +emitNonLazySymbolPointer(MCStreamer &OutStreamer, MCSymbol *StubLabel, + MachineModuleInfoImpl::StubValueTy &MCSym) { + // L_foo$stub: + OutStreamer.EmitLabel(StubLabel); + // .indirect_symbol _foo + OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), MCSA_IndirectSymbol); + + if (MCSym.getInt()) + // External to current translation unit. + OutStreamer.EmitIntValue(0, 4/*size*/); + else + // Internal to current translation unit. + // + // When we place the LSDA into the TEXT section, the type info + // pointers need to be indirect and pc-rel. We accomplish this by + // using NLPs; however, sometimes the types are local to the file. + // We need to fill in the value for the NLP in those cases. + OutStreamer.EmitValue( + MCSymbolRefExpr::Create(MCSym.getPointer(), OutStreamer.getContext()), + 4 /*size*/); +} + + void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { if (Subtarget->isTargetMacho()) { @@ -571,44 +595,24 @@ void X86AsmPrinter::EmitEndOfAsmFile(Module &M) { SectionKind::getMetadata()); OutStreamer.SwitchSection(TheSection); - for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { - // L_foo$non_lazy_ptr: - OutStreamer.EmitLabel(Stubs[i].first); - // .indirect_symbol _foo - MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second; - OutStreamer.EmitSymbolAttribute(MCSym.getPointer(), - MCSA_IndirectSymbol); - // .long 0 - if (MCSym.getInt()) - // External to current translation unit. - OutStreamer.EmitIntValue(0, 4/*size*/); - else - // Internal to current translation unit. - // - // When we place the LSDA into the TEXT section, the type info - // pointers need to be indirect and pc-rel. We accomplish this by - // using NLPs. However, sometimes the types are local to the file. So - // we need to fill in the value for the NLP in those cases. - OutStreamer.EmitValue(MCSymbolRefExpr::Create(MCSym.getPointer(), - OutContext), 4/*size*/); - } + for (auto &Stub : Stubs) + emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); + Stubs.clear(); OutStreamer.AddBlankLine(); } Stubs = MMIMacho.GetHiddenGVStubList(); if (!Stubs.empty()) { - OutStreamer.SwitchSection(getObjFileLowering().getDataSection()); - EmitAlignment(2); + const MCSection *TheSection = + OutContext.getMachOSection("__IMPORT", "__pointers", + MachO::S_NON_LAZY_SYMBOL_POINTERS, + SectionKind::getMetadata()); + OutStreamer.SwitchSection(TheSection); + + for (auto &Stub : Stubs) + emitNonLazySymbolPointer(OutStreamer, Stub.first, Stub.second); - for (unsigned i = 0, e = Stubs.size(); i != e; ++i) { - // L_foo$non_lazy_ptr: - OutStreamer.EmitLabel(Stubs[i].first); - // .long _foo - OutStreamer.EmitValue(MCSymbolRefExpr:: - Create(Stubs[i].second.getPointer(), - OutContext), 4/*size*/); - } Stubs.clear(); OutStreamer.AddBlankLine(); } diff --git a/test/CodeGen/X86/indirect-hidden.ll b/test/CodeGen/X86/indirect-hidden.ll new file mode 100644 index 00000000000..309375d9302 --- /dev/null +++ b/test/CodeGen/X86/indirect-hidden.ll @@ -0,0 +1,43 @@ +; RUN: llc -mtriple=i686-apple-macosx -o - %s | FileCheck %s + +; x86 doesn't normally use indirect symbols, particularly hidden ones, but it +; can be tricked into it for exception-handling typeids. + +@hidden_typeid = external hidden constant i8* +@normal_typeid = external constant i8* + +declare void @throws() + +define void @get_indirect_hidden() { + invoke void @throws() to label %end unwind label %lpad +lpad: + %tmp = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast (i8** @hidden_typeid to i8*) + br label %end + +end: + ret void +} + +define void @get_indirect() { + invoke void @throws() to label %end unwind label %lpad +lpad: + %tmp = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + catch i8* bitcast (i8** @normal_typeid to i8*) + br label %end + +end: + ret void +} + +declare i32 @__gxx_personality_v0(...) + +; CHECK: .section __IMPORT,__pointers,non_lazy_symbol_pointers + +; CHECK-NOT: __DATA,__data +; CHECK: .indirect_symbol _normal_typeid +; CHECK-NEXT: .long 0 + +; CHECK-NOT: __DATA,__data +; CHECK: .indirect_symbol _hidden_typeid +; CHECK-NEXT: .long 0