Linux 我可以在已编译的二进制文件中更改“rpath”吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13769141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can I change 'rpath' in an already compiled binary?
提问by Rich Homolka
I have an old executable that's scheduled for the scrap heap, but it's not there yet. It relies on some libs that have been removed from my environment, but I have some stub libs someplace where it works fine. Id like to point this executable to these stub libs. Yes, i could set LD_LIBRARY_PATH, but this executable is called from many scripts, and many users and I'd love to fix it in one spot.
我有一个计划用于废料堆的旧可执行文件,但它还没有。它依赖于一些已从我的环境中删除的库,但我有一些存根库可以正常工作。我想将此可执行文件指向这些存根库。是的,我可以设置 LD_LIBRARY_PATH,但是这个可执行文件是从许多脚本和许多用户中调用的,我很想在一个地方修复它。
I don't have source for this, and would be hard to get it. I was thinking - can I edit this file, using an ELF aware editor, and add a simple PATH to rpath to have it hit the new libs? Is this possible, or once you create an ELF binary, you fix things to locations and they can't be moved?
我没有这个来源,而且很难得到它。我在想 - 我可以编辑这个文件,使用 ELF 感知编辑器,并添加一个简单的 PATH 到 rpath 让它命中新的库吗?这可能吗,或者一旦你创建了一个 ELF 二进制文件,你将东西固定到位置并且它们不能移动?
采纳答案by TomH
There is a tool called chrpath
which can do this - it's probably available in your distribution's packages.
有一个名为的工具chrpath
可以执行此操作 - 它可能在您的发行版软件包中可用。
回答by user7610
There is a more universal tool than chrpath
called patchelf
. It was originally created for use in making packages for Nix and NixOS (packaging system and a GNU/Linux distribution).
有一种比chrpath
所谓的更通用的工具patchelf
。它最初创建用于为 Nix 和 NixOS(打包系统和 GNU/Linux 发行版)制作软件包。
In case there is no rpath in a binary (here called rdsamp), chrpath
fails:
如果二进制文件中没有 rpath(此处称为 rdsamp),则chrpath
失败:
chrpath -r '$ORIGIN/../lib64' rdsamp
rdsamp: no rpath or runpath tag found.
On the other hand,
另一方面,
patchelf --set-rpath '$ORIGIN/../lib64' rdsamp
succeeds just fine.
成功就好了。
回答by vikram kedlaya
This worked for me, replacing XORIGIN with $ORIGIN.
这对我有用,用 $ORIGIN 替换 XORIGIN。
chrpath -r '\$\ORIGIN/../lib64' httpd
chrpath -r '\$\ORIGIN/../lib64' httpd
回答by Daniel Trugman
Just like @user7610 said, the right way to go is the patchelf
tool.
正如@user7610 所说,正确的方法是使用patchelf
工具。
But, I feel that I can give a more comprehensive answer, covering all the commands one needs to do exactly that.
但是,我觉得我可以给出一个更全面的答案,涵盖一个人需要做的所有命令。
For a comprehensive article on the subject, click here
有关该主题的综合文章,请单击此处
First of all, many developers talk about RPATH
, but they actually mean RUNPATH
. These are two different optional dynamic sections, and the loader handles them very differently. You can read more about the difference between them in the link I mentioned before.
首先,很多开发者都在谈论RPATH
,但实际上他们的意思是RUNPATH
。这是两个不同的可选动态部分,加载程序处理它们的方式非常不同。您可以在我之前提到的链接中阅读有关它们之间差异的更多信息。
For now, just remember:
现在,请记住:
- If
RUNPATH
is set,RPATH
is ignored RPATH
is deprecated and should be avoidedRUNPATH
is preferred because it can be overridden byLD_LIBRARY_PATH
- 如果
RUNPATH
设置,RPATH
则忽略 RPATH
已弃用,应避免RUNPATH
是首选,因为它可以被覆盖LD_LIBRARY_PATH
See the current R[UN]PATH
查看当前的 R[UN]PATH
readelf -d <path-to-elf> | egrep "RPATH|RUNPATH"
Clear the R[UN]PATH
清除 R[UN]PATH
patchelf --remove-rpath <path-to-elf>
Notes:
笔记:
- Removes both
RPATH
andRUNPATH
- 删除
RPATH
和RUNPATH
Add values to R[UN]PATH
将值添加到 R[UN]PATH
patchelf [--force-rpath] --set-rpath "<desired-rpath>" <path-to-elf>
Notes:
笔记:
<desired-path>
is a comma separated directories list, e.g:/my/libs:/my/other/libs
- If you specify
--force-rpath
, setsRPATH
, otherwise setsRUNPATH
<desired-path>
是逗号分隔的目录列表,例如:/my/libs:/my/other/libs
- 如果指定
--force-rpath
,则设置RPATH
,否则设置RUNPATH