I wrote the following sample code. But it generates "near, absolute indirect, address given in r/m32" (as given at [1]) variant of the call instruction which fails with a segmentation fault since the address is interpreted as an absolute one. Is there any way for generating PC relative call with GCC inline assembly? By the way the code correctly calculates the relative distance so there is no issue with that.
#include <stdio.h>
void print_fn() {
printf("Hello there..\n");
}
int main() {
long relative = (long) ((unsigned char*)&&label - (unsigned char*)print_fn);
__asm__ volatile ("call *%0;"
:
: "r"(relative)
);
label:
;
return 0;
}
The disassembler output is as follows.
Dump of assembler code for function main:
0x00000000004004d4 <+0>: 55 push %rbp
0x00000000004004d5 <+1>: 48 89 e5 mov %rsp,%rbp
0x00000000004004d8 <+4>: ba f5 04 40 00 mov $0x4004f5,%edx
0x00000000004004dd <+9>: b8 c4 04 40 00 mov $0x4004c4,%eax
0x00000000004004e2 <+14>: 48 89 d1 mov %rdx,%rcx
0x00000000004004e5 <+17>: 48 29 c1 sub %rax,%rcx
0x00000000004004e8 <+20>: 48 89 c8 mov %rcx,%rax
0x00000000004004eb <+23>: 48 89 45 f8 mov %rax,-0x8(%rbp)
0x00000000004004ef <+27>: 48 8b 45 f8 mov -0x8(%rbp),%rax
0x00000000004004f3 <+31>: ff d0 callq *%rax
0x00000000004004f5 <+33>: b8 00 00 00 00 mov $0x0,%eax
0x00000000004004fa <+38>: c9 leaveq
0x00000000004004fb <+39>: c3 retq
[1] http://x86.renejeschke.de/html/file_module_x86_id_26.html