This is a replacement and extension for this patch:
The standard representation of Thread Local Storage (TLS) is as follows:
addis r3, r2, x@got@tlsgd@ha // R_PPC64_GOT_TLSGD16_HA addi r3, r3, x@got@tlsgd@l // R_PPC64_GOT_TLSGD16_LO bl __tls_get_addr(x@tlsgd) // R_PPC64_TLSGD followed by R_PPC64_REL24 nop
The above is specified in the Power PC ELFv2 ABI in section:
18.104.22.168. General Dynamic TLS Model
However, there are two deviations form the above that have been seen in actual
- A direct call to __tls_get_addr.
bl __tls_get_addr nop
- Missing R_PPC64_TLSGD relocation.
addis r3, r2, x@got@tlsgd@ha // R_PPC64_GOT_TLSGD16_HA addi r3, r3, x@got@tlsgd@l // R_PPC64_GOT_TLSGD16_LO bl __tls_get_addr // R_PPC64_REL24 nop
A direct call does not cause lld to produce incorrect code gen. If
the user is careful enough to correctly setup the inputs to the function the
code will work. Also, it appears that some implementations of ld.so do this
The second situation where the R_PPC64_TLSGD relocation is missing is a
different story. Generating the second code sequence will cause lld to produce
incorrect code gen when relaxing the sequence to Local Exec. The first two
relocations (R_PPC64_GOT_TLSGD16_HA and R_PPC64_GOT_TLSGD16_LO) will be relaxed
correctly but since the call is missing a relocation it will be left as-is
which will ultimately result in an incorrect TLS address being computed.
This patch tries to address the problem of the missing R_PPC64_TLSGD relocaiton.
An option has been added --fix-ppc64-tls-reloc.
By default if the option is not specified lld will behave just as it has done in the past.
If the option is specified then lld will check all calls to __tls_get_addr for the missing relocation.
If the relocation is missing then TLS relaxation will be turned off so the the incorrect
code is not produced.