Bug 17311 - Wrong libgcc_s.so.1 is used by lt-gij
Summary: Wrong libgcc_s.so.1 is used by lt-gij
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libgcj (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: 17464 17574
  Show dependency treegraph
 
Reported: 2004-09-03 20:27 UTC by H.J. Lu
Modified: 2006-03-02 07:09 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-02-07 16:16:28


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2004-09-03 20:27:14 UTC
libtool doesn't put the right path in lt-gij when building it to be used during
build:

# readelf -d ia64-unknown-linux-gnu/libjava/.libs/lt-gij

                                                                                
Dynamic section at offset 0x2460 contains 33 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libgcj.so.5]
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [libz.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6.1]
 0x0000000000000001 (NEEDED)             Shared library: [libunwind.so.7]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6.1]
 0x000000000000000f (RPATH)              Library rpath:
[/export/build/gnu/gcc-3.4-redhat/build-ia64-linux/ia64-unknown-linux-gnu/libjava/.libs:/usr/gcc-3.4-redhat/lib]
 0x000000000000000c (INIT)               0x4000000000000980
 0x000000000000000d (FINI)               0x4000000000001ac0
 0x0000000000000019 (INIT_ARRAY)         0x6000000000002418
 0x000000000000001b (INIT_ARRAYSZ)       24 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x6000000000002430
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x0000000000000004 (HASH)               0x4000000000000238
 0x0000000000000005 (STRTAB)             0x4000000000000560
 0x0000000000000006 (SYMTAB)             0x40000000000002f0
 0x000000000000000a (STRSZ)              584 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000015 (DEBUG)              0x0
 0x0000000070000000 (IA_64_PLT_RESERVE)  0x60000000000026c8 -- 0x60000000000026e0
 0x0000000000000003 (PLTGOT)             0x60000000000026c8
 0x0000000000000002 (PLTRELSZ)           264 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x4000000000000878
 0x0000000000000007 (RELA)               0x4000000000000800
 0x0000000000000008 (RELASZ)             120 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x40000000000007e0
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x40000000000007a8
 0x0000000000000000 (NULL)               0x0

The gcc build directory needs to be in DT_RPATH. Otherwise, the wrong
libgcc_s.so will be used.
Comment 1 Bryce McKinlay 2004-09-03 20:46:42 UTC
Most likely, this is also due to automake passing the wrong -B directories to
libtool/gcj while building libjava. 
Comment 2 H.J. Lu 2004-09-03 20:52:49 UTC
I don't think so. The problem is similar to bug 16633.
Comment 3 Andrew Pinski 2004-09-09 03:42:26 UTC
Is this fixed?
Comment 4 H.J. Lu 2004-09-09 16:25:36 UTC
No. Although the nature of this bug is the same as bug 16633,
they requires different fixes. I posted 2 patches to fix this
bug. The first one is

http://gcc.gnu.org/ml/gcc-patches/2004-09/msg00663.html

and the second one is

http://gcc.gnu.org/ml/gcc-patches/2004-09/msg00836.html
Comment 5 H.J. Lu 2004-09-14 18:42:01 UTC
The updated second patch is at

http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01449.html
Comment 6 H.J. Lu 2004-09-16 00:11:49 UTC
An updated second patch is at

http://gcc.gnu.org/ml/gcc-patches/2004-09/msg01486.html
Comment 7 Tom Tromey 2004-10-11 20:13:37 UTC
I read through these patches a little.

I don't understand why ltmain.sh is the way it is,
but Gary's comment seemed appropriate.
http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02333.html

Doesn't the second patch eliminate the need for
the first one?  I still don't understand why the
second patch is needed, though.  To me it looks like
libjava.exp:libjava_init initializes the various
forms of LD_LIBRARY_PATH appropriately, finding libgcc_s.so.
Can you tell me why this doesn't work?
Comment 8 H.J. Lu 2004-10-11 20:32:51 UTC
See

http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02467.html

I don't know how to do --disable-fast-install for gcc.
--enable-fast-install is totally wrong for ELF. It should
never be used for any ELF targets.
Comment 9 Tom Tromey 2004-10-11 20:49:37 UTC
I read that.  What I observe is that .libs/gij is created
by the build.  Then if I run gij (not .libs/gij), it creates
.libs/lt-gij.

My understanding is that --enable-fast-install is what makes
all this work as it does.  .libs/gij has the install tree
in its DT_RPATH -- but that is ok since this executable is never
run from the build tree.  It exists only so that installation
can be as simple as "cp".

.libs/lt-gij is relinked lazily, when gij is run.  Its DT_RPATH
is:

opsy. readelf -d .libs/lt-gij |grep RPATH
 0x0000000f (RPATH)                      Library rpath:
[/home/tromey/gnu/Trunk/build/i686-pc-linux-gnu/libjava/.libs:/home/tromey/gnu/Trunk/install/lib]

So to me it looks like we're missing an entry here for the libgcc_s.so
directory.  So, probably, your first patch is the way to go... I'd like
a bona fide libtool expert to look at this though.

I still don't understand why the second patch is needed.

As for --disable-fast-install, did you try just passing that to the
top-level configure?  (I didn't)
Comment 10 H.J. Lu 2004-10-11 21:01:21 UTC
.libs/lt-gij is used by "make check". Try

# grep -i gij */*.exp

in libjava/testsuite.
Comment 11 Tom Tromey 2004-10-11 21:27:19 UTC
I'm afraid I couldn't really parse that.

To me it looks like libjava_find_gij looks for
"gij" in the build directory.  This in turn is
a shell script which, if needed, creates lt-gij.

The fact that the install tree is put in DT_RPATH
is, like I mentioned in comment #9, a problem.
For this we probably need your patch.

I suppose what I would really like to know is why
you needed the second patch.  What is wrong with
the current code for setting LD_LIBRARY_PATH in
libjava.exp?
Comment 12 H.J. Lu 2004-10-12 19:52:48 UTC
You are right. The second patch isn't needed.
Comment 13 Andrew Pinski 2005-08-17 03:12:10 UTC
What is the status of this bug (why is this still in waiting)?
Comment 14 H.J. Lu 2005-08-17 18:06:21 UTC
FWIW, the bug is still there.
Comment 15 Ralf Wildenhues 2006-02-06 18:24:45 UTC
(In reply to comment #8 by H. J. Lu)
> See
> 
> http://gcc.gnu.org/ml/gcc-patches/2004-09/msg02467.html
> 
> I don't know how to do --disable-fast-install for gcc.
> --enable-fast-install is totally wrong for ELF. It should
> never be used for any ELF targets.

I don't understand this comment.  You seem to imply that libtool
should not add DT_RPATH entries pointing to installed paths to
libraries/executables in the build tree.

But given --enable-fast-install, and given that there are no indirect
library dependencies, this is the correct thing: both libraries and
programs can be copied to their final location without relink and
will work correctly.  libtool creates a shell wrapper for uninstalled
programs that does relink-upon-execution and adds DT_RPATH entries for
all direct dependencies.

Of course, given --enable-fast-install but *indirect* library dependencies
inside the build tree, adding DT_RPATH entries with the installed paths
would not work: the wrong indirect libs would be picked up.  However,
libtool could still solve this: all systems which support indirect library
dependencies well (i.e.: GNU/Linux) have measures make both the link editing
step work (-rpath-link) as well as relink-upon-execution (just put all
paths for uninstalled indirect dependencies in the run path of the relinked
executable).

What am I missing?

Cheers,
Ralf
Comment 16 H.J. Lu 2006-02-06 19:03:07 UTC
Please read the summary line: "Wrong libgcc_s.so.1 is used by lt-gij". Ld.so will
search DT_RPATH first for any shared libraries. If you have DT_RPATH entries
pointing to installed paths to libraries/executables in the build tree, when you
run such an executable in the build tree, the shared libraries in installed paths
will be used, if they exist. That is the newly built shared libraries in the
build tree may never be used. Sometimes it is fatal if the shared library in the
installed path isn't 100% compatible with the newly built one.
Comment 17 Ralf Wildenhues 2006-02-07 05:48:18 UTC
(In reply to comment #16)
> Please read the summary line: "Wrong libgcc_s.so.1 is used by lt-gij". Ld.so
> will search DT_RPATH first for any shared libraries.

Yes.  So all that is missing is a notion in libtool to tell it
  "this path is to be added to the list of *uninstalled* run paths"
which would be added to the relinked-for-execution executable (after all
other uninstalled paths) but not the unrelinked one and not either to any
uninstalled libraries (on ELF, of course).  You have to have that notion
anyway because otherwise there would be no way you could add the run path
to libgcc_s to libtool safely at all (i.e. without ending up in installed
files).

In comment #8 you said:
> I don't know how to do --disable-fast-install for gcc.

As for --disable-fast-install, it's not optimal either.  But libtool could
create all libraries/programs with the uninstalled run paths (also the ones
given by above new flag) and after that all other given ones.  `make install'
will surely have to relink all of those; but I don't see the necessity for
a shell wrapper in this case either (on system where
shlibpath_overrides_runpath=no).

All there is missing for decent libtool support for "libtool + non-libtool
libraries in one build tree" is a notion to pass uninstalled run paths and
uninstalled link editor paths (-L), AFAICS.

By the way, I don't see any reason why the installed run paths should not be
put after the uninstalled ones (into the relinked-upon-execution executable).
You have to assume anyway that incompatible libraries may be found in the
default runtime linker search path, so really they are not contributing much
to the problem.
Comment 18 H.J. Lu 2006-02-07 16:16:28 UTC
There are

[hjl@gnu-13 gcc]$ readelf -d /usr/gcc-4.2/bin/gij | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: [/usr/gcc-4.2/lib/../lib64]
[hjl@gnu-13 gcc]$

Why do I want

[hjl@gnu-13 gcc]$ readelf -d /usr/gcc-4.2/bin/gij | grep RPATH
 0x000000000000000f (RPATH)              Library rpath:  /export/build/gnu/gcc/build-x86_64-linux/gcc
 0x000000000000000f (RPATH)              Library rpath: [/usr/gcc-4.2/lib/../lib64]
[hjl@gnu-13 gcc]$

It may cause more problems than it solves.

Comment 19 Ralf Wildenhues 2006-02-07 16:28:02 UTC
(In reply to comment #18)
> Why do I want
> 
> [hjl@gnu-13 gcc]$ readelf -d /usr/gcc-4.2/bin/gij | grep RPATH
>  0x000000000000000f (RPATH)              Library rpath: 
> /export/build/gnu/gcc/build-x86_64-linux/gcc
>  0x000000000000000f (RPATH)              Library rpath:
> [/usr/gcc-4.2/lib/../lib64]
> [hjl@gnu-13 gcc]$
> 
> It may cause more problems than it solves.

Certainly, that's a bad bug and has to be avoided at all
(the fact that this may not work correctly now is clear:
libtool does not yet fully support what I outlined).

Where was I talking about the desire to have run paths
in *installed programs* pointing *to the build tree* though?

Maybe my notation was bad: a relinked-upon-execution executable
is some program .libs/lt-foo inside the build tree that gets
created when foo is executed; foo is a shell script that does this.
Does this make things clearer now?

Sorry for the confusion.
Comment 20 H.J. Lu 2006-02-07 16:48:17 UTC
What did you mean by *installed programs*. The executable in question is

[hjl@gnu-13 .libs]$ readelf -d /export/build/gnu/gcc/build-x86_64-linux/x86_64-unknown-linux-gnu/libjava/.libs/gij | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: [/usr/gcc-4.2/lib/../lib64]

Is is your *installed programs*? My point is when you run a newly built executable
in the build tree, it should use the newly built shared libraries in the build
tree. It is a long standing bug in gcc/libtool.
Comment 21 Ralf Wildenhues 2006-02-07 17:18:34 UTC
(In reply to comment #20)
> What did you mean by *installed programs*

In my notation, installed programs live below $prefix.
They must not contain any reference to the build tree.
You showed an installed program in comment #18, which
has an erroneous run path.

> The executable in question is
> 
> [hjl@gnu-13 .libs]$ readelf -d
> /export/build/gnu/gcc/build-x86_64-linux/x86_64-unknown-linux-gnu/libjava/.libs/gij
> | grep RPATH
>  0x000000000000000f (RPATH)              Library rpath:
> [/usr/gcc-4.2/lib/../lib64]

This is an uninstalled program: it lives below $builddir.
It should of course have a run path entry to the newly-built
library (which also lives below $builddir).

One of my points was that, if that uninstalled program also
has a run path entry pointing to /usr/gcc-4.2/lib/../lib64,
but that comes after all the run paths which point to inside $builddir,
then that is not a big problem.

> Is is your *installed programs*?

No.

> My point is when you run a newly built executable
> in the build tree, it should use the newly built shared libraries in the build
> tree. It is a long standing bug in gcc/libtool.

Yes, correct.  It's one of my medium term quests to fix this.

The converse issue (from a libtool POV) is just GCC bug 5291.
Again from a libtool POV it is convenient and useful to attack both
issues at the same time.

One of the open questions that I could not answer myself yet:
When you issue `make install' for GCC, is there a guarantee by the GCC
build machinery that
- libraries are installed in the correct order
  (libgcc_s.so before libgcj)?  I strongly assume yes.
- For each libtool-created library, in case it needs to be relinked
  at install time, does the relink command have appropriate -L (and maybe -R)
  flags pointing to the installed non-libtool libraries
  (e.g., $prefix/lib/libgcc_s)?

In comment #18, you show that for this build, the second question is true.
I need to know however if it is true in any case, for any value of $host.

Iff both questions can be affirmed, then the next question can also
be made true:
- If libtool erased both all `-L' and all `-R' flags pointing inside the
  build tree from the relink command that may be issued at `make install'
  time, would installation still succeed?

Then we have a chance to fix this portably in libtool, not only for
GNU/Linux.

Another small but important question:
- Do there exist directories in the GCC build tree where both libtool-created
  and non-libtool-created libraries are (possibly) built?
Comment 22 H.J. Lu 2006-02-07 17:25:23 UTC
Another small but important question:
- Do there exist directories in the GCC build tree where both libtool-created
  and non-libtool-created libraries are (possibly) built?

That is THE KEY question. The executable in question is lt-gij:

hjl@gnu-13 .libs]$ readelf -d /export/build/gnu/gcc/build-x86_64-linux/x86_64-unknown-linux-gnu/libjava/.libs/lt-gij | grep RPATH
 0x000000000000000f (RPATH)              Library rpath: [/export/build/gnu/gcc/build-x86_64-linux/x86_64-unknown-linux-gnu/libjava/.libs]
[hjl@gnu-13 .libs]$

libgcc_s.so.1 isn't built by libtool.
Comment 23 Ralf Wildenhues 2006-02-07 17:43:45 UTC
(In reply to comment #22)
> - Do there exist directories in the GCC build tree where both libtool-created
>   and non-libtool-created libraries are (possibly) built?
> 
> That is THE KEY question. The executable in question is lt-gij:
> 
> hjl@gnu-13 .libs]$ readelf -d
> /export/build/gnu/gcc/build-x86_64-linux/x86_64-unknown-linux-gnu/libjava/.libs/lt-gij
> | grep RPATH
>  0x000000000000000f (RPATH)              Library rpath:
> [/export/build/gnu/gcc/build-x86_64-linux/x86_64-unknown-linux-gnu/libjava/.libs]
> [hjl@gnu-13 .libs]$
> 
> libgcc_s.so.1 isn't built by libtool.

Yes, but the one is $stage/gcc/libgcc_s.so.1 and the other is
$stage/x86_64-unknown-linux-gnu/libjava/lib/libgcj.la, so they are built
in different directories.

Libtool has to know that $stage/gcc is something that is necessary for the
uninstalled link and run paths; but libtool also needs to be able to deduce
that the path $stage/gcc must not be used for any installed libraries or
programs.

Now, if I want to fix this properly (in Libtool), then I need to know whether
above question can be answered with yes not only for libgcc_s/libgcj,
but for each library created in GCC.  And also the other questions, really.
Comment 24 H.J. Lu 2006-02-07 18:45:55 UTC
For uninstalled executables in the build tree, like lt-gij, libtool may put all directories, which are in the build tree, passed by -L, into DT_RPATH. It may
add more DT_RPATH entries than necessary. If you want fancy one, you can check
out how linker deccides the library in which directory to use.
Comment 25 hjl@gcc.gnu.org 2006-03-01 17:39:40 UTC
Subject: Bug 17311

Author: hjl
Date: Wed Mar  1 17:39:35 2006
New Revision: 111607

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=111607
Log:
2006-03-01  H.J. Lu  <hongjiu.lu@intel.com>

	PR libgcj/17311
	* ltmain.sh: Don't use "$finalize_rpath" for compile.

Modified:
    trunk/ChangeLog
    trunk/ltmain.sh

Comment 26 H.J. Lu 2006-03-01 17:42:40 UTC
Fixed.
Comment 27 Ralf Wildenhues 2006-03-02 07:09:24 UTC
(In reply to comment #25)
>         PR libgcj/17311
>         * ltmain.sh: Don't use "$finalize_rpath" for compile.

This change will cause breakage on systems when relinking is done at
installation time, and on systems where fast-install works and is selected.

I'm sorry that due to time constraints I don't have more constructive feedback
ATM, but this is definitely not a good fix (and has a good chance of breaking
quite unrelated parts of the build process).

Cheers,
Ralf