ld-linux.so以什么顺序搜索共享库?

时间:2010-09-01 09:02:35

标签: linux linker shared-libraries

当ld-linux解析符号时,它会按特定顺序搜索共享库,并在找到具有匹配符号的共享库时停止。

什么决定了它在图书馆中搜索的顺序?如果未解析的符号在主程序中或在另一个共享库中,它会有所不同吗?

如何在不调用外部程序(如ldd?

)的情况下以编程方式确定搜索顺序

3 个答案:

答案 0 :(得分:9)

来自http://www.muppetlabs.com/~breadbox/software/ELF.txt(如sarnold所述):

  

解析符号引用时,   动态链接器检查符号   具有广度优先搜索的表格。   也就是说,它首先查看符号   可执行程序的表   本身,然后在符号表   然后是DT_NEEDED条目(按顺序)   在第二级DT_NEEDED条目,   等等。

答案 1 :(得分:3)

本书http://www.network-theory.co.uk/docs/gccintro/gccintro_18.html建议在gcc命令行中给出从左到右的顺序。 (我很久以前就学会了将-lm作为图书馆列表中最后一个图书馆的链接,但我也早就忘记了这个库存原因。)

修改

啊哈,谢谢你的更新。你需要自己解析ELF;在http://www.muppetlabs.com/~breadbox/software/ELF.txt中查找“共享对象依赖关系”和“DT_RPATH”。 (我也推荐http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html,但它不太适用于你的问题 - 只是有趣的阅读。)

/usr/include/linux/elf.h包含所有typedef。

答案 2 :(得分:-1)

实际上链接顺序可以通过使用ldd来推断; 如果library1在library2之前位于链接器命令行中,那么ldd将在library2

之前显示library1

现在基于此我编写了一个简短的python脚本,以链接顺序显示共享库 - 它对ldd显示的所有依赖项进行了广度优先搜索(对于给定的可执行文件。

这是脚本

编辑:请注意脚本使用ldd,仍然可能有用; - )

#!/usr/bin/python

import subprocess
import sys
import re

visited_so = {}
ssplit = re.compile('\S+')
verbose = 0

def run_ldd( sopath ):
        ret = []

        pop = subprocess.Popen( [ 'ldd', sopath ], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
        [out, err] = pop.communicate()

        for l in out.splitlines():
            toks = ssplit.findall( l )
            if len(toks) > 3:
                ret.append( toks[2] )
        return ret

def load_order_bfs( pqueue ):
    while len(pqueue) != 0:
        nextexe = pqueue.pop(0)
        if verbose:
            print 'visit ' + nextexe

        if not nextexe in visited_so:
            print nextexe
            visited_so[ nextexe ] = 1

            dependents = run_ldd( nextexe )
            for sopath in dependents:
                    if not sopath in visited_so:
                        if verbose:
                            print '\tnext ' + sopath
                        pqueue.append( sopath )

if len( sys.argv ) == 1:
    print sys.argv[0] + """ <path>
shows dependents of executable in symbol search order;
does a breadth first search over the dependents of the executable
"""
    sys.exit(1)

load_order_bfs( [ sys.argv[1] ] )