aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/elfnn-loongarch.c30
-rw-r--r--ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp1
-rw-r--r--ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.d4
-rw-r--r--ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s3
4 files changed, 36 insertions, 2 deletions
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index da84aab..41463ea 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;
@@ -2859,8 +2883,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 2d67c4f..4d9f4ae 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 0000000..3431329
--- /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 0000000..6649f2b
--- /dev/null
+++ b/ld/testsuite/ld-loongarch-elf/r_larch_32_elf64.s
@@ -0,0 +1,3 @@
+.data
+x:
+ .4byte x