aboutsummaryrefslogtreecommitdiff
path: root/bfd/elfnn-riscv.c
diff options
context:
space:
mode:
authorJim Wilson <jimw@sifive.com>2018-05-18 13:05:21 -0700
committerJim Wilson <jimw@sifive.com>2018-05-18 13:06:19 -0700
commit6487709f3fca687ba1420b6487db5cd1e7cf8cde (patch)
treea7320cd19ae82136438809bbf71b7ffd810d69c0 /bfd/elfnn-riscv.c
parentd3d02dee8d33ef46ed91b3e87ea1b377b14ec845 (diff)
downloadgdb-6487709f3fca687ba1420b6487db5cd1e7cf8cde.zip
gdb-6487709f3fca687ba1420b6487db5cd1e7cf8cde.tar.gz
gdb-6487709f3fca687ba1420b6487db5cd1e7cf8cde.tar.bz2
RISC-V: Fix ld-elf/pr22269* testcases.
bfd/ * elfnn-riscv.c (allocate_dynrelocs): Discard dynamic relocations if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (riscv_elf_relocate_section): Don't generate dynamic relocation if UNDEFWEAK_NO_DYNAMIC_RELOC is true. (riscv_elf_finish_dynamic_symbol): Likewise.
Diffstat (limited to 'bfd/elfnn-riscv.c')
-rw-r--r--bfd/elfnn-riscv.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 582c8d1..b17c0e1 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -1001,7 +1001,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
else
{
s->size += RISCV_ELF_WORD_BYTES;
- if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h))
+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
+ && ! UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
}
}
@@ -1040,7 +1041,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (eh->dyn_relocs != NULL
&& h->root.type == bfd_link_hash_undefweak)
{
- if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
eh->dyn_relocs = NULL;
/* Make sure undefined weak symbols are output as a dynamic
@@ -1731,6 +1733,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
reloc_howto_type *howto = riscv_elf_rtype_to_howto (input_bfd, r_type);
const char *msg = NULL;
+ bfd_boolean resolved_to_zero;
if (howto == NULL
|| r_type == R_RISCV_GNU_VTINHERIT || r_type == R_RISCV_GNU_VTENTRY)
@@ -1785,6 +1788,9 @@ riscv_elf_relocate_section (bfd *output_bfd,
name = bfd_section_name (input_bfd, sec);
}
+ resolved_to_zero = (h != NULL
+ && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
+
switch (r_type)
{
case R_RISCV_NONE:
@@ -2032,7 +2038,8 @@ riscv_elf_relocate_section (bfd *output_bfd,
if ((bfd_link_pic (info)
&& (h == NULL
- || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ && !resolved_to_zero)
|| h->root.type != bfd_link_hash_undefweak)
&& (! howto->pc_relative
|| !SYMBOL_CALLS_LOCAL (info, h)))
@@ -2356,7 +2363,8 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
}
if (h->got.offset != (bfd_vma) -1
- && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
+ && !(riscv_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+ && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
{
asection *sgot;
asection *srela;