[PATCH] D61824: [ARM][AArch64] Overalign SHF_TLS instead of PT_TLS (Android Bionic hack) to make glibc happy

Ryan Prichard via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 15 03:16:10 PDT 2019


rprichard added a comment.

In D61824#1500063 <https://reviews.llvm.org/D61824#1500063>, @MaskRay wrote:

> @rprichard Rich Felker briefly mentioned this can be worked around in crt1.o. My understanding is that:
>
> 1. create a dummy `.tdata` ((a) with placeholder TLS variables of `8*sizeof(void*)` bytes (b) `sh_addralign=8*sizeof(void*)`) in `crt1.o` (and its variants)
> 2. create a `R_{ARM,AARCH64}_NONE` from `.text` offset 0 to the `.tdata` (this prevents `--gc-sections` stripping)
> 3. no hack is needed in ld.bfd/gold/lld. crt1.o is linked into executables. The linker applies its usual Rules for Linking Unrecognized Sections <http://www.sco.com/developers/gabi/latest/ch4.sheader.html> and concatenates `.tdata` and `.tbss`. The `.tdata` from `crt1.o` will be the first input section in the TLS segment. Don't use the dummy part of the TLS block (they may collide with Bionic's reserved TLS slots)
>
>   Does this approach work?


I think that basically works. It would add a TLS segment to every Android executable, even those that aren't using ELF TLS:

- If the placeholder symbol has size 1 and 64-byte alignment, then every Android executable (targeting Q(29) and up) would have a PT_TLS segment of 64-byte size and alignment with gold or lld.
- If the placeholder symbol in .tdata has size 0 instead, then ld.bfd omits the .tdata section from the output if there aren't any other non-empty .tdata sections. This is a problem if there are other TLS sections (.tbss). Android is switching to lld, though, so maybe it's OK. (The NDK still defaults to bfd and gold.)
- If the placeholder symbol has a size of 48 bytes and 1-byte alignment, then libc.so can't use alignment to detect whether space was reserved. I can think of a couple ways for space to not be reserved:
  - Using an NDK that's too old
  - Using a too-old NDK API level, assuming this placeholder symbol is omitted when targeting old versions of Bionic (because Q(29) is currently rejecting an underaligned TLS segment...)

> The linker applies its usual Rules for Linking Unrecognized Sections

I don't think these rules apply to .tdata and .tbss, because the linker should recognize the SHF_TLS flag?

Bionic is requiring that executables (dynamic ones, at least) leave their section tables unstripped. Maybe Bionic could look for a special SHF_TLS section (.tcb_reservation?) at the start of the TLS segment to sanity-check whether space was properly reserved? The section would need to be located before .tdata and .tbss, but I think it could be output in crtbegin*.o.

Aside: An `R_{ARM,AARCH64}_NONE` relocation to a TLS symbol has the desired effect. Is there a better way to create this relocation than by using a hex editor?


Repository:
  rLLD LLVM Linker

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61824/new/

https://reviews.llvm.org/D61824





More information about the llvm-commits mailing list