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

Rework emulated TLS patch for Android #3

Merged
merged 2 commits into from
Sep 24, 2018
Merged

Rework emulated TLS patch for Android #3

merged 2 commits into from
Sep 24, 2018

Conversation

joakim-noah
Copy link

@joakim-noah joakim-noah commented Sep 23, 2018

Switches all four Android targets- ARM, AArch64, x86, and x64- to the same approach for inserting __tls_get_addr used by Dan for AArch64. Tested by cross-compiling from linux/x64 and natively running the stdlib tests on ARM and AArch64 and for x86 and x64 in an Anbox Android/x64 container, also natively built on Android/AArch64.

This meant I tried out Android/x64 for the first time, pull forthcoming for druntime and will enable that Termux package with 1.12, for those running Termux in an x64 Chromebook.

LLVM 7 enables the built-in gcc-alike scheme for emulated TLS for Android by default, rather than having language frontends like clang or ldc enable it, so I had to disable that first now disable it from ldc, pull forthcoming.

@@ -682,7 +682,7 @@ class Triple {

/// Tests whether the target uses emulated TLS as default.
bool hasDefaultEmulatedTLS() const {
return isAndroid() || isOSOpenBSD() || isWindowsCygwinEnvironment();
return /* LDC isAndroid() ||*/ isOSOpenBSD() || isWindowsCygwinEnvironment();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we fix this on the LDC side? I noticed that there are llvm::TargetOptions::{EmulatedTLS,ExplicitEmulatedTLS}.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, just being lazy in figuring out that mess, :) this is the easiest fix that works. Since we're the only ones using this LLVM, rather just do it this way.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you're right. I was stupidly thinking that I'd have to fix it elsewhere in LLVM, and misread what you wrote as that. Best to fix it in LDC as you said, will do that.

@@ -3664,6 +3664,9 @@ class TargetLowering : public TargetLoweringBase {
virtual SDValue LowerToTLSEmulatedModel(const GlobalAddressSDNode *GA,
SelectionDAG &DAG) const;

virtual SDValue LowerToAndroidEmulatedTLSAddress(SDValue Op, SDValue Result,
SelectionDAG &DAG, bool is64bit) const; // LDC

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't need to be virtual, right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, it's a cut-n-paste of LowerToTLSEmulatedModel above, which doesn't have multiple class implementations either. I have almost zero knowledge of the LLVM class hierarchy, just followed suit.

@@ -264,6 +265,7 @@ static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
return SectionKind::getThreadData();

if (Name == ".tbss" ||
(TargetTriple.isAndroid() && Name == ".tcommon") || // LDC
Copy link
Member

@kinke kinke Sep 23, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only found a single occurrence of .tcommon, as section for the _tlsend symbol. Is this line (and the extra param) really only required because of that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it ensures that the final executable always has the _tlsend symbol after all emulated TLS symbols, believe it was a trick Walter used in the original version of this emulated TLS scheme for dmd with OS X, which I copied to ldc.

This reminds me though that I'll likely be taking this out once I finally get emulated TLS working with reading the ELF headers and ditching these delimiter symbols, so this will likely change before the final 1.12 release anyway.

@kinke
Copy link
Member

kinke commented Sep 23, 2018

Lgtm. I'd suggest force-pushing directly onto the ldc-release_70 branch, replacing the previous commit by this reworked one.

@joakim-noah
Copy link
Author

I thought about removing the old version, but on the off chance someone already pulled this branch, I figured better not mess with the git history. We can always do that on a later branch.

@kinke
Copy link
Member

kinke commented Sep 23, 2018

Alright. A short summary as commit msg would be nice, based on the druntime comment in rt/sections_android.d, something like:

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 scheme 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.d). 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.

@joakim-noah
Copy link
Author

Sure, rebuilding LLVM now with the changes you suggested.

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.
@joakim-noah
Copy link
Author

Made the two changes you suggested, third is pending getting rid of section delimiters later, and expanded the commit message. Running through all the stdlib tests again, so far so good.

@joakim-noah joakim-noah merged commit aaa4575 into ldc-release_70 Sep 24, 2018
@joakim-noah joakim-noah deleted the tls branch September 24, 2018 06:19
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants