动态库搜索ld的规则是什么?

时间:2017-03-15 11:45:27

标签: linux gcc linker ld

Linux将链接器时间搜索路径和运行时搜索路径分开。

对于运行时搜索路径,我在其man page (8 ld.so)中找到了{ "result": [ { "number": "1234", "short_description": "TEST", "priority": "4 - Low", "caller_id": "Some, User" }, { "number": "12345", "short_description": "TEST 2", "priority": "4 - Low", "caller_id": "Some, User2" } ] } 的规则:

  1. DT_RPATH
  2. environment LD_LIBRARY_PATH
  3. DT_RUNPATH
  4. ld.so.cache
  5. / lib,/ usr / lib
  6. 但是对于链接器时间搜索路径,ld.so没有运气:(

    Man page for ld (1 ld)说,除了ld选项:

      

    搜索到的默认路径集(未指定-L)取决于ld正在使用的仿真模式,在某些情况下还取决于它的配置方式。

         

    也可以使用“-L”命令在链接脚本中指定路径。在链接描述文件出现在命令行中的位置搜索以这种方式指定的目录。

    取决于仿真模式的“默认路径集”是否意味着“SEARCH_DIR”?

3 个答案:

答案 0 :(得分:0)

说到ld本身,库路径搜索顺序如下:

  1. 通过-L命令行标志指定的目录
  2. LIBRARY_PATH环境变量
  3. 中的目录 链接器脚本中的
  4. SEARCH_DIR变量。
  5. 您可以通过运行ld --verbose | grep SEARCH_DIR来查看默认链接描述文件中指定的目录。请注意,=值中的SEARCH_DIR如果您指定,则会被--sysroot选项的值替换。

    通常不直接调用ld,而是通过编译器驱动程序调用,该驱动程序将多个-L选项传递给链接器。对于gccclang,您可以通过使用-print-search-dirs选项调用编译器添加的其他库搜索目录。另请注意,如果您指定某些特定于机器的编译器标志(例如,如提到的misssprite,例如-m32),则链接器可根据所选的ELF仿真使用不同的链接描述文件。在gcc的情况下,您可以使用-dumpspecs选项查看不同的编译器标志如何影响链接器调用。但IMHO寻找链接器命令行的最简单方法是编译并链接一个指定了-v的简单程序。

答案 1 :(得分:0)

misssprite,要查找特定ELF仿真的链接器搜索路径,只需运行ld -m<emulation> --verbose | grep SEARCH_DIR

答案 2 :(得分:0)

misssprite,在binutils的ld链接器中没有搜索ld.sold-linux.so

使用gcc构建动态程序时,它使用ld(collect2)程序的-dynamic-linker选项:http://man7.org/linux/man-pages/man1/ld.1.html

  

-Ifile--dynamic-linker=file

  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),检查输出{{1} }。正如我所理解的那样,这个字段用于完整路径。

当没有gcc(直接称为'ld'程序)或没有给出此选项时,readelf -l ./dynamic_application使用硬编码的完整路径字符串ld;对于大多数操作系统,此默认设置不正确,包括Linux:

https://github.com/bneumeier/binutils/blob/db980de65ca9f296aae8db4d13ee884f0c18ac8a/bfd/elf64-x86-64.c#L510

ld.so

https://github.com/bneumeier/binutils/blob/db980de65ca9f296aae8db4d13ee884f0c18ac8a/gold/x86_64.cc#L816

/* 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"

正确的动态链接器/加载器路径在gcc的机器spec files中硬编码,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 命令的grep输出用于gcc -dumpspecs选项值的ld-linux。