This allows the local-exec model to be used for any non-PIC TLS reference,
even if it cannot be proven at compile time that the access binds locally.
It essentially obviates the need for IE -> LE relaxations.
Previously, we had multiple low-part PC-relative relocs, e.g.
R_RISCV_GOT_LO12 and R_RISCV_TLS_GD_LO12. But since these are indirect
relocs and enough info is encoded in the high part, they are redundant.
Now, we only have two: R_RISCV_PCREL_LO12_I and R_RISCV_PCREL_LO12_S.
For example, the following PIC code adds TLS variables x and y:
.L1: auipc a0, %tls_ie_pcrel_hi(x)
.L2: auipc a1, %tls_ie_pcrel_hi(y)
ld a0, %pcrel_lo(.L1)(a0)
ld a1, %pcrel_lo(.L2)(a1)
ld a0, 0(a0)
ld a1, 0(a1)
add a0, a0, a1
The new BFD port is primarily based upon TILE-Gx, which is conveniently
simple and vanilla. We no longer have dynamic REL relocations, and the
GOT no longer needs to be sorted a la MIPS. So GNU-style shared object
hashes are now supported.
Note that there are probably a few lingering issues.
First of all, never spill symbolic addresses to the constant pool. This
creates costly dynamic relocations while providing little benefit.
Second, due to a bug, we were failing to elide the GOT for local symbol
references with nonzero offsets.
The low part uses an indirect relocation to the high part to determine
how to fill itself in. For example:
.L1:
auipc t0, %pcrel_hi(foo)
[unrelated code]
addi t0, t0, %pcrel_lo(.L1)
will correctly load &foo into t0.
It turns out that this instruction sequence can be generated to call
an absolute address. This adds a comment to the JALR with the full
expanded address, which is useful for debugging (it turns out it's
easier to just let my PC do addition rather than having to do it in my
head).
Note that amd64 does this exact thing, so it's probably correct... :)
Signed-off-by: Palmer Dabbelt <palmer.dabbelt@eecs.berkeley.edu>
Doing so removes their commonness, as though -fno-common had been set.
The sbss optimization is still available by specifying -fno-common.
h/t Matt Thomas