【问题标题】:ELF Relocation - where came from these symbols?ELF 重定位 - 这些符号从何而来?
【发布时间】:2012-09-22 21:43:01
【问题描述】:

在我的 Debian x86 32 位中,当我执行 readelf -r /usr/lib/libstdc++.so.6 | grep pthread,我得到这个输出:

000eceac  00006206 R_386_GLOB_DAT    00000000   pthread_cancel
000ed058  00000807 R_386_JUMP_SLOT   00000000   pthread_cond_destroy
000ed148  00001207 R_386_JUMP_SLOT   00000000   pthread_cond_signal
000ed1e8  00001e07 R_386_JUMP_SLOT   00000000   pthread_key_create
000ed320  00002a07 R_386_JUMP_SLOT   00000000   pthread_once
000ed418  00003607 R_386_JUMP_SLOT   00000000   pthread_getspecific
000ed42c  00003a07 R_386_JUMP_SLOT   00000000   pthread_mutex_unlock
000ed4ec  00004607 R_386_JUMP_SLOT   00000000   pthread_create
000ed54c  00004b07 R_386_JUMP_SLOT   00000000   pthread_equal
000ed678  00005607 R_386_JUMP_SLOT   00000000   pthread_mutex_lock
000ed71c  00006007 R_386_JUMP_SLOT   00000000   pthread_cond_wait
000ed7b0  00006907 R_386_JUMP_SLOT   00000000   pthread_key_delete
000ed8b4  00007307 R_386_JUMP_SLOT   00000000   pthread_cond_broadcast
000ed8c0  00007507 R_386_JUMP_SLOT   00000000   pthread_detach
000ed8f0  00007a07 R_386_JUMP_SLOT   00000000   pthread_setspecific
000ed968  00007c07 R_386_JUMP_SLOT   00000000   pthread_join

但是,当我列出 /usr/lib/libstdc++.so.6 的依赖项时,libpthread 没有列出:

john@ThirdEarth:~$ ldd /usr/lib/libstdc++.so.6
linux-gate.so.1 =>  (0xb77df000)
libm.so.6 => /lib/i686/cmov/libm.so.6 (0xb76ad000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7566000)
/lib/ld-linux.so.2 (0xb77e0000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7547000)

那么动态加载器是如何解决这些依赖关系的呢?我发现了一个与 __gmon_start__ 类似的问题,粗略地说,这个符号的定义在哪里?

【问题讨论】:

  • 为什么这些定义没有出现在定义为依赖项的库中?

标签: linux gcc assembly ld binutils


【解决方案1】:

Linux 中的 pthread 函数是在 libc 中实现的。

例如,在我必须手头的系统上:

objdump -T /lib/libc-2.11.1.so | grep pthread

给予

00000000000f64a0 g    DF .text  0000000000000026  GLIBC_2.3.2 pthread_cond_signal
0000000000126100 g    DF .text  0000000000000026 (GLIBC_2.2.5) pthread_cond_signal
00000000000f6be0 g    DF .text  000000000000005a  GLIBC_PRIVATE __libc_pthread_init
00000000000f65f0 g    DF .text  0000000000000026  GLIBC_2.2.5 pthread_mutex_lock
00000000000f63e0 g    DF .text  0000000000000026  GLIBC_2.2.5 pthread_condattr_init
00000000000f6290 g    DF .text  0000000000000026  GLIBC_2.2.5 pthread_attr_getschedparam
...

【讨论】:

    【解决方案2】:

    要回答问题的第二部分,__gmon_start__ 是 C 运行时,并在构建可执行文件时使用 gprof(1) 风格的分析。

    在 Ubuntu GNU/Linux 上,相关定义见/usr/lib/gcrt1.o

    % nm /usr/lib/gcrt1.o| grep -C2 gmon_start
    00000000 R _IO_stdin_used
    00000000 D __data_start
    00000030 T __gmon_start__
             U __libc_csu_fini
             U __libc_csu_init
    

    对于正常的编译运行,/usr/lib/crti.o 提供“弱”定义:

    % nm /usr/lib/crti.o| grep -C2 gmon_start
              U _GLOBAL_OFFSET_TABLE_
              w __gmon_start__
     00000000 T _fini
     00000000 T _init
    

    【讨论】:

    • 为什么 /usr/lib/crti.o 在我执行 ldd 时没有列出?
    • /usr/lib/crti.o 是一个普通的可重定位对象,而不是一个可动态加载的对象。您可以研究cc -v 的输出,以了解该对象在链接时是如何使用的。
    • 确实如此。那么在编译时不应该解决任何依赖关系吗?您能否更具体地了解 cc -v,我系统中的输出显然不包含与 crti.o 相关的任何内容,可能与问题相关的唯一性是 --enable-threads=posix。跨度>
    猜你喜欢
    • 2010-09-24
    • 2020-12-09
    • 1970-01-01
    • 2015-07-22
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2013-05-26
    相关资源
    最近更新 更多