mirror of
git://c9x.me/qbe.git
synced 2026-08-02 15:44:39 +00:00
When extern was added, the rv64 code switched regular globals from using la (a pseudo-instruction that uses pc-relative addressing with auipc + addi) to lui + addi (absolute addressing). Presumably, this was done to match gcc's output with -fPIC and -fno-PIC respectively. However, the key difference here is actually the directive `%option pic` vs `%option nopic`, which determines whether la uses the GOT or not. This broke linking as PIE (for instance in compilers with --enable-default-pie), even when there are no global references outside the executable. The other architectures always use pc-relative addressing, so rv64 should do the same. It turns out there are more specific pseudo-instructions lla and lga we can use instead. lla uses auipc+addi, and lga uses auipc+ld from the GOT. lga does not allow an offset. If you try to use one, it will assemble without error, but fail at link time with (.text+0x10): dangerous relocation: The addend isn't allowed for R_RISCV_GOT_HI20 For now, just add a check for this. A proper fix involves some changes to rv64/isel like is done for amd64. |
||
|---|---|---|
| .. | ||
| abi.c | ||
| all.h | ||
| emit.c | ||
| isel.c | ||
| targ.c | ||