aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog4
-rw-r--r--bfd/elf64-mmix.c3
-rw-r--r--ld/ChangeLog9
-rw-r--r--ld/ldexp.c51
-rw-r--r--ld/ldexp.h5
5 files changed, 38 insertions, 34 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index abd7c96..dc3aa2f 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,7 @@
+2017-11-28 Alan Modra <amodra@gmail.com>
+
+ * elf64-mmix.c (bfd_elf64_bfd_copy_link_hash_symbol_type): Define.
+
2017-11-28 H.J. Lu <hongjiu.lu@intel.com>
PR ld/22502
diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c
index c057d34..ae6afc2 100644
--- a/bfd/elf64-mmix.c
+++ b/bfd/elf64-mmix.c
@@ -2908,6 +2908,9 @@ mmix_elf_relax_section (bfd *abfd,
#define elf_backend_omit_section_dynsym \
((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define bfd_elf64_bfd_copy_link_hash_symbol_type \
+ _bfd_generic_copy_link_hash_symbol_type
+
#define bfd_elf64_bfd_is_local_label_name \
mmix_elf_is_local_label_name
diff --git a/ld/ChangeLog b/ld/ChangeLog
index ed63236..058318d 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,12 @@
+2017-11-28 Alan Modra <amodra@gmail.com>
+
+ * ldexp.h (struct ldexp_control): Add "assign_src".
+ * ldexp.c (fold_trinary): Save and restore assign_src around
+ condition evaluation.
+ (fold_name <NAME>): Set expld.assign_src.
+ (try_copy_symbol_type): Delete.
+ (exp_fold_tree_1): Set symbol type using expld.assign_src.
+
2017-11-28 H.J. Lu <hongjiu.lu@intel.com>
PR ld/22502
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 83d9f8f..33ca289 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -673,7 +673,10 @@ fold_binary (etree_type *tree)
static void
fold_trinary (etree_type *tree)
{
+ struct bfd_link_hash_entry *save = expld.assign_src;
+
exp_fold_tree_1 (tree->trinary.cond);
+ expld.assign_src = save;
if (expld.result.valid_p)
exp_fold_tree_1 (expld.result.value
? tree->trinary.lhs
@@ -790,6 +793,10 @@ fold_name (etree_type *tree)
if (h->u.undef.next == NULL && h != link_info.hash->undefs_tail)
bfd_link_add_undef (link_info.hash, h);
}
+ if (expld.assign_src == NULL)
+ expld.assign_src = h;
+ else
+ expld.assign_src = (struct bfd_link_hash_entry *) 0 - 1;
}
break;
@@ -1001,19 +1008,6 @@ is_align_conditional (const etree_type *tree)
return FALSE;
}
-/* Subroutine of exp_fold_tree_1 for copying a symbol type. */
-
-static void
-try_copy_symbol_type (struct bfd_link_hash_entry *h, etree_type *src)
-{
- struct bfd_link_hash_entry *hsrc;
-
- hsrc = bfd_link_hash_lookup (link_info.hash, src->name.name,
- FALSE, FALSE, TRUE);
- if (hsrc != NULL)
- bfd_copy_link_hash_symbol_type (link_info.output_bfd, h, hsrc);
-}
-
static void
exp_fold_tree_1 (etree_type *tree)
{
@@ -1162,6 +1156,7 @@ exp_fold_tree_1 (etree_type *tree)
}
expld.assign_name = tree->assign.dst;
+ expld.assign_src = NULL;
exp_fold_tree_1 (tree->assign.src);
/* expld.assign_name remaining equal to tree->assign.dst
below indicates the evaluation of tree->assign.src did
@@ -1209,27 +1204,15 @@ exp_fold_tree_1 (etree_type *tree)
if (tree->type.node_class == etree_provide)
tree->type.node_class = etree_provided;
- /* Copy the symbol type if this is a simple assignment of
- one symbol to another. Also, handle the case of a foldable
- ternary conditional with names on either side. */
- if (tree->assign.src->type.node_class == etree_name)
- try_copy_symbol_type (h, tree->assign.src);
- else if (tree->assign.src->type.node_class == etree_trinary)
- {
- exp_fold_tree_1 (tree->assign.src->trinary.cond);
- if (expld.result.valid_p)
- {
- if (expld.result.value
- && tree->assign.src->trinary.lhs->type.node_class
- == etree_name)
- try_copy_symbol_type (h, tree->assign.src->trinary.lhs);
-
- if (!expld.result.value
- && tree->assign.src->trinary.rhs->type.node_class
- == etree_name)
- try_copy_symbol_type (h, tree->assign.src->trinary.rhs);
- }
- }
+ /* Copy the symbol type if this is an expression only
+ referencing a single symbol. (If the expression
+ contains ternary conditions, ignoring symbols on
+ false branches.) */
+ if (expld.result.valid_p
+ && expld.assign_src != NULL
+ && expld.assign_src != (struct bfd_link_hash_entry *) 0 - 1)
+ bfd_copy_link_hash_symbol_type (link_info.output_bfd, h,
+ expld.assign_src);
}
else if (expld.phase == lang_final_phase_enum)
{
diff --git a/ld/ldexp.h b/ld/ldexp.h
index 5ff0fa0..189570a 100644
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -163,6 +163,11 @@ struct ldexp_control {
does the false branch of a trinary expression. */
const char *assign_name;
+ /* If evaluating an assignment, the source if it is an expression
+ referencing single etree_name NAME, or a trinary expression where
+ the true branch references a single etree_name NAME. */
+ struct bfd_link_hash_entry *assign_src;
+
/* Working results. */
etree_value_type result;
bfd_vma dot;