Skip to content
This repository was archived by the owner on Dec 20, 2019. It is now read-only.

Commit 38955d9

Browse files
joakim-noahkinke
authored andcommitted
LDC: Rework emulated TLS patch for Android and include x64 target.
The Bionic C library ignores thread-local data stored in the normal .tbss/.tdata ELF sections, which are marked with the SHF_TLS/STT_TLS flags. LDC rolls its own emulated TLS scheme for Android instead, by keeping TLS data in the .tdata/.tbss sections but removing the SHF_TLS/STT_TLS flags, and replacing direct access to these globals by a call to __tls_get_addr() (implemented in druntime's rt.sections_android). The function is expected to translate an address in the TLS static data to the corresponding address in the actual TLS dynamic per-thread data.
1 parent 5c1d425 commit 38955d9

9 files changed

+70
-15
lines changed

include/llvm/CodeGen/TargetLowering.h

+3
Original file line numberDiff line numberDiff line change
@@ -3880,6 +3880,9 @@ class TargetLowering : public TargetLoweringBase {
38803880
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA,
38813881
SelectionDAG &DAG) const;
38823882

3883+
SDValue LowerToAndroidEmulatedTLSAddress(SDValue Op, SDValue Result,
3884+
SelectionDAG &DAG, bool is64bit) const; // LDC
3885+
38833886
/// Expands target specific indirect branch for the case of JumpTable
38843887
/// expanasion.
38853888
virtual SDValue expandIndirectJTBranch(const SDLoc& dl, SDValue Value, SDValue Addr,

lib/CodeGen/SelectionDAG/TargetLowering.cpp

+27
Original file line numberDiff line numberDiff line change
@@ -5209,6 +5209,33 @@ SDValue TargetLowering::getVectorElementPointer(SelectionDAG &DAG,
52095209
return DAG.getNode(ISD::ADD, dl, IdxVT, VecPtr, Index);
52105210
}
52115211

5212+
SDValue
5213+
TargetLowering::LowerToAndroidEmulatedTLSAddress(SDValue Op, SDValue Result,
5214+
SelectionDAG &DAG, bool is64bit) const { // LDC
5215+
SDLoc DL(Op);
5216+
SDValue Chain = DAG.getEntryNode();
5217+
ArgListTy Args;
5218+
ArgListEntry Entry;
5219+
Type *Ty;
5220+
if (is64bit)
5221+
Ty = (Type *)Type::getInt64Ty(*DAG.getContext());
5222+
else
5223+
Ty = (Type *)Type::getInt32Ty(*DAG.getContext());
5224+
Entry.Node = Result;
5225+
Entry.Ty = Ty;
5226+
Args.push_back(Entry);
5227+
5228+
// copied, modified from ARMTargetLowering::LowerToTLSGeneralDynamicModel
5229+
TargetLowering::CallLoweringInfo CLI(DAG);
5230+
CLI.setDebugLoc(DL).setChain(Chain).setLibCallee(
5231+
CallingConv::C, Ty,
5232+
DAG.getExternalSymbol("__tls_get_addr",
5233+
getPointerTy(DAG.getDataLayout())),
5234+
std::move(Args));
5235+
std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
5236+
return CallResult.first;
5237+
}
5238+
52125239
//===----------------------------------------------------------------------===//
52135240
// Implementation of Emulated TLS Model
52145241
//===----------------------------------------------------------------------===//

lib/CodeGen/TargetLoweringObjectFileImpl.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,8 @@ const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(
387387
MMI, Streamer);
388388
}
389389

390-
static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
390+
static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K,
391+
const Triple &TargetTriple) {
391392
// N.B.: The defaults used in here are not the same ones used in MC.
392393
// We follow gcc, MC follows gas. For example, given ".section .eh_frame",
393394
// both gas and MC will produce a section with no flags. Given
@@ -419,6 +420,7 @@ static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
419420
return SectionKind::getThreadData();
420421

421422
if (Name == ".tbss" ||
423+
(TargetTriple.isAndroid() && Name == ".tcommon") || // LDC
422424
Name.startswith(".tbss.") ||
423425
Name.startswith(".gnu.linkonce.tb.") ||
424426
Name.startswith(".llvm.linkonce.tb."))
@@ -449,7 +451,7 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) {
449451
return ELF::SHT_PROGBITS;
450452
}
451453

452-
static unsigned getELFSectionFlags(SectionKind K) {
454+
static unsigned getELFSectionFlags(SectionKind K, const Triple &TargetTriple) {
453455
unsigned Flags = 0;
454456

455457
if (!K.isMetadata())
@@ -464,7 +466,7 @@ static unsigned getELFSectionFlags(SectionKind K) {
464466
if (K.isWriteable())
465467
Flags |= ELF::SHF_WRITE;
466468

467-
if (K.isThreadLocal())
469+
if (K.isThreadLocal() && !TargetTriple.isAndroid()) // LDC
468470
Flags |= ELF::SHF_TLS;
469471

470472
if (K.isMergeableCString() || K.isMergeableConst())
@@ -554,10 +556,10 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
554556
}
555557

556558
// Infer section flags from the section name if we can.
557-
Kind = getELFKindForNamedSection(SectionName, Kind);
559+
Kind = getELFKindForNamedSection(SectionName, Kind, getTargetTriple());
558560

559561
StringRef Group = "";
560-
unsigned Flags = getELFSectionFlags(Kind);
562+
unsigned Flags = getELFSectionFlags(Kind, getTargetTriple());
561563
if (const Comdat *C = getELFComdat(GO)) {
562564
Group = C->getName();
563565
Flags |= ELF::SHF_GROUP;
@@ -657,7 +659,7 @@ static MCSectionELF *selectELFSectionForGlobal(
657659

658660
MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
659661
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
660-
unsigned Flags = getELFSectionFlags(Kind);
662+
unsigned Flags = getELFSectionFlags(Kind, getTargetTriple());
661663

662664
// If we have -ffunction-section or -fdata-section then we should emit the
663665
// global value to a uniqued section specifically for it.

lib/MC/MCELFStreamer.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,12 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
448448
break;
449449
}
450450
getAssembler().registerSymbol(symRef.getSymbol());
451-
cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS);
451+
// LDC
452+
{
453+
auto ofi = getContext().getObjectFileInfo();
454+
if (!(ofi && ofi->getTargetTriple().isAndroid()))
455+
cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS);
456+
}
452457
break;
453458
}
454459

lib/MC/MCObjectFileInfo.cpp

+7-5
Original file line numberDiff line numberDiff line change
@@ -354,12 +354,14 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
354354
ReadOnlySection =
355355
Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
356356

357-
TLSDataSection =
358-
Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS,
359-
ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE);
357+
// LDC
358+
const auto tlsFlag = (!getTargetTriple().isAndroid() ? ELF::SHF_TLS : 0);
360359

361-
TLSBSSSection = Ctx->getELFSection(
362-
".tbss", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE);
360+
TLSDataSection = Ctx->getELFSection(
361+
".tdata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | tlsFlag | ELF::SHF_WRITE);
362+
363+
TLSBSSSection = Ctx->getELFSection(".tbss", ELF::SHT_NOBITS,
364+
ELF::SHF_ALLOC | tlsFlag | ELF::SHF_WRITE);
363365

364366
DataRelROSection = Ctx->getELFSection(".data.rel.ro", ELF::SHT_PROGBITS,
365367
ELF::SHF_ALLOC | ELF::SHF_WRITE);

lib/Target/AArch64/AArch64ISelLowering.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -4367,8 +4367,12 @@ SDValue AArch64TargetLowering::LowerGlobalTLSAddress(SDValue Op,
43674367

43684368
if (Subtarget->isTargetDarwin())
43694369
return LowerDarwinGlobalTLSAddress(Op, DAG);
4370-
if (Subtarget->isTargetELF())
4371-
return LowerELFGlobalTLSAddress(Op, DAG);
4370+
if (Subtarget->isTargetELF()) {
4371+
if (Subtarget->isTargetAndroid())
4372+
return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, true); // LDC
4373+
else
4374+
return LowerELFGlobalTLSAddress(Op, DAG);
4375+
}
43724376
if (Subtarget->isTargetWindows())
43734377
return LowerWindowsGlobalTLSAddress(Op, DAG);
43744378

lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
#include "AArch64MCExpr.h"
1616
#include "llvm/BinaryFormat/ELF.h"
17+
#include "llvm/MC/MCAssembler.h" // LDC
1718
#include "llvm/MC/MCContext.h"
19+
#include "llvm/MC/MCObjectFileInfo.h" // LDC
1820
#include "llvm/MC/MCStreamer.h"
1921
#include "llvm/MC/MCSymbolELF.h"
2022
#include "llvm/MC/MCValue.h"
@@ -124,7 +126,12 @@ static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
124126
// We're known to be under a TLS fixup, so any symbol should be
125127
// modified. There should be only one.
126128
const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
127-
cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
129+
// LDC
130+
{
131+
auto ofi = Asm.getContext().getObjectFileInfo();
132+
if (!(ofi && ofi->getTargetTriple().isAndroid()))
133+
cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
134+
}
128135
break;
129136
}
130137

lib/Target/ARM/ARMISelLowering.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -3041,6 +3041,8 @@ ARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
30413041

30423042
// TODO: implement the "local dynamic" model
30433043
assert(Subtarget->isTargetELF() && "Only ELF implemented here");
3044+
if (Subtarget->isTargetAndroid())
3045+
return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, false); // LDC
30443046
TLSModel::Model model = getTargetMachine().getTLSModel(GA->getGlobal());
30453047

30463048
switch (model) {

lib/Target/X86/X86ISelLowering.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -17058,6 +17058,9 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
1705817058
bool PositionIndependent = isPositionIndependent();
1705917059

1706017060
if (Subtarget.isTargetELF()) {
17061+
if (Subtarget.isTargetAndroid())
17062+
return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, Subtarget.is64Bit()); // LDC
17063+
1706117064
TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
1706217065
switch (model) {
1706317066
case TLSModel::GeneralDynamic:

0 commit comments

Comments
 (0)