% elfdump -d /bin/true
Dynamic Section: .dynamic
index tag value
[0] NEEDED 0x1d6 libc.so.1
[1] INIT 0x8050d20
and it goes on a bit. But basically you're looking at the NEEDED lines to see which shared libraries you need. (The other field that's generally of interest for a shared library is the SONAME field.)
However, you can go beyond this, and use elfedit to manipulate what's present here. You can essentially replicate the above with:
elfedit -r -e dyn:dump /bin/true
Here the -r flag says read-only (we're just looking), and -e says execute the command that follows, which is dyn:dump - or just show the dynamic section.
If you look around, you'll see that the classic example is to set the runpath (which you might see as RPATH or RUNPATH in the dump output). This was used to fix up binaries that had been built incorrectly, or where you've moved the libraries somewhere other than where the binary normally looks for them. Which might look like:
elfedit -e 'dyn:runpath /my/local/lib' prog
This is the first example in the man page, and the standard example wherever you look. (Note the quotes - that's a single command input to elfedit.)
However, another common case I come across is where libtool has completely mangled the link so the full pathname of the library (at build time, no less) has been embedded in the binary (either in absolute or relative form). In other words, rather than the NEEDED section being
libfoo.so.1
it ends up being
/home/ptribble/build/bar/.libs/libfoo.so.1
With this sort of error, no amount of tinkering with RPATH is going to help the binary find the library. Fortunately, elfedit can help us here too.
First you need to work out which element you want to modify. Back to elfedit again to dump out the structure
% elfedit -r -e dyn:dump /bin/baz
index tag value
[0] POSFLAG_1 0x1 [ LAZY ]
[1] NEEDED 0x8e2 /home/.../libfoo.so.1
It might be further down, of course. But the entry we want to edit is index number 1. We can narrow down the output just to this element by using the -dynndx flag to the dyn:dump command, for example
elfedit -r -e 'dyn:dump -dynndx 1' /bin/baz
or, equivalently, using dyn:value
elfedit -r -e 'dyn:value -dynndx 1' /bin/baz
And we can actually set the value as well. This requires the -s flag to set a string, but you end up with:
elfedit -e 'dyn:value -dynndx -s 1 libfoo.so.1' /bin/baz
and then if you use elfdump or elfedit or ldd to look at the binary, it should pick up the library correctly.
This is really very simple (the hardest part is having to work out what the index of the right entry is). I didn't find anything when searching that actually describes how simple it is, so I thought it worth documenting for the next time I need it.
1 comment:
Hi Peter.
Thanks for this nice article about elfedit.
One nice thing to note about the libtool example that you used is that the desired string libfoo.so.1 is at the tail of the existing value. Therefore, this edit doesn't consume any of the reserved space that the Solaris ld creates for such edits. As such, you will see that the value of SUNWSTRPAD doesn't change. This edit comes at no cost.
If you execute the command 'set d 1' before that command, or run elfedit with the -d option, elfedit will show you how it satisfied the request. That's not really necessary, but interesting to the curious with some ELF background.
Identifying the specific NEEDED entry to modify has always been the weak part of this story. -dynndx does indeed work, but doing that in an automated way requires some sort of wrapper script to run elfdump or elfedit to get that index, and then create the necessary elfedit with the actual index value. With Solaris 11.3, I introduced a plethora of -with- selection options, intended to make it easier to do things like that in a single step. Your example would be:
% elfedit -e 'dyn:value -with-valstr /home/ptribble/build/bar/.libs/libfoo.so.1 -s libfoo.so.1'
The next release of Solaris will have a dyn:needed command intended to simplify NEEDED manipulations further and handle some of the tricker corner cases (not relevant to the simple example here).
Happy Editing!
- Ali Bahrami
Post a Comment