出于某些原因,我想在PLT部分强制一些条目。我已经成功地完成了一些条目,但是有些函数从来没有插入到PLT中。
所以,让我们说我有main.c
int main(){
// some code
strcmp(a,b); //suppose a, b strings
// more code
// suppose that result of strcmp is used, so it won't be optimised away
}和help.c
// declaration
void forceplt() __attribute__((__used__));
// definition
void forceplt(){
abs(-1);
__aeabi_dadd(0, 0);
}然后,我编译并将上述两个可重定位对象链接到一个可执行对象中。为了确保abs和dadd函数保留在PLT部分,我使用-O0编译helper.o。main.o可以用更高的级别编译,比如‘-O1’。
在可执行对象上,我希望看到所有三个函数的条目:strcmp、abs和dadd。然而,情况并非如此。
我是不是漏掉了什么?有没有可能链接器忽略了一些东西,因为它发现它们从来没有被调用过?尽管使用O0作为助手,并使用属性作为forceplt函数?
帮我好好庆祝一下。十。百万美元。问题!
干杯!
发布于 2015-08-20 20:35:13
abs和strcmp是GCC特别认可的,编译器认为即使在-O0中,这些调用也是无用的。如果查看生成程序集(gcc foo.c -S -o-),就会发现没有相应的调用指令。
PLT条目不是由编译器生成的:它们不存在于.o文件中。当它们在一个输入.o文件中找到相应的重新定位时,它们将由链接编辑器生成。为了生成一个PLT条目,您需要在一个输入.o文件中生成一个合适的重新定位条目。.o重定位总是应用于.o文件的一部分:您需要在某些.o的某个部分中有一些内存字节,这样就可以使用PLT感知的重新定位来重新定位。它可以是(可能无用的)指令,也可以是其他字节(可能无用)。
一个解决方案是创建(在程序集中)指令,这些指令显式地使用预期的PLT条目。使用x86_64,这可以通过以下方法来完成:
.text
.type forceplt2,@function
forceplt2:
callq abs@plt我想这是用手臂写的:
.text
.type forceplt2,%function
forceplt2:
bl abs@plt也可以为重新定位生成原始字节(再次在x86_64上):
.data
.align 8
.type forceplt3, @object
.size forceplt3, 8
forceplt3:
.quad socket@GOTPLT64,您应该能够使用@GOT、@GOTPLT、@GOTOFF、@GOTPCREL、@PLT或@PLTOFF。我不太确定这是怎么写的,臂用。
这些解决方案中的任何一个都会发出一个合适的重新定位条目,这将导致链接编辑器发出一个PLT条目和一个PLT GOT条目。
https://stackoverflow.com/questions/32127528
复制相似问题