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

mengqinggang mengqinggang@loongson.cn
Wed Jul 15 07:51:45 GMT 2026


LGTM, thanks!


在 2026/7/14 23:51, Xi Ruoyao 写道:
> 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 <xry111@xry111.site>
> ---
>
> 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-*-*] {



More information about the Binutils mailing list