[PATCH] D61824: [ARM][AArch64] Overalign .tbss (Android Bionic hack) to avoid p_vaddr%p_align!=0

Ryan Prichard via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 15 21:04:32 PDT 2019


rprichard added a comment.

In D61824#1502750 <https://reviews.llvm.org/D61824#1502750>, @nsz wrote:

> In D61824#1502690 <https://reviews.llvm.org/D61824#1502690>, @rprichard wrote:
>
> > 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...)
>
>
> i think the placeholder tls symbol size and alignment should
>  be exactly such that it covers the bionic internal tls slots.


If the placeholder symbol has 48-byte-size, 1-byte-alignment, it would cover the internal slots as long as the executable's TLS alignment is 16 or less. At higher levels of alignment, the placeholder shifts forward. At an alignment of 64 bytes, the placeholder isn't needed anymore, but it's still wasting TLS memory.

Linker magic could compute the TLS section alignment and insert a placeholder section/symbol of the size needed to cover the slots exactly.

In any case, as long as libc could find the placeholder symbol, it could verify that it covered the intersection of the TLS segment and the internal slots.

> in principle the symbol check can be done using weak reference
>  but i don't think undef weak tls sym reliably evaluates to 0,
>  so i'd just rely on plain symbol interposition (placeholder
>  is size 1 extern tls sym in libc that is interposed by the
>  placeholder from the .exe)
> 
>> 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?
> 
> why not export the symbol?
>  then it cannot be removed for sure.
>  (i think gas has a .reloc directive that accepts R_AARCH64_NONE as argument, not sure if llvm handles that)

It looks like using a version script on an executable (e.g. with a `local: *;` wildcard) would hide an interposed symbol. libc.so wouldn't find the placeholder and would abort the process. Version scripts on executables are probably rare, though?


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