共享库中的地址分配

时间:2013-09-26 03:21:54

标签: gcc shared-libraries elf prelink

我正在尝试理解共享库。据我所知,共享库的基址为零,因此可以在运行时在任何地址加载它们,因此在运行时或加载时间内正确地重定位变量。因此,在加载库之前,所有符号都会从库的基础中获得一些偏移量。因此,我尝试调查一些现有的库,并创建了一个库。但我发现了一些差异。对于libc.so,我发现的是:

$ objdump -D /lib64/libc.so.6

    /lib64/libc.so.6:     file format elf64-x86-64


    Disassembly of section .note.gnu.build-id:

    0000003b47a00270 <.note.gnu.build-id>:
      3b47a00270:   04 00                   add    $0x0,%al
      3b47a00272:   00 00                   add    %al,(%rax)
      3b47a00274:   14 00                   adc    $0x0,%al
      3b47a00276:   00 00                   add    %al,(%rax)
      3b47a00278:   03 00                   add    (%rax),%eax
    [More contents...]

据我所知,精灵标题占用了一些空间。但即使这样,它也不会占用从0到0x3b47a00270的地址。 所以,我创建了自己的库(使用-fPIC和-shared标志),我看到了这个:

$ objdump -D ./libvector.so
./libvector.so:     file format elf64-x86-64


Disassembly of section .note.gnu.build-id:

00000000000001c8 <.note.gnu.build-id>:
 1c8:   04 00                   add    $0x0,%al
 1ca:   00 00                   add    %al,(%rax)
 1cc:   14 00                   adc    $0x0,%al
 1ce:   00 00                   add    %al,(%rax)
 1d0:   03 00                   add    (%rax),%eax
[More contents...]

这个地址在地址方面似乎更合理。 .note.gnu.build-id从0x1c8开始。所以,伙计们有任何想法,为什么在libc或libpthread等其他现有库的情况下,情况有所不同?我正在使用fedora 18 x86_64。我认为这可能是一个预连接的情况,但我不确定,即使它是如何发现它是预先链接的? 非常感谢...

1 个答案:

答案 0 :(得分:1)

  

objdump -D /lib64/libc.so.6

您正在反汇编不包含代码的部分。既然你还没有(还)理解你在做什么,那就坚持objdump -d - 这会让你更加困惑。

  

据我所知,共享库的基地址为零

上述陈述不正确:共享库可能的基址为零,但他们没有。

  

为什么在libc或libpthread等其他现有库的情况下,情况不同

因为这些库已预先链接。参见“man prelink”,例如here

您可以使用readelf -l更清楚地看到这一点。您想查看第一个VirtAddr细分的LOAD

如果是非预链接库,则该地址为0.如果是预链接libc.so.6,则为0x3b47a00000。另请注意,RedHat系统通常设置为每两周重新运行预链接,因此libc.so.6预先链接的地址可能会随时间而变化。