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
Both forms are technically not valid according to the ABI. No new code should
be producing either of the two forms.
However, 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
direct call. Therefore, this patch silently allows for the simple direct call.
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 --add-missing-tls-reloc.
By default if the option is not specified lld will report an error or a warning
when the missing relocation is encountered. If the option is specified then lld
will try to add the missing relocation to the __tls_get_addr call.