Recetly, this function rip_rel_ptr has been added to Linux kernel.
https://elixir.bootlin.com/linux/latest/source/arch/x86/include/asm/asm.h#L118.
I can compile the kernel, but when I copy this function for myself,
static inline
__attribute__((__always_inline__))
__attribute__((__pure__)) void *rip_rel_ptr(void *var)
{
asm("leaq %c1(%%rip), %0" : "=r"(var) : "i"(var));
return var;
}
#define RIP_REL_REF(var) (*(typeof(&(var)))rip_rel_ptr(&(var)))
int x;
int main(void)
{
RIP_REL_REF(x);
return 0;
}
I see this error:
a.c: In function ‘main’:
a.c:8:2: warning: ‘asm’ operand 1 probably does not match constraints
8 | asm("leaq %c1(%%rip), %0" : "=r"(var) : "i"(var));
| ^~~
a.c:8:2: error: impossible constraint in ‘asm’
I can not figure out why it compiles in the kernel on the same machine but can not compile it separately.
-mcmodel=kernel; user-space programs are compiled with-fPIE(by default). I'm not sure if kernel builds also use-fPIE, but probably yes because kernel ASLR is a thing..text. I'd expect that to work with a global orstaticvariable whose address can be obtained with a RIP-relative LEA.-O1optimizations and a global variable.void *varto theasmstatement.always_inlinedoesn't stop function parameters from being actual variables which (in debug mode) actually exist with their own address. (Why is this C++ wrapper class not being inlined away? - inlined yes, away no)