public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* IA64 linker is broken
@ 2005-01-30 19:22 H. J. Lu
  2005-01-31  0:02 ` Alan Modra
  0 siblings, 1 reply; 20+ messages in thread
From: H. J. Lu @ 2005-01-30 19:22 UTC (permalink / raw)
  To: binutils; +Cc: amodra

When bootstrapping gcc with today's binutils, I got

stage1/xgcc -Bstage1/ -B/usr/gcc-4.0/ia64-unknown-linux-gnu/bin/
-DUSE_LIBUNWIND_EXCEPTIONS -g -O2 -DIN_GCC   -W -Wall -Wwrite-strings
-Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-long-long
-Wno-variadic-macros -Wold-style-definition -Werror    -DHAVE_CONFIG_H
-DGENERATOR_FILE  -o build/gengenrtl \
 build/gengenrtl.o build/errors.o
../build-ia64-unknown-linux-gnu/libiberty/libiberty.a
/usr/lib/crt1.o:(.dynamic+0x0): multiple definition of `_DYNAMIC'
collect2: ld returned 1 exit status
make[4]: *** [build/gengenrtl] Error 1
make[4]: *** Waiting for unfinished jobs....
make[4]: Leaving directory `/export/build/gnu/gcc/build-ia64-linux/gcc'
make[3]: *** [stage2_build] Error 2
make[3]: Leaving directory `/export/build/gnu/gcc/build-ia64-linux/gcc'
make[2]: *** [bootstrap] Error 2

The 2005-01-24 binutils is OK. It may have something to do with

http://sources.redhat.com/ml/binutils/2005-01/msg00405.html

I will look into it on Monday.


H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is broken
  2005-01-30 19:22 IA64 linker is broken H. J. Lu
@ 2005-01-31  0:02 ` Alan Modra
  2005-01-31  7:13   ` Alan Modra
  0 siblings, 1 reply; 20+ messages in thread
From: Alan Modra @ 2005-01-31  0:02 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Sun, Jan 30, 2005 at 11:22:49AM -0800, H. J. Lu wrote:
> /usr/lib/crt1.o:(.dynamic+0x0): multiple definition of `_DYNAMIC'
[snip]
> The 2005-01-24 binutils is OK. It may have something to do with
> 
> http://sources.redhat.com/ml/binutils/2005-01/msg00405.html

Possible, I suppose.  An as-needed shared lib will define syms whether
or not the lib is actually linked.  It will be linked if any symbol it
defines satisfies an undefined reference, and conversely it isn't linked
then there are no references to its symbols.  That should make it safe
to leave its symbols in the symbol table, so long as we properly treat
them in _bfd_elf_merge_symbol.  If there is a problem, it's likely to be
in _bfd_elf_merge_symbol.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is broken
  2005-01-31  0:02 ` Alan Modra
@ 2005-01-31  7:13   ` Alan Modra
  2005-01-31  8:29     ` Alan Modra
                       ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Alan Modra @ 2005-01-31  7:13 UTC (permalink / raw)
  To: H. J. Lu, binutils

[-- Attachment #1: Type: text/plain, Size: 1394 bytes --]

On Mon, Jan 31, 2005 at 10:32:27AM +1030, Alan Modra wrote:
> On Sun, Jan 30, 2005 at 11:22:49AM -0800, H. J. Lu wrote:
> > /usr/lib/crt1.o:(.dynamic+0x0): multiple definition of `_DYNAMIC'
> [snip]
> > The 2005-01-24 binutils is OK. It may have something to do with
> > 
> > http://sources.redhat.com/ml/binutils/2005-01/msg00405.html
> 
> Possible, I suppose.  An as-needed shared lib will define syms whether
> or not the lib is actually linked.  It will be linked if any symbol it
> defines satisfies an undefined reference, and conversely it isn't linked
> then there are no references to its symbols.  That should make it safe
> to leave its symbols in the symbol table, so long as we properly treat
> them in _bfd_elf_merge_symbol.  If there is a problem, it's likely to be
> in _bfd_elf_merge_symbol.

I'm testing the following on powerpc and x86 to ensure I haven't made
any silly mistakes.  It's a big hammer approach but cleaner than what we
had before, I think.  Rather than tweaking _bfd_elf_merge_symbol and
other places to specially handle symbols defined in unused --as-needed
libs, I've munged all such symbols back to their new state.  Hopefully
this won't break too many back-end elf_link_hash_traverse functions..

Would you please test this on ia64?  I don't have access to ia64
hardware, so testing this isn't so easy.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

[-- Attachment #2: curr.diff --]
[-- Type: text/plain, Size: 14131 bytes --]

include/
	* bfdlink.h (bfd_link_repair_undef_list): Declare.
bfd/
	* elf64-ppc.c (ppc64_elf_check_directives): Move undefs list fixup..
	* linker.c (bfd_link_repair_undef_list): ..to new function, but don't
	remove anything but new and undefweak.
	* elflink.c (bfd_elf_record_link_assignment): Call
	bfd_link_repair_undef_list.
	(_bfd_elf_merge_symbol): Don't handle as-needed syms here.
	(struct elf_smash_data): New.
	(elf_smash_syms): New function.
	(elf_link_add_object_symbols): Call elf_smash_syms.  Don't add
	unneeded dynamic objects to loaded list.
	(elf_link_output_extsym): Don't handle as-needed here.  Strip
	bfd_link_hash_new symbols.
	* elf32-cris.c (elf_cris_discard_excess_program_dynamics): Don't
	delref when dynindx is already -1.
	* elf64-alpha.c (elf64_alpha_output_extsym): Strip bfd_link_hash_new
	symbols.
	* elfxx-mips.c (mips_elf_output_extsym): Likewise.
ld/
	* ld.texinfo: Clarify --as-needed operation.

Index: include/bfdlink.h
===================================================================
RCS file: /cvs/src/src/include/bfdlink.h,v
retrieving revision 1.50
diff -u -p -r1.50 bfdlink.h
--- include/bfdlink.h	15 Nov 2004 23:21:26 -0000	1.50
+++ include/bfdlink.h	31 Jan 2005 06:46:06 -0000
@@ -197,6 +197,10 @@ extern void bfd_link_hash_traverse
 extern void bfd_link_add_undef
   (struct bfd_link_hash_table *, struct bfd_link_hash_entry *);
 
+/* Remove symbols from the undefs list that don't belong there.  */
+extern void bfd_link_repair_undef_list
+  (struct bfd_link_hash_table *table);
+
 struct bfd_sym_chain
 {
   struct bfd_sym_chain *next;
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.185
diff -u -p -r1.185 elf64-ppc.c
--- bfd/elf64-ppc.c	11 Jan 2005 09:32:52 -0000	1.185
+++ bfd/elf64-ppc.c	31 Jan 2005 06:45:19 -0000
@@ -4066,34 +4066,7 @@ ppc64_elf_check_directives (bfd *abfd AT
      undef_weak.  */
   if (htab->twiddled_syms)
     {
-      struct bfd_link_hash_entry **pun;
-
-      pun = &htab->elf.root.undefs;
-      while (*pun != NULL)
-	{
-	  struct bfd_link_hash_entry *h = *pun;
-
-	  if (h->type != bfd_link_hash_undefined
-	      && h->type != bfd_link_hash_common)
-	    {
-	      *pun = h->u.undef.next;
-	      h->u.undef.next = NULL;
-	      if (h == htab->elf.root.undefs_tail)
-		{
-		  if (pun == &htab->elf.root.undefs)
-		    htab->elf.root.undefs_tail = NULL;
-		  else
-		    /* pun points at an u.undef.next field.  Go back to
-		       the start of the link_hash_entry.  */
-		    htab->elf.root.undefs_tail = (struct bfd_link_hash_entry *)
-		      ((char *) pun - ((char *) &h->u.undef.next - (char *) h));
-		  break;
-		}
-	    }
-	  else
-	    pun = &h->u.undef.next;
-	}
-
+      bfd_link_repair_undef_list (&htab->elf.root);
       htab->twiddled_syms = 0;
     }
   return TRUE;
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.42
diff -u -p -r1.42 linker.c
--- bfd/linker.c	21 Oct 2004 15:28:30 -0000	1.42
+++ bfd/linker.c	31 Jan 2005 06:45:32 -0000
@@ -623,6 +623,45 @@ bfd_link_add_undef (struct bfd_link_hash
     table->undefs = h;
   table->undefs_tail = h;
 }
+
+/* The undefs list was designed so that in normal use we don't need to
+   remove entries.  However, if symbols on the list are changed from
+   bfd_link_hash_undefined to either bfd_link_hash_undefweak or
+   bfd_link_hash_new for some reason, then they must be removed from the
+   list.  Failure to do so might result in the linker attempting to add
+   the symbol to the list again at a later stage.  */
+
+void
+bfd_link_repair_undef_list (struct bfd_link_hash_table *table)
+{
+  struct bfd_link_hash_entry **pun;
+
+  pun = &table->undefs;
+  while (*pun != NULL)
+    {
+      struct bfd_link_hash_entry *h = *pun;
+
+      if (h->type == bfd_link_hash_new
+	  || h->type == bfd_link_hash_undefweak)
+	{
+	  *pun = h->u.undef.next;
+	  h->u.undef.next = NULL;
+	  if (h == table->undefs_tail)
+	    {
+	      if (pun == &table->undefs)
+		table->undefs_tail = NULL;
+	      else
+		/* pun points at an u.undef.next field.  Go back to
+		   the start of the link_hash_entry.  */
+		table->undefs_tail = (struct bfd_link_hash_entry *)
+		  ((char *) pun - ((char *) &h->u.undef.next - (char *) h));
+	      break;
+	    }
+	}
+      else
+	pun = &h->u.undef.next;
+    }
+}
 \f
 /* Routine to create an entry in a generic link hash table.  */
 
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.124
diff -u -p -r1.124 elflink.c
--- bfd/elflink.c	25 Jan 2005 01:40:01 -0000	1.124
+++ bfd/elflink.c	31 Jan 2005 06:45:25 -0000
@@ -442,15 +442,16 @@ bfd_elf_record_link_assignment (bfd *out
 
   /* Since we're defining the symbol, don't let it seem to have not
      been defined.  record_dynamic_symbol and size_dynamic_sections
-     may depend on this.
-     ??? Changing bfd_link_hash_undefined to bfd_link_hash_new (or
-     to bfd_link_hash_undefweak, see linker.c:link_action) runs the risk
-     of some later symbol manipulation setting the symbol back to
-     bfd_link_hash_undefined, and the linker trying to add the symbol to
-     the undefs list twice.  */
+     may depend on this.  */
   if (h->root.type == bfd_link_hash_undefweak
       || h->root.type == bfd_link_hash_undefined)
-    h->root.type = bfd_link_hash_new;
+    {
+      struct elf_link_hash_table *htab = elf_hash_table (info);
+
+      if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root)
+	bfd_link_repair_undef_list (&htab->root);
+      h->root.type = bfd_link_hash_new;
+    }
 
   if (h->root.type == bfd_link_hash_new)
     h->non_elf = 0;
@@ -728,7 +729,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
   int bind;
   bfd *oldbfd;
   bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
-  bfd_boolean newweak, oldweak, old_asneeded;
+  bfd_boolean newweak, oldweak;
 
   *skip = FALSE;
   *override = FALSE;
@@ -858,14 +859,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
   else
     olddef = TRUE;
 
-  /* If the old definition came from an as-needed dynamic library which
-     wasn't found to be needed, treat the sym as undefined.  */
-  old_asneeded = FALSE;
-  if (newdyn
-      && olddyn
-      && (elf_dyn_lib_class (oldbfd) & DYN_AS_NEEDED) != 0)
-    old_asneeded = TRUE;
-
   /* Check TLS symbol.  */
   if ((ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)
       && ELF_ST_TYPE (sym->st_info) != h->type)
@@ -1068,7 +1061,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   if (olddyn
       && olddef
-      && !old_asneeded
       && h->root.type == bfd_link_hash_defined
       && h->def_dynamic
       && (h->root.u.def.section->flags & SEC_ALLOC) != 0
@@ -1120,7 +1112,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   if (newdyn
       && newdef
-      && ((olddef && !old_asneeded)
+      && (olddef
 	  || (h->root.type == bfd_link_hash_common
 	      && (newweak
 		  || ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
@@ -1170,7 +1162,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
      symbol is a function or is weak.  */
 
   flip = NULL;
-  if ((!newdyn || old_asneeded)
+  if (!newdyn
       && (newdef
 	  || (bfd_is_com_section (sec)
 	      && (oldweak
@@ -2813,6 +2805,69 @@ elf_add_dt_needed_tag (bfd *abfd,
   return 0;
 }
 
+/* Called via elf_link_hash_traverse, elf_smash_syms sets all symbols
+   belonging to NOT_NEEDED to bfd_link_hash_new.  We know there are no
+   references to these symbols.  */
+
+struct elf_smash_syms_data
+{
+  bfd *not_needed;
+  struct elf_link_hash_table *htab;
+  bfd_boolean twiddled;
+};
+
+static bfd_boolean
+elf_smash_syms (struct elf_link_hash_entry *h, void *data)
+{
+  struct elf_smash_syms_data *inf = (struct elf_smash_syms_data *) data;
+  struct bfd_link_hash_entry *bh;
+
+  switch (h->root.type)
+    {
+    default:
+    case bfd_link_hash_new:
+      return TRUE;
+
+    case bfd_link_hash_undefined:
+    case bfd_link_hash_undefweak:
+      if (h->root.u.undef.abfd != inf->not_needed)
+	return TRUE;
+      break;
+
+    case bfd_link_hash_defined:
+    case bfd_link_hash_defweak:
+      if (h->root.u.def.section->owner != inf->not_needed)
+	return TRUE;
+      break;
+
+    case bfd_link_hash_common:
+      if (h->root.u.c.p->section->owner != inf->not_needed)
+	return TRUE;
+      break;
+
+    case bfd_link_hash_warning:
+    case bfd_link_hash_indirect:
+      elf_smash_syms ((struct elf_link_hash_entry *) h->root.u.i.link, data);
+      if (h->root.u.i.link->type != bfd_link_hash_new)
+	return TRUE;
+      if (h->root.u.i.link->u.undef.abfd != inf->not_needed)
+	return TRUE;
+      break;
+    }
+
+  /* Set sym back to newly created state, but keep undefs list pointer.  */
+  bh = h->root.u.undef.next;
+  if (bh != NULL || inf->htab->root.undefs_tail == &h->root)
+    inf->twiddled = TRUE;
+  (*inf->htab->root.table.newfunc) (&h->root.root,
+				    &inf->htab->root.table,
+				    h->root.root.string);
+  h->root.u.undef.next = bh;
+  h->root.u.undef.abfd = inf->not_needed;
+  h->non_elf = 0;
+  return TRUE;
+}
+
 /* Sort symbol by value and section.  */
 static int
 elf_sort_symbol (const void *arg1, const void *arg2)
@@ -4031,6 +4086,18 @@ elf_link_add_object_symbols (bfd *abfd, 
     free (isymbuf);
   isymbuf = NULL;
 
+  if (!add_needed)
+    {
+      struct elf_smash_syms_data inf;
+      inf.not_needed = abfd;
+      inf.htab = hash_table;
+      inf.twiddled = FALSE;
+      elf_link_hash_traverse (hash_table, elf_smash_syms, &inf);
+      if (inf.twiddled)
+	bfd_link_repair_undef_list (&hash_table->root);
+      weaks = NULL;
+    }
+
   /* Now set the weakdefs field correctly for all the weak defined
      symbols we found.  The only way to do this is to search all the
      symbols.  Since we only need the information for non functions in
@@ -4263,7 +4330,7 @@ elf_link_add_object_symbols (bfd *abfd, 
 	}
     }
 
-  if (is_elf_hash_table (hash_table))
+  if (is_elf_hash_table (hash_table) && add_needed)
     {
       /* Add this bfd to the loaded list.  */
       struct elf_link_loaded_list *n;
@@ -6143,11 +6210,7 @@ elf_link_output_extsym (struct elf_link_
   const struct elf_backend_data *bed;
 
   if (h->root.type == bfd_link_hash_warning)
-    {
-      h = (struct elf_link_hash_entry *) h->root.u.i.link;
-      if (h->root.type == bfd_link_hash_new)
-	return TRUE;
-    }
+    h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
   /* Decide whether to output this symbol in this pass.  */
   if (eoinfo->localsyms)
@@ -6170,7 +6233,6 @@ elf_link_output_extsym (struct elf_link_
   if (h->root.type == bfd_link_hash_undefined
       && h->ref_dynamic
       && !h->ref_regular
-      && (elf_dyn_lib_class (h->root.u.undef.abfd) & DYN_AS_NEEDED) == 0
       && ! elf_link_check_versioned_symbol (finfo->info, bed, h)
       && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
     {
@@ -6212,7 +6274,8 @@ elf_link_output_extsym (struct elf_link_
   if (h->indx == -2)
     strip = FALSE;
   else if ((h->def_dynamic
-	    || h->ref_dynamic)
+	    || h->ref_dynamic
+	    || h->root.type == bfd_link_hash_new)
 	   && !h->def_regular
 	   && !h->ref_regular)
     strip = TRUE;
Index: bfd/elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.61
diff -u -p -r1.61 elf32-cris.c
--- bfd/elf32-cris.c	11 Jan 2005 09:32:46 -0000	1.61
+++ bfd/elf32-cris.c	31 Jan 2005 06:45:12 -0000
@@ -3130,6 +3130,7 @@ elf_cris_discard_excess_program_dynamics
 	 introduce new problems.  Of course we don't do this if we're
 	 exporting all dynamic symbols.  */
       if (! info->export_dynamic
+	  && h->root.dynindx != -1
 	  && !h->root.def_dynamic
 	  && !h->root.ref_dynamic)
 	{
Index: bfd/elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.125
diff -u -p -r1.125 elf64-alpha.c
--- bfd/elf64-alpha.c	21 Oct 2004 15:28:25 -0000	1.125
+++ bfd/elf64-alpha.c	31 Jan 2005 06:45:15 -0000
@@ -2741,7 +2741,9 @@ elf64_alpha_output_extsym (h, data)
 
   if (h->root.indx == -2)
     strip = FALSE;
-  else if ((h->root.def_dynamic || h->root.ref_dynamic)
+  else if ((h->root.def_dynamic
+	    || h->root.ref_dynamic
+	    || h->root.root.type == bfd_link_hash_new)
 	   && !h->root.def_regular
 	   && !h->root.ref_regular)
     strip = TRUE;
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.117
diff -u -p -r1.117 elfxx-mips.c
--- bfd/elfxx-mips.c	14 Dec 2004 09:48:10 -0000	1.117
+++ bfd/elfxx-mips.c	31 Jan 2005 06:45:30 -0000
@@ -1491,7 +1491,8 @@ mips_elf_output_extsym (struct mips_elf_
   if (h->root.indx == -2)
     strip = FALSE;
   else if ((h->root.def_dynamic
-	    || h->root.ref_dynamic)
+	    || h->root.ref_dynamic
+	    || h->root.type == bfd_link_hash_new)
 	   && !h->root.def_regular
 	   && !h->root.ref_regular)
     strip = TRUE;
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.138
diff -u -p -r1.138 ld.texinfo
--- ld/ld.texinfo	28 Jan 2005 17:24:40 -0000	1.138
+++ ld/ld.texinfo	31 Jan 2005 06:46:12 -0000
@@ -994,8 +994,9 @@ This option affects ELF DT_NEEDED tags f
 on the command line after the @option{--as-needed} option.  Normally,
 the linker will add a DT_NEEDED tag for each dynamic library mentioned
 on the command line, regardless of whether the library is actually
-needed. @option{--as-needed} causes DT_NEEDED tags to only be emitted
-for libraries that satisfy some reference from regular objects.
+needed.  @option{--as-needed} causes DT_NEEDED tags to only be emitted
+for libraries that satisfy some symbol reference from regular objects
+which is undefined at the point that the library was linked.
 @option{--no-as-needed} restores the default behaviour.
 
 @kindex --add-needed

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is broken
  2005-01-31  7:13   ` Alan Modra
@ 2005-01-31  8:29     ` Alan Modra
  2005-01-31 18:38       ` H. J. Lu
  2005-01-31 21:22     ` ELF " H. J. Lu
  2005-02-01  1:41     ` IA64 " Alan Modra
  2 siblings, 1 reply; 20+ messages in thread
From: Alan Modra @ 2005-01-31  8:29 UTC (permalink / raw)
  To: H. J. Lu, binutils

On Mon, Jan 31, 2005 at 05:43:08PM +1030, Alan Modra wrote:
> @@ -6143,11 +6210,7 @@ elf_link_output_extsym (struct elf_link_
>    const struct elf_backend_data *bed;
>  
>    if (h->root.type == bfd_link_hash_warning)
> -    {
> -      h = (struct elf_link_hash_entry *) h->root.u.i.link;
> -      if (h->root.type == bfd_link_hash_new)
> -	return TRUE;
> -    }
> +    h = (struct elf_link_hash_entry *) h->root.u.i.link;
>  
>    /* Decide whether to output this symbol in this pass.  */
>    if (eoinfo->localsyms)

Oops, this hunk wasn't supposed to be included.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is broken
  2005-01-31  8:29     ` Alan Modra
@ 2005-01-31 18:38       ` H. J. Lu
  0 siblings, 0 replies; 20+ messages in thread
From: H. J. Lu @ 2005-01-31 18:38 UTC (permalink / raw)
  To: binutils

On Mon, Jan 31, 2005 at 06:59:24PM +1030, Alan Modra wrote:
> On Mon, Jan 31, 2005 at 05:43:08PM +1030, Alan Modra wrote:
> > @@ -6143,11 +6210,7 @@ elf_link_output_extsym (struct elf_link_
> >    const struct elf_backend_data *bed;
> >  
> >    if (h->root.type == bfd_link_hash_warning)
> > -    {
> > -      h = (struct elf_link_hash_entry *) h->root.u.i.link;
> > -      if (h->root.type == bfd_link_hash_new)
> > -	return TRUE;
> > -    }
> > +    h = (struct elf_link_hash_entry *) h->root.u.i.link;
> >  
> >    /* Decide whether to output this symbol in this pass.  */
> >    if (eoinfo->localsyms)
> 
> Oops, this hunk wasn't supposed to be included.

It doesn't work on ia64. Now I am getting

gnu-2:pts/1[5]> stage1/xgcc -Bstage1/
-B/usr/gcc-4.0/ia64-unknown-linux-gnu/bin/   -DUSE_LIBUNWIND_EXCEPTIONS
-g -O2 -DIN_GCC   -W -Wall -Wwrite-strings -Wstrict-prototypes
-Wmissing-prototypes -pedantic -Wno-long-long -Wno-variadic-macros
-Wold-style-definition -Werror    -DHAVE_CONFIG_H -DGENERATOR_FILE  -o
build/gengenrtl \
 build/gengenrtl.o build/errors.o
../build-ia64-unknown-linux-gnu/libiberty/libiberty.a -B./
/usr/lib/crt1.o:(.dynamic+0x0): multiple definition of `_DYNAMIC'
/usr/lib/crt1.o: In function `_start':
: undefined reference to `__libc_csu_init'
build/gengenrtl.o: In function `find_formats':
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:178: undefined
reference to `strcmp'
build/gengenrtl.o: In function `genlegend':
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:289: undefined
reference to `puts'
build/gengenrtl.o: In function `gencode':
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:322: undefined
reference to `puts'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:323: undefined
reference to `puts'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:324: undefined
reference to `puts'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:325: undefined
reference to `puts'
build/gengenrtl.o:/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:326:
more undefined references to `puts' follow
build/gengenrtl.o: In function `main':
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:160: undefined
reference to `strcmp'
build/gengenrtl.o: In function `special_rtx':
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:146: undefined
reference to `strcmp'
build/gengenrtl.o: In function `main':
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:245: undefined
reference to `puts'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:146: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:146: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:146: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gengenrtl.c:146: undefined
reference to `strcmp'
/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
: undefined reference to `__init_array_start'
/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
: undefined reference to `__init_array_start'
./ld: BFD 2.15.94.0.3 20050130 assertion fail
/net/gnu/export/linux/src/binutils/binutils/bfd/elf-strtab.c:241
collect2: ld returned 1 exit status


H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* ELF linker is broken
  2005-01-31  7:13   ` Alan Modra
  2005-01-31  8:29     ` Alan Modra
@ 2005-01-31 21:22     ` H. J. Lu
  2005-01-31 22:02       ` PATCH: " H. J. Lu
  2005-01-31 23:16       ` ELF linker is broken Alan Modra
  2005-02-01  1:41     ` IA64 " Alan Modra
  2 siblings, 2 replies; 20+ messages in thread
From: H. J. Lu @ 2005-01-31 21:22 UTC (permalink / raw)
  To: binutils; +Cc: amodra

[-- Attachment #1: Type: text/plain, Size: 1876 bytes --]

On Mon, Jan 31, 2005 at 05:43:08PM +1030, Alan Modra wrote:
> On Mon, Jan 31, 2005 at 10:32:27AM +1030, Alan Modra wrote:
> > On Sun, Jan 30, 2005 at 11:22:49AM -0800, H. J. Lu wrote:
> > > /usr/lib/crt1.o:(.dynamic+0x0): multiple definition of `_DYNAMIC'
> > [snip]
> > > The 2005-01-24 binutils is OK. It may have something to do with
> > > 
> > > http://sources.redhat.com/ml/binutils/2005-01/msg00405.html
> > 
> > Possible, I suppose.  An as-needed shared lib will define syms whether
> > or not the lib is actually linked.  It will be linked if any symbol it
> > defines satisfies an undefined reference, and conversely it isn't linked
> > then there are no references to its symbols.  That should make it safe
> > to leave its symbols in the symbol table, so long as we properly treat
> > them in _bfd_elf_merge_symbol.  If there is a problem, it's likely to be
> > in _bfd_elf_merge_symbol.
> 
> I'm testing the following on powerpc and x86 to ensure I haven't made
> any silly mistakes.  It's a big hammer approach but cleaner than what we
> had before, I think.  Rather than tweaking _bfd_elf_merge_symbol and
> other places to specially handle symbols defined in unused --as-needed
> libs, I've munged all such symbols back to their new state.  Hopefully
> this won't break too many back-end elf_link_hash_traverse functions..
> 
> Would you please test this on ia64?  I don't have access to ia64
> hardware, so testing this isn't so easy.

I am enclosing a testcase here. I saw the same problem on ia32, ia64
and x86_64:

[hjl@gnu-4 needed]$ make
gcc    -c -o foo.o foo.c
gcc -shared -fPIC -o libneeded.so needed.c
gcc -o foo foo.o \
        -Wl,--as-needed -lneeded -L. -Wl,--no-as-needed
/usr/lib/gcc-lib/ia64-redhat-linux/3.2.3/../../../crt1.o:(.dynamic+0x0):
multiple definition of `_DYNAMIC'
collect2: ld returned 1 exit status
make: *** [foo] Error 1


H.J.

[-- Attachment #2: bug.tar.gz --]
[-- Type: application/x-gzip, Size: 354 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* PATCH: ELF linker is broken
  2005-01-31 21:22     ` ELF " H. J. Lu
@ 2005-01-31 22:02       ` H. J. Lu
  2005-02-01  0:08         ` Alan Modra
  2005-01-31 23:16       ` ELF linker is broken Alan Modra
  1 sibling, 1 reply; 20+ messages in thread
From: H. J. Lu @ 2005-01-31 22:02 UTC (permalink / raw)
  To: binutils; +Cc: amodra

On Mon, Jan 31, 2005 at 01:22:03PM -0800, H. J. Lu wrote:
> On Mon, Jan 31, 2005 at 05:43:08PM +1030, Alan Modra wrote:
> > On Mon, Jan 31, 2005 at 10:32:27AM +1030, Alan Modra wrote:
> > > On Sun, Jan 30, 2005 at 11:22:49AM -0800, H. J. Lu wrote:
> > > > /usr/lib/crt1.o:(.dynamic+0x0): multiple definition of `_DYNAMIC'
> > > [snip]
> > > > The 2005-01-24 binutils is OK. It may have something to do with
> > > > 
> > > > http://sources.redhat.com/ml/binutils/2005-01/msg00405.html
> > > 
> > > Possible, I suppose.  An as-needed shared lib will define syms whether
> > > or not the lib is actually linked.  It will be linked if any symbol it
> > > defines satisfies an undefined reference, and conversely it isn't linked
> > > then there are no references to its symbols.  That should make it safe
> > > to leave its symbols in the symbol table, so long as we properly treat
> > > them in _bfd_elf_merge_symbol.  If there is a problem, it's likely to be
> > > in _bfd_elf_merge_symbol.
> > 
> > I'm testing the following on powerpc and x86 to ensure I haven't made
> > any silly mistakes.  It's a big hammer approach but cleaner than what we
> > had before, I think.  Rather than tweaking _bfd_elf_merge_symbol and
> > other places to specially handle symbols defined in unused --as-needed
> > libs, I've munged all such symbols back to their new state.  Hopefully
> > this won't break too many back-end elf_link_hash_traverse functions..
> > 
> > Would you please test this on ia64?  I don't have access to ia64
> > hardware, so testing this isn't so easy.
> 
> I am enclosing a testcase here. I saw the same problem on ia32, ia64
> and x86_64:
> 

This patch works for me.

H.J.
----
2005-01-31  H.J. Lu  <hongjiu.lu@intel.com>

	* elflink.c (_bfd_elf_link_create_dynamic_sections): Discard
	previous "_DYNAMIC" before creating the new one.

--- bfd/elflink.c.dynamic	2005-01-31 12:19:55.000000000 -0800
+++ bfd/elflink.c	2005-01-31 13:59:00.463355292 -0800
@@ -216,7 +216,19 @@ _bfd_elf_link_create_dynamic_sections (b
      linker script, but we only want to define it if we are, in fact,
      creating a .dynamic section.  We don't want to define it if there
      is no .dynamic section, since on some ELF platforms the start up
-     code examines it to decide how to initialize the process.  */
+     code examines it to decide how to initialize the process. 
+   
+     _DYNAMIC is a special symbol. We used to create it before reading
+     symbol tables from shared libraries. But now it is delayed. We
+     discard any previous definition from shared library before we
+     create this one.  */
+  h = elf_link_hash_lookup (elf_hash_table (info), "_DYNAMIC", FALSE,
+			    FALSE, FALSE);
+  if (h)
+    {
+      h->root.type = bfd_link_hash_undefined;
+      h->root.u.undef.abfd = abfd;
+    }
   bh = NULL;
   if (! (_bfd_generic_link_add_one_symbol
 	 (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, 0, NULL, FALSE,

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: ELF linker is broken
  2005-01-31 21:22     ` ELF " H. J. Lu
  2005-01-31 22:02       ` PATCH: " H. J. Lu
@ 2005-01-31 23:16       ` Alan Modra
  1 sibling, 0 replies; 20+ messages in thread
From: Alan Modra @ 2005-01-31 23:16 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Mon, Jan 31, 2005 at 01:22:03PM -0800, H. J. Lu wrote:
> I am enclosing a testcase here. I saw the same problem on ia32, ia64
> and x86_64:

Thanks.  That makes it clear what is happening.

  /* The special symbol _DYNAMIC is always set to the start of the
     .dynamic section.  This call occurs before we have processed the
     symbols for any dynamic object, so we don't have to worry about
     overriding a dynamic definition.  We could set _DYNAMIC in a
     linker script, but we only want to define it if we are, in fact,
     creating a .dynamic section.  We don't want to define it if there
     is no .dynamic section, since on some ELF platforms the start up
     code examines it to decide how to initialize the process.  */
  bh = NULL;
  if (! (_bfd_generic_link_add_one_symbol
	 (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, 0, NULL, FALSE,
	  get_elf_backend_data (abfd)->collect, &bh)))
    return FALSE;

The comment 'before we have processed the symbols for any dynamic
object' is no longer true.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: PATCH: ELF linker is broken
  2005-01-31 22:02       ` PATCH: " H. J. Lu
@ 2005-02-01  0:08         ` Alan Modra
  2005-02-01  5:56           ` IA64 linker is totally broken (Re: PATCH: ELF linker is broken) H. J. Lu
  0 siblings, 1 reply; 20+ messages in thread
From: Alan Modra @ 2005-02-01  0:08 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Mon, Jan 31, 2005 at 02:02:14PM -0800, H. J. Lu wrote:
> 	* elflink.c (_bfd_elf_link_create_dynamic_sections): Discard
> 	previous "_DYNAMIC" before creating the new one.

I'll be commiting a patch that looks similar to this one in a few
minutes.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is broken
  2005-01-31  7:13   ` Alan Modra
  2005-01-31  8:29     ` Alan Modra
  2005-01-31 21:22     ` ELF " H. J. Lu
@ 2005-02-01  1:41     ` Alan Modra
  2 siblings, 0 replies; 20+ messages in thread
From: Alan Modra @ 2005-02-01  1:41 UTC (permalink / raw)
  To: binutils; +Cc: Nick Clifton, Ian Lance Taylor

This is what I applied.  Note the following comment

+	 This is a symptom of a larger problem:  Absolute symbols
+	 defined in shared libraries can't be overridden, because we
+	 lose the link to the bfd which is via the symbol section.  */

I'm tempted to exclude absolute symbols defined in dynamic objects from
the symbol table, but worried this might break something.  Absolute syms
in dynamic objects aren't really absolute anyway, since typically ld.so
relocates them by the base of the dynamic object, so there's not much
sense in an app using absolute syms from a dynamic object.  Nick, Ian,
what do you think?

Two proper fixes occur to me
a) Use new bfd_link_hash_defined_abs and bfd_link_hash_defweak_abs hash
   types, and change zillions of places thoughout the code.
or
b) Dispense with the global bfd_abs_section and instead create a fake
   abs section attached to each input bfd.  Perhaps extend this to
   get rid of bfd_{und,com,ind}_section too.  This would be a major
   change too.

include/
	* bfdlink.h (bfd_link_repair_undef_list): Declare.
bfd/
	* elf64-ppc.c (ppc64_elf_check_directives): Move undefs list fixup..
	* linker.c (bfd_link_repair_undef_list): ..to new function, but don't
	remove anything but new and undefweak.
	* elflink.c (_bfd_elf_link_create_dynamic_sections): Override any
	existing _DYNAMIC.
	(_bfd_elf_create_dynamic_sections): Formatting.
	(bfd_elf_record_link_assignment): Call bfd_link_repair_undef_list.
	(_bfd_elf_merge_symbol): Don't handle as-needed syms here.
	(struct elf_smash_data): New.
	(elf_smash_syms): New function.
	(elf_link_add_object_symbols): Call elf_smash_syms.  Don't add
	unneeded dynamic objects to loaded list.
	(elf_link_output_extsym): Don't handle as-needed here.  Strip
	bfd_link_hash_new symbols.
	* elf32-cris.c (elf_cris_discard_excess_program_dynamics): Don't
	delref when dynindx is already -1.
	* elf64-alpha.c (elf64_alpha_output_extsym): Strip bfd_link_hash_new
	symbols.
	* elfxx-mips.c (mips_elf_output_extsym): Likewise.
ld/
	* ld.texinfo: Clarify --as-needed operation.

Index: include/bfdlink.h
===================================================================
RCS file: /cvs/src/src/include/bfdlink.h,v
retrieving revision 1.50
diff -u -p -r1.50 bfdlink.h
--- include/bfdlink.h	15 Nov 2004 23:21:26 -0000	1.50
+++ include/bfdlink.h	1 Feb 2005 00:42:06 -0000
@@ -1,6 +1,6 @@
 /* bfdlink.h -- header file for BFD link routines
    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003,
-   2004 Free Software Foundation, Inc.
+   2004, 2005 Free Software Foundation, Inc.
    Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -197,6 +197,10 @@ extern void bfd_link_hash_traverse
 extern void bfd_link_add_undef
   (struct bfd_link_hash_table *, struct bfd_link_hash_entry *);
 
+/* Remove symbols from the undefs list that don't belong there.  */
+extern void bfd_link_repair_undef_list
+  (struct bfd_link_hash_table *table);
+
 struct bfd_sym_chain
 {
   struct bfd_sym_chain *next;
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.185
diff -u -p -r1.185 elf64-ppc.c
--- bfd/elf64-ppc.c	11 Jan 2005 09:32:52 -0000	1.185
+++ bfd/elf64-ppc.c	1 Feb 2005 00:41:25 -0000
@@ -4066,34 +4066,7 @@ ppc64_elf_check_directives (bfd *abfd AT
      undef_weak.  */
   if (htab->twiddled_syms)
     {
-      struct bfd_link_hash_entry **pun;
-
-      pun = &htab->elf.root.undefs;
-      while (*pun != NULL)
-	{
-	  struct bfd_link_hash_entry *h = *pun;
-
-	  if (h->type != bfd_link_hash_undefined
-	      && h->type != bfd_link_hash_common)
-	    {
-	      *pun = h->u.undef.next;
-	      h->u.undef.next = NULL;
-	      if (h == htab->elf.root.undefs_tail)
-		{
-		  if (pun == &htab->elf.root.undefs)
-		    htab->elf.root.undefs_tail = NULL;
-		  else
-		    /* pun points at an u.undef.next field.  Go back to
-		       the start of the link_hash_entry.  */
-		    htab->elf.root.undefs_tail = (struct bfd_link_hash_entry *)
-		      ((char *) pun - ((char *) &h->u.undef.next - (char *) h));
-		  break;
-		}
-	    }
-	  else
-	    pun = &h->u.undef.next;
-	}
-
+      bfd_link_repair_undef_list (&htab->elf.root);
       htab->twiddled_syms = 0;
     }
   return TRUE;
Index: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.42
diff -u -p -r1.42 linker.c
--- bfd/linker.c	21 Oct 2004 15:28:30 -0000	1.42
+++ bfd/linker.c	1 Feb 2005 00:41:38 -0000
@@ -1,6 +1,6 @@
 /* linker.c -- BFD linker routines
    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004 Free Software Foundation, Inc.
+   2003, 2004, 2005 Free Software Foundation, Inc.
    Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -623,6 +623,45 @@ bfd_link_add_undef (struct bfd_link_hash
     table->undefs = h;
   table->undefs_tail = h;
 }
+
+/* The undefs list was designed so that in normal use we don't need to
+   remove entries.  However, if symbols on the list are changed from
+   bfd_link_hash_undefined to either bfd_link_hash_undefweak or
+   bfd_link_hash_new for some reason, then they must be removed from the
+   list.  Failure to do so might result in the linker attempting to add
+   the symbol to the list again at a later stage.  */
+
+void
+bfd_link_repair_undef_list (struct bfd_link_hash_table *table)
+{
+  struct bfd_link_hash_entry **pun;
+
+  pun = &table->undefs;
+  while (*pun != NULL)
+    {
+      struct bfd_link_hash_entry *h = *pun;
+
+      if (h->type == bfd_link_hash_new
+	  || h->type == bfd_link_hash_undefweak)
+	{
+	  *pun = h->u.undef.next;
+	  h->u.undef.next = NULL;
+	  if (h == table->undefs_tail)
+	    {
+	      if (pun == &table->undefs)
+		table->undefs_tail = NULL;
+	      else
+		/* pun points at an u.undef.next field.  Go back to
+		   the start of the link_hash_entry.  */
+		table->undefs_tail = (struct bfd_link_hash_entry *)
+		  ((char *) pun - ((char *) &h->u.undef.next - (char *) h));
+	      break;
+	    }
+	}
+      else
+	pun = &h->u.undef.next;
+    }
+}
 \f
 /* Routine to create an entry in a generic link hash table.  */
 
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.125
diff -u -p -r1.125 elflink.c
--- bfd/elflink.c	31 Jan 2005 23:13:26 -0000	1.125
+++ bfd/elflink.c	1 Feb 2005 00:41:30 -0000
@@ -210,14 +210,22 @@ _bfd_elf_link_create_dynamic_sections (b
     return FALSE;
 
   /* The special symbol _DYNAMIC is always set to the start of the
-     .dynamic section.  This call occurs before we have processed the
-     symbols for any dynamic object, so we don't have to worry about
-     overriding a dynamic definition.  We could set _DYNAMIC in a
-     linker script, but we only want to define it if we are, in fact,
-     creating a .dynamic section.  We don't want to define it if there
-     is no .dynamic section, since on some ELF platforms the start up
-     code examines it to decide how to initialize the process.  */
-  bh = NULL;
+     .dynamic section.  We could set _DYNAMIC in a linker script, but we
+     only want to define it if we are, in fact, creating a .dynamic
+     section.  We don't want to define it if there is no .dynamic
+     section, since on some ELF platforms the start up code examines it
+     to decide how to initialize the process.  */
+  h = elf_link_hash_lookup (elf_hash_table (info), "_DYNAMIC",
+			    FALSE, FALSE, FALSE);
+  if (h != NULL)
+    {
+      /* Zap symbol defined in an as-needed lib that wasn't linked.
+	 This is a symptom of a larger problem:  Absolute symbols
+	 defined in shared libraries can't be overridden, because we
+	 lose the link to the bfd which is via the symbol section.  */
+      h->root.type = bfd_link_hash_new;
+    }
+  bh = &h->root;
   if (! (_bfd_generic_link_add_one_symbol
 	 (info, abfd, "_DYNAMIC", BSF_GLOBAL, s, 0, NULL, FALSE,
 	  get_elf_backend_data (abfd)->collect, &bh)))
@@ -322,16 +330,16 @@ _bfd_elf_create_dynamic_sections (bfd *a
 	return FALSE;
 
       /* The .rel[a].bss section holds copy relocs.  This section is not
-     normally needed.  We need to create it here, though, so that the
-     linker will map it to an output section.  We can't just create it
-     only if we need it, because we will not know whether we need it
-     until we have seen all the input files, and the first time the
-     main linker code calls BFD after examining all the input files
-     (size_dynamic_sections) the input sections have already been
-     mapped to the output sections.  If the section turns out not to
-     be needed, we can discard it later.  We will never need this
-     section when generating a shared object, since they do not use
-     copy relocs.  */
+	 normally needed.  We need to create it here, though, so that the
+	 linker will map it to an output section.  We can't just create it
+	 only if we need it, because we will not know whether we need it
+	 until we have seen all the input files, and the first time the
+	 main linker code calls BFD after examining all the input files
+	 (size_dynamic_sections) the input sections have already been
+	 mapped to the output sections.  If the section turns out not to
+	 be needed, we can discard it later.  We will never need this
+	 section when generating a shared object, since they do not use
+	 copy relocs.  */
       if (! info->shared)
 	{
 	  s = bfd_make_section (abfd,
@@ -442,15 +450,16 @@ bfd_elf_record_link_assignment (bfd *out
 
   /* Since we're defining the symbol, don't let it seem to have not
      been defined.  record_dynamic_symbol and size_dynamic_sections
-     may depend on this.
-     ??? Changing bfd_link_hash_undefined to bfd_link_hash_new (or
-     to bfd_link_hash_undefweak, see linker.c:link_action) runs the risk
-     of some later symbol manipulation setting the symbol back to
-     bfd_link_hash_undefined, and the linker trying to add the symbol to
-     the undefs list twice.  */
+     may depend on this.  */
   if (h->root.type == bfd_link_hash_undefweak
       || h->root.type == bfd_link_hash_undefined)
-    h->root.type = bfd_link_hash_new;
+    {
+      struct elf_link_hash_table *htab = elf_hash_table (info);
+
+      if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root)
+	bfd_link_repair_undef_list (&htab->root);
+      h->root.type = bfd_link_hash_new;
+    }
 
   if (h->root.type == bfd_link_hash_new)
     h->non_elf = 0;
@@ -728,7 +737,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
   int bind;
   bfd *oldbfd;
   bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
-  bfd_boolean newweak, oldweak, old_asneeded;
+  bfd_boolean newweak, oldweak;
 
   *skip = FALSE;
   *override = FALSE;
@@ -858,14 +867,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
   else
     olddef = TRUE;
 
-  /* If the old definition came from an as-needed dynamic library which
-     wasn't found to be needed, treat the sym as undefined.  */
-  old_asneeded = FALSE;
-  if (newdyn
-      && olddyn
-      && (elf_dyn_lib_class (oldbfd) & DYN_AS_NEEDED) != 0)
-    old_asneeded = TRUE;
-
   /* Check TLS symbol.  */
   if ((ELF_ST_TYPE (sym->st_info) == STT_TLS || h->type == STT_TLS)
       && ELF_ST_TYPE (sym->st_info) != h->type)
@@ -1068,7 +1069,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   if (olddyn
       && olddef
-      && !old_asneeded
       && h->root.type == bfd_link_hash_defined
       && h->def_dynamic
       && (h->root.u.def.section->flags & SEC_ALLOC) != 0
@@ -1120,7 +1120,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   if (newdyn
       && newdef
-      && ((olddef && !old_asneeded)
+      && (olddef
 	  || (h->root.type == bfd_link_hash_common
 	      && (newweak
 		  || ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
@@ -1170,7 +1170,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
      symbol is a function or is weak.  */
 
   flip = NULL;
-  if ((!newdyn || old_asneeded)
+  if (!newdyn
       && (newdef
 	  || (bfd_is_com_section (sec)
 	      && (oldweak
@@ -2813,6 +2813,69 @@ elf_add_dt_needed_tag (bfd *abfd,
   return 0;
 }
 
+/* Called via elf_link_hash_traverse, elf_smash_syms sets all symbols
+   belonging to NOT_NEEDED to bfd_link_hash_new.  We know there are no
+   references to these symbols.  */
+
+struct elf_smash_syms_data
+{
+  bfd *not_needed;
+  struct elf_link_hash_table *htab;
+  bfd_boolean twiddled;
+};
+
+static bfd_boolean
+elf_smash_syms (struct elf_link_hash_entry *h, void *data)
+{
+  struct elf_smash_syms_data *inf = (struct elf_smash_syms_data *) data;
+  struct bfd_link_hash_entry *bh;
+
+  switch (h->root.type)
+    {
+    default:
+    case bfd_link_hash_new:
+      return TRUE;
+
+    case bfd_link_hash_undefined:
+    case bfd_link_hash_undefweak:
+      if (h->root.u.undef.abfd != inf->not_needed)
+	return TRUE;
+      break;
+
+    case bfd_link_hash_defined:
+    case bfd_link_hash_defweak:
+      if (h->root.u.def.section->owner != inf->not_needed)
+	return TRUE;
+      break;
+
+    case bfd_link_hash_common:
+      if (h->root.u.c.p->section->owner != inf->not_needed)
+	return TRUE;
+      break;
+
+    case bfd_link_hash_warning:
+    case bfd_link_hash_indirect:
+      elf_smash_syms ((struct elf_link_hash_entry *) h->root.u.i.link, data);
+      if (h->root.u.i.link->type != bfd_link_hash_new)
+	return TRUE;
+      if (h->root.u.i.link->u.undef.abfd != inf->not_needed)
+	return TRUE;
+      break;
+    }
+
+  /* Set sym back to newly created state, but keep undefs list pointer.  */
+  bh = h->root.u.undef.next;
+  if (bh != NULL || inf->htab->root.undefs_tail == &h->root)
+    inf->twiddled = TRUE;
+  (*inf->htab->root.table.newfunc) (&h->root.root,
+				    &inf->htab->root.table,
+				    h->root.root.string);
+  h->root.u.undef.next = bh;
+  h->root.u.undef.abfd = inf->not_needed;
+  h->non_elf = 0;
+  return TRUE;
+}
+
 /* Sort symbol by value and section.  */
 static int
 elf_sort_symbol (const void *arg1, const void *arg2)
@@ -4031,6 +4094,18 @@ elf_link_add_object_symbols (bfd *abfd, 
     free (isymbuf);
   isymbuf = NULL;
 
+  if (!add_needed)
+    {
+      struct elf_smash_syms_data inf;
+      inf.not_needed = abfd;
+      inf.htab = hash_table;
+      inf.twiddled = FALSE;
+      elf_link_hash_traverse (hash_table, elf_smash_syms, &inf);
+      if (inf.twiddled)
+	bfd_link_repair_undef_list (&hash_table->root);
+      weaks = NULL;
+    }
+
   /* Now set the weakdefs field correctly for all the weak defined
      symbols we found.  The only way to do this is to search all the
      symbols.  Since we only need the information for non functions in
@@ -4263,7 +4338,7 @@ elf_link_add_object_symbols (bfd *abfd, 
 	}
     }
 
-  if (is_elf_hash_table (hash_table))
+  if (is_elf_hash_table (hash_table) && add_needed)
     {
       /* Add this bfd to the loaded list.  */
       struct elf_link_loaded_list *n;
@@ -6170,7 +6245,6 @@ elf_link_output_extsym (struct elf_link_
   if (h->root.type == bfd_link_hash_undefined
       && h->ref_dynamic
       && !h->ref_regular
-      && (elf_dyn_lib_class (h->root.u.undef.abfd) & DYN_AS_NEEDED) == 0
       && ! elf_link_check_versioned_symbol (finfo->info, bed, h)
       && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE)
     {
@@ -6212,7 +6286,8 @@ elf_link_output_extsym (struct elf_link_
   if (h->indx == -2)
     strip = FALSE;
   else if ((h->def_dynamic
-	    || h->ref_dynamic)
+	    || h->ref_dynamic
+	    || h->root.type == bfd_link_hash_new)
 	   && !h->def_regular
 	   && !h->ref_regular)
     strip = TRUE;
Index: bfd/elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.61
diff -u -p -r1.61 elf32-cris.c
--- bfd/elf32-cris.c	11 Jan 2005 09:32:46 -0000	1.61
+++ bfd/elf32-cris.c	1 Feb 2005 00:41:19 -0000
@@ -3130,6 +3130,7 @@ elf_cris_discard_excess_program_dynamics
 	 introduce new problems.  Of course we don't do this if we're
 	 exporting all dynamic symbols.  */
       if (! info->export_dynamic
+	  && h->root.dynindx != -1
 	  && !h->root.def_dynamic
 	  && !h->root.ref_dynamic)
 	{
Index: bfd/elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.125
diff -u -p -r1.125 elf64-alpha.c
--- bfd/elf64-alpha.c	21 Oct 2004 15:28:25 -0000	1.125
+++ bfd/elf64-alpha.c	1 Feb 2005 00:41:20 -0000
@@ -1,5 +1,5 @@
 /* Alpha specific support for 64-bit ELF
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@tamu.edu>.
 
@@ -2741,7 +2741,9 @@ elf64_alpha_output_extsym (h, data)
 
   if (h->root.indx == -2)
     strip = FALSE;
-  else if ((h->root.def_dynamic || h->root.ref_dynamic)
+  else if ((h->root.def_dynamic
+	    || h->root.ref_dynamic
+	    || h->root.root.type == bfd_link_hash_new)
 	   && !h->root.def_regular
 	   && !h->root.ref_regular)
     strip = TRUE;
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.118
diff -u -p -r1.118 elfxx-mips.c
--- bfd/elfxx-mips.c	31 Jan 2005 20:39:09 -0000	1.118
+++ bfd/elfxx-mips.c	1 Feb 2005 00:41:35 -0000
@@ -1,6 +1,6 @@
 /* MIPS-specific support for ELF
    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004 Free Software Foundation, Inc.
+   2003, 2004, 2005 Free Software Foundation, Inc.
 
    Most of the information added by Ian Lance Taylor, Cygnus Support,
    <ian@cygnus.com>.
@@ -1491,7 +1491,8 @@ mips_elf_output_extsym (struct mips_elf_
   if (h->root.indx == -2)
     strip = FALSE;
   else if ((h->root.def_dynamic
-	    || h->root.ref_dynamic)
+	    || h->root.ref_dynamic
+	    || h->root.type == bfd_link_hash_new)
 	   && !h->root.def_regular
 	   && !h->root.ref_regular)
     strip = TRUE;
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.138
diff -u -p -r1.138 ld.texinfo
--- ld/ld.texinfo	28 Jan 2005 17:24:40 -0000	1.138
+++ ld/ld.texinfo	1 Feb 2005 00:42:11 -0000
@@ -994,8 +994,9 @@ This option affects ELF DT_NEEDED tags f
 on the command line after the @option{--as-needed} option.  Normally,
 the linker will add a DT_NEEDED tag for each dynamic library mentioned
 on the command line, regardless of whether the library is actually
-needed. @option{--as-needed} causes DT_NEEDED tags to only be emitted
-for libraries that satisfy some reference from regular objects.
+needed.  @option{--as-needed} causes DT_NEEDED tags to only be emitted
+for libraries that satisfy some symbol reference from regular objects
+which is undefined at the point that the library was linked.
 @option{--no-as-needed} restores the default behaviour.
 
 @kindex --add-needed

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 20+ messages in thread

* IA64 linker is totally broken (Re: PATCH: ELF linker is broken)
  2005-02-01  0:08         ` Alan Modra
@ 2005-02-01  5:56           ` H. J. Lu
  2005-02-01  6:18             ` H. J. Lu
  0 siblings, 1 reply; 20+ messages in thread
From: H. J. Lu @ 2005-02-01  5:56 UTC (permalink / raw)
  To: binutils

On Tue, Feb 01, 2005 at 10:38:25AM +1030, Alan Modra wrote:
> On Mon, Jan 31, 2005 at 02:02:14PM -0800, H. J. Lu wrote:
> > 	* elflink.c (_bfd_elf_link_create_dynamic_sections): Discard
> > 	previous "_DYNAMIC" before creating the new one.
> 
> I'll be commiting a patch that looks similar to this one in a few
> minutes.
> 

Alan,

I have told you that your patch

http://sources.redhat.com/ml/binutils/2005-01/msg00529.html

doesn't work on ia64:

http://sources.redhat.com/ml/binutils/2005-01/msg00561.html

Now I got

FAIL: bootstrap
FAIL: bootstrap with strip
FAIL: bootstrap with --traditional-format
FAIL: bootstrap with --no-keep-memory
FAIL: bootstrap with --relax
FAIL: vers23d
FAIL: vers23
FAIL: visibility (hidden_normal)
FAIL: visibility (hidden_normal) (PIC main)
FAIL: visibility (protected)
FAIL: visibility (protected) (PIC main)
FAIL: visibility (protected_undef_def)
FAIL: visibility (protected_undef_def) (PIC main)
FAIL: visibility (normal)
FAIL: visibility (normal) (PIC main)

on Linux/ia64 with

http://sources.redhat.com/ml/binutils/2005-02/msg00005.html


H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is totally broken (Re: PATCH: ELF linker is broken)
  2005-02-01  5:56           ` IA64 linker is totally broken (Re: PATCH: ELF linker is broken) H. J. Lu
@ 2005-02-01  6:18             ` H. J. Lu
  2005-02-01  7:16               ` Alan Modra
  0 siblings, 1 reply; 20+ messages in thread
From: H. J. Lu @ 2005-02-01  6:18 UTC (permalink / raw)
  To: binutils; +Cc: amodra

On Mon, Jan 31, 2005 at 09:56:18PM -0800, H. J. Lu wrote:
> On Tue, Feb 01, 2005 at 10:38:25AM +1030, Alan Modra wrote:
> > On Mon, Jan 31, 2005 at 02:02:14PM -0800, H. J. Lu wrote:
> > > 	* elflink.c (_bfd_elf_link_create_dynamic_sections): Discard
> > > 	previous "_DYNAMIC" before creating the new one.
> > 
> > I'll be commiting a patch that looks similar to this one in a few
> > minutes.
> > 
> 
> Alan,
> 
> I have told you that your patch
> 
> http://sources.redhat.com/ml/binutils/2005-01/msg00529.html
> 
> doesn't work on ia64:
> 
> http://sources.redhat.com/ml/binutils/2005-01/msg00561.html
> 
> Now I got
> 
> FAIL: bootstrap
> FAIL: bootstrap with strip
> FAIL: bootstrap with --traditional-format
> FAIL: bootstrap with --no-keep-memory
> FAIL: bootstrap with --relax
> FAIL: vers23d
> FAIL: vers23
> FAIL: visibility (hidden_normal)
> FAIL: visibility (hidden_normal) (PIC main)
> FAIL: visibility (protected)
> FAIL: visibility (protected) (PIC main)
> FAIL: visibility (protected_undef_def)
> FAIL: visibility (protected_undef_def) (PIC main)
> FAIL: visibility (normal)
> FAIL: visibility (normal) (PIC main)
> 
> on Linux/ia64 with
> 
> http://sources.redhat.com/ml/binutils/2005-02/msg00005.html

I can't build anything on ia64 with the new linker. Without
--as-needed, I got

./ld  -dynamic-linker /lib/ld-linux-ia64.so.2 -o build/foo
/usr/lib/crt1.o /usr/lib/crti.o ./crtbegin.o -L. -Lstage1
-L/usr/gcc-4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.0
-L/usr/gcc-4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.0/../../..
build/genmddeps.o build/gensupport.o build/dummy-conditions.o
build/rtl.o build/read-rtl.o build/ggc-none.o build/min-insn-modes.o
build/errors.o ../build-ia64-unknown-linux-gnu/libiberty/libiberty.a
-lgcc  -lgcc_s -lunwind  -lc -lgcc  -lgcc_s -lunwind  ./crtend.o
/usr/lib/crtn.o
./ld: BFD 2.15.94.0.3 20050201 assertion fail
/net/gnu/export/linux/src/binutils/binutils/bfd/elf-strtab.c:241
./ld: BFD 2.15.94.0.3 20050201 assertion fail
/net/gnu/export/linux/src/binutils/binutils/bfd/elf-strtab.c:241

Or I got

./ld  -dynamic-linker /lib/ld-linux-ia64.so.2 -o build/foo
/usr/lib/crt1.o /usr/lib/crti.o ./crtbegin.o -L. -Lstage1
-L/usr/gcc-4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.0
-L/usr/gcc-4.0/lib/gcc/ia64-unknown-linux-gnu/4.0.0/../../..
build/genmddeps.o build/gensupport.o build/dummy-conditions.o
build/rtl.o build/read-rtl.o build/ggc-none.o build/min-insn-modes.o
build/errors.o ../build-ia64-unknown-linux-gnu/libiberty/libiberty.a
-lgcc --as-needed -lgcc_s -lunwind --no-as-needed -lc -lgcc --as-needed
-lgcc_s -lunwind --no-as-needed ./crtend.o /usr/lib/crtn.o
build/gensupport.o: In function `cmp_c_test':
/net/gnu/export/gnu/src/gcc/gcc/gcc/gensupport.c:1108: undefined
reference to `strcmp'
build/gensupport.o: In function `eq_struct_pred_data':
/net/gnu/export/gnu/src/gcc/gcc/gcc/gensupport.c:1196: undefined
reference to `strcmp'
build/gensupport.o: In function `init_md_reader_args_cb':
/net/gnu/export/gnu/src/gcc/gcc/gcc/gensupport.c:963: undefined
reference to `strrchr'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gensupport.c:446: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gensupport.c:365: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gensupport.c:373: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gensupport.c:383: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/gensupport.c:489: undefined
reference to `strcmp'
build/gensupport.o:/net/gnu/export/gnu/src/gcc/gcc/gcc/gensupport.c:491:
more undefined references to `strcmp' follow
build/read-rtl.o: In function `apply_macro_to_string':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:281: undefined reference
to `_obstack_newchunk'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:282: undefined reference
to `_obstack_newchunk'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:287: undefined reference
to `_obstack_newchunk'
build/read-rtl.o: In function `add_condition_to_string':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:407: undefined reference
to `asprintf'
build/read-rtl.o: In function `read_name':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:644: undefined reference
to `ungetc'
build/read-rtl.o: In function `read_escape':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:726: undefined reference
to `_obstack_newchunk'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:722: undefined reference
to `_obstack_newchunk'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:715: undefined reference
to `_obstack_newchunk'
build/read-rtl.o: In function `read_string':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:788: undefined reference
to `_obstack_newchunk'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:767: undefined reference
to `_obstack_newchunk'
build/read-rtl.o:/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:791:
more undefined references to `_obstack_newchunk' follow
build/read-rtl.o: In function `def_name_eq_p':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:890: undefined reference
to `strcmp'
build/read-rtl.o: In function `read_mapping':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1030: undefined
reference to `ungetc'
build/read-rtl.o: In function `read_rtx_1':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1153: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1161: undefined
reference to `strcmp'
build/read-rtl.o: In function `read_constants':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:925: undefined reference
to `ungetc'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:935: undefined reference
to `strcmp'
build/read-rtl.o: In function `read_rtx_1':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:925: undefined reference
to `ungetc'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1166: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1171: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1176: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1181: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1067: undefined
reference to `strcmp'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1204: undefined
reference to `ungetc'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1223: undefined
reference to `ungetc'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1246: undefined
reference to `ungetc'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1248: undefined
reference to `_obstack_newchunk'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1270: undefined
reference to `ungetc'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1303: undefined
reference to `_obstack_newchunk'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1304: undefined
reference to `_obstack_newchunk'
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1306: undefined
reference to `_obstack_newchunk'
build/read-rtl.o: In function `read_rtx':
/net/gnu/export/gnu/src/gcc/gcc/gcc/read-rtl.c:1104: undefined
reference to `ungetc'
/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
: undefined reference to `__init_array_start'
/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
: undefined reference to `__init_array_start'
./ld: BFD 2.15.94.0.3 20050201 assertion fail
/net/gnu/export/linux/src/binutils/binutils/bfd/elf-strtab.c:241
./ld: BFD 2.15.94.0.3 20050201 assertion fail
/net/gnu/export/linux/src/binutils/binutils/bfd/elf-strtab.c:241


H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is totally broken (Re: PATCH: ELF linker is broken)
  2005-02-01  6:18             ` H. J. Lu
@ 2005-02-01  7:16               ` Alan Modra
  2005-02-01 22:46                 ` H. J. Lu
  0 siblings, 1 reply; 20+ messages in thread
From: Alan Modra @ 2005-02-01  7:16 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Mon, Jan 31, 2005 at 10:18:26PM -0800, H. J. Lu wrote:
> ./ld: BFD 2.15.94.0.3 20050201 assertion fail
> /net/gnu/export/linux/src/binutils/binutils/bfd/elf-strtab.c:241
> ./ld: BFD 2.15.94.0.3 20050201 assertion fail
> /net/gnu/export/linux/src/binutils/binutils/bfd/elf-strtab.c:241

Can you tell me what is in table[i]->root.string, so I have a clue
what's going wrong?  Or better, send me a set of ia64 object files
and libs that exhibit the problem.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is totally broken (Re: PATCH: ELF linker is broken)
  2005-02-01  7:16               ` Alan Modra
@ 2005-02-01 22:46                 ` H. J. Lu
  2005-02-01 23:57                   ` Alan Modra
  0 siblings, 1 reply; 20+ messages in thread
From: H. J. Lu @ 2005-02-01 22:46 UTC (permalink / raw)
  To: binutils

On Tue, Feb 01, 2005 at 05:46:06PM +1030, Alan Modra wrote:
> On Mon, Jan 31, 2005 at 10:18:26PM -0800, H. J. Lu wrote:
> > ./ld: BFD 2.15.94.0.3 20050201 assertion fail
> > /net/gnu/export/linux/src/binutils/binutils/bfd/elf-strtab.c:241
> > ./ld: BFD 2.15.94.0.3 20050201 assertion fail
> > /net/gnu/export/linux/src/binutils/binutils/bfd/elf-strtab.c:241
> 
> Can you tell me what is in table[i]->root.string, so I have a clue
> what's going wrong?  Or better, send me a set of ia64 object files
> and libs that exhibit the problem.

There are quite a few failures on ia64. I am not sure if they can be
fixed by a single change. I am enclosing the cause of all the problems
I have seen so far on ia64. IA64 linker has a relaxation pass, which
seems to be the problem. Dos it ring a bell to you? If not, I will
send you a bunch of ia64 binaries as a testcase.


H.J.
---
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.125
diff -u -p -r1.125 elflink.c
--- bfd/elflink.c	31 Jan 2005 23:13:26 -0000	1.125
+++ bfd/elflink.c	1 Feb 2005 00:41:30 -0000
@@ -2813,6 +2813,69 @@ elf_add_dt_needed_tag (bfd *abfd,
   return 0;
 }
 
+/* Called via elf_link_hash_traverse, elf_smash_syms sets all symbols
+   belonging to NOT_NEEDED to bfd_link_hash_new.  We know there are no
+   references to these symbols.  */
+
+struct elf_smash_syms_data
+{
+  bfd *not_needed;
+  struct elf_link_hash_table *htab;
+  bfd_boolean twiddled;
+};
+
+static bfd_boolean
+elf_smash_syms (struct elf_link_hash_entry *h, void *data)
+{
+  struct elf_smash_syms_data *inf = (struct elf_smash_syms_data *) data;
+  struct bfd_link_hash_entry *bh;
+
+  switch (h->root.type)
+    {
+    default:
+    case bfd_link_hash_new:
+      return TRUE;
+
+    case bfd_link_hash_undefined:
+    case bfd_link_hash_undefweak:
+      if (h->root.u.undef.abfd != inf->not_needed)
+	return TRUE;
+      break;
+
+    case bfd_link_hash_defined:
+    case bfd_link_hash_defweak:
+      if (h->root.u.def.section->owner != inf->not_needed)
+	return TRUE;
+      break;
+
+    case bfd_link_hash_common:
+      if (h->root.u.c.p->section->owner != inf->not_needed)
+	return TRUE;
+      break;
+
+    case bfd_link_hash_warning:
+    case bfd_link_hash_indirect:
+      elf_smash_syms ((struct elf_link_hash_entry *) h->root.u.i.link, data);
+      if (h->root.u.i.link->type != bfd_link_hash_new)
+	return TRUE;
+      if (h->root.u.i.link->u.undef.abfd != inf->not_needed)
+	return TRUE;
+      break;
+    }
+
+  /* Set sym back to newly created state, but keep undefs list pointer.  */
+  bh = h->root.u.undef.next;
+  if (bh != NULL || inf->htab->root.undefs_tail == &h->root)
+    inf->twiddled = TRUE;
+  (*inf->htab->root.table.newfunc) (&h->root.root,
+				    &inf->htab->root.table,
+				    h->root.root.string);
+  h->root.u.undef.next = bh;
+  h->root.u.undef.abfd = inf->not_needed;
+  h->non_elf = 0;
+  return TRUE;
+}
+
 /* Sort symbol by value and section.  */
 static int
 elf_sort_symbol (const void *arg1, const void *arg2)
@@ -4031,6 +4094,18 @@ elf_link_add_object_symbols (bfd *abfd, 
     free (isymbuf);
   isymbuf = NULL;
 
+  if (!add_needed)
+    {
+      struct elf_smash_syms_data inf;
+      inf.not_needed = abfd;
+      inf.htab = hash_table;
+      inf.twiddled = FALSE;
+      elf_link_hash_traverse (hash_table, elf_smash_syms, &inf);
+      if (inf.twiddled)
+	bfd_link_repair_undef_list (&hash_table->root);
+      weaks = NULL;
+    }
+
   /* Now set the weakdefs field correctly for all the weak defined
      symbols we found.  The only way to do this is to search all the
      symbols.  Since we only need the information for non functions in

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is totally broken (Re: PATCH: ELF linker is broken)
  2005-02-01 22:46                 ` H. J. Lu
@ 2005-02-01 23:57                   ` Alan Modra
  2005-02-02  0:39                     ` H. J. Lu
  2005-02-02  2:23                     ` H. J. Lu
  0 siblings, 2 replies; 20+ messages in thread
From: Alan Modra @ 2005-02-01 23:57 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Tue, Feb 01, 2005 at 02:45:50PM -0800, H. J. Lu wrote:
> There are quite a few failures on ia64. I am not sure if they can be
> fixed by a single change. I am enclosing the cause of all the problems
> I have seen so far on ia64. IA64 linker has a relaxation pass, which
> seems to be the problem. Dos it ring a bell to you? If not, I will
> send you a bunch of ia64 binaries as a testcase.

Please send me the binaries!  I can only make wild guesses otherwise.
BTW, I still can't send email to you directly.  Your anti-spam filters
don't like my ISP's mail hub, nor do they like smtp directly from my
dynamic ip address.  :-(  Hmm, a bounce through gcc.gnu.org might
work.

> @@ -4031,6 +4094,18 @@ elf_link_add_object_symbols (bfd *abfd, 
>      free (isymbuf);
>    isymbuf = NULL;
>  
> +  if (!add_needed)

You might also try changing this condition to

  if (!add_needed
      && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0)

As it was, we would remove symbols from DT_NEEDED libraries, which is
possibly what is breaking ia64.  The intention here was just to remove
symbols from as-needed libs that weren't referenced anywhere from
regular object.  I'll commit this change.

> +    {
> +      struct elf_smash_syms_data inf;
> +      inf.not_needed = abfd;
> +      inf.htab = hash_table;
> +      inf.twiddled = FALSE;
> +      elf_link_hash_traverse (hash_table, elf_smash_syms, &inf);
> +      if (inf.twiddled)
> +	bfd_link_repair_undef_list (&hash_table->root);
> +      weaks = NULL;
> +    }
> +
>    /* Now set the weakdefs field correctly for all the weak defined
>       symbols we found.  The only way to do this is to search all the
>       symbols.  Since we only need the information for non functions in

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is totally broken (Re: PATCH: ELF linker is broken)
  2005-02-01 23:57                   ` Alan Modra
@ 2005-02-02  0:39                     ` H. J. Lu
  2005-02-02  1:12                       ` Alan Modra
  2005-02-02  2:23                     ` H. J. Lu
  1 sibling, 1 reply; 20+ messages in thread
From: H. J. Lu @ 2005-02-02  0:39 UTC (permalink / raw)
  To: binutils; +Cc: amodra

On Wed, Feb 02, 2005 at 10:27:01AM +1030, Alan Modra wrote:
> On Tue, Feb 01, 2005 at 02:45:50PM -0800, H. J. Lu wrote:
> > There are quite a few failures on ia64. I am not sure if they can be
> > fixed by a single change. I am enclosing the cause of all the problems
> > I have seen so far on ia64. IA64 linker has a relaxation pass, which
> > seems to be the problem. Dos it ring a bell to you? If not, I will
> > send you a bunch of ia64 binaries as a testcase.
> 
> Please send me the binaries!  I can only make wild guesses otherwise.
> BTW, I still can't send email to you directly.  Your anti-spam filters
> don't like my ISP's mail hub, nor do they like smtp directly from my

I will see what I can do.

> dynamic ip address.  :-(  Hmm, a bounce through gcc.gnu.org might
> work.
> 

I have sent you a testcase. I think this patch should do the trick.
We have to keep the next pointer. Otherwise, out hash table may be
screwed up.


H.J.
--- elflink.c.relax	2005-01-31 21:41:46.000000000 -0800
+++ elflink.c	2005-02-01 16:35:34.177300019 -0800
@@ -2829,6 +2829,7 @@ elf_smash_syms (struct elf_link_hash_ent
 {
   struct elf_smash_syms_data *inf = (struct elf_smash_syms_data *) data;
   struct bfd_link_hash_entry *bh;
+  struct bfd_hash_entry *next;
 
   switch (h->root.type)
     {
@@ -2865,12 +2866,14 @@ elf_smash_syms (struct elf_link_hash_ent
 
   /* Set sym back to newly created state, but keep undefs list pointer.  */
   bh = h->root.u.undef.next;
+  next = h->root.root.next;
   if (bh != NULL || inf->htab->root.undefs_tail == &h->root)
     inf->twiddled = TRUE;
   (*inf->htab->root.table.newfunc) (&h->root.root,
 				    &inf->htab->root.table,
 				    h->root.root.string);
   h->root.u.undef.next = bh;
+  h->root.root.next = next;
   h->root.u.undef.abfd = inf->not_needed;
   h->non_elf = 0;
   return TRUE;

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is totally broken (Re: PATCH: ELF linker is broken)
  2005-02-02  0:39                     ` H. J. Lu
@ 2005-02-02  1:12                       ` Alan Modra
  2005-02-02  1:37                         ` Alan Modra
  0 siblings, 1 reply; 20+ messages in thread
From: Alan Modra @ 2005-02-02  1:12 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils

On Tue, Feb 01, 2005 at 04:39:25PM -0800, H. J. Lu wrote:
> On Wed, Feb 02, 2005 at 10:27:01AM +1030, Alan Modra wrote:
> > On Tue, Feb 01, 2005 at 02:45:50PM -0800, H. J. Lu wrote:
> > > There are quite a few failures on ia64. I am not sure if they can be
> > > fixed by a single change. I am enclosing the cause of all the problems
> > > I have seen so far on ia64. IA64 linker has a relaxation pass, which
> > > seems to be the problem. Dos it ring a bell to you? If not, I will
> > > send you a bunch of ia64 binaries as a testcase.
> > 
> > Please send me the binaries!  I can only make wild guesses otherwise.
> > BTW, I still can't send email to you directly.  Your anti-spam filters
> > don't like my ISP's mail hub, nor do they like smtp directly from my
> 
> I will see what I can do.
> 
> > dynamic ip address.  :-(  Hmm, a bounce through gcc.gnu.org might
> > work.
> > 
> 
> I have sent you a testcase. I think this patch should do the trick.
> We have to keep the next pointer. Otherwise, out hash table may be
> screwed up.

But that shouldn't be zapped.  The lowest level hash newfunc doesn't
clear any of it's fields.  Ah!  But ia64 newfunc clears the whole
hash entry!  That would lose the string too.

	* elfxx-ia64.c (elfNN_ia64_new_elf_hash_entry): Don't clear
	everything, just the field specific to ia64.

Index: bfd/elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.144
diff -u -p -r1.144 elfxx-ia64.c
--- bfd/elfxx-ia64.c	28 Oct 2004 14:55:41 -0000	1.144
+++ bfd/elfxx-ia64.c	2 Feb 2005 01:10:26 -0000
@@ -1616,15 +1616,12 @@ elfNN_ia64_new_elf_hash_entry (entry, ta
   if (!ret)
     return 0;
 
-  /* Initialize our local data.  All zeros, and definitely easier
-     than setting a handful of bit fields.  */
-  memset (ret, 0, sizeof (*ret));
-
   /* Call the allocation method of the superclass.  */
   ret = ((struct elfNN_ia64_link_hash_entry *)
 	 _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret,
 				     table, string));
 
+  ret->info = 0;
   return (struct bfd_hash_entry *) ret;
 }
 
-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is totally broken (Re: PATCH: ELF linker is broken)
  2005-02-02  1:12                       ` Alan Modra
@ 2005-02-02  1:37                         ` Alan Modra
  0 siblings, 0 replies; 20+ messages in thread
From: Alan Modra @ 2005-02-02  1:37 UTC (permalink / raw)
  To: binutils

This one too.

Index: bfd/ChangeLog
===================================================================
RCS file: /cvs/src/src/bfd/ChangeLog,v
retrieving revision 1.2879
diff -u -p -r1.2879 ChangeLog
--- bfd/ChangeLog	2 Feb 2005 01:16:30 -0000	1.2879
+++ bfd/ChangeLog	2 Feb 2005 01:36:37 -0000
@@ -2,6 +2,7 @@
 
 	* elfxx-ia64.c (elfNN_ia64_new_elf_hash_entry): Don't clear
 	everything, just the field specific to ia64.
+	* elf64-hppa.c (elf64_hppa_new_dyn_hash_entry): Likewise.
 
 2005-02-01  Alan Modra  <amodra@bigpond.net.au>
 
Index: bfd/elf64-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-hppa.c,v
retrieving revision 1.52
diff -u -p -r1.52 elf64-hppa.c
--- bfd/elf64-hppa.c	10 Oct 2004 13:58:05 -0000	1.52
+++ bfd/elf64-hppa.c	2 Feb 2005 01:36:39 -0000
@@ -1,5 +1,5 @@
 /* Support for HPPA 64-bit ELF
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004
+   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -305,14 +305,15 @@ elf64_hppa_new_dyn_hash_entry (entry, ta
   if (!ret)
     return 0;
 
-  /* Initialize our local data.  All zeros, and definitely easier
-     than setting 8 bit fields.  */
-  memset (ret, 0, sizeof (*ret));
-
   /* Call the allocation method of the superclass.  */
   ret = ((struct elf64_hppa_dyn_hash_entry *)
 	 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
 
+  /* Initialize our local data.  All zeros.  */
+  memset (&ret->dlt_offset, 0,
+	  (sizeof (struct elf64_hppa_dyn_hash_entry)
+	   - offsetof (struct elf64_hppa_dyn_hash_entry, dlt_offset)));
+
   return &ret->root;
 }
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: IA64 linker is totally broken (Re: PATCH: ELF linker is broken)
  2005-02-01 23:57                   ` Alan Modra
  2005-02-02  0:39                     ` H. J. Lu
@ 2005-02-02  2:23                     ` H. J. Lu
  1 sibling, 0 replies; 20+ messages in thread
From: H. J. Lu @ 2005-02-02  2:23 UTC (permalink / raw)
  To: binutils


The patch for elfNN_ia64_new_elf_hash_entry works so far.


H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* IA64 linker is broken
@ 2003-03-04 20:13 H. J. Lu
  0 siblings, 0 replies; 20+ messages in thread
From: H. J. Lu @ 2003-03-04 20:13 UTC (permalink / raw)
  To: rth; +Cc: binutils

Hi Richard,

You added a call to get_dyn_sym_info in your last change without checking
relocation type. Now

--foo.s--
        .section .text
 {   .mib
        nop.m   0
        nop.i   0
        br.cond.dpnt.many       .b1_1 ;;
 }
        .section .text1
 .b1_1:
 {   .mii
        nop.m   0
        nop.i   0
        nop.i   0
 }
----

No longer works. You may want to check the relocation type first.


H.J.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2005-02-02  2:23 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-30 19:22 IA64 linker is broken H. J. Lu
2005-01-31  0:02 ` Alan Modra
2005-01-31  7:13   ` Alan Modra
2005-01-31  8:29     ` Alan Modra
2005-01-31 18:38       ` H. J. Lu
2005-01-31 21:22     ` ELF " H. J. Lu
2005-01-31 22:02       ` PATCH: " H. J. Lu
2005-02-01  0:08         ` Alan Modra
2005-02-01  5:56           ` IA64 linker is totally broken (Re: PATCH: ELF linker is broken) H. J. Lu
2005-02-01  6:18             ` H. J. Lu
2005-02-01  7:16               ` Alan Modra
2005-02-01 22:46                 ` H. J. Lu
2005-02-01 23:57                   ` Alan Modra
2005-02-02  0:39                     ` H. J. Lu
2005-02-02  1:12                       ` Alan Modra
2005-02-02  1:37                         ` Alan Modra
2005-02-02  2:23                     ` H. J. Lu
2005-01-31 23:16       ` ELF linker is broken Alan Modra
2005-02-01  1:41     ` IA64 " Alan Modra
  -- strict thread matches above, loose matches on Subject: below --
2003-03-04 20:13 H. J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).