起始地址对动态库意味着什么?

时间:2018-01-31 07:06:53

标签: dynamic shared-libraries

我刚刚发现共享库也有start address

objdump -f /usr/lib/libTH.so

/usr/lib/libTH.so:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000026e60

很清楚它对可执行文件意味着什么,但它对于共享对象是什么意思?

1 个答案:

答案 0 :(得分:1)

就像在程序中一样,共享库的起始地址(a.k.a 入口点地址)就是简单的 .text段的起始地址,包含所有可执行文件 代码。

这是一个玩具共享库也说明了:

<强> foo.c的

#include <stdio.h>

void foo(void)
{
    printf(__func__);
}

编译和链接:

$ gcc -Wall -Wextra -fPIC -c foo.c
$ gcc -shared -o libfoo.so foo.o -Wl,-Map=libfoo.map

让我们看看它的起始地址:

$ objdump -f libfoo.so 

libfoo.so:     file format elf64-x86-64
architecture: i386:x86-64, flags 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
start address 0x0000000000000530

当我们链接SO时,我们请求了一个链接器映射文件libfoo.map。这里的 该地图文件中的.text部分:

.text           0x0000000000000530       0xf2
 *(.text.unlikely .text.*_unlikely .text.unlikely.*)
 *(.text.exit .text.exit.*)
 *(.text.startup .text.startup.*)
 *(.text.hot .text.hot.*)
 *(.text .stub .text.* .gnu.linkonce.t.*)
 .text          0x0000000000000530        0x0 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o
 .text          0x0000000000000530       0xda /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
 .text          0x000000000000060a       0x18 foo.o
                0x000000000000060a                foo
 .text          0x0000000000000622        0x0 /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
 .text          0x0000000000000622        0x0 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o
 *(.gnu.warning)

根据objdump,它从地址0x530开始。它的长度为0xf2字节。从五 链接器加载的文件:

 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crti.o
 /usr/lib/gcc/x86_64-linux-gnu/7/crtbeginS.o
 foo.o
 /usr/lib/gcc/x86_64-linux-gnu/7/crtendS.o
 /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/crtn.o

.text的输入crti.o部分为空,贡献了0个字节。 然后crtbeginS.o贡献了0xda字节,但没有符号。然后foo.o 在地址0x60a处提供0x18字节,包括符号foo。然后 crtendS.ocrtn.o各占0个字节。 0xda + 0x18 = 0xf2。 (该 具有空.text部分的文件将有所贡献 其他输出部分,未显示)。

因此,在库的起始地址,我们找到代码crtbeginS.o, 这是C运行时初始化代码 - 共享库版本 - 用于查找全局构造函数(即任何C ++的构造函数) 全局对象或C函数合格 与__attribute((constructor)))。请参阅this question and answer

总之,共享库的起始地址进入该库的贡献 到动态链接的程序的运行时初始化。