【发布时间】:2016-04-01 10:41:33
【问题描述】:
考虑以下函数:
extern void test1(void);
extern void test2(void) {
test1();
}
这是 gcc 在 amd64 Linux 上没有-fpic 时生成的代码:
test2:
jmp test1
当我使用 -fpic 编译时,gcc 通过 PLT 显式调用以启用符号插入:
test2:
jmp test1@PLT
但是,对于位置无关的代码,这并不是严格需要的,如果我不想支持,可以省略。如有必要,链接器无论如何都会将跳转目标重写为 PLT 符号。
如何在不更改源代码且不使编译后的代码不适用于共享库的情况下,使函数调用直接转到其目标而不是显式通过 PLT?
【问题讨论】:
-
你的意思是你的库/可执行文件中的调用?这应该是可能的,也许通过定义一个私人别名或其他东西。但是对于仅动态链接的库中函数的调用,我不确定运行时链接器能否解析此类引用。
-
@PeterCordes 如果没有
-fpic,链接器会在适当/需要时自动将对符号的引用重写为 PLT 引用。这就是我想要的行为,即编译器生成对所有函数的正常调用,而链接器重写调用到另一个共享对象的调用。 -
-fno-semantic-interposition做你想做的事吗?另见stackoverflow.com/questions/34102989/…。这个问题是不是其中任何一个问题的重复? -
@PeterCordes 似乎没有什么不同,但我记住了这个选项。
-
未来读者:另请参阅stackoverflow.com/questions/10849308/…,了解在跨共享对象边界调用时试图避免 PLT。 (例如从程序到库)。
标签: c gcc x86 position-independent-code plt