[PATCH] D53906: [ELF] Allow configuring the TLS layout for an Android executable

Ryan Prichard via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 30 16:31:52 PDT 2018


rprichard added reviewers: ruiu, aivchenk, kristof.beyls, peter.smith, srhines.
rprichard added a comment.

I'm currently planning to use a 16-word TCB layout on all architectures for Android, but I'm not completely committed to that yet. This patch can accommodate a larger TCB. I'm also considering using a variant 2 layout instead, which would reuse some of this patch, but would require additional work to accommodate negative offsets on arm64.

Details:

Android can't use the standard TLS layout on arm64 because of the stack protector cookie conflict described above.

There is another problem with the golang runtime that currently requires allocating the pthread keys (1KB on 32-bit, 2KB on 64-bit) after the thread pointer. On Android/arm{32,64}, golang allocates a "g" register by scanning from the thread pointer until it has found a TLS slot. (https://github.com/golang/go/blob/0ad332d80cf3e2bbeef5f1e5f5eb50272bbde92e/src/runtime/cgo/gcc_android_arm64.c). I'm hoping that golang can find a more robust way of allocating its TLS memory, but Android might need to work with the current runtime regardless.

Allocating a much larger TCB is a simple workaround, but tends to make future changes to the Bionic pthread layout harder in the future.

Alternatively, maybe Android could use variant 2 everywhere instead. That's problematic on arm64 because the 12-bit and 24-bit TLS models relocate add/ld/st instructions using 12-bit unsigned offsets. arm64 also has 32-, 48-, and 64-bit models that use signed offsets, but they're less efficient, and LLVM only implements the 24-bit model.

The most obvious way to adopt the 24-bit model to variant 2 requires replacing a "add xN, xN, :tprel_hi12:VAR" instruction with a subtract instruction of an adjusted offset. (If I got the math right, it needs to subtract ((-Offset + 0xfff) >> 12). The lower 12-bits are then added using an add or a ld/st instruction. The R_AARCH64_TLSLE_ADD_TPREL_HI12 relocation is intended to relocate an add instruction, so we'd need to define a new relocation or perhaps modify R_AARCH64_TLSLE_ADD_TPREL_HI12 to switch the add to a subtract. Both approaches seem unpleasant.


Repository:
  rLLD LLVM Linker

https://reviews.llvm.org/D53906





More information about the llvm-commits mailing list