[PATCH] LoongArch: Fix the bug of R_LARCH_AGLIN caused by discard section

mengqinggang mengqinggang@loongson.cn
Sun Feb 4 06:53:38 GMT 2024


To represent the first and third expression of .align, R_LARCH_ALIGN need to
associate with a symbol. We defind a local symbol for R_LARCH_AGLIN.
But if the section of the local symbo is discarded, it may result in
a undefined symbol error.

Instead, we use the section name symbols, and this does not need to
add extra symbols.

During partial linking (ld -r), if the symbol associated with a relocation is
STT_SECTION type, the addend of relocation needs to add the section output
offset. We prevent it for R_LARCH_ALIGN.
---
 bfd/elflink.c                                 |  9 +++++++--
 gas/config/tc-loongarch.c                     |  5 +----
 gas/testsuite/gas/loongarch/relax_align.d     | 20 +++++++++----------
 .../ld-loongarch-elf/relax-align-discard.lds  |  4 ++++
 .../ld-loongarch-elf/relax-align-discard.s    | 17 ++++++++++++++++
 ld/testsuite/ld-loongarch-elf/relax.exp       | 12 +++++++++++
 6 files changed, 51 insertions(+), 16 deletions(-)
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-discard.lds
 create mode 100644 ld/testsuite/ld-loongarch-elf/relax-align-discard.s

diff --git a/bfd/elflink.c b/bfd/elflink.c
index c2494b3e12e..33abac85fa2 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11813,8 +11813,13 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 			}
 
 		      /* Adjust the addend according to where the
-			 section winds up in the output section.  */
-		      if (rela_normal)
+			 section winds up in the output section.
+			 The addend of R_LARCH_ALIGN is used to represent the
+			 first and the third expression of .align and not need
+			 to add sec->output_offset.  */
+		      if (rela_normal
+			  && !(bed->elf_machine_code == EM_LOONGARCH
+				&& (irela->r_info & 0xff) == 0x66))
 			irela->r_addend += sec->output_offset;
 		    }
 		  else
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 91f5f1d0681..3fa70c1c85f 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -1746,10 +1746,7 @@ loongarch_frag_align_code (int n, int max)
 
   nops = frag_more (worst_case_bytes);
 
-  s = symbol_find (".Lla-relax-align");
-  if (s == NULL)
-    s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg,
-				      &zero_address_frag, 0);
+  s = symbol_find (now_seg->name);
 
   ex.X_add_symbol = s;
   ex.X_op = O_symbol;
diff --git a/gas/testsuite/gas/loongarch/relax_align.d b/gas/testsuite/gas/loongarch/relax_align.d
index 2cc6c86d38a..6710927be1b 100644
--- a/gas/testsuite/gas/loongarch/relax_align.d
+++ b/gas/testsuite/gas/loongarch/relax_align.d
@@ -1,4 +1,4 @@
-#as: --no-warn
+#as:
 #objdump: -dr
 #skip: loongarch32-*-*
 
@@ -7,27 +7,27 @@
 
 Disassembly of section .text:
 
-[ 	]*0000000000000000 <.Lla-relax-align>:
+[ 	]*0000000000000000 <.text>:
 [ 	]+0:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0, 0
 [ 	]+0: R_LARCH_PCALA_HI20[ 	]+L1
 [ 	]+0: R_LARCH_RELAX[ 	]+\*ABS\*
 [ 	]+4:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0, \$a0, 0
 [ 	]+4: R_LARCH_PCALA_LO12[ 	]+L1
 [ 	]+4: R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+8:[ 	]+03400000[ 	]+nop.*
-[ 	]+8: R_LARCH_ALIGN[ 	]+.Lla-relax-align\+0x4
-[ 	]+c:[ 	]+03400000[ 	]+nop.*
-[ 	]+10:[ 	]+03400000[ 	]+nop.*
+[ 	]+8:[ 	]+03400000[ 	]+nop
+[ 	]+8: R_LARCH_ALIGN[ 	]+.text\+0x4
+[ 	]+c:[ 	]+03400000[ 	]+nop
+[ 	]+10:[ 	]+03400000[ 	]+nop
 [ 	]+14:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0, 0
 [ 	]+14: R_LARCH_PCALA_HI20[ 	]+L1
 [ 	]+14: R_LARCH_RELAX[ 	]+\*ABS\*
 [ 	]+18:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0, \$a0, 0
 [ 	]+18: R_LARCH_PCALA_LO12[ 	]+L1
 [ 	]+18: R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+1c:[ 	]+03400000[ 	]+nop.*
-[ 	]+1c: R_LARCH_ALIGN[ 	]+.Lla-relax-align\+0x404
-[ 	]+20:[ 	]+03400000[ 	]+nop.*
-[ 	]+24:[ 	]+03400000[ 	]+nop.*
+[ 	]+1c:[ 	]+03400000[ 	]+nop
+[ 	]+1c: R_LARCH_ALIGN[ 	]+.text\+0x404
+[ 	]+20:[ 	]+03400000[ 	]+nop
+[ 	]+24:[ 	]+03400000[ 	]+nop
 [ 	]+28:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0, 0
 [ 	]+28: R_LARCH_PCALA_HI20[ 	]+L1
 [ 	]+28: R_LARCH_RELAX[ 	]+\*ABS\*
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-discard.lds b/ld/testsuite/ld-loongarch-elf/relax-align-discard.lds
new file mode 100644
index 00000000000..4a81323d926
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-discard.lds
@@ -0,0 +1,4 @@
+SECTIONS
+{
+  /DISCARD/ : { *(.another.*) }
+}
diff --git a/ld/testsuite/ld-loongarch-elf/relax-align-discard.s b/ld/testsuite/ld-loongarch-elf/relax-align-discard.s
new file mode 100644
index 00000000000..b65d63f370f
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/relax-align-discard.s
@@ -0,0 +1,17 @@
+# Use the section name symbol for R_LARCH_ALIGN to avoid discard section problem
+.section ".another.text", "ax"
+.cfi_startproc
+break 0
+.cfi_def_cfa_offset 16
+.p2align 5
+break 1
+.cfi_endproc
+
+.text
+.cfi_startproc
+break 0
+.cfi_def_cfa_offset 16
+.p2align 5
+break 1
+.cfi_endproc
+
diff --git a/ld/testsuite/ld-loongarch-elf/relax.exp b/ld/testsuite/ld-loongarch-elf/relax.exp
index f421e8af8dd..a1465dca21c 100644
--- a/ld/testsuite/ld-loongarch-elf/relax.exp
+++ b/ld/testsuite/ld-loongarch-elf/relax.exp
@@ -295,6 +295,18 @@ if [istarget loongarch64-*-*] {
 		"relax-align" \
 	    ] \
 	]
+
+    run_ld_link_tests \
+      [list \
+	[list \
+	  "loongarch relax align discard" \
+	  "-e 0x0 -T relax-align-discard.lds -r" "" \
+	  "" \
+	  {relax-align-discard.s} \
+	  {} \
+	  "relax-align-discard" \
+	] \
+      ]
   }
 
   set objdump_flags "-s -j .data"
-- 
2.36.0



More information about the Binutils mailing list