0

我正在尝试了解共享库。据我所知,共享库的基地址为零,因此它们可以在运行时加载到任何地址,因此变量在运行时或加载时被正确重定位。因此,在加载库之前,所有符号都被赋予了与库基数的一些偏移量。因此,我尝试调查一些现有的库并创建了一个库。但我发现了一些不同之处。对于 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。我认为这可能是预链接的情况,但我不确定,即使它是如何找到它是预链接的?非常感谢提前...

4

1 回答 1

1

objdump -D /lib64/libc.so.6

您正在反汇编不包含代码的部分。既然你(还)不明白你在做什么,那就坚持objdump -d吧——它会让你不那么困惑。

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

上述说法不正确:共享库的基地址可能为零,但并非必须如此。

为什么在 libc 或其他现有库(如 libpthread)的情况下,情况有所不同

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

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

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

于 2013-10-04T05:45:09.740 回答