GCC内联asm:如何在共享库中使用变量地址作为立即操作数?

时间:2014-06-12 20:51:40

标签: gcc inline-assembly relocation

以下代码编译成一个没有问题的可执行文件:

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中的直接整数操作数。


更新:我最终使用了一个带内存操作数的不同指令,因为显然没有办法用立即操作数来做这个。

1 个答案:

答案 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或命令行选项,而不是编译器)来完成。

否则...... movabslea和/或使用P / X可能会执行您正在寻找的内容。

相关问题