Saturday, June 20, 2009

Changing the RPATH of a binary

Suppose that you have two different versions of a library installed on /usr/lib and /usr/local/lib. Further suppose that for most software you run you will want to use the standard one in /usr/lib, but for a specific program you're compiling you need to make it use /usr/local/lib. The problem is that GCC builds in a search path used at runtime where /usr/lib is always before /usr/local/lib. This means that the binary will always find the wrong library in /usr/lib before it finds the library in /usr/local/lib. You can use ldd and "ldd -s" to check which libraries the binary uses.

Because I don't have a good solution I do this: Use elfedit to edit the binary to change the search path.

Step 1.
Get the current search path. (-r means read-only so you will only display the current one)
# elfedit -r -e 'dyn:runpath' file
index tag value
[31] RUNPATH 0x494b /usr/ccs/lib:/lib:/usr/lib:/usr/sfw/lib:/usr/local/lib
[32] RPATH 0x494b /usr/ccs/lib:/lib:/usr/lib:/usr/sfw/lib:/usr/local/lib

See how /usr/lib is before /usr/local/lib? That is my problem here.

Step 2.
Change the path so that /usr/local/lib is before /usr/lib.
# elfedit -e 'dyn:runpath /usr/ccs/lib:/lib:/usr/local/lib:/usr/lib:/usr/sfw/lib' file

Step 3.
Verify that it has changed.
# elfedit -r -e 'dyn:runpath' file
index tag value
[31] RUNPATH 0x4982 /usr/ccs/lib:/lib:/usr/local/lib:/usr/lib:/usr/sfw/lib
[32] RPATH 0x4982 /usr/ccs/lib:/lib:/usr/local/lib:/usr/lib:/usr/sfw/lib

This is the problem I

No comments: