I want to know, how the linker determines that printf is called @ 0xd1: If I look into the symbol table for the address of _printf I see it's 0x0, because this function is not already relocated. But how does the linker and objdump know that at address 1e relocation should be done? Objdump says DISP32 _printf, but I can't find an entry in the objfile that says at address 1e relocation should be done.
objdump -d -r -t test.obj
Output:
test.obj: file format pe-i386
SYMBOL TABLE:
[ 0](sec -2)(fl 0x00)(ty 0)(scl 103) (nx 1) 0x00000000 test.c
File
[ 2](sec 1)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 _main
[ 3](sec 1)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .text
AUX scnlen 0x29 nreloc 3 nlnno 0
[ 5](sec 2)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .data
AUX scnlen 0x0 nreloc 0 nlnno 0
[ 7](sec 3)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .bss
AUX scnlen 0x0 nreloc 0 nlnno 0
[ 9](sec 4)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .rdata
AUX scnlen 0x3 nreloc 0 nlnno 0
[ 11](sec 5)(fl 0x00)(ty 0)(scl 3) (nx 1) 0x00000000 .eh_frame
AUX scnlen 0x38 nreloc 1 nlnno 0
[ 13](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 1) 0x00000000 ___main
AUX tagndx 0 ttlsiz 0x0 lnnos 0 next 0
[ 15](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 _printf
Disassembly of section .text:
00000000 <_main>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: 83 e4 f0 and $0xfffffff0,%esp
6: 83 ec 10 sub $0x10,%esp
9: e8 00 00 00 00 call e <_main+0xe>
a: DISP32 ___main
e: c7 44 24 04 05 00 00 movl $0x5,0x4(%esp)
15: 00
16: c7 04 24 00 00 00 00 movl $0x0,(%esp)
19: dir32 .rdata
1d: e8 00 00 00 00 call 22 <_main+0x22>
1e: DISP32 _printf
22: b8 00 00 00 00 mov $0x0,%eax
27: c9 leave
28: c3 ret
29: 90 nop
2a: 90 nop
2b: 90 nop
After I studied the PE / COFF - Format and looked into the OBJ-Code I've found a table for the relocation entries:
@ 0x16C is the entry for _printf. 0x1E is the address of the address part of the call instruction. The linker inserts the relocated symbol at this position. It's a 32 Bit Word. At 0x174 you find the type of the relocation. The type id is 14 and says the linker should replace this part with the relative address of printf: