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

Commit c0a76db

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 8097236 commit c0a76db

File tree

9 files changed

+70
-15
lines changed

9 files changed

+70
-15
lines changed

include/llvm/CodeGen/TargetLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4047,6 +4047,9 @@ class TargetLowering : public TargetLoweringBase {
40474047
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA,
40484048
SelectionDAG &DAG) const;
40494049

4050+
SDValue LowerToAndroidEmulatedTLSAddress(SDValue Op, SDValue Result,
4051+
SelectionDAG &DAG, bool is64bit) const; // LDC
4052+
40504053
/// Expands target specific indirect branch for the case of JumpTable
40514054
/// expanasion.
40524055
virtual SDValue expandIndirectJTBranch(const SDLoc& dl, SDValue Value, SDValue Addr,

lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5772,6 +5772,33 @@ SDValue TargetLowering::getVectorElementPointer(SelectionDAG &DAG,
57725772
return DAG.getNode(ISD::ADD, dl, IdxVT, VecPtr, Index);
57735773
}
57745774

5775+
SDValue
5776+
TargetLowering::LowerToAndroidEmulatedTLSAddress(SDValue Op, SDValue Result,
5777+
SelectionDAG &DAG, bool is64bit) const { // LDC
5778+
SDLoc DL(Op);
5779+
SDValue Chain = DAG.getEntryNode();
5780+
ArgListTy Args;
5781+
ArgListEntry Entry;
5782+
Type *Ty;
5783+
if (is64bit)
5784+
Ty = (Type *)Type::getInt64Ty(*DAG.getContext());
5785+
else
5786+
Ty = (Type *)Type::getInt32Ty(*DAG.getContext());
5787+
Entry.Node = Result;
5788+
Entry.Ty = Ty;
5789+
Args.push_back(Entry);
5790+
5791+
// copied, modified from ARMTargetLowering::LowerToTLSGeneralDynamicModel
5792+
TargetLowering::CallLoweringInfo CLI(DAG);
5793+
CLI.setDebugLoc(DL).setChain(Chain).setLibCallee(
5794+
CallingConv::C, Ty,
5795+
DAG.getExternalSymbol("__tls_get_addr",
5796+
getPointerTy(DAG.getDataLayout())),
5797+
std::move(Args));
5798+
std::pair<SDValue, SDValue> CallResult = LowerCallTo(CLI);
5799+
return CallResult.first;
5800+
}
5801+
57755802
//===----------------------------------------------------------------------===//
57765803
// Implementation of Emulated TLS Model
57775804
//===----------------------------------------------------------------------===//

lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,8 @@ const MCExpr *TargetLoweringObjectFileELF::getTTypeGlobalReference(
409409
MMI, Streamer);
410410
}
411411

412-
static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
412+
static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K,
413+
const Triple &TargetTriple) {
413414
// N.B.: The defaults used in here are not the same ones used in MC.
414415
// We follow gcc, MC follows gas. For example, given ".section .eh_frame",
415416
// both gas and MC will produce a section with no flags. Given
@@ -441,6 +442,7 @@ static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
441442
return SectionKind::getThreadData();
442443

443444
if (Name == ".tbss" ||
445+
(TargetTriple.isAndroid() && Name == ".tcommon") || // LDC
444446
Name.startswith(".tbss.") ||
445447
Name.startswith(".gnu.linkonce.tb.") ||
446448
Name.startswith(".llvm.linkonce.tb."))
@@ -471,7 +473,7 @@ static unsigned getELFSectionType(StringRef Name, SectionKind K) {
471473
return ELF::SHT_PROGBITS;
472474
}
473475

474-
static unsigned getELFSectionFlags(SectionKind K) {
476+
static unsigned getELFSectionFlags(SectionKind K, const Triple &TargetTriple) {
475477
unsigned Flags = 0;
476478

477479
if (!K.isMetadata())
@@ -486,7 +488,7 @@ static unsigned getELFSectionFlags(SectionKind K) {
486488
if (K.isWriteable())
487489
Flags |= ELF::SHF_WRITE;
488490

489-
if (K.isThreadLocal())
491+
if (K.isThreadLocal() && !TargetTriple.isAndroid()) // LDC
490492
Flags |= ELF::SHF_TLS;
491493

492494
if (K.isMergeableCString() || K.isMergeableConst())
@@ -576,10 +578,10 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
576578
}
577579

578580
// Infer section flags from the section name if we can.
579-
Kind = getELFKindForNamedSection(SectionName, Kind);
581+
Kind = getELFKindForNamedSection(SectionName, Kind, getTargetTriple());
580582

581583
StringRef Group = "";
582-
unsigned Flags = getELFSectionFlags(Kind);
584+
unsigned Flags = getELFSectionFlags(Kind, getTargetTriple());
583585
if (const Comdat *C = getELFComdat(GO)) {
584586
Group = C->getName();
585587
Flags |= ELF::SHF_GROUP;
@@ -679,7 +681,7 @@ static MCSectionELF *selectELFSectionForGlobal(
679681

680682
MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal(
681683
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
682-
unsigned Flags = getELFSectionFlags(Kind);
684+
unsigned Flags = getELFSectionFlags(Kind, getTargetTriple());
683685

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

lib/MC/MCELFStreamer.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,12 @@ void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) {
450450
break;
451451
}
452452
getAssembler().registerSymbol(symRef.getSymbol());
453-
cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS);
453+
// LDC
454+
{
455+
auto ofi = getContext().getObjectFileInfo();
456+
if (!(ofi && ofi->getTargetTriple().isAndroid()))
457+
cast<MCSymbolELF>(symRef.getSymbol()).setType(ELF::STT_TLS);
458+
}
454459
break;
455460
}
456461

lib/MC/MCObjectFileInfo.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,12 +357,14 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
357357
ReadOnlySection =
358358
Ctx->getELFSection(".rodata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC);
359359

360-
TLSDataSection =
361-
Ctx->getELFSection(".tdata", ELF::SHT_PROGBITS,
362-
ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE);
360+
// LDC
361+
const auto tlsFlag = (!getTargetTriple().isAndroid() ? ELF::SHF_TLS : 0);
363362

364-
TLSBSSSection = Ctx->getELFSection(
365-
".tbss", ELF::SHT_NOBITS, ELF::SHF_ALLOC | ELF::SHF_TLS | ELF::SHF_WRITE);
363+
TLSDataSection = Ctx->getELFSection(
364+
".tdata", ELF::SHT_PROGBITS, ELF::SHF_ALLOC | tlsFlag | ELF::SHF_WRITE);
365+
366+
TLSBSSSection = Ctx->getELFSection(".tbss", ELF::SHT_NOBITS,
367+
ELF::SHF_ALLOC | tlsFlag | ELF::SHF_WRITE);
366368

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

lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4447,8 +4447,12 @@ SDValue AArch64TargetLowering::LowerGlobalTLSAddress(SDValue Op,
44474447

44484448
if (Subtarget->isTargetDarwin())
44494449
return LowerDarwinGlobalTLSAddress(Op, DAG);
4450-
if (Subtarget->isTargetELF())
4451-
return LowerELFGlobalTLSAddress(Op, DAG);
4450+
if (Subtarget->isTargetELF()) {
4451+
if (Subtarget->isTargetAndroid())
4452+
return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, true); // LDC
4453+
else
4454+
return LowerELFGlobalTLSAddress(Op, DAG);
4455+
}
44524456
if (Subtarget->isTargetWindows())
44534457
return LowerWindowsGlobalTLSAddress(Op, DAG);
44544458

lib/Target/AArch64/MCTargetDesc/AArch64MCExpr.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313

1414
#include "AArch64MCExpr.h"
1515
#include "llvm/BinaryFormat/ELF.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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3199,6 +3199,8 @@ ARMTargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
31993199

32003200
// TODO: implement the "local dynamic" model
32013201
assert(Subtarget->isTargetELF() && "Only ELF implemented here");
3202+
if (Subtarget->isTargetAndroid())
3203+
return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, false); // LDC
32023204
TLSModel::Model model = getTargetMachine().getTLSModel(GA->getGlobal());
32033205

32043206
switch (model) {

lib/Target/X86/X86ISelLowering.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17658,6 +17658,9 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
1765817658
bool PositionIndependent = isPositionIndependent();
1765917659

1766017660
if (Subtarget.isTargetELF()) {
17661+
if (Subtarget.isTargetAndroid())
17662+
return LowerToAndroidEmulatedTLSAddress(Op, LowerGlobalAddress(Op, DAG), DAG, Subtarget.is64Bit()); // LDC
17663+
1766117664
TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
1766217665
switch (model) {
1766317666
case TLSModel::GeneralDynamic:

0 commit comments

Comments
 (0)