@@ -730,6 +730,21 @@ loongarch_tls_transition (bfd *input_bfd,
allocate space in the global offset table or procedure linkage
table. */
+static bool
+bad_static_reloc (bfd *abfd, unsigned r_type, struct elf_link_hash_entry *h)
+{
+ /* We propably can improve the information to tell users that they should
+ be recompile the code with -fPIC or -fPIE, just like what x86 does. */
+ reloc_howto_type * r = loongarch_elf_rtype_to_howto (abfd, r_type);
+ (*_bfd_error_handler)
+ (_("%pB: relocation %s against `%s` can not be used when making a shared "
+ "object; recompile with -fPIC"),
+ abfd, r ? r->name : _("<unknown>"),
+ h != NULL ? h->root.root.string : "a local symbol");
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+}
+
static bool
loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
asection *sec, const Elf_Internal_Rela *relocs)
@@ -874,7 +889,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_LARCH_TLS_LE_HI20_R:
case R_LARCH_SOP_PUSH_TLS_TPREL:
if (!bfd_link_executable (info))
- return false;
+ return bad_static_reloc (abfd, r_type, h);
if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
r_symndx,
@@ -892,6 +907,9 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_LARCH_ABS_HI20:
case R_LARCH_SOP_PUSH_ABSOLUTE:
+ if (bfd_link_pic (info))
+ return bad_static_reloc (abfd, r_type, h);
+
if (h != NULL)
/* If this reloc is in a read-only section, we might
need a copy reloc. We can't check reliably at this
@@ -2550,6 +2568,15 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
})
+static bfd_vma
+tls_tpoff_base (struct bfd_link_info *info)
+{
+ /* If tls_sec is NULL, we should have signalled an error already. */
+ if (elf_hash_table (info)->tls_sec == NULL)
+ return 0;
+ return elf_hash_table (info)->tls_sec->vma;
+}
+
static bfd_vma
tls_dtpoff_base (struct bfd_link_info *info)
{
@@ -3416,7 +3443,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
case R_LARCH_TLS_LE_HI20_R:
relocation += rel->r_addend;
- relocation -= elf_hash_table (info)->tls_sec->vma;
+ relocation -= tls_tpoff_base (info);
RELOCATE_TLS_TP32_HI20 (relocation);
break;
@@ -3599,7 +3626,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
BFD_ASSERT (resolved_local && elf_hash_table (info)->tls_sec);
relocation += rel->r_addend;
- relocation -= elf_hash_table (info)->tls_sec->vma;
+ relocation -= tls_tpoff_base (info);
break;
/* TLS IE LD/GD process separately is troublesome.
@@ -131,6 +131,9 @@ if [istarget "loongarch64-*-*"] {
run_dump_test "tlsdesc-dso"
run_dump_test "desc-norelax"
run_dump_test "desc-relax"
+ run_dump_test "reloc_le_with_shared"
+ run_dump_test "reloc_ler_with_shared"
+ run_dump_test "reloc_abs_with_shared"
}
if [check_pie_support] {
new file mode 100644
@@ -0,0 +1,6 @@
+#source: reloc_abs_with_shared.s
+#as:
+#ld: -shared
+#error: .*relocation R_LARCH_ABS_HI20 against `s` can not be used when making a shared object; recompile with -fPIC
+#...
+#pass
new file mode 100644
@@ -0,0 +1,13 @@
+ .text
+ .globl s
+ .section .data,"awT",@progbits
+ .align 2
+ .type s, @object
+ .size s, 4
+ s:
+ .word 123
+
+ .text
+
+ lu12i.w $r4,%abs_hi20(s)
+ addi.d $r4,$r4,%abs_lo12(s)
new file mode 100644
@@ -0,0 +1,6 @@
+#source: reloc_le_with_shared.s
+#as:
+#ld: -shared
+#error: .*relocation R_LARCH_TLS_LE_HI20 against `s` can not be used when making a shared object; recompile with -fPIC
+#...
+#pass
new file mode 100644
@@ -0,0 +1,12 @@
+ .text
+ .globl s
+ .section .tdata,"awT",@progbits
+ .align 2
+ .type s, @object
+ .size s, 4
+ s:
+ .word 123
+
+ .text
+
+ la.tls.le $r4, s
new file mode 100644
@@ -0,0 +1,6 @@
+#source: reloc_ler_with_shared.s
+#as:
+#ld: -shared
+#error:.*relocation R_LARCH_TLS_LE_HI20_R against `s` can not be used when making a shared object; recompile with -fPIC
+#...
+#pass
new file mode 100644
@@ -0,0 +1,13 @@
+ .text
+ .globl s
+ .section .tdata,"awT",@progbits
+ .align 2
+ .type s, @object
+ .size s, 4
+ s:
+ .word 123
+
+ .text
+
+ lu12i.w $r4,%le_hi20_r(s)
+ add.d $r4,$r4,$r2,%le_add_r(s)