public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [BUG] runpath broken for .so's in ld
@ 2002-10-15 13:19 Kenny Simpson
  2002-10-15 17:02 ` H. J. Lu
  2002-10-17  0:08 ` PATCH: Fix " H. J. Lu
  0 siblings, 2 replies; 6+ messages in thread
From: Kenny Simpson @ 2002-10-15 13:19 UTC (permalink / raw)
  To: binutils

The runpath of a shared object is not always being
searched when linking an executable.

The behavior I'm seeing is the following:
  I have an external library (libext1.so), which lives
in ~/ext1.
  A shared library (libfoo.so) is created which links
against libext.so and records a DT_RUNPATH for ~/ext1.
  Another shared library (libbar.so) is created with a
DT_RUNPATH for some other directory (ext2/libext2.so).
  I attempt to create a binary (baz) that links
against libfoo, and libbar.
  The link fails as libext1 cannot be found.

Just to codify the above:

mkdir ext1;
mkdir ext2;

dummy.c:
        /* empty */

main.c:
        int main() { return 0; }

Makefile:
        ext1/libext1.so: dummy.c
                gcc -shared dummy.c -o $@

        ext2/libext2.so: dummy.c
                gcc -shared dummy.c -o $@

        libfoo.so: ext1/libext1.so
                gcc -shared -Lext1 -Wl,-rpath,ext1
-Wl,--enable-new-dtags -lext1 -o $@

        libbar.so: ext2/libext2.so
                gcc -shared -Lext2 -Wl,-rpath,ext2
-Wl,--enable-new-dtags -lext2 -o $@

        baz: main.c libbar.so libfoo.so
                gcc main.c -L. -Wl,-rpath,. -lfoo
-lbar -o $@

make baz


Looking at the source I see in elflink.h:
        /* When we see DT_RPATH before DT_RUNPATH, we
have
           to clear runpath.  Do _NOT_ bfd_release, as
that
           frees all more recently bfd_alloc'd blocks
as
           well.  */
        if (rpath && hash_table->runpath)
            hash_table->runpath = NULL;


but this clears all the runpath info during a link as
the hash table from the info is shared.
In eelf_i386.c:
        rp = bfd_elf_get_runpath_list (output_bfd,
&link_info);
        for (; !found && rp != NULL; rp = rp->next)
          {
            found = (rp->by == l->by
                && gldelf_i386_search_needed
(rp->name,
                                   l->name,
                                   force));

With the runpath-clearing line commented out, my
example works.  With it, it fails with:
        warning: libext1.so, needed by ./libfoo.so,
not found (try using -rpath, or -rpath-link)

Peppering printf's in eelf_i386.c shows that it only
sees the runpath entries from libbar.so.

This is with binutils-2.13.90.0.10 on a Linux
2.4.18/glibc 2.2.5/P4 using
gcc 2.95.2.

Thanks,
-Kenny

__________________________________________________
Do you Yahoo!?
Faith Hill - Exclusive Performances, Videos & More
http://faith.yahoo.com

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

* Re: [BUG] runpath broken for .so's in ld
  2002-10-15 13:19 [BUG] runpath broken for .so's in ld Kenny Simpson
@ 2002-10-15 17:02 ` H. J. Lu
  2002-10-17  0:08 ` PATCH: Fix " H. J. Lu
  1 sibling, 0 replies; 6+ messages in thread
From: H. J. Lu @ 2002-10-15 17:02 UTC (permalink / raw)
  To: Kenny Simpson; +Cc: binutils

On Tue, Oct 15, 2002 at 01:19:09PM -0700, Kenny Simpson wrote:
> The runpath of a shared object is not always being
> searched when linking an executable.
> 

I will look into it.


H.J.

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

* PATCH: Fix [BUG] runpath broken for .so's in ld
  2002-10-15 13:19 [BUG] runpath broken for .so's in ld Kenny Simpson
  2002-10-15 17:02 ` H. J. Lu
@ 2002-10-17  0:08 ` H. J. Lu
  2002-10-17 20:37   ` Kenny Simpson
  1 sibling, 1 reply; 6+ messages in thread
From: H. J. Lu @ 2002-10-17  0:08 UTC (permalink / raw)
  To: Kenny Simpson; +Cc: binutils, amodra

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

On Tue, Oct 15, 2002 at 01:19:09PM -0700, Kenny Simpson wrote:
> The runpath of a shared object is not always being
> searched when linking an executable.
> 
> The behavior I'm seeing is the following:
>   I have an external library (libext1.so), which lives
> in ~/ext1.
>   A shared library (libfoo.so) is created which links
> against libext.so and records a DT_RUNPATH for ~/ext1.
>   Another shared library (libbar.so) is created with a
> DT_RUNPATH for some other directory (ext2/libext2.so).
>   I attempt to create a binary (baz) that links
> against libfoo, and libbar.
>   The link fails as libext1 cannot be found.
> 
> Just to codify the above:
> 
> mkdir ext1;
> mkdir ext2;
> 
> dummy.c:
>         /* empty */
> 
> main.c:
>         int main() { return 0; }
> 
> Makefile:
>         ext1/libext1.so: dummy.c
>                 gcc -shared dummy.c -o $@
> 
>         ext2/libext2.so: dummy.c
>                 gcc -shared dummy.c -o $@
> 
>         libfoo.so: ext1/libext1.so
>                 gcc -shared -Lext1 -Wl,-rpath,ext1
> -Wl,--enable-new-dtags -lext1 -o $@
> 
>         libbar.so: ext2/libext2.so
>                 gcc -shared -Lext2 -Wl,-rpath,ext2
> -Wl,--enable-new-dtags -lext2 -o $@
> 
>         baz: main.c libbar.so libfoo.so
>                 gcc main.c -L. -Wl,-rpath,. -lfoo
> -lbar -o $@
> 
> make baz
> 

Thanks for your bug repart. It will be nice to provide a tar file so that I don't
have to recreate each file by hand. Here is a patch. It is late. Alan, could you
please double check it? Also please check my patch still works right for the bug

http://sources.redhat.com/ml/binutils/2000-08/msg00242.html

tried to fix.

Thanks.


H.J.

[-- Attachment #2: bfd-runpatch.patch --]
[-- Type: text/plain, Size: 2926 bytes --]

2002-10-16  H.J. Lu <hjl@gnu.org>

	* elflink.h (elf_link_add_object_symbols): Correctly handle DT_RPATH and
	DT_RUNPATH.

--- bfd/elflink.h.runpath	Sat Oct 12 08:44:36 2002
+++ bfd/elflink.h	Thu Oct 17 00:03:53 2002
@@ -1298,6 +1298,7 @@ elf_link_add_object_symbols (abfd, info)
       const char *name;
       bfd_size_type oldsize;
       bfd_size_type strindex;
+      struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
 
       /* Find the name to use in a DT_NEEDED entry that refers to this
 	 object.  If the object has a DT_SONAME entry, we use it.
@@ -1327,8 +1328,6 @@ elf_link_add_object_symbols (abfd, info)
 	  Elf_External_Dyn *extdynend;
 	  int elfsec;
 	  unsigned long shlink;
-	  int rpath;
-	  int runpath;
 
 	  dynbuf = (Elf_External_Dyn *) bfd_malloc (s->_raw_size);
 	  if (dynbuf == NULL)
@@ -1345,8 +1344,6 @@ elf_link_add_object_symbols (abfd, info)
 
 	  extdyn = dynbuf;
 	  extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn);
-	  rpath = 0;
-	  runpath = 0;
 	  for (; extdyn < extdynend; extdyn++)
 	    {
 	      Elf_Internal_Dyn dyn;
@@ -1390,13 +1387,6 @@ elf_link_add_object_symbols (abfd, info)
 		  char *fnm, *anm;
 		  unsigned int tagv = dyn.d_un.d_val;
 
-		  /* When we see DT_RPATH before DT_RUNPATH, we have
-		     to clear runpath.  Do _NOT_ bfd_release, as that
-		     frees all more recently bfd_alloc'd blocks as
-		     well.  */
-		  if (rpath && hash_table->runpath)
-		    hash_table->runpath = NULL;
-
 		  amt = sizeof (struct bfd_link_needed_list);
 		  n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt);
 		  fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
@@ -1410,13 +1400,11 @@ elf_link_add_object_symbols (abfd, info)
 		  n->name = anm;
 		  n->by = abfd;
 		  n->next = NULL;
-		  for (pn = & hash_table->runpath;
+		  for (pn = & runpath;
 		       *pn != NULL;
 		       pn = &(*pn)->next)
 		    ;
 		  *pn = n;
-		  runpath = 1;
-		  rpath = 0;
 		}
 	      /* Ignore DT_RPATH if we have seen DT_RUNPATH.  */
 	      if (!runpath && dyn.d_tag == DT_RPATH)
@@ -1442,18 +1430,32 @@ elf_link_add_object_symbols (abfd, info)
 		  n->name = anm;
 		  n->by = abfd;
 		  n->next = NULL;
-		  for (pn = & hash_table->runpath;
+		  for (pn = & rpath;
 		       *pn != NULL;
 		       pn = &(*pn)->next)
 		    ;
 		  *pn = n;
-		  rpath = 1;
 		}
 	    }
 
 	  free (dynbuf);
 	}
 
+      /* DT_RUNPATH overrides DT_RPATH.  Do _NOT_ bfd_release, as that
+	 frees all more recently bfd_alloc'd blocks as well.  */
+      if (runpath)
+	rpath = runpath;
+
+      if (rpath)
+	{
+	  struct bfd_link_needed_list **pn;
+	  for (pn = & hash_table->runpath;
+	       *pn != NULL;
+	       pn = &(*pn)->next)
+	    ;
+	  *pn = rpath;
+	}
+
       /* We do not want to include any of the sections in a dynamic
 	 object in the output file.  We hack by simply clobbering the
 	 list of sections in the BFD.  This could be handled more

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

* Re: PATCH: Fix [BUG] runpath broken for .so's in ld
  2002-10-17  0:08 ` PATCH: Fix " H. J. Lu
@ 2002-10-17 20:37   ` Kenny Simpson
  2002-10-17 23:04     ` H. J. Lu
  0 siblings, 1 reply; 6+ messages in thread
From: Kenny Simpson @ 2002-10-17 20:37 UTC (permalink / raw)
  To: H. J. Lu; +Cc: binutils, amodra

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

--- "H. J. Lu" <hjl@lucon.org> wrote:
> Thanks for your bug repart. It will be nice to
> provide a tar file so that I don't
> have to recreate each file by hand.
Ok, attached is my attempt at a tar file.
Enjoy.

-Kenny



__________________________________________________
Do you Yahoo!?
Faith Hill - Exclusive Performances, Videos & More
http://faith.yahoo.com

[-- Attachment #2: runpath_test.tar --]
[-- Type: application/x-tar, Size: 10240 bytes --]

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

* Re: PATCH: Fix [BUG] runpath broken for .so's in ld
  2002-10-17 20:37   ` Kenny Simpson
@ 2002-10-17 23:04     ` H. J. Lu
  2002-10-17 23:19       ` Alan Modra
  0 siblings, 1 reply; 6+ messages in thread
From: H. J. Lu @ 2002-10-17 23:04 UTC (permalink / raw)
  To: Kenny Simpson; +Cc: binutils, amodra

On Thu, Oct 17, 2002 at 08:37:37PM -0700, Kenny Simpson wrote:
> --- "H. J. Lu" <hjl@lucon.org> wrote:
> > Thanks for your bug repart. It will be nice to
> > provide a tar file so that I don't
> > have to recreate each file by hand.
> Ok, attached is my attempt at a tar file.
> Enjoy.
> 

Thanks. My patch works fine. I will check it in this weekend if I
can't find any problems with it.


H.J.

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

* Re: PATCH: Fix [BUG] runpath broken for .so's in ld
  2002-10-17 23:04     ` H. J. Lu
@ 2002-10-17 23:19       ` Alan Modra
  0 siblings, 0 replies; 6+ messages in thread
From: Alan Modra @ 2002-10-17 23:19 UTC (permalink / raw)
  To: H. J. Lu; +Cc: Kenny Simpson, binutils

On Thu, Oct 17, 2002 at 11:04:00PM -0700, H. J. Lu wrote:
> Thanks. My patch works fine. I will check it in this weekend if I
> can't find any problems with it.

The idea looks OK to me too.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

end of thread, other threads:[~2002-10-18  6:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-15 13:19 [BUG] runpath broken for .so's in ld Kenny Simpson
2002-10-15 17:02 ` H. J. Lu
2002-10-17  0:08 ` PATCH: Fix " H. J. Lu
2002-10-17 20:37   ` Kenny Simpson
2002-10-17 23:04     ` H. J. Lu
2002-10-17 23:19       ` Alan Modra

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).