I'm confused as to when a function appears in the .plt section.
I was trying to print the address of printf
from inside the code (not by objdump
) and I stumbled upon this problem. I wanted to "follow" printf
through .plt and .got in C and with gdb.
The source for this experiment is the following (it's not "nice", but it is enough to show what I'm trying to do):
int main(int argc, char *argv[]) {
printf("Warm up\n");
// int (*plt)(const char *format, ...) = printf;
int *plt = argv;
long got = *((int*)plt);
printf("plt 0x%016lx\n", plt);
printf("got 0x%016lx\n", got);
return 0;
}
objdump
gives as expected printf
in the .plt:
$ objdump -d -j .plt ./a.out
./a.out: file format elf64-x86-64
Disassembly of section .plt:
0000000000000540 <.plt>:
540: ff 35 72 0a 20 00 pushq 0x200a72(%rip) # 200fb8 <_GLOBAL_OFFSET_TABLE_+0x8>
546: ff 25 74 0a 20 00 jmpq *0x200a74(%rip) # 200fc0 <_GLOBAL_OFFSET_TABLE_+0x10>
54c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000000550 <puts@plt>:
550: ff 25 72 0a 20 00 jmpq *0x200a72(%rip) # 200fc8 <puts@GLIBC_2.2.5>
556: 68 00 00 00 00 pushq $0x0
55b: e9 e0 ff ff ff jmpq 540 <.plt>
0000000000000560 <printf@plt>:
560: ff 25 6a 0a 20 00 jmpq *0x200a6a(%rip) # 200fd0 <printf@GLIBC_2.2.5>
566: 68 01 00 00 00 pushq $0x1
56b: e9 d0 ff ff ff jmpq 540 <.plt>
Now instead of int *plt = argv;
I use (the line commented out above):
int (*plt)(const char *format, ...) = printf;
Now objdump
gives:
$ objdump -d -j .plt ./a.out
./a.out: file format elf64-x86-64
Disassembly of section .plt:
0000000000000540 <.plt>:
540: ff 35 72 0a 20 00 pushq 0x200a72(%rip) # 200fb8 <_GLOBAL_OFFSET_TABLE_+0x8>
546: ff 25 74 0a 20 00 jmpq *0x200a74(%rip) # 200fc0 <_GLOBAL_OFFSET_TABLE_+0x10>
54c: 0f 1f 40 00 nopl 0x0(%rax)
0000000000000550 <puts@plt>:
550: ff 25 72 0a 20 00 jmpq *0x200a72(%rip) # 200fc8 <puts@GLIBC_2.2.5>
556: 68 00 00 00 00 pushq $0x0
55b: e9 e0 ff ff ff jmpq 540 <.plt>
Where is printf
? Why is it not in the .plt anymore?