我正在研究动态重定位过程,并创建了一个非常简单的共享对象:

int func_1(int v)
{
    v + 10;
}

int func_2()
{
   return func_1(10);
}

编译为:
gcc -fPIC -c libtest.c
gcc -shared -nostdlib -o libtest.so libtest.o

如果我们查看共享对象的动态重定位:
$ objdump -R libtest.so

libtest.so:    file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
00002000 R_386_JUMP_SLOT   func_1

符号func_1有一个R__跳转槽,因此func_2中的调用由PLT解决。我无法找出原因…如果func_1声明为private(static),则重新定位将消失,调用将通过一个相对分支(通过静态链接器)解析。为什么从PLT传来比相对跳跃好?

最佳答案

使用PLT,您可以覆盖从func_2调用以在运行时调用其他版本的func_1。例如,通过LD_PRELOAD。使用static关键字,您只需硬编码自己的私有版本func_1。它的灵活性与小的运行时间开销。

10-04 13:39