【问题标题】:What does start address mean for dynamic library?动态库的起始地址是什么意思?
【发布时间】:2018-01-31 07:06:53
【问题描述】:

我刚刚发现共享库也有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

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

【问题讨论】:

    标签: dynamic shared-libraries


    【解决方案1】:

    就像在程序中一样,共享库的起始地址(也称为 入口点地址)很简单 .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
    

    crti.o 的输入 .text 部分为空并贡献了 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

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

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      • 2013-04-12
      • 2020-07-19
      • 2015-12-05
      • 1970-01-01
      • 2021-03-24
      相关资源
      最近更新 更多