以下代码编译成一个没有问题的可执行文件:
static const char *foo = "bar";
void main(void)
{
__asm__ ("mov %0,%%rax"
:
: "i"(&foo)
: "%rax");
}
但作为共享库,我收到错误:
static const char *foo = "bar";
void zot(void)
{
__asm__ ("mov %0,%%rax"
:
: "i"(&foo)
: "%rax");
}
编制结果:
hacker@lab$ gcc -shared -o mini-lib mini-lib.c
/usr/bin/ld: /tmp/ccwume3d.o: relocation R_X86_64_32S against `.data'
can not be used when making a shared object; recompile with -fPIC
/tmp/ccwume3d.o: error adding symbols: Bad value
使用-fPIC
进行编译没有任何区别。如何以链接器将引用重定位到foo
的地址的方式调整此方法?它必须是asm中的直接整数操作数。
更新:我最终使用了一个带内存操作数的不同指令,因为显然没有办法用立即操作数来做这个。
答案 0 :(得分:0)
如果你能澄清你到底想要达到的目的,那将会很好。
没有64位movq $imm64, %reg
,因此您必须改为使用movabs
。
但也有X
and P
operand modifiers可能有助于放弃PLT参考/ PC相关地址;你可以写:
static void *foo;
[ ... ]
void *out[2];
asm("lea %P2, %0\n\t"
"movabs %X2, %1\n\t" : "=r"(out[0]), "=a"(out[1]) : "g"(foo));
所以问题是,你知道(或想明确指定)foo
的确切地址吗?
如果是这样,必须通过链接器(链接器的mapfiles或命令行选项,而不是编译器)来完成。
否则...... movabs
,lea
和/或使用P
/ X
可能会执行您正在寻找的内容。