133 lines
4.4 KiB
Diff
133 lines
4.4 KiB
Diff
|
|
From b1375201b1643fee97a240ba17523a529b286e12 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Xi Ruoyao <xry111@xry111.site>
|
||
|
|
Date: Sun, 30 Jun 2024 15:18:21 +0800
|
||
|
|
Subject: [PATCH 095/123] LoongArch: Reject R_LARCH_32 from becoming a runtime
|
||
|
|
reloc in ELFCLASS64
|
||
|
|
|
||
|
|
We were converting R_LARCH_32 to R_LARCH_RELATIVE for ELFCLASS64:
|
||
|
|
|
||
|
|
$ cat t.s
|
||
|
|
.data
|
||
|
|
x:
|
||
|
|
.4byte x
|
||
|
|
.4byte 0xdeadbeef
|
||
|
|
$ as/as-new t.s -o t.o
|
||
|
|
$ ld/ld-new -shared t.o
|
||
|
|
$ objdump -R
|
||
|
|
a.out: file format elf64-loongarch
|
||
|
|
|
||
|
|
DYNAMIC RELOCATION RECORDS
|
||
|
|
OFFSET TYPE VALUE
|
||
|
|
00000000000001a8 R_LARCH_RELATIVE *ABS*+0x00000000000001a8
|
||
|
|
|
||
|
|
But this is just wrong: at runtime the dynamic linker will run
|
||
|
|
*(uintptr *)&x += load_address, clobbering the next 4 bytes of data
|
||
|
|
("0xdeadbeef" in the example).
|
||
|
|
|
||
|
|
If we keep the R_LARCH_32 reloc as-is in ELFCLASS64, it'll be rejected
|
||
|
|
by the Glibc dynamic linker anyway. And it does not make too much sense
|
||
|
|
to modify Glibc to support it. So we can just reject it like x86_64:
|
||
|
|
|
||
|
|
relocation R_X86_64_32 against `.data' can not be used when making a
|
||
|
|
shared object; recompile with -fPIC
|
||
|
|
|
||
|
|
or RISC-V:
|
||
|
|
|
||
|
|
relocation R_RISCV_32 against non-absolute symbol `a local symbol'
|
||
|
|
can not be used in RV64 when making a shared object
|
||
|
|
|
||
|
|
Signed-off-by: Xi Ruoyao <xry111@xry111.site>
|
||
|
|
---
|
||
|
|
bfd/elfnn-loongarch.c | 30 +++++++++++++++++--
|
||
|
|
.../ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
|
||
|
|
.../ld-loongarch-elf/r_larch_32_elf64.d | 4 +++
|
||
|
|
.../ld-loongarch-elf/r_larch_32_elf64.s | 3 ++
|
||
|
|
4 files changed, 36 insertions(+), 2 deletions(-)
|
||
|
|
create mode 100644 ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d
|
||
|
|
create mode 100644 ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
|
||
|
|
|
||
|
|
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
|
||
|
|
index 840cdd35..fa0a5e38 100644
|
||
|
|
--- a/bfd/elfnn-loongarch.c
|
||
|
|
+++ b/bfd/elfnn-loongarch.c
|
||
|
|
@@ -1036,8 +1036,32 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
||
|
|
only_need_pcrel = 1;
|
||
|
|
break;
|
||
|
|
|
||
|
|
- case R_LARCH_JUMP_SLOT:
|
||
|
|
case R_LARCH_32:
|
||
|
|
+ if (ARCH_SIZE > 32
|
||
|
|
+ && bfd_link_pic (info)
|
||
|
|
+ && (sec->flags & SEC_ALLOC) != 0)
|
||
|
|
+ {
|
||
|
|
+ bool is_abs_symbol = false;
|
||
|
|
+
|
||
|
|
+ if (r_symndx < symtab_hdr->sh_info)
|
||
|
|
+ is_abs_symbol = isym->st_shndx == SHN_ABS;
|
||
|
|
+ else
|
||
|
|
+ is_abs_symbol = bfd_is_abs_symbol (&h->root);
|
||
|
|
+
|
||
|
|
+ if (!is_abs_symbol)
|
||
|
|
+ {
|
||
|
|
+ _bfd_error_handler
|
||
|
|
+ (_("%pB: relocation R_LARCH_32 against non-absolute "
|
||
|
|
+ "symbol `%s' cannot be used in ELFCLASS64 when "
|
||
|
|
+ "making a shared object or PIE"),
|
||
|
|
+ abfd, h ? h->root.root.string : "a local symbol");
|
||
|
|
+ bfd_set_error (bfd_error_bad_value);
|
||
|
|
+ return false;
|
||
|
|
+ }
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ /* Fall through. */
|
||
|
|
+ case R_LARCH_JUMP_SLOT:
|
||
|
|
case R_LARCH_64:
|
||
|
|
|
||
|
|
need_dynreloc = 1;
|
||
|
|
@@ -2858,8 +2882,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||
|
|
outrel.r_addend = relocation + rel->r_addend;
|
||
|
|
}
|
||
|
|
|
||
|
|
- /* No alloc space of func allocate_dynrelocs. */
|
||
|
|
+ /* No alloc space of func allocate_dynrelocs.
|
||
|
|
+ No alloc space of invalid R_LARCH_32 in ELFCLASS64. */
|
||
|
|
if (unresolved_reloc
|
||
|
|
+ && (ARCH_SIZE == 32 || r_type != R_LARCH_32)
|
||
|
|
&& !(h && (h->is_weakalias || !h->dyn_relocs)))
|
||
|
|
loongarch_elf_append_rela (output_bfd, sreloc, &outrel);
|
||
|
|
}
|
||
|
|
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
|
||
|
|
index 89552a11..7ffabe2c 100644
|
||
|
|
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
|
||
|
|
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
|
||
|
|
@@ -132,6 +132,7 @@ if [istarget "loongarch64-*-*"] {
|
||
|
|
run_dump_test "reloc_le_with_shared"
|
||
|
|
run_dump_test "reloc_ler_with_shared"
|
||
|
|
run_dump_test "reloc_abs_with_shared"
|
||
|
|
+ run_dump_test "r_larch_32_elf64"
|
||
|
|
}
|
||
|
|
|
||
|
|
if [check_pie_support] {
|
||
|
|
diff --git a/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..34313295
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d
|
||
|
|
@@ -0,0 +1,4 @@
|
||
|
|
+#name: R_LARCH_32 in ELFCLASS64
|
||
|
|
+#source: r_larch_32_elf64.s
|
||
|
|
+#ld: -shared -melf64loongarch
|
||
|
|
+#error: R_LARCH_32 .* cannot be used in ELFCLASS64
|
||
|
|
diff --git a/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..6649f2bc
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
|
||
|
|
@@ -0,0 +1,3 @@
|
||
|
|
+.data
|
||
|
|
+x:
|
||
|
|
+ .4byte x
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|