[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