summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/MachineModuleInfoImpls.h13
-rw-r--r--include/llvm/MC/MCObjectFileInfo.h4
-rw-r--r--lib/MC/MCAsmInfoDarwin.cpp1
-rw-r--r--lib/MC/MCObjectFileInfo.cpp5
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp8
-rw-r--r--lib/MC/MachObjectWriter.cpp1
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp20
-rw-r--r--test/CodeGen/ARM/darwin-tls.ll17
-rw-r--r--test/MC/ARM/tls-directives.s46
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