lddtree.sh: Add an "ldd-mode" for when the command is executed as *ldd
Dracut needs ldd to identify which libraries it needs to pull into the initrd. The regular ldd does not work across architectures though, so it suggests using this gist, which is based on a script from crosstool-ng. I suggested adding this to Gentoo's crossdev but there was little appetite to add yet another ldd implementation.
lddtree.sh almost outputs what we need, the main issue being that it includes the file being examined, even when it is the only file being examined. I decided to add an "ldd-mode" to make the output more like regular ldd when it is executed as *ldd. The intention is to install a symlink to it with crossdev. I had to restructure the code a bit to ensure it was still readable after adding a third output format.
lddtree.sh currently doesn't get installed when the Python implementation is chosen, which would make things awkward for crossdev. I have therefore made Meson install lddtree.sh unconditionally, adding an lddtree symlink pointing to the chosen implementation instead.
Both lddtree implementations enable the auto-root feature by default. This breaks Dracut as it passes regular rooted paths to ldd, meaning that /foo/bin/ls becomes /foo/foo/bin/ls. I don't want to have to create a wrapper to disable this option, and it seems like quite a counter-intuitive feature anyway, so I have now disabled it by default. Hopefully this isn't controversial. I can't see any use of lddtree by packages at build time or runtime.
Ah, I'd overlooked the tests. :sweat_smile:
Sample "ldd-mode" output with real ldd comparison:
$ ./foo-ldd /bin/bash /bin/ls
/bin/bash:
/lib64/ld-linux-x86-64.so.2 (0xdeadbeef)
libreadline.so.8 => /usr/lib64/libreadline.so.8 (0xdeadbeef)
libtinfow.so.6 => /usr/lib64/libtinfow.so.6 (0xdeadbeef)
libc.so.6 => /usr/lib64/libc.so.6 (0xdeadbeef)
/bin/ls:
/lib64/ld-linux-x86-64.so.2 (0xdeadbeef)
libcap.so.2 => /usr/lib64/libcap.so.2 (0xdeadbeef)
libc.so.6 => /usr/lib64/libc.so.6 (0xdeadbeef)
$ ldd /bin/bash /bin/ls
/bin/bash:
linux-vdso.so.1 (0x00007f9a01161000)
libreadline.so.8 => /usr/lib64/libreadline.so.8 (0x00007f9a00fcb000)
libc.so.6 => /usr/lib64/libc.so.6 (0x00007f9a00dd9000)
libtinfow.so.6 => /usr/lib64/libtinfow.so.6 (0x00007f9a00d95000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9a01162000)
/bin/ls:
linux-vdso.so.1 (0x00007f85f07a1000)
libcap.so.2 => /usr/lib64/libcap.so.2 (0x00007f85f0725000)
libc.so.6 => /usr/lib64/libc.so.6 (0x00007f85f0533000)
/lib64/ld-linux-x86-64.so.2 (0x00007f85f07a2000)
0xdeadbeef is what the gist script outputs, so that seems good enough. We don't care about linux-vdso.so.1 because it doesn't really exist.
I'd missed that you'd prepared this. There's a fair bit in master which needs a release and we should do one for https://bugs.gentoo.org/890577 especially, so I don't want to rush trying to review it now, will come back to it later (remind me if I forget).
This is less necessary now that Dracut no longer uses ldd. It's still potentially useful though.