I wanted to know how linker resolves the printf symbol in the following assembly code.
#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
Bit of Low Level Explanation will be highly appreciated.
Thanks in advance.
Assuming ELF file format, the assembler will generate an undefined symbol reference in the object file. This’ll look like this:
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 exitIt’ll also create a relocation entry to point to the part of the code image that needs to be updated by the linker with the correct address. It’ll look like this:
The linker’s job is then to walk through the relocation table fixing up the code image with the final symbol addresses.
There’s an excellent book, but I can’t find the details right now (and it’s out of print). However, this looks like it may be useful: http://www.linuxjournal.com/article/6463