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

Commit ecba7c7

Browse files
committed
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 5a67f67 commit ecba7c7

9 files changed

+70
-15
lines changed

include/llvm/CodeGen/TargetLowering.h

+3
Original file line numberDiff line numberDiff line change
@@ -3664,6 +3664,9 @@ class TargetLowering : public TargetLoweringBase {
36643664
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA,
36653665
SelectionDAG &DAG) const;
36663666

3667+
SDValue LowerToAndroidEmulatedTLSAddress(SDValue Op, SDValue Result,
3668+
SelectionDAG &DAG, bool is64bit) const; // LDC
3669+
36673670
/// Expands target specific indirect branch for the case of JumpTable
36683671
/// expanasion.
36693672
virtual SDValue expandIndirectJTBranch(const SDLoc& dl, SDValue Value, SDValue Addr,

lib/CodeGen/SelectionDAG/TargetLowering.cpp

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

4337+
SDValue
4338+
TargetLowering::LowerToAndroidEmulatedTLSAddress(SDValue Op, SDValue Result,
4339+
SelectionDAG &DAG, bool is64bit) const { // LDC
4340+
SDLoc DL(Op);
4341+
SDValue Chain = DAG.getEntryNode();
4342+
ArgListTy Args;
4343+
ArgListEntry Entry;
4344+
Type *Ty;
4345+
if (is64bit)
4346+
Ty = (Type *)Type::getInt64Ty(*DAG.getContext());
4347+
else
4348+
Ty = (Type *)Type::getInt32Ty(*DAG.getContext());
4349+
Entry.Node = Result;
4350+
Entry.Ty = Ty;
4351+
Args.push_back(Entry);
4352+
4353+
// copied, modified from ARMTargetLowering::LowerToTLSGeneralDynamicModel
4354+
TargetLowering::CallLoweringInfo CLI(DAG);
4355+
CLI.setDebugLoc(DL).setChain(Chain).setLibCallee(
4356+
CallingConv::C, Ty,
4357+
DAG.getExternalSymbol("__tls_get_addr",
4358+
getPointerTy(DAG.getDataLayout())),
4359+
std::move(Args));
4360+
std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
4361+
return CallResult.first;
4362+
}
4363+
43374364
//===----------------------------------------------------------------------===//
43384365
// Implementation of Emulated TLS Model
43394366
//===----------------------------------------------------------------------===//

lib/CodeGen/TargetLoweringObjectFileImpl.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,8 @@ const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(
232232
MMI, Streamer);
233233
}
234234

235-
static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
235+
static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K,
236+
const Triple &TargetTriple) {
236237
// N.B.: The defaults used in here are not the same ones used in MC.
237238
// We follow gcc, MC follows gas. For example, given ".section .eh_frame",
238239
// both gas and MC will produce a section with no flags. Given
@@ -264,6 +265,7 @@ static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
264265
return SectionKind::getThreadData();
265266

266267
if (Name == ".tbss" ||
268+
(TargetTriple.isAndroid() && Name == ".tcommon") || // LDC
267269
Name.startswith(".tbss.") ||
268270
Name.startswith(".gnu.linkonce.tb.") ||
269271
Name.startswith(".llvm.linkonce.tb."))
@@ -294,7 +296,7 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) {
294296
return ELF::SHT_PROGBITS;
295297
}
296298

297-
static unsigned getELFSectionFlags(SectionKind K) {
299+
static unsigned getELFSectionFlags(SectionKind K, const Triple &TargetTriple) {
298300
unsigned Flags = 0;
299301

300302
if (!K.isMetadata())
@@ -309,7 +311,7 @@ static unsigned getELFSectionFlags(SectionKind K) {
309311
if (K.isWriteable())
310312
Flags |= ELF::SHF_WRITE;
311313

312-
if (K.isThreadLocal())
314+
if (K.isThreadLocal() && !TargetTriple.isAndroid()) // LDC
313315
Flags |= ELF::SHF_TLS;
314316

315317
if (K.isMergeableCString() || K.isMergeableConst())
@@ -375,10 +377,10 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
375377
}
376378

377379
// Infer section flags from the section name if we can.
378-
Kind = getELFKindForNamedSection(SectionName, Kind);
380+
Kind = getELFKindForNamedSection(SectionName, Kind, getTargetTriple());
379381

380382
StringRef Group = "";
381-
unsigned Flags = getELFSectionFlags(Kind);
383+
unsigned Flags = getELFSectionFlags(Kind, getTargetTriple());
382384
if (const Comdat *C = getELFComdat(GO)) {
383385
Group = C->getName();
384386
Flags |= ELF::SHF_GROUP;
@@ -502,7 +504,7 @@ static MCSectionELF *selectELFSectionForGlobal(
502504

503505
MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
504506
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
505-
unsigned Flags = getELFSectionFlags(Kind);
507+
unsigned Flags = getELFSectionFlags(Kind, getTargetTriple());
506508

507509
// If we have -ffunction-section or -fdata-section then we should emit the
508510
// 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
@@ -497,12 +497,14 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
497497
ReadOnlySection =
498498
Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
499499

500-
TLSDataSection =
501-
Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS,
502-
ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE);
500+
// LDC
501+
const auto tlsFlag = (!getTargetTriple().isAndroid() ? ELF::SHF_TLS : 0);
503502

504-
TLSBSSSection = Ctx->getELFSection(
505-
".tbss", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE);
503+
TLSDataSection = Ctx->getELFSection(
504+
".tdata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | tlsFlag | ELF::SHF_WRITE);
505+
506+
TLSBSSSection = Ctx->getELFSection(".tbss", ELF::SHT_NOBITS,
507+
ELF::SHF_ALLOC | tlsFlag | ELF::SHF_WRITE);
506508

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

lib/Target/AArch64/AArch64ISelLowering.cpp

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

42174217
if (Subtarget->isTargetDarwin())
42184218
return LowerDarwinGlobalTLSAddress(Op, DAG);
4219-
if (Subtarget->isTargetELF())
4220-
return LowerELFGlobalTLSAddress(Op, DAG);
4219+
if (Subtarget->isTargetELF()) {
4220+
if (Subtarget->isTargetAndroid())
4221+
return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, true); // LDC
4222+
else
4223+
return LowerELFGlobalTLSAddress(Op, DAG);
4224+
}
42214225
if (Subtarget->isTargetWindows())
42224226
return LowerWindowsGlobalTLSAddress(Op, DAG);
42234227

lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
#include "AArch64MCExpr.h"
16+
#include "llvm/MC/MCAssembler.h" // LDC
1617
#include "llvm/MC/MCContext.h"
18+
#include "llvm/MC/MCObjectFileInfo.h" // LDC
1719
#include "llvm/MC/MCStreamer.h"
1820
#include "llvm/MC/MCSymbolELF.h"
1921
#include "llvm/MC/MCValue.h"
@@ -122,7 +124,12 @@ static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
122124
// We're known to be under a TLS fixup, so any symbol should be
123125
// modified. There should be only one.
124126
const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
125-
cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
127+
// LDC
128+
{
129+
auto ofi = Asm.getContext().getObjectFileInfo();
130+
if (!(ofi && ofi->getTargetTriple().isAndroid()))
131+
cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
132+
}
126133
break;
127134
}
128135

lib/Target/ARM/ARMISelLowering.cpp

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

30193019
// TODO: implement the "local dynamic" model
30203020
assert(Subtarget->isTargetELF() && "Only ELF implemented here");
3021+
if (Subtarget->isTargetAndroid())
3022+
return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, false); // LDC
30213023
TLSModel::Model model = getTargetMachine().getTLSModel(GA->getGlobal());
30223024

30233025
switch (model) {

lib/Target/X86/X86ISelLowering.cpp

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

1603916039
if (Subtarget.isTargetELF()) {
16040+
if (Subtarget.isTargetAndroid())
16041+
return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, Subtarget.is64Bit()); // LDC
16042+
1604016043
TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
1604116044
switch (model) {
1604216045
case TLSModel::GeneralDynamic:

0 commit comments

Comments
 (0)