This is the mail archive of the binutils@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]

Re: [PATCH] ELF: Don't check DT_NEEDED for linker script defined symbols


On Mon, Nov 27, 2017 at 07:12:59AM +1030, Alan Modra wrote:
> We already process some assignments in open_input_bfds to have
> --defsym symbols defined early, so (3) shouldn't be too hard.

I'm testing the following.

bfd/
	* elflink.c (_bfd_elf_merge_symbol): Allow weak symbols to override
	early passes over linker script symbols.
	* linker.c (_bfd_generic_link_add_one_symbol): Allow symbols to
	override early passes over linker script symbols.  Clear ldscript_def
	on symbol definitions.
ld/
	* ldexp.c (struct definedness_hash_entry): Delete by_script.
	(definedness_newfunc): Adjust to suit.
	(update_definedness): Test ldscript_def rather than by_script.
	(is_sym_value): Likewise.
	(fold_name <DEFINED>): Test ldscript_def.
	(exp_fold_tree_1): Set script symbol values in early pass.
	* ldlang.c (open_input_bfds): Process all assignments, not just
	defsym.

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 99f867d..e0ed135 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -1471,10 +1471,15 @@ _bfd_elf_merge_symbol (bfd *abfd,
      treated as strong if the new symbol is from a dynamic library.
      This reflects the way glibc's ld.so works.
 
+     Also allow a weak symbol to override a linker script symbol
+     defined by an early pass over the script.  This is done so the
+     linker knows the symbol is defined in an object file, for the
+     DEFINED script function.
+
      Do this before setting *type_change_ok or *size_change_ok so that
      we warn properly when dynamic library symbols are overridden.  */
 
-  if (newdef && !newdyn && olddyn)
+  if (newdef && !newdyn && (olddyn || h->root.ldscript_def))
     newweak = FALSE;
   if (olddef && newdyn)
     oldweak = FALSE;
diff --git a/bfd/linker.c b/bfd/linker.c
index a96c6ed..9c19df4 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1443,9 +1443,14 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
   do
     {
       enum link_action action;
+      int prev;
 
+      prev = h->type;
+      /* Treat symbols defined by early linker script pass as undefined.  */
+      if (h->ldscript_def)
+	prev = bfd_link_hash_undefined;
       cycle = FALSE;
-      action = link_action[(int) row][(int) h->type];
+      action = link_action[(int) row][prev];
       switch (action)
 	{
 	case FAIL:
@@ -1489,6 +1494,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
 	    h->u.def.section = section;
 	    h->u.def.value = value;
 	    h->linker_def = 0;
+	    h->ldscript_def = 0;
 
 	    /* If we have been asked to, we act like collect2 and
 	       identify all functions that might be global
@@ -1588,6 +1594,7 @@ _bfd_generic_link_add_one_symbol (struct bfd_link_info *info,
 	  else
 	    h->u.c.p->section = section;
 	  h->linker_def = 0;
+	  h->ldscript_def = 0;
 	  break;
 
 	case REF:
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 83d9f8f..dddb76d 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -63,9 +63,6 @@ struct definedness_hash_entry
   /* Symbol was defined by an object file.  */
   unsigned int by_object : 1;
 
-  /* Symbols was defined by a script.  */
-  unsigned int by_script : 1;
-
   /* Low bit of iteration count.  Symbols with matching iteration have
      been defined in this pass over the script.  */
   unsigned int iteration : 1;
@@ -286,7 +283,6 @@ definedness_newfunc (struct bfd_hash_entry *entry,
     einfo (_("%P%F: bfd_hash_allocate failed creating symbol %s\n"), name);
 
   ret->by_object = 0;
-  ret->by_script = 0;
   ret->iteration = 0;
   return &ret->root;
 }
@@ -320,7 +316,7 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h)
   /* If the symbol was already defined, and not by a script, then it
      must be defined by an object file or by the linker target code.  */
   ret = TRUE;
-  if (!defentry->by_script
+  if (!h->ldscript_def
       && (h->type == bfd_link_hash_defined
 	  || h->type == bfd_link_hash_defweak
 	  || h->type == bfd_link_hash_common))
@@ -332,7 +328,6 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h)
 	ret = FALSE;
     }
 
-  defentry->by_script = 1;
   defentry->iteration = lang_statement_iteration;
   defentry->final_sec = bfd_abs_section_ptr;
   if (expld.phase == lang_final_phase_enum
@@ -713,7 +708,8 @@ fold_name (etree_type *tree)
 		      && (h->type == bfd_link_hash_defined
 			  || h->type == bfd_link_hash_defweak
 			  || h->type == bfd_link_hash_common)
-		      && ((def = symbol_defined (tree->name.name)) == NULL
+		      && (!h->ldscript_def
+			  || (def = symbol_defined (tree->name.name)) == NULL
 			  || def->by_object
 			  || def->iteration == (lang_statement_iteration & 1)));
 	}
@@ -950,12 +946,12 @@ is_sym_value (const etree_type *tree, bfd_vma val)
   return (tree->type.node_class == etree_name
 	  && tree->type.node_code == NAME
 	  && (def = symbol_defined (tree->name.name)) != NULL
-	  && def->by_script
 	  && def->iteration == (lang_statement_iteration & 1)
 	  && (h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
 						&link_info,
 						tree->name.name,
 						FALSE, FALSE, TRUE)) != NULL
+	  && h->ldscript_def
 	  && h->type == bfd_link_hash_defined
 	  && h->u.def.section == bfd_abs_section_ptr
 	  && h->u.def.value == val);
@@ -1173,11 +1169,10 @@ exp_fold_tree_1 (etree_type *tree)
 	     converted to absolute values, as is required by many
 	     expressions, until final section sizing is complete.  */
 	  if ((expld.result.valid_p
+	       || (expld.phase <= lang_mark_phase_enum
+		   && tree->type.node_class == etree_assign))
 	       && (expld.phase == lang_final_phase_enum
 		   || expld.assign_name != NULL))
-	      || (expld.phase <= lang_mark_phase_enum
-		  && tree->type.node_class == etree_assign
-		  && tree->assign.defsym))
 	    {
 	      if (h == NULL)
 		{
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 674004e..5e96dd4 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3359,9 +3359,7 @@ open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode)
 #endif
 	  break;
 	case lang_assignment_statement_enum:
-	  if (s->assignment_statement.exp->type.node_class != etree_assert
-	      && s->assignment_statement.exp->assign.defsym)
-	    /* This is from a --defsym on the command line.  */
+	  if (s->assignment_statement.exp->type.node_class != etree_assert)
 	    exp_fold_tree_no_dot (s->assignment_statement.exp);
 	  break;
 	default:

-- 
Alan Modra
Australia Development Lab, IBM


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