Linux 什么';动态库搜索ld的规则是什么?
Linux将链接器时搜索路径和运行时搜索路径分开 对于运行时搜索路径,我在其Linux 什么';动态库搜索ld的规则是什么?,linux,gcc,linker,ld,Linux,Gcc,Linker,Ld,Linux将链接器时搜索路径和运行时搜索路径分开 对于运行时搜索路径,我在其 DT_RPATH 环境LD_库_路径 DT_运行路径 ld.so.cache /lib,/usr/lib 但是对于链接器时间搜索路径,ld:( 除了-L选项外,还表示: 搜索的默认路径集(未使用-L指定)取决于ld使用的仿真模式,在某些情况下还取决于其配置方式 还可以使用“SEARCH\u DIR”命令在链接脚本中指定路径。以这种方式指定的目录将在链接器脚本出现在命令行中的位置进行搜索 取决于仿真模式的“默认路径集”是
ld
:(
除了-L
选项外,还表示:
搜索的默认路径集(未使用-L
指定)取决于ld使用的仿真模式,在某些情况下还取决于其配置方式
还可以使用“SEARCH\u DIR
”命令在链接脚本中指定路径。以这种方式指定的目录将在链接器脚本出现在命令行中的位置进行搜索
取决于仿真模式的“默认路径集”是否意味着“
SEARCH\u DIR
”?说到ld
本身,库路径搜索顺序如下:
-L
命令行标志指定的目录库路径中的目录
环境变量SEARCH\u DIR
链接器脚本中的变量ld--verbose | grep SEARCH_DIR
可以查看默认链接器脚本中指定的目录。请注意,SEARCH_DIR
中的=
值将被指定的--sysroot
选项的值替换
通常不会直接调用
ld
,而是通过编译器驱动程序将多个-L
选项传递给链接器。在gcc
或clang
的情况下,您可以通过调用-print search dirs
选项来打印编译器添加的附加库搜索目录。还请注意,如果指定一些特定于机器的编译器标志(如前面提到的-m32)然后,链接器可以根据所选的ELF仿真使用不同的链接器脚本。在gcc
的情况下,您可以使用-dumpspecs
选项查看不同的编译器标志如何影响链接器调用。但是,查找链接器命令行的最简单方法是编译一个简单的程序并将其链接到-v,要查找特定ELF仿真的链接器搜索路径,只需运行ld-m--verbose | grep search_DIRmisssprite,在binutils的ld链接器中不搜索ld.so
或ld linux.so
当使用gcc构建动态程序时,它使用ld(collect2)程序的选项-dynamic linker
:
-Ifile
,-动态链接器=文件
Set the name of the dynamic linker. This is only meaningful when
generating dynamically linked ELF executables. The default
dynamic linker is normally correct; don't use this unless you
know what you are doing.")
通常用作ELF的运行时加载程序,“ld linux.so”在动态ELF文件中注册为解释器,程序头INTERP
(.INTERP
),检查输出readelf-l./dynamic_应用程序
。据我所知,此字段用于完整路径
当没有gcc(直接称为'ld'程序)或没有提供此选项时,ld
使用ld的完整路径的硬编码字符串。因此
;此默认值对于大多数操作系统(包括Linux)是不正确的:
模板
常量目标::目标\u信息目标\u x86\u 64::x86\u 64\u信息=
...
“/lib/ld64.so.1”,//程序解释器
常量目标::目标\u信息目标\u x86\u 64::x86\u 64\u信息=
...
“/libx32/ldx32.so.1”,//程序解释器
正确的动态链接器/加载程序路径是在gcc机器中硬编码的,gcc-dumpspecs
ld-linux命令的grep输出用于-dynamic linker
选项值。LIBRARY\u路径对我不起作用。我编辑了这个问题来澄清这个问题。你能更新对这两个问题的响应吗?顺便说一下,我没有提到-m32
。似乎另一个伙伴删除了他的答案。@misssprite,您试图用LIBRARY\u PATH修改的确切命令是什么?我在binutils中的ld sources中没有看到LIBRARY\u PATH的读取:ldfile\u add\u LIBRARY\u PATH
中填充了链接器脚本()的SEARCH\u DIR选项和ld-L options
@osgx,该命令应该是OK的,导出库路径=:$LIBRARY\u路径
。因此src代码还指示库路径不生效。@osgx,我运行ld hello.o-ltest-L.
和ld hello.o-ltest
,并设置了LIRARY\u路径。前者在pwd中找到了libtest.So
,而后者没有。@osgx,是的,它是ubuntu gnu ld。正如你之前所说,LIBRARY\u PATH
没有出现在ld源代码中,它不应该生效。这是有意义的。misssprite,什么是“ld”?是“ld.so”,还是“ld linux.so”或“libdl.so”?(ELF动态链接器/加载程序)在动态ELF文件的第…节中注册为解释器,请检查readelf-l./dynamic_应用程序
.PS您使用了哪个手册页,是它还是其他?我指的是GCC中的链接器
,而不是加载程序。我会编辑它。@OSGxmissprite,您对手册页1 ld的理解不正确,DT_RPATH和其他用于搜索ng动态库(它们被命名为libSOMETHING.so
likelibc.so
),是应用程序所需的,带有动态部分所需的条目(检查readelf-d./dynamic\u程序的输出
)。没有名为ld.so
的动态库。我知道ld.so
是加载程序,而不是.so库。也许您可以帮助我编辑问题以修复任何令人困惑的地方。@osgxdynamic库由动态加载程序ld-linux搜索(在运行时)。如您在问题中所述。以及ld-linux.so路径(在编译+链接过程结束时)在binutils链接器ld
(错误)和gcc(正确,请检查gcc-dumpspecs | grep动态链接器
)中进行硬编码,并从gcc传递到ld(检查我的答案)。规范和ld.so路径在gcc源代码中进行硬编码:&在gcc/confi中
/* The name of the dynamic interpreter. This is put in the .interp
section. */
#define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
#define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"
template<>
const Target::Target_info Target_x86_64<64>::x86_64_info =
...
"/lib/ld64.so.1", // program interpreter
const Target::Target_info Target_x86_64<32>::x86_64_info =
...
"/libx32/ldx32.so.1", // program interpreter