在PLT部分强制输入

时间:2015-08-20 20:15:32

标签: c compilation linker objdump object-files

由于原因,我想强制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);
}

然后,我将上述两个可重定位目标文件编译并链接到一个可执行对象中。为确保absdadd函数保留在PLT部分中,我使用helper.o编译-O0main.o可以用更高级别编译,比如说'-O1'。

在可执行对象上,我希望看到所有3个函数的条目:strcmpabsdadd。但事实并非如此。

我在这里遗漏了什么吗? 链接器是否有可能省略某些东西,因为它发现它们从未被调用过?尽管使用O0作为辅助函数,并使用了forceplt函数的属性?

帮我做一个正确的庆祝活动......十。百万。问题!

干杯!

1 个答案:

答案 0 :(得分:2)

absstrcmp由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

我猜它在ARM中写得如此:

  .text
  .type forceplt2,%function
forceplt2:
  bl abs@plt

或者您可以为重定位生成原始字节(再次在x86_64上):

   .data
   .align  8
   .type   forceplt3, @object
   .size   forceplt3, 8
 forceplt3:
   .quad   socket@GOTPLT

On x_86_64,您应该能够使用@GOT@GOTPLT@GOTOFF@GOTPCREL@PLT或{{1} }。我不确定如何编写for ARM

这些解决方案中的任何一个都会发出一个合适的重定位条目,这将导致链接编辑器发出PLT条目和PLT GOT条目。