-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Open
Labels
Description
Code:
#include <stdio.h>
#include <inttypes.h>
unsigned long SYMBOL = 0x000000000000002A;
__attribute__((noinline, used))
unsigned long read_symbol(void) {
unsigned long result = 0;
__asm__ __volatile__ (
"movq %[symbol]@GOTPCREL(%%rip), %%rax\n\t"
"movq (%%rax), %[result]"
: [result] "=r" (result)
: [symbol] "m" (SYMBOL)
: "rax"
);
return result;
}
int main(void) {
unsigned long result = read_symbol();
printf("Value of symbol: 0x%08" PRIx64 "\n", result);
return 0;
}
Compiler automatically adds (%rip), error:
<FILE>:10:9: error: unexpected token in argument list
10 | "movq %[symbol]@GOTPCREL(%%rip), %%rax\n\t"
| ^
<inline asm>:1:19: note: instantiated into assembly here
1 | movq SYMBOL(%rip)@GOTPCREL(%rip), %rax
| ^
1 error generated.
It is also not entirely clear how to specify the symbol; in some cases, "m" is sufficient, while in other cases, ":" is documented, but it does not work. This is a temporary solution:
__attribute__((noinline, used))
unsigned long read_symbol(void) {
unsigned long result = 0;
__asm__ __volatile__ (
"movq SYMBOL@GOTPCREL(%%rip), %%rax\n\t"
"movq (%%rax), %[result]"
: [result] "=r" (result)
:
: "rax"
);
return result;
}
But this version is difficult to manage; when you change the slot name, you also need to change ASM. This problem exists only for x86 (64) for i686, i386 - everything is fine! The compiler automatically expands %[symbol]
to %[symbol](%rip)
on the x86 (64) platform, which is true for all cases:
"movq %[symbol](%%rip), %[result]\n\t"
"leaq %[symbol](%%rip), %%rax\n\t"
"movq %[symbol]@GOTPCREL(%%rip), %%rax\n\t"