This is an archive of the discontinued LLVM Phabricator instance.

Fix fatal linker error on R_MIPS_JALR against a local TLS symbol
AbandonedPublic

Authored by arichardson on Nov 17 2019, 11:17 AM.

Details

Summary

In order to determine whether R_MIPS_JALR should use R_PC or R_NONE, the
MIPS code checks whether the target is preemptible and not microMIPS.
To check the later condition we look at the low bit of the virtual address.
However, for TLS symbols calling Symbol::getVA() will report a fatal error
until Out::tlsPhdr has been initialized (which only happens later).

It is unclear whether clang should be emitting these relocations for TLS
symbols in the first place, but we should be able to handle this without
failing in LLD even if clang is later change to not emit the relocation.

Event Timeline

arichardson created this revision.Nov 17 2019, 11:17 AM

Check objdump output

Add .set noreorder to avoid excessive nops and make test more readable

Harbormaster completed remote builds in B41092: Diff 229725.

R_MIPS_JALR really should not be being emitted here; its semantics are a hint to say that you are making a direct call to the referenced symbol (albeit by indirecting through a loaded GOT entry), but this is an indirect call. Interestingly, Local Dynamic is the only case where LLVM wants to emit the relocation; the three other models all leave it out, as does a normal global. This is because it happens to have the same structure as a direct call in the SelectionDAG representation, with the second operand for the instruction defining $t9 being a GlobalAddressSDNode, just this time an MO_DTPREL_LO rather than the expected MO_GOT_CALL (%call16)/MO_CALL_LO16 (%call_lo).

This change is no longer necessary after https://reviews.llvm.org/D70406. I wonder if the testcase is still useful?

arichardson abandoned this revision.Nov 19 2019, 3:57 AM

No longer required after integrating test into D70406