This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Copying symbol type in ld script assignments


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cd5b2babea487b0a71a14b593af98330efd8d73e

commit cd5b2babea487b0a71a14b593af98330efd8d73e
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Nov 27 18:43:03 2017 +1030

    Copying symbol type in ld script assignments
    
    There is a call to update_definedness between code that evaluates an
    assignment expression value and code that transfers symbol
    attributes.  When script assignment expressions contain DEFINED, that
    can mean the wrong symbol type is copied.  This patch tracks symbols
    read during expression evaluation, rather than examining the
    expression and re-evaluating conditionals.  Not only does this
    simplify the code, it also means ld can now copy symbol types in more
    complex expressions.
    
    An unfortunate side effect of copying symbol type for more complex
    expressions affects mmix, which uses
     PROVIDE (Main = DEFINED (Main) ? Main : (DEFINED (_start) ? _start : _start.));
    in a default script.  So now _start or _start. symbol type may be
    copied, losing the function type specially set up for Main.  This can
    be avoided by making bfd_copy_link_hash_symbol_type do nothing for
    mmix.
    
    bfd/
    	* elf64-mmix.c (bfd_elf64_bfd_copy_link_hash_symbol_type): Define.
    ld/
    	* 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.

Diff:
---
 bfd/ChangeLog    |  4 ++++
 bfd/elf64-mmix.c |  3 +++
 ld/ChangeLog     |  9 +++++++++
 ld/ldexp.c       | 51 +++++++++++++++++----------------------------------
 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
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;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]