diff --git a/include/llvm/CodeGen/TargetLowering.h b/include/llvm/CodeGen/TargetLowering.h index 23dbaac03ebea..6721a42dad7d5 100644 --- a/include/llvm/CodeGen/TargetLowering.h +++ b/include/llvm/CodeGen/TargetLowering.h @@ -3880,6 +3880,9 @@ class TargetLowering : public TargetLoweringBase { virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA, SelectionDAG &DAG) const; + SDValue LowerToAndroidEmulatedTLSAddress(SDValue Op, SDValue Result, + SelectionDAG &DAG, bool is64bit) const; // LDC + /// Expands target specific indirect branch for the case of JumpTable /// expanasion. virtual SDValue expandIndirectJTBranch(const SDLoc& dl, SDValue Value, SDValue Addr, diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index a2f05c1e3cef3..a64f95ad2110d 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -5209,6 +5209,33 @@ SDValue TargetLowering::getVectorElementPointer(SelectionDAG &DAG, return DAG.getNode(ISD::ADD, dl, IdxVT, VecPtr, Index); } +SDValue +TargetLowering::LowerToAndroidEmulatedTLSAddress(SDValue Op, SDValue Result, + SelectionDAG &DAG, bool is64bit) const { // LDC + SDLoc DL(Op); + SDValue Chain = DAG.getEntryNode(); + ArgListTy Args; + ArgListEntry Entry; + Type *Ty; + if (is64bit) + Ty = (Type *)Type::getInt64Ty(*DAG.getContext()); + else + Ty = (Type *)Type::getInt32Ty(*DAG.getContext()); + Entry.Node = Result; + Entry.Ty = Ty; + Args.push_back(Entry); + + // copied, modified from ARMTargetLowering::LowerToTLSGeneralDynamicModel + TargetLowering::CallLoweringInfo CLI(DAG); + CLI.setDebugLoc(DL).setChain(Chain).setLibCallee( + CallingConv::C, Ty, + DAG.getExternalSymbol("__tls_get_addr", + getPointerTy(DAG.getDataLayout())), + std::move(Args)); + std::pair CallResult = LowerCallTo(CLI); + return CallResult.first; +} + //===----------------------------------------------------------------------===// // Implementation of Emulated TLS Model //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index cb2fe691d7021..ff84eee0f9299 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -387,7 +387,8 @@ const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference( MMI, Streamer); } -static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) { +static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K, + const Triple &TargetTriple) { // N.B.: The defaults used in here are not the same ones used in MC. // We follow gcc, MC follows gas. For example, given ".section .eh_frame", // both gas and MC will produce a section with no flags. Given @@ -419,6 +420,7 @@ static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) { return SectionKind::getThreadData(); if (Name == ".tbss" || + (TargetTriple.isAndroid() && Name == ".tcommon") || // LDC Name.startswith(".tbss.") || Name.startswith(".gnu.linkonce.tb.") || Name.startswith(".llvm.linkonce.tb.")) @@ -449,7 +451,7 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) { return ELF::SHT_PROGBITS; } -static unsigned getELFSectionFlags(SectionKind K) { +static unsigned getELFSectionFlags(SectionKind K, const Triple &TargetTriple) { unsigned Flags = 0; if (!K.isMetadata()) @@ -464,7 +466,7 @@ static unsigned getELFSectionFlags(SectionKind K) { if (K.isWriteable()) Flags |= ELF::SHF_WRITE; - if (K.isThreadLocal()) + if (K.isThreadLocal() && !TargetTriple.isAndroid()) // LDC Flags |= ELF::SHF_TLS; if (K.isMergeableCString() || K.isMergeableConst()) @@ -554,10 +556,10 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( } // Infer section flags from the section name if we can. - Kind = getELFKindForNamedSection(SectionName, Kind); + Kind = getELFKindForNamedSection(SectionName, Kind, getTargetTriple()); StringRef Group = ""; - unsigned Flags = getELFSectionFlags(Kind); + unsigned Flags = getELFSectionFlags(Kind, getTargetTriple()); if (const Comdat *C = getELFComdat(GO)) { Group = C->getName(); Flags |= ELF::SHF_GROUP; @@ -657,7 +659,7 @@ static MCSectionELF *selectELFSectionForGlobal( MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { - unsigned Flags = getELFSectionFlags(Kind); + unsigned Flags = getELFSectionFlags(Kind, getTargetTriple()); // If we have -ffunction-section or -fdata-section then we should emit the // global value to a uniqued section specifically for it. diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 95b48e6abc740..cdb85eab66c36 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -448,7 +448,12 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { break; } getAssembler().registerSymbol(symRef.getSymbol()); - cast(symRef.getSymbol()).setType(ELF::STT_TLS); + // LDC + { + auto ofi = getContext().getObjectFileInfo(); + if (!(ofi && ofi->getTargetTriple().isAndroid())) + cast(symRef.getSymbol()).setType(ELF::STT_TLS); + } break; } diff --git a/lib/MC/MCObjectFileInfo.cpp b/lib/MC/MCObjectFileInfo.cpp index 883e38f145bee..478d010d6191c 100644 --- a/lib/MC/MCObjectFileInfo.cpp +++ b/lib/MC/MCObjectFileInfo.cpp @@ -354,12 +354,14 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) { ReadOnlySection = Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC); - TLSDataSection = - Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS, - ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE); + // LDC + const auto tlsFlag = (!getTargetTriple().isAndroid() ? ELF::SHF_TLS : 0); - TLSBSSSection = Ctx->getELFSection( - ".tbss", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE); + TLSDataSection = Ctx->getELFSection( + ".tdata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | tlsFlag | ELF::SHF_WRITE); + + TLSBSSSection = Ctx->getELFSection(".tbss", ELF::SHT_NOBITS, + ELF::SHF_ALLOC | tlsFlag | ELF::SHF_WRITE); DataRelROSection = Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | ELF::SHF_WRITE); diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 762f4413d72b9..cc48893fc85dc 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -4367,8 +4367,12 @@ SDValue AArch64TargetLowering::LowerGlobalTLSAddress(SDValue Op, if (Subtarget->isTargetDarwin()) return LowerDarwinGlobalTLSAddress(Op, DAG); - if (Subtarget->isTargetELF()) - return LowerELFGlobalTLSAddress(Op, DAG); + if (Subtarget->isTargetELF()) { + if (Subtarget->isTargetAndroid()) + return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, true); // LDC + else + return LowerELFGlobalTLSAddress(Op, DAG); + } if (Subtarget->isTargetWindows()) return LowerWindowsGlobalTLSAddress(Op, DAG); diff --git a/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp b/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp index 729486b1020c9..a24cd306e2f2c 100644 --- a/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp +++ b/lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp @@ -14,7 +14,9 @@ #include "AArch64MCExpr.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAssembler.h" // LDC #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCObjectFileInfo.h" // LDC #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCValue.h" @@ -124,7 +126,12 @@ static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) { // We're known to be under a TLS fixup, so any symbol should be // modified. There should be only one. const MCSymbolRefExpr &SymRef = *cast(Expr); - cast(SymRef.getSymbol()).setType(ELF::STT_TLS); + // LDC + { + auto ofi = Asm.getContext().getObjectFileInfo(); + if (!(ofi && ofi->getTargetTriple().isAndroid())) + cast(SymRef.getSymbol()).setType(ELF::STT_TLS); + } break; } diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 21de0f6a7630e..51939d5cb5c96 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -3041,6 +3041,8 @@ ARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const { // TODO: implement the "local dynamic" model assert(Subtarget->isTargetELF() && "Only ELF implemented here"); + if (Subtarget->isTargetAndroid()) + return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, false); // LDC TLSModel::Model model = getTargetMachine().getTLSModel(GA->getGlobal()); switch (model) { diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 2dfee3a4701e6..763ae0347f57d 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -17058,6 +17058,9 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const { bool PositionIndependent = isPositionIndependent(); if (Subtarget.isTargetELF()) { + if (Subtarget.isTargetAndroid()) + return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, Subtarget.is64Bit()); // LDC + TLSModel::Model model = DAG.getTarget().getTLSModel(GV); switch (model) { case TLSModel::GeneralDynamic: