[PATCH v2] LoongArch: Fix wrong relocation handling of symbols defined by PROVIDE
Lulu Cai
cailulu@loongson.cn
Fri Aug 16 01:33:51 GMT 2024
If the symbol defined by PROVIDE in the linker scripts is not in SECTION,
the symbol is placed in the ABS section. The linker considers that
symbols in the ABS section do not need to calculate PC relative offsets.
We only allow ABS symbols defined in the linker scripts to be affected by
PC relative relocations.
---
Changes from v1:
* Only ABS symbols defined in the linker scripts can be affected by PC
relative relocations.
v1 link: https://sourceware.org/pipermail/binutils/2024-August/136211.html
---
bfd/elfnn-loongarch.c | 15 +++++++++++----
.../ld-loongarch-elf/ld-loongarch-elf.exp | 3 +++
ld/testsuite/ld-loongarch-elf/provide_abs.d | 12 ++++++++++++
ld/testsuite/ld-loongarch-elf/provide_abs.ld | 1 +
ld/testsuite/ld-loongarch-elf/provide_noabs.d | 13 +++++++++++++
ld/testsuite/ld-loongarch-elf/provide_noabs.ld | 7 +++++++
ld/testsuite/ld-loongarch-elf/provide_sym.s | 7 +++++++
7 files changed, 54 insertions(+), 4 deletions(-)
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_abs.d
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_abs.ld
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_noabs.d
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_noabs.ld
create mode 100644 ld/testsuite/ld-loongarch-elf/provide_sym.s
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index f58ced30ac3..59dfd03d089 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -3315,10 +3315,17 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
script. Also for R_*_SOP_PUSH_ABSOLUTE and PCREL to specify const. */
if (r_symndx == STN_UNDEF || bfd_is_abs_section (sec))
{
- defined_local = false;
- resolved_local = false;
- resolved_dynly = false;
- resolved_to_const = true;
+ /* Allows ABS symbols defined in the linker script to be referenced
+ by pc relative relocations. */
+ if (h != NULL && (h)->root.ldscript_def)
+ ;
+ else
+ {
+ defined_local = false;
+ resolved_local = false;
+ resolved_dynly = false;
+ resolved_to_const = true;
+ }
}
/* The ifunc reference generate plt. */
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index d80014d9563..4328f6e941e 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -184,5 +184,8 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "ie-le-relax"
run_dump_test "tlsdesc_abs"
run_dump_test "tlsdesc_extreme"
+ run_dump_test "provide_abs"
+ run_dump_test "provide_noabs"
+
}
diff --git a/ld/testsuite/ld-loongarch-elf/provide_abs.d b/ld/testsuite/ld-loongarch-elf/provide_abs.d
new file mode 100644
index 00000000000..1514fb18b01
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_abs.d
@@ -0,0 +1,12 @@
+#source: provide_sym.s
+#as:
+#ld: -T provide_abs.ld
+#objdump: -d
+
+.*: +file format .*
+
+#...
+ 0: 58001085 beq \$a0, \$a1, 16 # 10 <fun1>
+ 4: 40000c80 beqz \$a0, 12 # 10 <fun1>
+ 8: 54000800 bl 8 # 10 <fun1>
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/provide_abs.ld b/ld/testsuite/ld-loongarch-elf/provide_abs.ld
new file mode 100644
index 00000000000..473476cdc65
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_abs.ld
@@ -0,0 +1 @@
+PROVIDE(fun1 = 0x10);
diff --git a/ld/testsuite/ld-loongarch-elf/provide_noabs.d b/ld/testsuite/ld-loongarch-elf/provide_noabs.d
new file mode 100644
index 00000000000..7d6bc4d1baf
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_noabs.d
@@ -0,0 +1,13 @@
+#source: provide_sym.s
+#as:
+#ld: -T provide_noabs.ld
+#objdump: -d
+
+.*: +file format .*
+
+
+#...
+ 0: 58001085 beq \$a0, \$a1, 16 # 10 <fun1>
+ 4: 40000c80 beqz \$a0, 12 # 10 <fun1>
+ 8: 54000800 bl 8 # 10 <fun1>
+#pass
diff --git a/ld/testsuite/ld-loongarch-elf/provide_noabs.ld b/ld/testsuite/ld-loongarch-elf/provide_noabs.ld
new file mode 100644
index 00000000000..0154c6f3a29
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_noabs.ld
@@ -0,0 +1,7 @@
+SECTIONS
+{
+ .text :
+ {
+ PROVIDE(fun1 = 0x10);
+ }
+}
diff --git a/ld/testsuite/ld-loongarch-elf/provide_sym.s b/ld/testsuite/ld-loongarch-elf/provide_sym.s
new file mode 100644
index 00000000000..6610894edbe
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/provide_sym.s
@@ -0,0 +1,7 @@
+ .text
+ .globl main
+ .type main, @function
+main:
+ beq $a0,$a1,%b16(fun1)
+ beqz $a0,%b21(fun1)
+ bl %b26(fun1)
--
2.34.1
More information about the Binutils
mailing list