2

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

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 中的立即整数操作数。


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

4

1 回答 1

1

如果你能澄清你到底想要达到什么目标会很好。

没有 64bit movq $imm64, %reg,因此您必须movabs改用。

但是还有XandP操作数修饰符可能有助于放弃 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吗?

如果是这样,这必须通过链接器(映射文件或链接器的命令行选项而不是编译器)来完成。

否则 ... movabslea和/或 / 的使用P可能X会满足您的需求。

于 2014-06-17T16:29:03.037 回答