public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Alan Modra <amodra@bigpond.net.au>
To: binutils@sources.redhat.com
Subject: Fix an --as-needed linker problem
Date: Wed, 22 Dec 2004 03:55:00 -0000	[thread overview]
Message-ID: <20041222035542.GA18274@bubble.modra.org> (raw)

This is a fix for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17608
Quoting from the PR:

When linking we use:
-lgcc --as-needed -lgcc_s --no-as-needed -lc_p -lgcc --as-needed -lgcc_s
--no-as-needed.

During the first scan of libgcc_s.so, the linker finds no reason to mark
libgcc_s.so as needed, because no symbols in libgcc_s.so are referenced
at that point.  After linking libc_p.a, the second scan of libgcc_s.so
does find referenced symbols.  However, the linker sees that these
symbols have already been defined, thus the "new" definitions found in
the second scan of libgcc_s.so aren't used.  (If a symbol is defined in
two shared libs, the one from the lib first encountered by the linker is
used.  As far as the linker is concerned the first libgcc_s.so is a
different shared lib from the second libgcc_s.so).  Thus the linker
decides that the second libgcc_s.so isn't needed, and so doesn't emit a
DT_NEEDED tag for libgcc_s.so.

With older glibc ld.so, this resulted in segfaults.  Current ld.so
complains with 
 Inconsistency detected by ld.so: dl-version.c: 230: _dl_check_map_versions:
Assertion `needed != ((void *)0)' failed!

	* elflink.c (_bfd_elf_merge_symbol): Treat old definitions from
	as-needed dynamic libs as undefined.
	(elf_link_add_object_symbols): Remove DYN_AS_NEEDED from as-needed
	libs when finding they are needed.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.121
diff -u -p -r1.121 elflink.c
--- bfd/elflink.c	10 Dec 2004 14:04:58 -0000	1.121
+++ bfd/elflink.c	22 Dec 2004 03:42:50 -0000
@@ -719,7 +719,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
   int bind;
   bfd *oldbfd;
   bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
-  bfd_boolean newweak, oldweak;
+  bfd_boolean newweak, oldweak, old_asneeded;
 
   *skip = FALSE;
   *override = FALSE;
@@ -849,6 +849,14 @@ _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)
@@ -1051,6 +1059,7 @@ _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
@@ -1102,7 +1111,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
 
   if (newdyn
       && newdef
-      && (olddef
+      && ((olddef && !old_asneeded)
 	  || (h->root.type == bfd_link_hash_common
 	      && (newweak
 		  || ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
@@ -1152,7 +1161,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
      symbol is a function or is weak.  */
 
   flip = NULL;
-  if (! newdyn
+  if ((!newdyn || old_asneeded)
       && (newdef
 	  || (bfd_is_com_section (sec)
 	      && (oldweak
@@ -3937,6 +3946,8 @@ elf_link_add_object_symbols (bfd *abfd, 
 		  goto error_free_vers;
 		}
 
+	      elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED;
+
 	      add_needed = TRUE;
 	      ret = elf_add_dt_needed_tag (info, soname, add_needed);
 	      if (ret < 0)

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

                 reply	other threads:[~2004-12-22  3:55 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20041222035542.GA18274@bubble.modra.org \
    --to=amodra@bigpond.net.au \
    --cc=binutils@sources.redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).