I have only seen this problem ono x86_64, cannot reproduce on i686.
Example code (a.c):
#include <stdio.h>
extern void my_asm_func(void);
asm(".text\n" \
"my_asm_func:\n" \
" mov 1234,%rax\n" \
" ret\n" \
".previous\n");
int my_c_func() { return 1; }
int main()
{
void *fred;
fred=(void *)my_asm_func;
printf("function = %p\n",fred);
fred=(void *)my_c_func;
printf("function = %p\n",fred);
return 0;
}
if this is compiled with the line:
gcc -c -g -o a.o a.c
The assemble code for the two "fred=" function pointer assignments are correct:
fred=(void *)my_asm_func;
1c: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp)
23: 00
fred=(void *)my_c_func;
37: 48 c7 45 f8 00 00 00 movq $0x0,-0x8(%rbp)
3e: 00
Values will be fixed up at link time:
gcc -g -o a a.o
Giving:
fred=(void *)my_asm_func;
400528: 48 c7 45 f8 0c 05 40 movq $0x40050c,-0x8(%rbp)
40052f: 00
fred=(void *)my_c_func;
400543: 48 c7 45 f8 15 05 40 movq $0x400515,-0x8(%rbp)
40054a: 00
as expected. However, when used with -fPIC:
gcc -fPIC -c -g -o a.o a.c
we get :
fred=(void *)my_asm_func;
1c: 48 8b 05 dd ff ff ff mov -0x23(%rip),%rax # 0
<my_asm_func>
23: 48 89 45 f8 mov %rax,-0x8(%rbp)
fred=(void *)my_c_func;
3c: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # 43 <main+0x2f>
43: 48 89 45 f8 mov %rax,-0x8(%rbp)
For some reason the asm function point has already been fixed up with a value,
which is actually the location the of the function, but it will move the value
at that address into rax, not the address itself. Linking with:
gcc -fPIC -g -o a a.o
gives:
fred=(void *)my_asm_func;
400568: 48 8b 05 dd ff ff ff mov -0x23(%rip),%rax # 40054c
<my_asm_func>
40056f: 48 89 45 f8 mov %rax,-0x8(%rbp)
fred=(void *)my_c_func;
400588: 48 8b 05 51 0a 20 00 mov 0x200a51(%rip),%rax #
600fe0 <_DYNAMIC+0x1a8>
40058f: 48 89 45 f8 mov %rax,-0x8(%rbp)
showing that the c function has correctly been fixed up, the asm one is still
incorrect.
I have reproduced this problem on gcc 4.3.2 and 4.4.1. I have only given
objdump -S output for the relevant sections of code. If you require more
information please please let me know.
This problem was actually found while compiling valgrind for a 64 bit x86
target machine.
--
Summary: incorrect code generated with asm function pointers when
compiled with -fPIC on x84_64
Product: gcc
Version: 4.4.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: inline-asm
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: scott dot gccbugs dot 2009 at scottrix dot co dot uk
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41422