aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elf32-hppa.c51
-rw-r--r--bfd/elf32-ppc.c26
-rw-r--r--bfd/elf64-ppc.c26
4 files changed, 59 insertions, 54 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 15f1a3f..3d09aa4 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2017-08-23 Alan Modra <amodra@gmail.com>
+
+ PR 21988
+ * elf64-ppc.c (ensure_undef_dynamic): Rename from
+ ensure_undefweak_dynamic. Handle undefined too.
+ * elf32-ppc.c (ensure_undef_dynamic): Likewise.
+ * elf32-hppa.c (ensure_undef_dynamic): Likewise.
+ (allocate_dynrelocs): Discard undefined non-default visibility
+ relocs first. Make undefined syms dynamic. Tidy goto.
+
2017-08-21 Alan Modra <amodra@gmail.com>
H.J. Lu <hongjiu.lu@intel.com>
diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c
index f63ff3f..3adac6d 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -1919,16 +1919,20 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
return _bfd_elf_adjust_dynamic_copy (info, eh, sec);
}
-/* Make an undefined weak symbol dynamic. */
+/* If EH is undefined, make it dynamic if that makes sense. */
static bfd_boolean
-ensure_undef_weak_dynamic (struct bfd_link_info *info,
- struct elf_link_hash_entry *eh)
+ensure_undef_dynamic (struct bfd_link_info *info,
+ struct elf_link_hash_entry *eh)
{
- if (eh->dynindx == -1
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+
+ if (htab->dynamic_sections_created
+ && (eh->root.type == bfd_link_hash_undefweak
+ || eh->root.type == bfd_link_hash_undefined)
+ && eh->dynindx == -1
&& !eh->forced_local
&& eh->type != STT_PARISC_MILLI
- && eh->root.type == bfd_link_hash_undefweak
&& ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT)
return bfd_elf_link_record_dynamic_symbol (info, eh);
return TRUE;
@@ -1957,7 +1961,7 @@ allocate_plt_static (struct elf_link_hash_entry *eh, void *inf)
if (htab->etab.dynamic_sections_created
&& eh->plt.refcount > 0)
{
- if (!ensure_undef_weak_dynamic (info, eh))
+ if (!ensure_undef_dynamic (info, eh))
return FALSE;
if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), eh))
@@ -2034,7 +2038,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
if (eh->got.refcount > 0)
{
- if (!ensure_undef_weak_dynamic (info, eh))
+ if (!ensure_undef_dynamic (info, eh))
return FALSE;
sec = htab->etab.sgot;
@@ -2070,8 +2074,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
changes. */
if (bfd_link_pic (info))
{
+ /* Discard relocs on undefined syms with non-default visibility. */
+ if ((eh->root.type == bfd_link_hash_undefined
+ || eh->root.type == bfd_link_hash_undefweak)
+ && ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
+ hh->dyn_relocs = NULL;
+
#if RELATIVE_DYNRELOCS
- if (SYMBOL_CALLS_LOCAL (info, eh))
+ else if (SYMBOL_CALLS_LOCAL (info, eh))
{
struct elf32_hppa_dyn_reloc_entry **hdh_pp;
@@ -2087,15 +2097,9 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
}
#endif
- /* Also discard relocs on undefined weak syms with non-default
- visibility. */
- if (hh->dyn_relocs != NULL
- && eh->root.type == bfd_link_hash_undefweak)
+ if (hh->dyn_relocs != NULL)
{
- if (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
- hh->dyn_relocs = NULL;
-
- else if (!ensure_undef_weak_dynamic (info, eh))
+ if (!ensure_undef_dynamic (info, eh))
return FALSE;
}
}
@@ -2113,19 +2117,14 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
&& (eh->root.type == bfd_link_hash_undefweak
|| eh->root.type == bfd_link_hash_undefined))))
{
- if (!ensure_undef_weak_dynamic (info, eh))
+ if (!ensure_undef_dynamic (info, eh))
return FALSE;
- /* If that succeeded, we know we'll be keeping all the
- relocs. */
- if (eh->dynindx != -1)
- goto keep;
+ if (eh->dynindx == -1)
+ hh->dyn_relocs = NULL;
}
-
- hh->dyn_relocs = NULL;
- return TRUE;
-
- keep: ;
+ else
+ hh->dyn_relocs = NULL;
}
/* Finally, allocate space. */
diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c
index f32ba9b..ac3b12bb 100644
--- a/bfd/elf32-ppc.c
+++ b/bfd/elf32-ppc.c
@@ -5942,17 +5942,18 @@ allocate_got (struct ppc_elf_link_hash_table *htab, unsigned int need)
return where;
}
-/* If H is undefined weak, make it dynamic if that makes sense. */
+/* If H is undefined, make it dynamic if that makes sense. */
static bfd_boolean
-ensure_undefweak_dynamic (struct bfd_link_info *info,
- struct elf_link_hash_entry *h)
+ensure_undef_dynamic (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
{
struct elf_link_hash_table *htab = elf_hash_table (info);
if (htab->dynamic_sections_created
- && info->dynamic_undefined_weak != 0
- && h->root.type == bfd_link_hash_undefweak
+ && ((info->dynamic_undefined_weak != 0
+ && h->root.type == bfd_link_hash_undefweak)
+ || h->root.type == bfd_link_hash_undefined)
&& h->dynindx == -1
&& !h->forced_local
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
@@ -5986,9 +5987,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
{
unsigned int need;
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
- if (!ensure_undefweak_dynamic (info, &eh->elf))
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (!ensure_undef_dynamic (info, &eh->elf))
return FALSE;
need = 0;
@@ -6102,9 +6102,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (eh->dyn_relocs != NULL)
{
- /* Make sure undefined weak symbols are output as a dynamic
- symbol in PIEs. */
- if (!ensure_undefweak_dynamic (info, h))
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (!ensure_undef_dynamic (info, h))
return FALSE;
}
}
@@ -6120,9 +6119,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
&& eh->has_addr16_lo
&& htab->params->pic_fixup > 0))
{
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
- if (!ensure_undefweak_dynamic (info, h))
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (!ensure_undef_dynamic (info, h))
return FALSE;
if (h->dynindx == -1)
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 7f4f7b6..f0fde1d 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -9743,17 +9743,18 @@ merge_got_entries (struct got_entry **pent)
}
}
-/* If H is undefined weak, make it dynamic if that makes sense. */
+/* If H is undefined, make it dynamic if that makes sense. */
static bfd_boolean
-ensure_undefweak_dynamic (struct bfd_link_info *info,
- struct elf_link_hash_entry *h)
+ensure_undef_dynamic (struct bfd_link_info *info,
+ struct elf_link_hash_entry *h)
{
struct elf_link_hash_table *htab = elf_hash_table (info);
if (htab->dynamic_sections_created
- && info->dynamic_undefined_weak != 0
- && h->root.type == bfd_link_hash_undefweak
+ && ((info->dynamic_undefined_weak != 0
+ && h->root.type == bfd_link_hash_undefweak)
+ || h->root.type == bfd_link_hash_undefined)
&& h->dynindx == -1
&& !h->forced_local
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
@@ -9832,9 +9833,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
for (gent = h->got.glist; gent != NULL; gent = gent->next)
if (!gent->is_indirect)
{
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
- if (!ensure_undefweak_dynamic (info, h))
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (!ensure_undef_dynamic (info, h))
return FALSE;
if (!is_ppc64_elf (gent->owner))
@@ -9888,9 +9888,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (eh->dyn_relocs != NULL)
{
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
- if (!ensure_undefweak_dynamic (info, h))
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (!ensure_undef_dynamic (info, h))
return FALSE;
}
}
@@ -9925,9 +9924,8 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
if (!h->non_got_ref
&& !h->def_regular)
{
- /* Make sure this symbol is output as a dynamic symbol.
- Undefined weak syms won't yet be marked as dynamic. */
- if (!ensure_undefweak_dynamic (info, h))
+ /* Make sure this symbol is output as a dynamic symbol. */
+ if (!ensure_undef_dynamic (info, h))
return FALSE;
if (h->dynindx == -1)