diff options
-rw-r--r-- | include/llvm/CodeGen/MachineModuleInfoImpls.h | 13 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectFileInfo.h | 4 | ||||
-rw-r--r-- | lib/MC/MCAsmInfoDarwin.cpp | 1 | ||||
-rw-r--r-- | lib/MC/MCObjectFileInfo.cpp | 5 | ||||
-rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 8 | ||||
-rw-r--r-- | lib/MC/MachObjectWriter.cpp | 1 | ||||
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 20 | ||||
-rw-r--r-- | test/CodeGen/ARM/darwin-tls.ll | 17 | ||||
-rw-r--r-- | test/MC/ARM/tls-directives.s | 46 |
9 files changed, 113 insertions, 2 deletions
diff --git a/include/llvm/CodeGen/MachineModuleInfoImpls.h b/include/llvm/CodeGen/MachineModuleInfoImpls.h index e7472145e71..0561ef5c0c0 100644 --- a/include/llvm/CodeGen/MachineModuleInfoImpls.h +++ b/include/llvm/CodeGen/MachineModuleInfoImpls.h @@ -38,6 +38,11 @@ class MachineModuleInfoMachO : public MachineModuleInfoImpl { /// this GV is external. DenseMap<MCSymbol *, StubValueTy> HiddenGVStubs; + /// ThreadLocalGVStubs - Darwin '$non_lazy_ptr' stubs. The key is something + /// like "Lfoo$non_lazy_ptr", the value is something like "_foo". The extra + /// bit is true if this GV is external. + DenseMap<MCSymbol *, StubValueTy> ThreadLocalGVStubs; + virtual void anchor(); // Out of line virtual method. public: MachineModuleInfoMachO(const MachineModuleInfo &) {} @@ -57,10 +62,18 @@ public: return HiddenGVStubs[Sym]; } + StubValueTy &getThreadLocalGVStubEntry(MCSymbol *Sym) { + assert(Sym && "Key cannot be null"); + return ThreadLocalGVStubs[Sym]; + } + /// Accessor methods to return the set of stubs in sorted order. SymbolListTy GetFnStubList() { return getSortedStubs(FnStubs); } SymbolListTy GetGVStubList() { return getSortedStubs(GVStubs); } SymbolListTy GetHiddenGVStubList() { return getSortedStubs(HiddenGVStubs); } + SymbolListTy GetThreadLocalGVStubList() { + return getSortedStubs(ThreadLocalGVStubs); + } }; /// MachineModuleInfoELF - This is a MachineModuleInfoImpl implementation diff --git a/include/llvm/MC/MCObjectFileInfo.h b/include/llvm/MC/MCObjectFileInfo.h index d0e34e63ff8..495c1c06a5e 100644 --- a/include/llvm/MC/MCObjectFileInfo.h +++ b/include/llvm/MC/MCObjectFileInfo.h @@ -185,6 +185,7 @@ protected: MCSection *SixteenByteConstantSection; MCSection *LazySymbolPointerSection; MCSection *NonLazySymbolPointerSection; + MCSection *ThreadLocalPointerSection; /// COFF specific sections. MCSection *DrectveSection; @@ -333,6 +334,9 @@ public: MCSection *getNonLazySymbolPointerSection() const { return NonLazySymbolPointerSection; } + MCSection *getThreadLocalPointerSection() const { + return ThreadLocalPointerSection; + } // COFF specific sections. MCSection *getDrectveSection() const { return DrectveSection; } diff --git a/lib/MC/MCAsmInfoDarwin.cpp b/lib/MC/MCAsmInfoDarwin.cpp index dff5dd0d63d..fc60313dd6b 100644 --- a/lib/MC/MCAsmInfoDarwin.cpp +++ b/lib/MC/MCAsmInfoDarwin.cpp @@ -48,6 +48,7 @@ bool MCAsmInfoDarwin::isSectionAtomizableBySymbols( case MachO::S_LITERAL_POINTERS: case MachO::S_NON_LAZY_SYMBOL_POINTERS: case MachO::S_LAZY_SYMBOL_POINTERS: + case MachO::S_THREAD_LOCAL_VARIABLE_POINTERS: case MachO::S_MOD_INIT_FUNC_POINTERS: case MachO::S_MOD_TERM_FUNC_POINTERS: case MachO::S_INTERPOSING: diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index b270f00ce64..ee69d08dddd 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -172,6 +172,11 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(Triple T) { MachO::S_NON_LAZY_SYMBOL_POINTERS, SectionKind::getMetadata()); + ThreadLocalPointerSection + = Ctx->getMachOSection("__DATA", "__thread_ptr", + MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, + SectionKind::getMetadata()); + if (RelocM == Reloc::Static) { StaticCtorSection = Ctx->getMachOSection("__TEXT", "__constructor", 0, SectionKind::getData()); diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index f033a1dfc7e..a871b31cb29 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -112,6 +112,9 @@ public: addDirectiveHandler< &DarwinAsmParser::parseSectionDirectiveNonLazySymbolPointers>( ".non_lazy_symbol_pointer"); + addDirectiveHandler< + &DarwinAsmParser::parseSectionDirectiveThreadLocalVariablePointers>( + ".thread_local_variable_pointer"); addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatClsMeth>( ".objc_cat_cls_meth"); addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveObjCCatInstMeth>( @@ -263,6 +266,10 @@ public: return parseSectionSwitch("__DATA", "__la_symbol_ptr", MachO::S_LAZY_SYMBOL_POINTERS, 4); } + bool parseSectionDirectiveThreadLocalVariablePointers(StringRef, SMLoc) { + return parseSectionSwitch("__DATA", "__thread_ptr", + MachO::S_THREAD_LOCAL_VARIABLE_POINTERS, 4); + } bool parseSectionDirectiveDyld(StringRef, SMLoc) { return parseSectionSwitch("__DATA", "__dyld"); } @@ -467,6 +474,7 @@ bool DarwinAsmParser::parseDirectiveIndirectSymbol(StringRef, SMLoc Loc) { MachO::SectionType SectionType = Current->getType(); if (SectionType != MachO::S_NON_LAZY_SYMBOL_POINTERS && SectionType != MachO::S_LAZY_SYMBOL_POINTERS && + SectionType != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS && SectionType != MachO::S_SYMBOL_STUBS) return Error(Loc, "indirect symbol not in a symbol pointer or stub " "section"); diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index 2013c253d2d..f33b866e6a5 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -457,6 +457,7 @@ void MachObjectWriter::bindIndirectSymbols(MCAssembler &Asm) { if (Section.getType() != MachO::S_NON_LAZY_SYMBOL_POINTERS && Section.getType() != MachO::S_LAZY_SYMBOL_POINTERS && + Section.getType() != MachO::S_THREAD_LOCAL_VARIABLE_POINTERS && Section.getType() != MachO::S_SYMBOL_STUBS) { MCSymbol &Symbol = *it->Symbol; report_fatal_error("indirect symbol '" + Symbol.getName() + diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 20c97e9835c..6d0608f9baa 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -527,6 +527,19 @@ void ARMAsmPrinter::EmitEndOfAsmFile(Module &M) { OutStreamer->AddBlankLine(); } + Stubs = MMIMacho.GetThreadLocalGVStubList(); + if (!Stubs.empty()) { + // Switch with ".non_lazy_symbol_pointer" directive. + OutStreamer->SwitchSection(TLOFMacho.getThreadLocalPointerSection()); + EmitAlignment(2); + + for (auto &Stub : Stubs) + emitNonLazySymbolPointer(*OutStreamer, Stub.first, Stub.second); + + Stubs.clear(); + OutStreamer->AddBlankLine(); + } + // Funny Darwin hack: This flag tells the linker that no global symbols // contain code that falls through to other global symbols (e.g. the obvious // implementation of multiple entry points). If this doesn't occur, the @@ -891,8 +904,11 @@ MCSymbol *ARMAsmPrinter::GetARMGVSymbol(const GlobalValue *GV, MachineModuleInfoMachO &MMIMachO = MMI->getObjFileInfo<MachineModuleInfoMachO>(); MachineModuleInfoImpl::StubValueTy &StubSym = - GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) - : MMIMachO.getGVStubEntry(MCSym); + GV->isThreadLocal() + ? MMIMachO.getThreadLocalGVStubEntry(MCSym) + : (GV->hasHiddenVisibility() ? MMIMachO.getHiddenGVStubEntry(MCSym) + : MMIMachO.getGVStubEntry(MCSym)); + if (!StubSym.getPointer()) StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV), !GV->hasInternalLinkage()); diff --git a/test/CodeGen/ARM/darwin-tls.ll b/test/CodeGen/ARM/darwin-tls.ll index e1995322202..1043cce6218 100644 --- a/test/CodeGen/ARM/darwin-tls.ll +++ b/test/CodeGen/ARM/darwin-tls.ll @@ -10,6 +10,8 @@ @local_tls_var = thread_local global i32 0 @external_tls_var = external thread_local global i32 +@hidden_external_tls_var = external hidden thread_local global i32 + define i32 @test_local_tls() { ; T2-MOVT-PIC-LABEL: test_local_tls: @@ -163,3 +165,18 @@ define i32 @test_external_tls() { %val = load i32, i32* @external_tls_var, align 4 ret i32 %val } + +; Just need something to trigger an indirect reference to the var. +define i32 @use_hidden_external_tls() { + %val = load i32, i32* @hidden_external_tls_var, align 4 + ret i32 %val +} + +; T2-MOVT-PIC: .section __DATA,__thread_ptr,thread_local_variable_pointers +; T2-MOVT-PIC: .p2align 2 +; T2-MOVT-PIC: L_external_tls_var$non_lazy_ptr: +; T2-MOVT-PIC: .indirect_symbol _external_tls_var +; T2-MOVT-PIC: .long 0 +; T2-MOVT-PIC: L_hidden_external_tls_var$non_lazy_ptr: +; T2-MOVT-PIC: .indirect_symbol _hidden_external_tls_var +; T2-MOVT-PIC: .long 0 diff --git a/test/MC/ARM/tls-directives.s b/test/MC/ARM/tls-directives.s new file mode 100644 index 00000000000..c0e9f6cc142 --- /dev/null +++ b/test/MC/ARM/tls-directives.s @@ -0,0 +1,46 @@ +@ RUN: llvm-mc -triple thumbv7-apple-ios -filetype=obj -o %t %s +@ RUN: llvm-objdump -p %t | FileCheck %s + +@ CHECK: sectname __thread_data +@ CHECK: segname __DATA +@ CHECK: type S_THREAD_LOCAL_REGULAR + +@ CHECK: sectname __thread_vars +@ CHECK: segname __DATA +@ CHECK: type S_THREAD_LOCAL_VARIABLES + +@ CHECK: sectname __thread_bss +@ CHECK: segname __DATA +@ CHECK: type S_THREAD_LOCAL_ZEROFILL + +@ CHECK: sectname __thread_ptr +@ CHECK: segname __DATA +@ CHECK: type S_THREAD_LOCAL_VARIABLE_POINTERS + + + .section __DATA,__thread_data,thread_local_regular + .p2align 2 +_b$tlv$init: + .long 42 + + .section __DATA,__thread_vars,thread_local_variables + .globl _b +_b: + .long __tlv_bootstrap + .long 0 + .long _b$tlv$init + +.tbss _c$tlv$init, 4, 2 @ @c + + .globl _c +_c: + .long __tlv_bootstrap + .long 0 + .long _c$tlv$init + + + .section __DATA,__thread_ptr,thread_local_variable_pointers + .p2align 2 +L_a$non_lazy_ptr: + .indirect_symbol _a + .long 0 |