Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I change the filename of a shared library after building a program that depends on it?

Tags:

I have a program that depends on a shared library it expects to find deep inside a directory structure. I'd like to move that shared library out and into a better place. On OS X, this can be done with install_name_tool. I'm unable to find an equivalent for Linux.

For reference, readelf -d myprogram spits out the following paraphrased output:

Dynamic section at offset 0x1e9ed4 contains 30 entries:   Tag        Type                         Name/Value  0x00000001 (NEEDED)                     Shared library: [this/is/terrible/library.so]  0x00000001 (NEEDED)                     Shared library: [libGL.so.1]  0x00000001 (NEEDED)                     Shared library: [libGLU.so.1]  0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6] (continues in an uninteresting fashion) 

(and by request, ldd myprogram:)

    linux-gate.so.1 =>  (0x0056a000)     this/is/terrible/library.so => not found     libGL.so.1 => /usr/lib/mesa/libGL.so.1 (0x0017d000)     libGLU.so.1 => /usr/lib/libGLU.so.1 (0x00a9c000)     libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00710000)    (etc, etc) 

and I would like to errata "this/is/terrible/library.so" to be "shared/library.so". Note that, if the program is left in its "built" location, where the relative path this/is/terrible/library.so actually exists, then ldd is able to find it, as you'd expect.

I know about RPATH and it isn't what I'm looking for, I don't need to change search paths globally.

like image 731
ZorbaTHut Avatar asked May 03 '10 15:05

ZorbaTHut


People also ask

Which of the following options is necessary to create a shared library?

The -shared or -dynamiclib option is required to create a shared library. The name of the source file is octagon.

What is a shared object file?

A shared library or shared object is a file that is intended to be shared by multiple programs. Symbols used by a program are loaded from shared libraries into memory at load time or runtime.

How do I open a shared library file?

If you want to open a shared-library file, you would open it like any other binary file -- with a hex-editor (also called a binary-editor). There are several hex-editors in the standard repositories such as GHex (https://packages.ubuntu.com/xenial/ghex) or Bless (https://packages.ubuntu.com/xenial/bless).


2 Answers

We can use patchelf:

patchelf --replace-needed liboriginal.so.1 libreplacement.so.1 my-program 

We can also remove a dependency:

patchelf --remove-needed libfoo.so.1 my-program 

Add a dependency:

patchelf --add-needed libfoo.so.1 my-program 

Or change the path where to search for the libraries (rpath):

patchelf --set-rpath /path/to/lib:/other/path my-program 
like image 50
Bernardo Ramos Avatar answered Oct 11 '22 06:10

Bernardo Ramos


Posting a tentative, horrible, hacky solution.

The library dependencies are stored in an ELF block known as the .depends block. The format of that block is a large array of identifier/stringpointer pairs, with the stringpointer pointing to a standard C null-terminated string located somewhere in the binary.

You see where this is going, right?

Yep, as long as the new path you need is no larger than the old path, you can just reach right into the binary and do a simple string replace. Make sure not to add or remove bytes or you'll break the entire binary. If you want to be safer about it, you could actually traverse the ELF structure to ensure you had the right location - right now I'm just checking to make sure the source string shows up exactly once.

ELF does include a checksum, but apparently there's no loader that actually verifies it, so it's "safe" - albeit messy - to ignore.

The "real solution" would be a utility that allowed low-level generalized manipulations of the ELF structure. As near as I can tell, no such utility exists, for anything except a few specialized cases (RPATH, mostly.) I don't pretend to know how difficult such a utility would be to write.

I would absolutely love a better solution to this, but, so far, this appears to work.

like image 40
ZorbaTHut Avatar answered Oct 11 '22 07:10

ZorbaTHut