ARM has three dynamic relocations for TLS:
- R_ARM_TPOFF32 (Offset of S from Thread Pointer)
- R_ARM_DTPMOD32 (Module-Id, always 1 for executables)
- R_ARM_DTPOFF32 (Offset of S from TLS block)
When static linking we must resolve these relocations statically by writing the values directly into the .got. In many ways ARM is similar to Mips:
- TLS is not relaxable so the linker can't rely on relaxing global and local dynamic away.
- ARM is type 1 TLS (TLS block is immediately after Thread Pointer and precedes TLS data) so the TCB size has to be accounted for when resolving R_ARM_TPOFF32.
- The R_ARM_DTPMOD32 needs to be hard coded to 1 in applications.
To implement this I've:
- Removed the fixme in handleNoRelaxTlsRelocation() which always added dynamic relocations for ARM TLS
- Recorded where symbols have been relocated by a Target->TlsGotRel, R_ARM_TLS_TPOFF32 for ARM
- Introduce a writeARMGot(), similar to writeMipsGot() to isolate the special cases from the other Targets.
- Write the module index to be 1 (from Global Dynamic or Local Dynamic)
- Account for the Target->TcbSize when writing the value of a symbol that has been recorded as being referenced by R_ARM_TPOFF32.
The changes show up in the existing tests. As we no longer need the dynamic relocation for the module index and the GOT entries that are statically resolved R_ARM_TLS_TPOFF32 relocations include the ARM TcbSize of 8.
The implementation of writeARMGot() is similar to writeMipsGot() in the way it handles TLS.
The Mips implementation uses Config->Pic consistently to use dynamic relocations. For ARM I've used Config->Shared as an executable can still use Pic, and can still be statically linked with Pic.
This is the same value as what R_TLS would compute, no?
now that the got is a synthetic section, it has a Relocations array. Could we maybe use that instead of Entries? So the code for having a non zero value in the got would become something like
Do you think that would be better? If not something like this (rebase now that .got is a synthetic section) is probably ok.