代码之家  ›  专栏  ›  技术社区  ›  Priyanka Mishra

链接器如何解析程序集代码中的符号

  •  8
  • Priyanka Mishra  · 技术社区  · 15 年前

    我想知道链接器如何解析以下程序集代码中的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
    

    一点低级的解释将受到高度赞赏。

    事先谢谢。

    4 回复  |  直到 15 年前
        1
  •  17
  •   DaveS    15 年前

    假设ELF文件格式,汇编程序将在对象文件中生成未定义的符号引用。这看起来像这样:

    Symbol table '.symtab' contains 11 entries:
       Num:    Value  Size Type    Bind   Vis      Ndx Name
         0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
         1: 00000000     0 FILE    LOCAL  DEFAULT  ABS test.c
         2: 00000000     0 SECTION LOCAL  DEFAULT    1
         3: 00000000     0 SECTION LOCAL  DEFAULT    3
         4: 00000000     0 SECTION LOCAL  DEFAULT    4
         5: 00000000     0 SECTION LOCAL  DEFAULT    5
         6: 00000000     0 SECTION LOCAL  DEFAULT    6
         7: 00000000     0 SECTION LOCAL  DEFAULT    7
         8: 00000000    52 FUNC    GLOBAL DEFAULT    1 main
         9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
        10: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND exit
    

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

    tool2 0>readelf -r test.o
    
    Relocation section '.rel.text' at offset 0x358 contains 3 entries:
     Offset     Info    Type            Sym.Value  Sym. Name
    0000001f  00000501 R_386_32          00000000   .rodata
    00000024  00000902 R_386_PC32        00000000   printf
    00000030  00000a02 R_386_PC32        00000000   exit
    

    然后,链接器的任务是遍历重新定位表,用最终符号地址修复代码图像。

    有本好书,但我现在找不到细节(而且已经绝版了)。但是,这看起来可能有用: http://www.linuxjournal.com/article/6463

    戴夫。

        2
  •  1
  •   anon    15 年前

    有关链接过程的好书,请参阅JohnLevine的Linkers&Loaders。你可以得到HTML格式的手稿章节 here .

        3
  •  1
  •   Bastien Léonard    15 年前
        4
  •  1
  •   javier-sanz    15 年前

    有助于你的论文是 How To Write Shared Libraries 乌尔里希·德雷珀。Ulritch是linux glibc的维护者,他是ELF的权威。

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

    我想它可以回答你的问题。