diff options
-rw-r--r-- | bfd/ChangeLog | 4 | ||||
-rw-r--r-- | bfd/elf64-mmix.c | 3 | ||||
-rw-r--r-- | ld/ChangeLog | 9 | ||||
-rw-r--r-- | ld/ldexp.c | 51 | ||||
-rw-r--r-- | ld/ldexp.h | 5 |
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 @@ -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) { @@ -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; |