aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorNelson Chu <nelson.chu@sifive.com>2020-12-15 19:03:34 -0800
committerNelson Chu <nelson.chu@sifive.com>2021-01-05 10:18:33 +0800
commit18b9872261b950a8d10a4ae6ccb8f2acdaebc3e6 (patch)
tree68413cf74c2d6906d4e7da73f09aa0da31f9fdb2 /bfd
parent3d52735bab7e6df662381f51ee00b10e170cd6e9 (diff)
downloadgdb-18b9872261b950a8d10a4ae6ccb8f2acdaebc3e6.zip
gdb-18b9872261b950a8d10a4ae6ccb8f2acdaebc3e6.tar.gz
gdb-18b9872261b950a8d10a4ae6ccb8f2acdaebc3e6.tar.bz2
RISC-V: Ouput __global_pointer$ as dynamic symbol when generating dynamic PDE.
When the ifunc resolver is in the executable, we may relax the variables to gp-relative access instruction in the ifunc resolver, or in other functions that called by the ifunc resolver. But this will cause the uninitialized gp problem since the ifunc need to be resolved at the early runtime, that is at the pre-load stage, but we set the gp until the startup code. At first, we try to add a new dynamic tag, DT_RISCV_GP, to stroe the gp value and let ld.so can init the gp register early, before the pre-load stage. But we need to extend the ABI if we want to add a new dynamic tag. Therefore, in the psabi discussion, we try another solution, which was suggested by the lld and FreeBSD linker experts, to let ld.so set the gp earlier - make sure __global_pointer$ is output as a dynamic symbol when we are generating pde, since we only do the relaxation for it. Afterwards, ld.so can search the DT_SYMTAB to get the gp value, and set the gp register before resolving ifunc. bfd/ * elfnn-riscv.c (allocate_dynrelocs): When we are generating pde, make sure gp symbol is output as a dynamic symbol.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog5
-rw-r--r--bfd/elfnn-riscv.c9
2 files changed, 14 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index f1ae342..20ccea5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2021-01-05 Nelson Chu <nelson.chu@sifive.com>
+
+ * elfnn-riscv.c (allocate_dynrelocs): When we are generating pde,
+ make sure gp symbol is output as a dynamic symbol.
+
2021-01-04 H.J. Lu <hongjiu.lu@intel.com>
PR ld/26256
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 047f31b..9da415e 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1083,6 +1083,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
htab = riscv_elf_hash_table (info);
BFD_ASSERT (htab != NULL);
+ /* When we are generating pde, make sure gp symbol is output as a
+ dynamic symbol. Then ld.so can set the gp register earlier, before
+ resolving the ifunc. */
+ if (!bfd_link_pic (info)
+ && htab->elf.dynamic_sections_created
+ && strcmp (h->root.root.string, RISCV_GP_SYMBOL) == 0
+ && !bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
/* Since STT_GNU_IFUNC symbols must go through PLT, we handle them
in the allocate_ifunc_dynrelocs and allocate_local_ifunc_dynrelocs,
if they are defined and referenced in a non-shared object. */