【问题标题】:how is ld-linux.so* itself linked and loaded?ld-linux.so* 本身是如何链接和加载的?
【发布时间】:2016-05-04 11:14:01
【问题描述】:

出于好奇,Linux 动态链接器/加载器ld-linux.so* 本身是如何链接和加载的?

  1. 上面的截图显示fileldd似乎给出了矛盾的结果:一个说静态链接,另一个说动态链接

  2. 那么loader本身是如何加载的呢?

【问题讨论】:

    标签: linux-kernel linker ld loader


    【解决方案1】:
    1. ld-linux.so* 不依赖于任何其他库。加载到内存后可自行运行。

    2. ldd是一个脚本,它通过loader加载object文件,loader检查object是动态链接还是静态链接,试试这个:

    LD_TRACE_LOADED_OBJECTS=1 /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2

    1. file 读取幻数或精灵头来判断对象是动态链接还是静态链接,它可能会输出与ldd 不同的值

    IMO,ld-linux.so 是静态链接的,因为它没有所有动态链接对象必须具有的 .interp 部分。

    【讨论】:

    • LD_TRACE_LOADED_OBJECTS=1 /lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 加载加载器本身并计算加载了多少对象?对了,一般来说,loader /lib64/ld-linux-x86-64.so.2 本身是如何进入内存的?
    • 内核加载加载器。
    • 和 loader 使用 open() 和 mmap() 调用
    【解决方案2】:

    @臧明杰

    你的回答对我帮助很大,但下面的话可能会让一些人感到困惑:

    IMO,ld-linux.so 是静态链接的,因为它没有所有动态链接对象必须具有的 .interp >部分。

    我们应该将“所有动态链接对象”分为两部分,我们称之为“共享对象”的一种是这样生成的:

    gcc -c -o test.o test.c -fPIC
    ld -o test.so test.o -shared
    

    另一种叫做“动态链接的可执行文件”:

    gcc -c -o test.o test.c -fPIC
    ld -o test.so test.o
    

    有两点很重要:

    1,共享对象没有'.iINTERP'段,而动态链接的可执行文件有。

    2,Linux内核不关心ELF文件是由elf头指示的EXEC还是DYN。他首先搜索.INTERP段,如果失败,他mmap()每个LOAD类型的段,并将控制权传递给eheader->e_entry,无论他是加载可执行文件还是共享对象。

    由于 ld-linux.so 是一个普通的共享对象,所以她没有 .INTERP 段也就不足为奇了。她可以作为可执行文件运行并不奇怪。每个共享对象都可以。

    这样写代码:

       void foobar(void){ while(1); }
    

    将它编译成一个共享对象(使用上面的命令行)。 运行它:

    gdb ./test.so
    

    您将让进程陷入死循环。 使用 Ctrl-C 中断它。你会看到(需要 gcc 的 -g 选项)

    Program received signal SIGINT, Interrupt.
    foobar (void) at test.c:1
    1       while(1);
    (gdb) 
    

    你可以走得更远:

    (gdb) p $eip
    $1 = (void (*)()) 0x80000183 <foobar+3>
    (gdb) 
    

    如果你熟悉linux内核,你应该知道0x80000000与内核变量'mmap_min_addr'的值有关。因为 test.so 是一个共享对象,所以她的加载地址为零,所以内核为她找到了一个默认的虚拟地址,即 0x80000000,而不是 0x804000。

    我不知道我是怎么跑题的……

    【讨论】:

    • 感谢您的解释!这不是那么离题。
    猜你喜欢
    • 2015-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 2013-01-29
    • 2013-09-13
    • 2015-10-20
    相关资源
    最近更新 更多