[PATCH v2] LoongArch: only insert align section for ld -r if an input has R_LARCH_ALIGN or R_LARCH_RELAX

Xi Ruoyao via Binutils <[email protected]>
Newsgroups gmane.comp.gnu.binutils
Message-ID <[email protected]>
Commit 8bf4b69718d4 ("LoongArch: Fix relaxation alignment with ld -r (PR
33236)") has broken the kernel modules on Debian sid.  The expectation
of the kernel is all the source files which would be linked into a
module are compiled with -mno-relax so the module should not contain
R_LARCH_ALIGN, thus the module loader rejects any module containing
R_LARCH_ALIGN.

To restore the correctness of the expectation, only insert the align
section if an input has R_LARCH_ALIGN or R_LARCH_ALIGN (i.e. bytes may
be removed from that input).  Regardless of the kernel modules, it also
does not make too much sense to bloat the output with NOPs and
R_LARCH_ALIGN if no input ever contains R_LARCH_ALIGN and R_LARCH_ALIGN
anyway.

Signed-off-by: Xi Ruoyao <[email protected]>
---

Superseds v1
(https://sourceware.org/pipermail/binutils/2026-July/150206.html).

 bfd/elfnn-loongarch.c                         | 31 +++++++++++++++++--
 .../relax-align-ld-r-norelax.d                |  9 ++++++
 ld/testsuite/ld-loongarch-elf/relax.exp       |  1 +
 3 files changed, 39 insertions(+), 2 deletions(-)
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-ld-r-norelax.d

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 03b0eb40ac7..4bdc3f26285 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -139,6 +139,10 @@ struct loongarch_elf_link_hash_table
   /* Pending relaxation (byte deletion) operations meant for roughly
      sequential access.  */
   splay_tree pending_delete_ops;
+
+  /* If any input contains a reloc potentially removing bytes, i.e.
+     R_LARCH_ALIGN or R_LARCH_RELAX.  */
+  bool reloc_may_remove_bytes;
 };
 
 struct loongarch_elf_section_data
@@ -1109,10 +1113,26 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
   const Elf_Internal_Rela *rel;
   asection *sreloc = NULL;
 
+  htab = loongarch_elf_hash_table (info);
+
   if (bfd_link_relocatable (info))
-    return true;
+    {
+      if (!htab->reloc_may_remove_bytes)
+	for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
+	  switch (ELFNN_R_TYPE (rel->r_info))
+	    {
+	    case R_LARCH_ALIGN:
+	    case R_LARCH_RELAX:
+	      htab->reloc_may_remove_bytes = true;
+	      return true;
+	    default:
+	      continue;
+	    }
+
+      /* No need for more checks with ld -r.  */
+      return true;
+    }
 
-  htab = loongarch_elf_hash_table (info);
   symtab_hdr = &elf_symtab_hdr (abfd);
   sym_hashes = elf_sym_hashes (abfd);
 
@@ -7098,7 +7118,14 @@ elfNN_loongarch_size_aligns (bfd *output_bfd,
 					  (const char *, asection *),
 			     void (*layout_sections_again) (void))
 {
+
+  struct loongarch_elf_link_hash_table *htab;
   bool need_laying_out = false;
+
+  htab = loongarch_elf_hash_table (info);
+  if (!htab->reloc_may_remove_bytes)
+    return true;
+
   for (bfd *input_bfd = info->input_bfds; input_bfd != NULL;
        input_bfd = input_bfd->link.next)
     {
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-ld-r-norelax.d b/ld/testsuite/ld-loongarch-elf/relax-align-ld-r-norelax.d
new file mode 100644
index 00000000000..5f33b8b4d89
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-ld-r-norelax.d
@@ -0,0 +1,9 @@
+#source: relax-align-ld-r.s
+#as: -mno-relax
+#ld: -r
+#objdump: -Dr
+
+#failif
+#...
+.*R_LARCH_ALIGN.*
+#...
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index bb8429ab515..bf4955f4c62 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -49,6 +49,7 @@ proc run_partial_linking_align_test {} {
 if [istarget loongarch*-*-*] {
   run_dump_test "relax-align-1"
   run_dump_test "relax-align-ld-r"
+  run_dump_test "relax-align-ld-r-norelax"
 }
 
 if [istarget loongarch64-*-*] {
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.