[PATCH] D92959: [ELF][PPC64] Add --fix-ppc64-tls-reloc to detect and fix missing R_PPC64_TLSGD/R_PPC64_TLSLD

Fangrui Song via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 9 11:55:40 PST 2020


MaskRay created this revision.
MaskRay added reviewers: PowerPC, nemanjai, sfertile, stefanp.
Herald added subscribers: dang, steven.zhang, s.egerton, shchenz, simoncook, kbarton, krytarowski, arichardson, emaste.
Herald added a reviewer: espindola.
MaskRay requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Alternative to D91611 <https://reviews.llvm.org/D91611>.

The TLS General Dynamic/Local Dynamic code sequences need to mark
`__tls_get_addr` with R_PPC64_TLSGD or R_PPC64_TLSLD, e.g.

  addis r3, r2, x at got@tlsgd at ha # R_PPC64_GOT_TLSGD16_HA
  addi r3, r3, x at got@tlsgd at l   # R_PPC64_GOT_TLSGD16_LO
  bl __tls_get_addr(x at tlsgd)   # R_PPC64_TLSGD followed by R_PPC64_REL24
  nop

However, there are two deviations form the above:

1. direct call to `__tls_get_addr`. This is essential to implement ld.so in glibc/musl/FreeBSD.

  bl __tls_get_addr
  nop

This is only used in a -shared link, and thus not subject to the GD/LD to IE/LE
relaxation issue below.

2. Missing R_PPC64_TLSGD/R_PPC64_TLSGD for compiler generated TLS references

According to Stefan Pintille, "In the early days of the transition from the
ELFv1 ABI that is used for big endian PowerPC Linux distributions to the ELFv2
ABI that is used for little endian PowerPC Linux distributions, there was some
ambiguity in the specification of the relocations for TLS. The GNU linker has
implemented support for correct handling of calls to __tls_get_addr with a
missing relocation.  Unfortunately, we didn't notice that the IBM XL compiler
did not handle TLS according to the updated ABI until we tried linking XL
compiled libraries with LLD."

In short, LLD needs to work around the old IBM XL compiler issue.
Otherwise, if the object file is linked in -no-pie or -pie mode,
the result will be incorrect because the 4 instructions are partially
rewritten (the latter 2 are not changed).

While GNU ld detects the missing R_PPC64_TLSGD/R_PPC64_TLSLD and disables GD/LD
to IE/LE relaxation automatically, this approach can affect performance and the
value of the workaround will dilute over time anyway, so our consensus on LLD
side is to implement the behavior under an option: --fix-ppc64-tls-reloc.

Note, we also disable Initial Exec to Local Exec relaxation for implementation
simplicity, though technically it can be kept.

ppc64-tls-missing-gdld.s demonstrates the updated behavior.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D92959

Files:
  lld/ELF/Config.h
  lld/ELF/Driver.cpp
  lld/ELF/InputFiles.h
  lld/ELF/Options.td
  lld/ELF/Relocations.cpp
  lld/test/ELF/ppc64-options.s
  lld/test/ELF/ppc64-tls-missing-gdld.s
  lld/test/ELF/ppc64-tocopt-option.s

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92959.310602.patch
Type: text/x-patch
Size: 9800 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201209/090a5c02/attachment.bin>


More information about the llvm-commits mailing list