public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: "H . J . Lu" <hjl@lucon.org>
To: Peter A Barros <p.a.barros@larc.nasa.gov>
Cc: binutils@sources.redhat.com
Subject: Re: Bug in dynamic linker
Date: Tue, 18 Jul 2000 15:24:00 -0000	[thread overview]
Message-ID: <20000718152402.A31994@lucon.org> (raw)
In-Reply-To: <Pine.GS4.4.10.10007171011240.7771-100000@express.larc.nasa.gov>

On Mon, Jul 17, 2000 at 10:12:10AM -0400, Peter A Barros wrote:
> 
> 
> 
>  Hi, I wrote a couple of days ago about an error message I was getting,
>  concerinng the dynamic linker.  This website probably explains the problem
>  better than I can:
>  http://x40.deja.com/getdoc.xp?AN=545891503&CONTEXT=958448712.1788280849&hitnum=29
>  
>  For my part, I don't really understand the problem.
>  If someone could explain a solution to be i would be very appreciative.
>  
> 

Here is a patch for the DT_NEEDED handling. At present, we don't add
files from DT_NEEDED to the DT_NEEDED list in the resulting binary.
That causes the problem if the resulting binary references the symbols
in files from DT_NEEDED and they are not passed to the linker at the
comand line. This patch tries to add those files to the DT_NEEDED list
if they are used by the regular files during the link. Any comments?



H.J.
---
2000-07-18  H.J. Lu  <hjl@gnu.org>

	* bfd-in.h (bfd_elf_set_dt_needed_soname): New.
	* bfd-in2.h: Rebuild.

	* elf-bfd.h (elf_obj_tdata): Add dt_soname.
	(elf_dt_soname): New.

	* elf.c (bfd_elf_set_dt_needed_soname): New.

	* elflink.h (elf_link_add_object_symbols): Add the DT_NEEDED
	entry if the shared object loaded by DT_NEEDED is used to
	resolve the reference in a regular object.

Index: bfd/bfd-in.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/bfd-in.h,v
retrieving revision 1.11
diff -u -p -r1.11 bfd-in.h
--- bfd/bfd-in.h	2000/07/13 16:00:33	1.11
+++ bfd/bfd-in.h	2000/07/18 19:32:33
@@ -627,6 +627,7 @@ extern boolean bfd_elf64_size_dynamic_se
 	   const char * const *, struct bfd_link_info *, struct sec **,
 	   struct bfd_elf_version_tree *));
 extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
+extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *));
 extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
 
 /* Return an upper bound on the number of bytes required to store a
Index: bfd/bfd-in2.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/bfd-in2.h,v
retrieving revision 1.35
diff -u -p -r1.35 bfd-in2.h
--- bfd/bfd-in2.h	2000/07/13 16:00:33	1.35
+++ bfd/bfd-in2.h	2000/07/18 19:34:06
@@ -627,6 +627,7 @@ extern boolean bfd_elf64_size_dynamic_se
 	   const char * const *, struct bfd_link_info *, struct sec **,
 	   struct bfd_elf_version_tree *));
 extern void bfd_elf_set_dt_needed_name PARAMS ((bfd *, const char *));
+extern void bfd_elf_set_dt_needed_soname PARAMS ((bfd *, const char *));
 extern const char *bfd_elf_get_dt_soname PARAMS ((bfd *));
 
 /* Return an upper bound on the number of bytes required to store a
Index: bfd/elf-bfd.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elf-bfd.h,v
retrieving revision 1.1.1.15
diff -u -p -r1.1.1.15 elf-bfd.h
--- bfd/elf-bfd.h	2000/07/09 23:37:28	1.1.1.15
+++ bfd/elf-bfd.h	2000/07/18 21:13:49
@@ -838,6 +838,14 @@ struct elf_obj_tdata
      one.  */
   const char *dt_name;
 
+  /* When a reference in a regular object is resolved by a shared
+     object is loaded into via the DT_NEEDED entries by the linker
+     ELF emulation code, we need to add the shared object to the
+     DT_NEEDED list of the resulting binary to indicate the dependency
+     as if the -l option is passed to the linker. This field holds the
+     name of the loaded shared object. */
+  const char *dt_soname;
+
   /* Irix 5 often screws up the symbol table, sorting local symbols
      after global symbols.  This flag is set if the symbol table in
      this BFD appears to be screwed up.  If it is, we ignore the
@@ -915,6 +923,7 @@ struct elf_obj_tdata
 #define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets)
 #define elf_local_ptr_offsets(bfd) (elf_tdata(bfd) -> linker_section_pointers)
 #define elf_dt_name(bfd)	(elf_tdata(bfd) -> dt_name)
+#define elf_dt_soname(bfd)	(elf_tdata(bfd) -> dt_soname)
 #define elf_bad_symtab(bfd)	(elf_tdata(bfd) -> bad_symtab)
 #define elf_flags_init(bfd)	(elf_tdata(bfd) -> flags_init)
 #define elf_linker_section(bfd,n) (elf_tdata(bfd) -> linker_section[(int)n])
Index: bfd/elf.c
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elf.c,v
retrieving revision 1.23
diff -u -p -r1.23 elf.c
--- bfd/elf.c	2000/07/13 16:00:33	1.23
+++ bfd/elf.c	2000/07/18 20:26:45
@@ -1023,6 +1023,16 @@ bfd_elf_set_dt_needed_name (abfd, name)
     elf_dt_name (abfd) = name;
 }
 
+void
+bfd_elf_set_dt_needed_soname (abfd, name)
+     bfd *abfd;
+     const char *name;
+{
+  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
+      && bfd_get_format (abfd) == bfd_object)
+    elf_dt_soname (abfd) = name;
+}
+
 /* Get the list of DT_NEEDED entries for a link.  This is a hook for
    the linker ELF emulation code.  */
 
Index: bfd/elflink.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elflink.h,v
retrieving revision 1.33
diff -u -p -r1.33 elflink.h
--- bfd/elflink.h	2000/06/20 17:47:42	1.33
+++ bfd/elflink.h	2000/07/18 21:57:20
@@ -890,6 +890,7 @@ elf_link_add_object_symbols (abfd, info)
   Elf_External_Sym *esym;
   Elf_External_Sym *esymend;
   struct elf_backend_data *bed;
+  boolean dt_needed;
 
   bed = get_elf_backend_data (abfd);
   add_symbol_hook = bed->elf_add_symbol_hook;
@@ -1049,6 +1050,8 @@ elf_link_add_object_symbols (abfd, info)
     goto error_return;
   elf_sym_hashes (abfd) = sym_hash;
 
+  dt_needed = false;
+
   if (! dynamic)
     {
       /* If we are creating a shared library, create all the dynamic
@@ -1085,7 +1088,12 @@ elf_link_add_object_symbols (abfd, info)
 	{
 	  name = elf_dt_name (abfd);
 	  if (*name == '\0')
-	    add_needed = false;
+	    {
+	      if (elf_dt_soname (abfd) != NULL)
+	        dt_needed = true;
+
+	      add_needed = false;
+	    }
 	}
       s = bfd_get_section_by_name (abfd, ".dynamic");
       if (s != NULL)
@@ -1863,6 +1871,53 @@ elf_link_add_object_symbols (abfd, info)
 		(*bed->elf_backend_hide_symbol) (info, h);
 		break;
 	      }
+
+	  if (dt_needed && definition
+	      && (h->elf_link_hash_flags
+		  & ELF_LINK_HASH_REF_REGULAR) != 0)
+	    {
+	      bfd_size_type oldsize;
+	      bfd_size_type strindex;
+
+	      /* The symbol from a DT_NEEDED object is referenced from
+	         the regular object to create a dynamic executable. We
+		 have to make sure there is a DT_NEEDED entry for it. */
+
+	      dt_needed = false;
+	      oldsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr);
+	      strindex = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
+	      				     elf_dt_soname (abfd),
+					     true, false);
+	      if (strindex == (bfd_size_type) -1)
+		goto error_return;
+
+	      if (oldsize
+		  == _bfd_stringtab_size (elf_hash_table (info)->dynstr))
+		{
+		  asection *sdyn;
+		  Elf_External_Dyn *dyncon, *dynconend;
+
+		  sdyn = bfd_get_section_by_name (elf_hash_table (info)->dynobj,
+						  ".dynamic");
+		  BFD_ASSERT (sdyn != NULL);
+
+		  dyncon = (Elf_External_Dyn *) sdyn->contents;
+		  dynconend = (Elf_External_Dyn *) (sdyn->contents +
+						    sdyn->_raw_size);
+		  for (; dyncon < dynconend; dyncon++)
+		    {
+		      Elf_Internal_Dyn dyn;
+
+		      elf_swap_dyn_in (elf_hash_table (info)->dynobj,
+				       dyncon, &dyn);
+		      BFD_ASSERT (dyn.d_tag != DT_NEEDED ||
+				  dyn.d_un.d_val != strindex);
+		    }
+		}
+
+	      if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
+		goto error_return;
+	    }
 	}
     }
 
 
2000-07-18  H.J. Lu  <hjl@gnu.org>

	* emultempl/elf32.em (gld${EMULATION_NAME}_try_needed): Call
	bfd_elf_set_dt_needed_soname ().

Index: ld/emultempl/elf32.em
===================================================================
RCS file: /work/cvs/gnu/binutils/ld/emultempl/elf32.em,v
retrieving revision 1.17
diff -u -p -r1.17 elf32.em
--- ld/emultempl/elf32.em	2000/07/13 16:00:36	1.17
+++ ld/emultempl/elf32.em	2000/07/18 21:13:41
@@ -532,6 +532,18 @@ cat >>e${EMULATION_NAME}.c <<EOF
      DT_NEEDED entry for this file.  */
   bfd_elf_set_dt_needed_name (abfd, "");
 
+  /* First strip off everything before the last '/'.  */
+  name = strrchr (abfd->filename, '/');
+  if (name)
+    name++;
+  else
+    name = abfd->filename;
+
+  /* Tell the ELF backend that the output file needs a DT_NEEDED
+     entry for this file if it is used to resolve the reference in
+     a regular object.  */
+  bfd_elf_set_dt_needed_soname (abfd, name);
+
   /* Add this file into the symbol table.  */
   if (! bfd_link_add_symbols (abfd, &link_info))
     einfo ("%F%B: could not read symbols: %E\n", abfd);

  reply	other threads:[~2000-07-18 15:24 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <Pine.GS4.4.10.10007171002550.7771-100000@express.larc.nasa.gov>
2000-07-17  7:12 ` Peter A Barros
2000-07-18 15:24   ` H . J . Lu [this message]
2000-07-27 16:56 Nick Clifton
2000-07-27 17:49 ` H . J . Lu
  -- strict thread matches above, loose matches on Subject: below --
2000-07-20  6:06 Mark Kettenis
2000-07-20  9:04 ` H . J . Lu
2000-07-20 10:11   ` Mark Kettenis
2000-07-20 10:16     ` H . J . Lu
2000-07-20 10:56       ` Mark Kettenis
2000-07-20 11:04         ` H . J . Lu
2000-07-20 15:23           ` H . J . Lu
2000-07-20  9:23 ` Ulrich Drepper
2000-07-20  9:51   ` H . J . Lu
2000-07-20  9:56     ` Ulrich Drepper
2000-07-20 10:02       ` H . J . Lu
2000-07-19 17:52 Nick Clifton
     [not found] <963602772.24226.ezmlm@sources.redhat.com>
2000-07-14 13:35 ` bug " Peter A Barros
2000-07-14 23:27   ` Alan Modra

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=20000718152402.A31994@lucon.org \
    --to=hjl@lucon.org \
    --cc=binutils@sources.redhat.com \
    --cc=p.a.barros@larc.nasa.gov \
    /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).