RISC-V: Fix ld-elf/pr22269* testcases.

Message ID 20180518200759.28583-1-jimw@sifive.com
State New
Headers show
Series
  • RISC-V: Fix ld-elf/pr22269* testcases.
Related show

Commit Message

Jim Wilson May 18, 2018, 8:07 p.m.
This fixes 3 linker testcase failures for RISC-V Linux targets.
FAIL: PR ld/22269
FAIL: PR ld/22269 (-z dynamic-undefined-weak)
FAIL: Build pr22269-1
They all pass with the patch.  The patch is effectively the same as the patch
added to elfnn-aarch64.c last year, which is close to the elfnn-riscv.c design.

This was tested with riscv{32,64}-{elf,linux} builds and checks.  There were
no regressions.  I also tested it with a native gcc linux build and check using
the configure option --enable-default-pie to test the PIE support.

Committed.

Jim

	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.
---
 bfd/elfnn-riscv.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

-- 
2.14.1

Patch

diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index 582c8d1748..b17c0e1000 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;