[PATCH v2 0/3] ld: shared library and PIE support for riscv*-elf and loongarch*-elf

mintsuki mintsuki@protonmail.com
Wed Sep 9 07:04:28 GMT 2026


ld refuses both -shared and -pie for riscv*-elf and loongarch*-elf,
because their emulparams files withhold GENERATE_SHLIB_SCRIPT and
GENERATE_PIE_SCRIPT from those two targets specifically.  This is not
the EMBEDDED policy at work -- neither file sets EMBEDDED -- but a pair
of one-off "case $target" checks: be1dce26256a for RISC-V, copied into
the LoongArch port from it.  Other bare-metal ELF targets generate the
scripts; aarch64*-elf was given PIE support on purpose in 3af09e8db308,
and f2aaebdb9797, which would have taken it away from EMBEDDED targets
generally, was reverted in 8a46e447a88d:

  https://inbox.sourceware.org/binutils/20191108103411.GU6708@bubble.grove.modra.org/

What this blocks in practice is freestanding relocatable outputs.
Those need -pie (or, alternatively, -shared -Bsymbolic), as already
supported by x86_64-elf, i686-elf, aarch64-elf, etc...
On riscv64-elf and loongarch64-elf compilers accept -fPIE and -fPIC,
but the link step using ld.bfd dies with "-pie not supported" or
"-shared not supported", so a bare-metal toolchain, that is otherwise
complete, cannot build a freestanding relocatable output. A *-linux
(or otherwise other hosted) ld.bfd (or LLVM's lld) has to be used
for the link step instead.

Patch 2 is testsuite preparation.  Three LoongArch DT_RELR tests write
out the symbol index of r_info in full, and that index depends on the
default hash style: GNU hash requires undefined symbols to precede
defined ones in .dynsym, so an undefined weak in those tests sorts to
index 2 under the linux default of "both" and to the end of the table
under the bare-metal default of sysv.  The relocations themselves are
correct either way.  Without that patch, patch 3 turns those three from
unsupported into FAIL.

Based on 2986ed8ba365 ("Constify targ_desc").  Tested with gcc 16.2.0
riscv64-elf and loongarch64-elf toolchains and dejagnu 1.6.3.
make check-ld, before and after the series:

  riscv64-elf       541 -> 763 passes, 0 unexpected failures either way
  loongarch64-elf   540 -> 703 passes, 0 unexpected failures either way

No test regresses on either target, and there are no unexpected
successes; the increase is the shared and PIE tests that were previously
skipped now running.  I have not tested the 32-bit variants, riscv32-elf
and loongarch32-elf, which the same emulparams files cover.

Mintsuki (3):
  RISC-V: Enable shared library and PIE support for riscv*-elf
  ld: Pin the hash style in the LoongArch DT_RELR shared tests
  LoongArch: Enable shared library and PIE support for loongarch*-elf

 ld/emulparams/elf32loongarch-defs.sh                | 11 ++---------
 ld/emulparams/elf32lriscv-defs.sh                   | 11 ++---------
 ld/emulparams/elf64loongarch-defs.sh                | 11 ++---------
 ld/testsuite/ld-loongarch-elf/relr-data-shared.d    |  2 +-
 ld/testsuite/ld-loongarch-elf/relr-discard-shared.d |  2 +-
 ld/testsuite/ld-loongarch-elf/relr-got-shared.d     |  2 +-
 6 files changed, 9 insertions(+), 30 deletions(-)



More information about the Binutils mailing list