Type casts in C and type safety-Collection of common programming errors
@Soroush, here’s an example that might help you better understand what’s going on behind the scenes:
#include
int main(void)
{
printf("begin\n");
printf("loop\n");
// declare a function pointer
int (*loopPtr)();
// set the function pointer to the current function
loopPtr = main;
// skip over the first printf();
loopPtr += 22;
// call the new location
loopPtr();
}
For me, it works on x86_64 when compiled with clang -O0
(well, it works until the stack is exhausted since this is infinite recursion and each function call chews through stack space).
I determined the offset 22 by compiling, then disassembling and subtracting the address of the start of main()
from the address of the second printf()
.
First, I compiled it:
clang -O0 test.c
Then disassembled it:
otool -tv a.out
…which produced this output:
[...]
_main:
0000000100000ee0 pushq %rbp
0000000100000ee1 movq %rsp,%rbp
0000000100000ee4 subq $0x20,%rsp
0000000100000ee8 leaq 0x00000073(%rip),%rdi
0000000100000eef movb $0x00,%al
0000000100000ef1 callq 0x100000f40
0000000100000ef6 leaq 0x0000006c(%rip),%rdi
0000000100000efd movl %eax,0xf4(%rbp)
0000000100000f00 movb $0x00,%al
0000000100000f02 callq 0x100000f40
[...]
_main:
indicates the entrypoint of the main()
function, whose first address is 0x100000ee0. The first callq
instruction corresponds with the first printf()
call, which I want to skip, so I chose the address just after that: 0x100000ef6. 0x100000ef6 minus 0x100000ee0 is 22 decimal.
Originally posted 2013-11-09 23:34:32.