链接器如何解析汇编代码中的符号

问题描述:

我想知道链接器如何解析下面汇编代码中的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 

位低位说明将不胜感激。

在此先感谢。

+1

一个很好的问题没有被问到,并导致大量的“未解决符号”问题! – xtofl 2009-07-29 11:22:06

假设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

Dave。

+0

令人印象深刻的答案戴夫。非常清楚地划定。非常感谢。如果你能提醒你自己,并且让我阅读那本书,这对你来说会很棒:) – mahesh 2009-07-29 12:26:44

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

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

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

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

+0

谢谢你的链接:)。看起来不错。 – mahesh 2009-07-30 03:18:35

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