【问题标题】:How linker resolves the symbol in assembly code链接器如何解析汇编代码中的符号
【发布时间】:2010-11-14 23:54:50
【问题描述】:

我想知道链接器如何解析以下汇编代码中的 printf 符号。

#include<stdio.h>
void main()
{
     printf("Hello ");
}




    .file   "test.c"
    .def    ___main;    .scl    2;  .type   32; .endef
    .section .rdata,"dr"
LC0:
    .ascii "Hello \0"
    .text
.globl _main
    .def    _main;  .scl    2;  .type   32; .endef
_main:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    andl    $-16, %esp
    movl    $0, %eax
    addl    $15, %eax
    addl    $15, %eax
    shrl    $4, %eax
    sall    $4, %eax
    movl    %eax, -4(%ebp)
    movl    -4(%ebp), %eax
    call    __alloca
    call    ___main
    movl    $LC0, (%esp)
    **call  _printf**
    leave
    ret
    .def    **_printf**;    .scl    3;  .type   32; .endef

我们将不胜感激。

提前致谢。

【问题讨论】:

  • 一个很好的问题没有被问到足够多,导致在 SO 上出现大量“未解决的符号”问题!

标签: c++ c assembly linker


【解决方案1】:

假设 ELF 文件格式,汇编器将在目标文件中生成一个未定义的符号引用。如下所示:

符号表 '.symtab' 包含 11 个条目: Num:值大小类型绑定 Vis Ndx 名称 0: 00000000 0 NOTYPE 本地默认值 1: 00000000 0 文件本地默认 ABS 测试.c 2: 00000000 0 部分本地默认值 1 3: 00000000 0 部分本地默认值 3 4: 00000000 0 部分本地默认值 4 5: 00000000 0 部分本地默认值 5 6: 00000000 0 部分本地默认值 6 7: 00000000 0 部分本地默认值 7 8: 00000000 52 FUNC 全局默认值 1 main 9: 00000000 0 NOTYPE 全局默认值和 printf 10: 00000000 0 NOTYPE GLOBAL DEFAULT UND 退出

它还将创建一个重定位条目,以指向需要由链接器使用正确地址更新的代码映像部分。它看起来像这样:

$ readelf -r test.o 偏移 0x358 处的重定位节“.rel.text”包含 3 个条目: 偏移信息类型 Sym.Value Sym。姓名 0000001f 00000501 R_386_32 00000000 .rodata 00000024 00000902 R_386_PC32 00000000 printf 00000030 00000a02 R_386_PC32 00000000 退出

然后,链接器的工作是遍历重定位表,用最终符号地址修复代码映像。

有一本很棒的书,但我现在找不到详细信息(而且已经绝版)。但是,这看起来可能有用:http://www.linuxjournal.com/article/6463

【讨论】:

  • 令人印象深刻的答案戴夫。描绘得很清楚。太感谢了。如果你能提醒自己并把那本书也给我的话,你会很高兴的:)
【解决方案2】:

有关链接过程的精彩书籍,请参阅 John Levine 的 Linkers & Loaders。您可以获取HTML格式的手稿章节here

【讨论】:

    【解决方案3】:

    关于链接器的另一个好资源是这一系列文章:http://www.google.fr/search?q=site%3Awww.airs.com%2Fblog%2Farchives+%22linkers+part%22

    【讨论】:

      【解决方案4】:

      Ulrich Drepper 的How To Write Shared Libraries 是一篇可能对您有所帮助的论文。 Ulritch 是 Linux glibc 的维护者,他是 ELF 的权威。

      尽管本文是关于如何编写共享库以及如何导出或不导出符号,但它解释了如何在 ELF 格式的 exefile 中动态解析这些符号。

      我想它可能会回答你的问题。

      【讨论】:

      • 谢谢你的链接:)。看起来不错。
      猜你喜欢
      • 2013-04-11
      • 2017-06-14
      • 2011-03-26
      • 1970-01-01
      • 2019-04-18
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      • 2010-09-05
      相关资源
      最近更新 更多