[PATCH] LoongArch: Fix relocation of ignored undefined symbols

zhaozhou zhaozhou@loongson.cn
Tue Sep 29 12:01:25 GMT 2026


For LoongArch, an ignored undefined symbol that fails to resolve locally
is treated as dynamically resolved.

Enable --unresolved-symbols=ignore-all Branch and call relocations of
ignored undefined symbol could request a non-exist PLT entry thus
trigger a BFD assertion.

Classify ignored symbols without a dynamic symbol entry as constants,
and keep ignored symbols with dynamic entries dynamically resolved,
since RM_IGNORE is also the default for shared links and their calls
must still use the PLT.
---
 bfd/elfnn-loongarch.c                                 |  5 +++--
 ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp    |  1 +
 ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.d | 11 +++++++++++
 ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.s |  4 ++++
 4 files changed, 19 insertions(+), 2 deletions(-)
 create mode 100644 ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.s

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 1a2b3b0399e..f5fa771f2e5 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3656,8 +3656,9 @@ loongarch_elf_relocate_section (struct bfd_link_info *info,
 	      defined_local = !unresolved_reloc && !ignored;
 	      resolved_local =
 		defined_local && LARCH_REF_LOCAL (info, h);
-	      resolved_dynly = !resolved_local;
-	      resolved_to_const = !resolved_local && !resolved_dynly;
+	      resolved_to_const =
+		!resolved_local && ignored && (!is_dyn || h->dynindx == -1);
+	      resolved_dynly = !resolved_local && !resolved_to_const;
 	    }
 	}
 
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 7ea99f1d0cc..6ea30f09e86 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -54,6 +54,7 @@ if [istarget "loongarch64-*-*"] {
     run_dump_test "relax-sym-size-1"
     run_dump_test "relax-sym-size-2"
     run_dump_test "check_got_relax"
+    run_dump_test "unresolved-ignore-all"
 
     # Tidy up, to not leave huge intermediate files.
     remote_file host delete tmpdir/relax-medium-call.o
diff --git a/ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.d b/ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.d
new file mode 100644
index 00000000000..96424ce2df6
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.d
@@ -0,0 +1,11 @@
+#source: unresolved-ignore-all.s
+#ld: -e 0 -Ttext=0x100 --unresolved-symbols=ignore-all
+#objdump: -d
+
+#...
+0000000000000100 <a>:
+[ 	]+100:[ 	]+1e000001[ 	]+pcaddu18i[ 	]+\$ra,[ 	]+0
+[ 	]+104:[ 	]+4c000021[ 	]+jirl[ 	]+\$ra,[ 	]+\$ra,[ 	]+0
+[ 	]+108:[ 	]+1e000001[ 	]+pcaddu18i[ 	]+\$ra,[ 	]+0
+[ 	]+10c:[ 	]+4ffff821[ 	]+jirl[ 	]+\$ra,[ 	]+\$ra,[ 	]+-8
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.s b/ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.s
new file mode 100644
index 00000000000..6db7a60cc34
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/unresolved-ignore-all.s
@@ -0,0 +1,4 @@
+       .text
+a:
+       call    undef_func
+       call    a
-- 
2.20.1



More information about the Binutils mailing list