[crosstool-ng] Small question and mini-patch

Yann E. MORIN yann.morin.1998@anciens.enib.fr
Fri Sep 26 22:04:00 GMT 2008

Brian, Joachim, and all,

On Friday 26 September 2008 22:36:38 Brian Dessent wrote:
> > > Now, the question.  Is it just me or does anyone else find a cross-ldd
> > > tool to be useful for the host?
> > Do you by chance know how to generate one? ;-)

I'm afraid I was a little bit ironic... Sorry.

> ldd is not so much a tool but a wrapper script that simply sets some
> environment variables that glibc recognises.
> The problem for a cross environment is obvious: you can't execute the
> target-glibc, and even if you could it still wouldn't work because it
> would expect to search for native paths and not sysroot-ed paths.

Correct. That's not easy.

> To a first approximation you can achieve the same thing by just listing
> the DT_NEEDED tags of the binary, e.g. "$target-objdump -p binary | grep
> NEEDED" or "$target-readelf -d binary | grep NEEDED".  This will show
> you the immediate first-order dependencies of 'binary', but to replicate
> what ldd shows you'd have to then recursively apply the same command to
> each listed element to compute the full set.

The populate script already has some code to do exactly that.

> An additional problem is that the NEEDED tag lists just the SONAME,
> without a path. This method completely lacks emulation of the 
> complicated path searching logic in the dynamic loader, which has to
> take into account all the various ways that shared libraries can be
> found:
> - LD_LIBRARY_PATH environment variable
> - DT_RPATH and DT_RUNPATH dynamic tags
> - ld.so.conf
> - hard-coded system defaults like /usr/lib

The first three are used to overide default hard-coded paths. BTW, you're
the LIB token (dynamic tag?) as well.

What's important is not wether they are set or not, but see below...

> So this means that any kind of cross-ldd would have to replicate all of
> this, which would be a non-trivial task, but not one that would be
> totally impossible.  But I think for the majority of cases you are
> really only interested in the first-order dependencies of a program or
> library anyway, so it's not necessary.

When X-building, it's first important to know if the needed libraries are
going to be in the target file system. Then, where it lies there is not really
meaningful. Let me explain...

Let's take a first example. Your program builds both a .so and an exec linked
againt that .so of yours. Odds are that the install procedure of the program
will just put the .so in a place where the exec can find it (at runtime,
obviously :-) ). If not, then your install procedure is borked.

Next, let's take a more complex example where a library is built from a
package (eg. libz.so) and installed in the root-to-be. Let's assume it is
installed in a standard place (eg. /usr/lib). A second package (your program,
for example) links against that library. At compile time, the linker will
find the library, and at runtime the dynamic linker will also. No problem.

Now let's assume that libz.so is not installed in a standard place. If you
want your program to link against it, you'll have to instruct the linker
where to search for libraries, and because you know that place, you'll be
able to prepare your program to in turn instruct the dynamic loader where
to find it at runtime. No problem.

Trying to use LD_LIBARY_PATH, LD_PRELOAD et al. with the X-ldd is doomed.
There is no way to know wether they are set or not when an executable is
called. (+)

So what a X-ldd should be able to do is to look at all NEEDED and check wether
it can find all the dependencies in the root-to-be, possibly reporting all the
libraries it finds for a single dependency. Bizarely enough, the populate
script already has code to do most of this (except reporting).

Output should ressemble as much as possible that of the native ldd, but
multiple reports would need some special formating, such as:
# ${target}-ldd /target-root-to-be/bin/sh
        linux-vdso.so.1 =>  (0x00007fff04bfe000)                  (*)
        libncurses.so.5 => /lib/libncurses.so.5 (0x00007f73fc6bf000)
        libdl.so.2 => /lib/libdl.so.2 (0x00007f73fc4bb000)
        libc.so.6 => /lib/libc.so.6 (0x00007f73fc168000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007f73c1f4c000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f73fc8fe000)
Warning: libc.so.6 resolved multiple times

(*) Note the fake linux-vdso.so dependency, BTW?

I may have missed some corner cases, but hey, it's friday and it's late here.

Yann E. MORIN.

Let's imagine a little shell script that does:
   eval export ${var1}_${var2}=/some/place/lib
   exec /your/program

And X-ldd can't know LD_LIBRARY_PATH was set... Doomed, I said... :-]

PS. And before any one asks, yes, I can do this silly stuff if pushed
    too hard... :-)

|  Yann E. MORIN  | Real-Time Embedded | /"\ ASCII RIBBON | Erics' conspiracy: |
| +0/33 662376056 | Software  Designer | \ / CAMPAIGN     |  ___               |
| --==< ^_^ >==-- `------------.-------:  X  AGAINST      |  \e/  There is no  |
| http://ymorin.is-a-geek.org/ | _/*\_ | / \ HTML MAIL    |   v   conspiracy.  |

For unsubscribe information see http://sourceware.org/lists.html#faq

More information about the crossgcc mailing list