在构建依赖于它的程序后,如何更改共享库的文件名?

时间:2021-09-05 06:29:31

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.

我有一个程序依赖于它希望在目录结构内部找到的共享库。我想把那个共享库搬到一个更好的地方。在OS X上,可以使用install_name_tool完成此操作。我无法找到Linux的等价物。

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

作为参考,readelf -d myprogram吐出以下释义输出:

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:)

(并根据要求,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.

我想将“this / is / terrible / library.so”改为“shared / library.so”。请注意,如果程序保留在其“构建”位置,其中/ / / ter / /。实际存在的相对路径,那么ldd能够找到它,正如您所期望的那样。

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

我知道RPATH,它不是我想要的,我不需要在全球范围内改变搜索路径。

4 个解决方案

#1


5  

HT - this might be helpful.

HT - 这可能会有所帮助。

HT is a file editor/viewer/analyzer for executables. The goal is to combine the low-level functionality of a debugger and the usability of IDEs. We plan to implement all (hex-)editing features and support of the most important file formats.

HT是可执行文件的文件编辑器/查看器/分析器。目标是结合调试器的低级功能和IDE的可用性。我们计划实现所有(十六进制)编辑功能并支持最重要的文件格式。

I couldn't find something much different from ZorbaTHut's solution, but perhaps it's possible to put a name with different length and still keep the binary valid.

我找不到与ZorbaTHut解决方案有很大不同的东西,但也许可以使用不同长度的名称并保持二进制有效。

gelf - this could be useful too.

gelf - 这也很有用。

GElf is a generic, ELF class-independent API for manipulat- ing ELF object files. GElf provides a single, common inter- face for handling 32-bit and 64-bit ELF format object files.

GElf是一个通用的,与ELF类无关的API,用于处理ELF目标文件。 GElf提供了一个单一的通用接口,用于处理32位和64位ELF格式的目标文件。

#2


7  

Posting a tentative, horrible, hacky solution.

发布一个试探性的,可怕的,hacky解决方案。

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.

库依赖项存储在称为.depends块的ELF块中。该块的格式是一大堆标识符/字符串指针对,其中stringpointer指向位于二进制文件中某个位置的标准C空终止字符串。

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结构以确保你有正确的位置 - 现在我只是检查以确保源字符串只显示一次。

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

ELF确实包含了一个校验和,但显然没有实际验证它的加载器,因此忽略它是“安全的” - 尽管是凌乱的。

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.

“真正的解决方案”将是允许对ELF结构进行低级广义操纵的实用程序。就像我所知道的那样,除了一些特殊情况(主要是RPATH)之外,没有这样的实用程序存在。我不会假装知道这样的实用程序有多难写。

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

我绝对会喜欢这个更好的解决方案,但到目前为止,这似乎有效。

#3


6  

We can use patchelf:

我们可以使用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):

或者更改搜索库的路径(rpath):

patchelf --set-rpath /path/to/lib:/other/path my-program

#4


-3  

You can use LD_LIBRARY_PATH to change the search path for shared libraries. If your program depends on a particular relative path like your example shows, you will still need to have that directory structure. In other words you can move the lib from /home/user/dev/project/this/is/terrible/library.so to /usr/local/lib/this/is/terrible/library.so but not to /usr/local/lib/library.so

您可以使用LD_LIBRARY_PATH更改共享库的搜索路径。如果您的程序依赖于特定的相对路径(如示例所示),则仍需要具有该目录结构。换句话说,您可以将lib从/home/user/dev/project/this/is/terrible/library.so移动到/usr/local/lib/this/is/terrible/library.so但不能移动到/ usr / local / lib目录/ library.so

If you can rebuild your program, then you can change the relative path it uses for the lib.

如果您可以重建程序,则可以更改它用于lib的相对路径。

There's some more info on shared libs in Linux at http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

有关Linux*享库的更多信息,请访问http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

#1


5  

HT - this might be helpful.

HT - 这可能会有所帮助。

HT is a file editor/viewer/analyzer for executables. The goal is to combine the low-level functionality of a debugger and the usability of IDEs. We plan to implement all (hex-)editing features and support of the most important file formats.

HT是可执行文件的文件编辑器/查看器/分析器。目标是结合调试器的低级功能和IDE的可用性。我们计划实现所有(十六进制)编辑功能并支持最重要的文件格式。

I couldn't find something much different from ZorbaTHut's solution, but perhaps it's possible to put a name with different length and still keep the binary valid.

我找不到与ZorbaTHut解决方案有很大不同的东西,但也许可以使用不同长度的名称并保持二进制有效。

gelf - this could be useful too.

gelf - 这也很有用。

GElf is a generic, ELF class-independent API for manipulat- ing ELF object files. GElf provides a single, common inter- face for handling 32-bit and 64-bit ELF format object files.

GElf是一个通用的,与ELF类无关的API,用于处理ELF目标文件。 GElf提供了一个单一的通用接口,用于处理32位和64位ELF格式的目标文件。

#2


7  

Posting a tentative, horrible, hacky solution.

发布一个试探性的,可怕的,hacky解决方案。

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.

库依赖项存储在称为.depends块的ELF块中。该块的格式是一大堆标识符/字符串指针对,其中stringpointer指向位于二进制文件中某个位置的标准C空终止字符串。

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结构以确保你有正确的位置 - 现在我只是检查以确保源字符串只显示一次。

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

ELF确实包含了一个校验和,但显然没有实际验证它的加载器,因此忽略它是“安全的” - 尽管是凌乱的。

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.

“真正的解决方案”将是允许对ELF结构进行低级广义操纵的实用程序。就像我所知道的那样,除了一些特殊情况(主要是RPATH)之外,没有这样的实用程序存在。我不会假装知道这样的实用程序有多难写。

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

我绝对会喜欢这个更好的解决方案,但到目前为止,这似乎有效。

#3


6  

We can use patchelf:

我们可以使用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):

或者更改搜索库的路径(rpath):

patchelf --set-rpath /path/to/lib:/other/path my-program

#4


-3  

You can use LD_LIBRARY_PATH to change the search path for shared libraries. If your program depends on a particular relative path like your example shows, you will still need to have that directory structure. In other words you can move the lib from /home/user/dev/project/this/is/terrible/library.so to /usr/local/lib/this/is/terrible/library.so but not to /usr/local/lib/library.so

您可以使用LD_LIBRARY_PATH更改共享库的搜索路径。如果您的程序依赖于特定的相对路径(如示例所示),则仍需要具有该目录结构。换句话说,您可以将lib从/home/user/dev/project/this/is/terrible/library.so移动到/usr/local/lib/this/is/terrible/library.so但不能移动到/ usr / local / lib目录/ library.so

If you can rebuild your program, then you can change the relative path it uses for the lib.

如果您可以重建程序,则可以更改它用于lib的相对路径。

There's some more info on shared libs in Linux at http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

有关Linux*享库的更多信息,请访问http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html