134 lines
4.6 KiB
Diff
134 lines
4.6 KiB
Diff
|
|
From 41abd06f7ba97c5b92a2d38c99c357772bba3ade Mon Sep 17 00:00:00 2001
|
||
|
|
From: Xin Wang <yw987194828@gmail.com>
|
||
|
|
Date: Fri, 16 Aug 2024 11:28:10 +0800
|
||
|
|
Subject: [PATCH 113/123] Not append rela for absolute symbol
|
||
|
|
|
||
|
|
LoongArch: Not append rela for absolute symbol
|
||
|
|
|
||
|
|
Use la.global to get absolute symbol like la.abs.
|
||
|
|
la.global put address of a global symbol into a got
|
||
|
|
entry and append a rela for it, which will be used
|
||
|
|
to relocate by dynamic linker. Dynamic linker should
|
||
|
|
not relocate for got entry of absolute symbol as it
|
||
|
|
stores symval not symbol's address.
|
||
|
|
---
|
||
|
|
bfd/elfnn-loongarch.c | 19 ++++++++++++++++++-
|
||
|
|
ld/testsuite/ld-loongarch-elf/abs-global.out | 1 +
|
||
|
|
ld/testsuite/ld-loongarch-elf/abs-global.s | 5 +++++
|
||
|
|
.../ld-loongarch-elf/get_abs_global_sym.c | 7 +++++++
|
||
|
|
.../ld-loongarch-elf/ld-loongarch-elf.exp | 12 ++++++++++++
|
||
|
|
5 files changed, 43 insertions(+), 1 deletion(-)
|
||
|
|
create mode 100644 ld/testsuite/ld-loongarch-elf/abs-global.out
|
||
|
|
create mode 100644 ld/testsuite/ld-loongarch-elf/abs-global.s
|
||
|
|
create mode 100644 ld/testsuite/ld-loongarch-elf/get_abs_global_sym.c
|
||
|
|
|
||
|
|
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
|
||
|
|
index 770483cd..09a9513b 100644
|
||
|
|
--- a/bfd/elfnn-loongarch.c
|
||
|
|
+++ b/bfd/elfnn-loongarch.c
|
||
|
|
@@ -4135,6 +4135,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||
|
|
if (!WILL_CALL_FINISH_DYNAMIC_SYMBOL (is_dyn,
|
||
|
|
bfd_link_pic (info),
|
||
|
|
h)
|
||
|
|
+ && !bfd_is_abs_section(h->root.u.def.section)
|
||
|
|
&& bfd_link_pic (info)
|
||
|
|
&& LARCH_REF_LOCAL (info, h)
|
||
|
|
&& !info->enable_dt_relr)
|
||
|
|
@@ -4157,7 +4158,8 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
|
||
|
|
&& local_got_offsets[r_symndx] != MINUS_ONE);
|
||
|
|
|
||
|
|
got_off = local_got_offsets[r_symndx] & (~(bfd_vma)1);
|
||
|
|
- if ((local_got_offsets[r_symndx] & 1) == 0)
|
||
|
|
+ if (sym->st_shndx != SHN_ABS
|
||
|
|
+ && (local_got_offsets[r_symndx] & 1) == 0)
|
||
|
|
{
|
||
|
|
if (bfd_link_pic (info) && !info->enable_dt_relr)
|
||
|
|
{
|
||
|
|
@@ -5314,6 +5316,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
|
||
|
|
bfd_vma symval;
|
||
|
|
asection *sym_sec;
|
||
|
|
bool local_got = false;
|
||
|
|
+ bool is_abs_symbol = false;
|
||
|
|
Elf_Internal_Rela *rel = relocs + i;
|
||
|
|
struct elf_link_hash_entry *h = NULL;
|
||
|
|
unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
|
||
|
|
@@ -5495,7 +5498,21 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
|
||
|
|
break;
|
||
|
|
|
||
|
|
case R_LARCH_GOT_PC_HI20:
|
||
|
|
+ if (h)
|
||
|
|
+ is_abs_symbol = bfd_is_abs_section(h->root.u.def.section);
|
||
|
|
+ else
|
||
|
|
+ {
|
||
|
|
+ Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
|
||
|
|
+ + ELFNN_R_SYM (rel->r_info);
|
||
|
|
+ is_abs_symbol = sym->st_shndx == SHN_ABS;
|
||
|
|
+ }
|
||
|
|
+ /* If symval is in the range [-2^31, 2^31), we can relax the
|
||
|
|
+ pair of instructions from pcalau12i/ld.d to lu12i.w/ori for
|
||
|
|
+ abosulte symbol. This is not implemented yet, so we just
|
||
|
|
+ remain the r_type which will be needed when relocate for
|
||
|
|
+ absolute symbol. */
|
||
|
|
if (local_got && 0 == info->relax_pass
|
||
|
|
+ && !is_abs_symbol
|
||
|
|
&& (i + 4) <= sec->reloc_count)
|
||
|
|
{
|
||
|
|
if (loongarch_relax_pcala_ld (abfd, sec, rel))
|
||
|
|
diff --git a/ld/testsuite/ld-loongarch-elf/abs-global.out b/ld/testsuite/ld-loongarch-elf/abs-global.out
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..3656652b
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/ld/testsuite/ld-loongarch-elf/abs-global.out
|
||
|
|
@@ -0,0 +1 @@
|
||
|
|
+abba
|
||
|
|
diff --git a/ld/testsuite/ld-loongarch-elf/abs-global.s b/ld/testsuite/ld-loongarch-elf/abs-global.s
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..93a5da6d
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/ld/testsuite/ld-loongarch-elf/abs-global.s
|
||
|
|
@@ -0,0 +1,5 @@
|
||
|
|
+.text
|
||
|
|
+.globl get_sym
|
||
|
|
+get_sym:
|
||
|
|
+ la.global $a0, sym
|
||
|
|
+ ret
|
||
|
|
diff --git a/ld/testsuite/ld-loongarch-elf/get_abs_global_sym.c b/ld/testsuite/ld-loongarch-elf/get_abs_global_sym.c
|
||
|
|
new file mode 100644
|
||
|
|
index 00000000..29781ad7
|
||
|
|
--- /dev/null
|
||
|
|
+++ b/ld/testsuite/ld-loongarch-elf/get_abs_global_sym.c
|
||
|
|
@@ -0,0 +1,7 @@
|
||
|
|
+#include <stdio.h>
|
||
|
|
+
|
||
|
|
+extern int get_sym();
|
||
|
|
+int main() {
|
||
|
|
+ printf("%x\n", get_sym());
|
||
|
|
+ return 0;
|
||
|
|
+}
|
||
|
|
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
|
||
|
|
index cb6d2296..555ebf92 100644
|
||
|
|
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
|
||
|
|
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
|
||
|
|
@@ -130,6 +130,18 @@ if [istarget "loongarch64-*-*"] {
|
||
|
|
"a.binary" \
|
||
|
|
] \
|
||
|
|
]
|
||
|
|
+
|
||
|
|
+
|
||
|
|
+ run_ld_link_exec_tests [list \
|
||
|
|
+ [list \
|
||
|
|
+ "get global abs symbol test" \
|
||
|
|
+ "-Wl,-z norelro -Wl,--defsym sym=0xabba" \
|
||
|
|
+ "" \
|
||
|
|
+ { abs-global.s get_abs_global_sym.c} \
|
||
|
|
+ "abs-global" \
|
||
|
|
+ "abs-global.out" \
|
||
|
|
+ ] \
|
||
|
|
+ ]
|
||
|
|
}
|
||
|
|
|
||
|
|
if [istarget "loongarch64-*-*"] {
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|