我正在编译一个静态库,它利用了一些内联汇编代码。
我注意到当我为jmp
指令使用标签时:
int foo(){
asm volatile
(
"mov 0x60(%r8),%r11d\n\t"
"jmp *S_401a70\n\t"
...
"S_401a70: xor %rax, %rax\n\t"
...
)
}
并使用以下标志将代码编译到静态库中:
-Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SOME_LIBRARY_PATH) \
-Wl,--whole-archive -l$(SOME_Library_Name) -Wl,--no-whole-archive \
-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
-Wl,-pie,-eenclave_entry -Wl,--export-dynamic \
-Wl,--defsym,__ImageBase=0
我会遇到一些错误:
/usr/bin/ld: Enclave/libtest.o: relocation R_X86_64_32S against `.text' can not be used when making a shared object; recompile with -fPIC
但是,由于我正在编译成静态库,我认为-fPIC
没有意义。我试过了,但它根本不起作用。
这似乎是gcc assembly extension
的一个问题,但我不确定。任何人都可以对此有所了解吗?谢谢!
答案 0 :(得分:1)
这不是工具问题。首先,-fPIC
仅影响C代码。并以这样的方式影响它:生成的代码不包含引用数据/代码的绝对地址,并且不依赖于它自己在内存中的地址(这是一个有点简化的解释)。接下来 - 它与汇编内联无关。因为这里代码是由程序员生成的。如果它是以引入绝对地址的方式编写的,或者是某些引入依赖于其内存位置的东西 - 编译器无法帮助它。
P.S。您可以使用依赖于位置的代码构建静态库,但是如果有人尝试将其链接到共享库,则链接器将不会接受它,因为生成的共享库应该与位置无关。