]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
LoongArch: Un-skip cross-segment alignment compensation during relax pass 2
authorWANG Xuerui <git@xen0n.name>
Fri, 11 Jul 2025 07:49:07 +0000 (15:49 +0800)
committercailulu <cailulu@loongson.cn>
Sat, 12 Jul 2025 02:36:10 +0000 (10:36 +0800)
It turned out wrong to skip compensating for segment alignment if the
current section is closed for deletion, as my recent system update with
binutils trunk revealed link failures of many high-profile packages such
as ffmpeg, numpy and wxGTK -- the dreaded "relocation truncated to fit"
errors regarding improperly produced R_LARCH_PCREL20_S2.

As it's near 2.45 branching time, revert the problematic change and
XFAIL the original test case for now.

Suggested-by: Xi Ruoyao <xry111@xry111.site>
Signed-off-by: WANG Xuerui <git@xen0n.name>
bfd/elfnn-loongarch.c
ld/testsuite/ld-loongarch-elf/relax-after-alignment.d

index c75f5206f2e05cb30a80cb697817c520ec828313..46fafb332de8ce98399a4f9321b3bc809e32ab4d 100644 (file)
@@ -5374,22 +5374,17 @@ loongarch_relax_pcala_addi (bfd *abfd, asection *sec, asection *sym_sec,
     symval = sec_addr (sec)
             + loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
 
-  /* If pc and symbol not in the same segment, add/sub segment alignment if the
-     section has not undergone alignment processing because distances may grow
-     after alignment.  */
-  if (!loongarch_sec_closed_for_deletion (sec))
-    {
-      if (!loongarch_two_sections_in_same_segment (info->output_bfd,
-                                                  sec->output_section,
-                                                  sym_sec->output_section))
-       max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
-                                                         : max_alignment;
-
-      if (symval > pc)
-       pc -= (max_alignment > 4 ? max_alignment : 0);
-      else if (symval < pc)
-       pc += (max_alignment > 4 ? max_alignment : 0);
-    }
+  /* If pc and symbol not in the same segment, add/sub segment alignment.  */
+  if (!loongarch_two_sections_in_same_segment (info->output_bfd,
+                                              sec->output_section,
+                                              sym_sec->output_section))
+    max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
+                                                     : max_alignment;
+
+  if (symval > pc)
+    pc -= (max_alignment > 4 ? max_alignment : 0);
+  else if (symval < pc)
+    pc += (max_alignment > 4 ? max_alignment : 0);
 
   const uint32_t pcaddi = LARCH_OP_PCADDI;
 
@@ -5444,22 +5439,17 @@ loongarch_relax_call36 (bfd *abfd, asection *sec, asection *sym_sec,
     symval = sec_addr (sec)
             + loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
 
-  /* If pc and symbol not in the same segment, add/sub segment alignment if the
-     section has not undergone alignment processing because distances may grow
-     after alignment.  */
-  if (!loongarch_sec_closed_for_deletion (sec))
-    {
-      if (!loongarch_two_sections_in_same_segment (info->output_bfd,
-                                                  sec->output_section,
-                                                  sym_sec->output_section))
-       max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
-                                                         : max_alignment;
-
-      if (symval > pc)
-       pc -= (max_alignment > 4 ? max_alignment : 0);
-      else if (symval < pc)
-       pc += (max_alignment > 4 ? max_alignment : 0);
-    }
+  /* If pc and symbol not in the same segment, add/sub segment alignment.  */
+  if (!loongarch_two_sections_in_same_segment (info->output_bfd,
+                                              sec->output_section,
+                                              sym_sec->output_section))
+    max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
+                                                     : max_alignment;
+
+  if (symval > pc)
+    pc -= (max_alignment > 4 ? max_alignment : 0);
+  else if (symval < pc)
+    pc += (max_alignment > 4 ? max_alignment : 0);
 
   /* Is pcalau12i + addi.d insns?  */
   if (!LARCH_INSN_JIRL (jirl)
@@ -5513,22 +5503,17 @@ loongarch_relax_pcala_ld (bfd *abfd, asection *sec,
     symval = sec_addr (sec)
             + loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
 
-  /* If pc and symbol not in the same segment, add/sub segment alignment if the
-     section has not undergone alignment processing because distances may grow
-     after alignment.  */
-  if (!loongarch_sec_closed_for_deletion (sec))
-    {
-      if (!loongarch_two_sections_in_same_segment (info->output_bfd,
-                                                  sec->output_section,
-                                                  sym_sec->output_section))
-       max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
-                                                         : max_alignment;
-
-      if (symval > pc)
-       pc -= (max_alignment > 4 ? max_alignment : 0);
-      else if (symval < pc)
-       pc += (max_alignment > 4 ? max_alignment : 0);
-    }
+  /* If pc and symbol not in the same segment, add/sub segment alignment.  */
+  if (!loongarch_two_sections_in_same_segment (info->output_bfd,
+                                              sec->output_section,
+                                              sym_sec->output_section))
+    max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
+                                                     : max_alignment;
+
+  if (symval > pc)
+    pc -= (max_alignment > 4 ? max_alignment : 0);
+  else if (symval < pc)
+    pc += (max_alignment > 4 ? max_alignment : 0);
 
   if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12)
       || (LARCH_GET_RD (ld) != rd)
@@ -5651,22 +5636,17 @@ loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
     symval = sec_addr (sec)
             + loongarch_calc_relaxed_addr (info, symval - sec_addr (sec));
 
-  /* If pc and symbol not in the same segment, add/sub segment alignment if the
-     section has not undergone alignment processing because distances may grow
-     after alignment.  */
-  if (!loongarch_sec_closed_for_deletion (sec))
-    {
-      if (!loongarch_two_sections_in_same_segment (info->output_bfd,
-                                                  sec->output_section,
-                                                  sym_sec->output_section))
-       max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
-                                                         : max_alignment;
-
-      if (symval > pc)
-       pc -= (max_alignment > 4 ? max_alignment : 0);
-      else if (symval < pc)
-       pc += (max_alignment > 4 ? max_alignment : 0);
-    }
+  /* If pc and symbol not in the same segment, add/sub segment alignment.  */
+  if (!loongarch_two_sections_in_same_segment (info->output_bfd,
+                                              sec->output_section,
+                                              sym_sec->output_section))
+    max_alignment = info->maxpagesize > max_alignment ? info->maxpagesize
+                                                     : max_alignment;
+
+  if (symval > pc)
+    pc -= (max_alignment > 4 ? max_alignment : 0);
+  else if (symval < pc)
+    pc += (max_alignment > 4 ? max_alignment : 0);
 
   const uint32_t pcaddi = LARCH_OP_PCADDI;
 
index 844c518e9c7e3e0ceded61d8a9c3275503935cd4..08def250998c64e266f70272d361e2355ca3c3f3 100644 (file)
@@ -2,6 +2,7 @@
 #as:
 #ld: --defsym _start=0
 #objdump: -d --no-show-raw-insn
+#xfail: *-*-*
 
 .*:\s+file format .*