链接器如何解析汇编代码中的符号
我想知道链接器如何解析下面汇编代码中的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
位低位说明将不胜感激。
在此先感谢。
假设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。
令人印象深刻的答案戴夫。非常清楚地划定。非常感谢。如果你能提醒你自己,并且让我阅读那本书,这对你来说会很棒:) – mahesh 2009-07-29 12:26:44
一篇可能对你有帮助的论文是Ulrich Drepper的How To Write Shared Libraries。 Ulritch是Linux glibc的维护者,他是ELF的权威人士。
尽管本文讨论如何编写共享库以及如何导出或不导出符号,它解释了如何在ELF格式的exe文件中动态解析这些符号。
我想它可能会回答你的问题。
谢谢你的链接:)。看起来不错。 – mahesh 2009-07-30 03:18:35
连接器上的另一个很好的资源是这个系列的文章:http://www.google.fr/search?q=site%3Awww.airs.com%2Fblog%2Farchives+%22linkers+part%22。
一个很好的问题没有被问到,并导致大量的“未解决符号”问题! – xtofl 2009-07-29 11:22:06