Support using const pointers in asm const operand by nbdd0121 · Pull Request #138618 · rust-lang/rust (original) (raw)

Looks like the i constraint doesn't work for GOT-rebased relocation

I've been playing around with this a bit, and I think the i operand works as long as using the symbol name would work. For example, this breaks:

#include <stdio.h>

static const int FORTY_TWO = 42;

int main(void) { const int *a;

__asm__ (
    "movabs %1, %0"
    : "=r" (a)
: "i" (&FORTY_TWO)
);

printf("%p\n", (void *)a);

return 0;

}

/usr/bin/ld: /tmp/ccptrDbi.o: warning: relocation in read-only section `.text'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE

But when we make it rip-relative, it works:

#include <stdio.h>

static const int FORTY_TWO = 42;

int main(void) { const int *a;

__asm__ (
    "movabs %1 - ., %0"
    : "=r" (a)
: "i" (&FORTY_TWO)
);

printf("%p\n", (void *)a);

return 0;

}

We can even force it to generate a GOT-entry with the address of FORTY_TWO and then look up the value through it:

#include <stdio.h>

static const int FORTY_TWO = 42;

int main(void) { const int **a;

__asm__ (
    "leaq (%c1)@GOTPCREL(%%rip), %0"
    : "=r" (a)
: "i" (&FORTY_TWO)
);

printf("%i\n", **a);

return 0;

}

This is exactly the same scenario as when writing FORTY_TWO would work as far as I can tell. Is there something I'm missing?