From a377ae2ad683d3c16ae74dba440ee441120a7d8a Mon Sep 17 00:00:00 2001
From: Szabolcs Nagy <szabolcs.nagy@arm.com>
Date: Wed, 15 Nov 2017 15:56:30 +0000
Subject: [PATCH] [PR ld/22269] aarch64: Handle local undefined weak symbols

With static pie linking undefined weak symbols are forced to resolve locally
to 0, so no GOT setup is needed in elfNN_aarch64_finish_dynamic_symbol,
which previously failed for these symbols.

The failure caused the unhelpful error message:
"ld: final link failed: Nonrepresentable section on output"

bfd/
	PR ld/22269
	* elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol): Use
	UNDEFWEAK_NO_DYNAMIC_RELOC to avoid dynamic GOT relocs.
	(elfNN_aarch64_allocate_dynrelocs): Likewise.
---
 bfd/ChangeLog       |  7 +++++++
 bfd/elfnn-aarch64.c | 10 ++++++++--
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0395dcf6cca..46c2a596331 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,10 @@
+2017-11-27  Szabolcs Nagy  <szabolcs.nagy@arm.com>
+
+	PR ld/22269
+	* elfnn-aarch64.c (elfNN_aarch64_finish_dynamic_symbol): Use
+	UNDEFWEAK_NO_DYNAMIC_RELOC to avoid dynamic GOT relocs.
+	(elfNN_aarch64_allocate_dynrelocs): Likewise.
+
 2017-11-24  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR binutils/22444
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 45218843d5c..7571a16ff9c 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -8022,7 +8022,10 @@ elfNN_aarch64_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	  if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 	       || h->root.type != bfd_link_hash_undefweak)
 	      && (bfd_link_pic (info)
-		  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
+		  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h))
+	      /* Undefined weak symbol in static PIE resolves to 0 without
+		 any dynamic relocations.  */
+	      && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
 	    {
 	      htab->root.srelgot->size += RELOC_SIZE (htab);
 	    }
@@ -8824,7 +8827,10 @@ elfNN_aarch64_finish_dynamic_symbol (bfd *output_bfd,
     }
 
   if (h->got.offset != (bfd_vma) - 1
-      && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL)
+      && elf_aarch64_hash_entry (h)->got_type == GOT_NORMAL
+      /* Undefined weak symbol in static PIE resolves to 0 without
+	 any dynamic relocations.  */
+      && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
     {
       Elf_Internal_Rela rela;
       bfd_byte *loc;