[Toybox] Implementing ldd.

Rob Landley rob at landley.net
Fri Jan 14 21:09:24 PST 2022


On 1/13/22 1:20 PM, enh wrote:
> TL;DR: unless you're writing your own dynamic linker, i'm not sure why
> you'd write an ldd?

Well to start with uClibc had a standalone one back in the day:

  https://git.busybox.net/uClibc/tree/utils/ldd.c

Which is basically a subset of readelf, and we have readelf...

The one built into glibc can't tell you anything about a musl or bionic binary
let alone something cross-compiled for another architecture.

I can never remember if it's "readelf -a" or "readelf -A" to fetch it with the
more complex tool, and it's way harder to script something like
https://git.busybox.net/busybox/tree/testsuite/testing.sh#n111 with readelf's
output.

"What libraries does this command fail if it can't load" seems a fairly
straightforward question to ask? Usually I'm trying to figure out what
dependencies to transplant when ripping binaries out of a system. (Disrto skew,
version skew, hacking together an initramfs on a USB stick...)

> personally i don't think a readelf-based ldd makes much sense? there
> are a ton of weird special cases that mean you really do need the
> "suck it and see" implementation

Such as?

> --- bionic already just has a
> one-line shell script that passes an argument to the dynamic linker
> (and i think glibc and musl work this way too).

Musl points an "ldd" symlink at the dynamic linker which notices the argv[0]
name and behaves differently. (I may have made puppy eyes at Rich years ago, I'd
have to check my back email...)

The script you mention does not appear to be shipped in the NDK:

  $ find android-ndk-r24-beta1 -name '*ldd*'
  $

Or aosp prebuilts:

  $ find aosp -name '*ldd'
  aosp/external/ltp/testcases/commands/ldd
  $

But then it doesn't seem to be installed in the cross compilers musl-cross-make
builds either. That said, I can symlink it myself:

$ cd x86_64-linux-musl-cross
$ ln -s x86_64-linux-musl/lib/libc.so ldd

If I point yours at an sh4 binary linked against musl will it work? Because the
musl one won't:

$ ./ldd ../sh2eb-linux-muslfdpic-cross/sh2eb-linux-muslfdpic/lib/libc.so
./ldd: ../sh2eb-linux-muslfdpic-cross/sh2eb-linux-muslfdpic/lib/libc.so: Not a
valid dynamic program
$ echo 'main() {;}' |
../sh2eb-linux-muslfdpic-cross/bin/sh2eb-linux-muslfdpic-cc -x c -
$ ./ldd a.out
./ldd: a.out: Not a valid dynamic program

But the old uClibc ldd from the dawn of time?

$ wget -O-
https://landley.net/aboriginal/downloads/old/binaries/1.4.0/cross-compiler-x86_64.tar.gz
| tar xvz
$ cross-compiler-x86_64/bin/x86_64-ldd a.out
	libc.so => not found (0x00000000)
	not a dynamic executable

Well it's a little unhappy (doesn't know about fdpic for one thing), but it did
tell me what shared library the file needed. Alas, it doesn't seem to recognize
the ndk toolchain's output at all, probably sanity checking header flags and new
ones have been added since...)

> which isn't to say that the question doesn't sometimes come up of "i'd
> like to print the transitive closure of DT_NEEDEDs *on the host*" but
> note that that's *not* the same thing, and so even if someone does
> write that, it probably deserves a different tool name and a big "note
> that your run-time mileage may vary wildly".

The ldd in uClibc showed the DT_NEEDED entries in an ELF file, and at the time
that's basically what glibc's did too (just... badly). I used it for ~10 years
and don't remember hitting one of the corner cases you're mentioning? (I'm
guessing a C++ name demangling thing?)

Admittedly, I wasn't trying to get vdso info out of it. I'll take you're word
they've grown more bells and whistles since, and am curious what those are?

Rich implemented his ldd as "make a symlink called ldd pointing at the dynamic
linker and it notices the argv[0] name and acts like ldd":

  http://git.musl-libc.org/cgit/musl/tree/ldso/dynlink.c?h=v1.2.2#n1793

Even if I _didn't_ suggest it to him back in the day (don't remember), given my
biases I just thought he was doing that old trick to reuse code. (Which
historically busybox copied from gzip/gunzip being hardlinked and supplying -d
to itself based on the name back in 1995, and I'm told there were unix v6
commands doing that back in the 1970s...)

Rob


More information about the Toybox mailing list