Linux 重新定位共享对象中本地符号的R_386_跳槽

Linux 重新定位共享对象中本地符号的R_386_跳槽,linux,gcc,linker,dynamic-linking,dynamic-library,Linux,Gcc,Linker,Dynamic Linking,Dynamic Library,我正在研究动态重新定位过程,并创建了一个非常简单的共享对象: int func_1(int v) { v + 10; } int func_2() { return func_1(10); } $ objdump -R libtest.so libtest.so: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 00002000 R_386_JUMP_

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

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

int func_2()
{
   return func_1(10);
}
$ objdump -R libtest.so

libtest.so:    file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
00002000 R_386_JUMP_SLOT   func_1
汇编如下:

gcc -fPIC -c libtest.c
gcc -shared -nostdlib -o libtest.so libtest.o
如果我们查看共享对象的动态重新定位:

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

int func_2()
{
   return func_1(10);
}
$ 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_386_跳转槽,因此
func_2
中的调用由PLT解决。我无法找出原因…如果
func_1
被声明为private(
static
),重新定位将消失,调用将通过相对分支解决(由静态链接器)。为什么从PLT传递优于相对跳转?

使用PLT,您可以在运行时覆盖从
func_2
调用,以调用其他版本的
func_1
。例如,通过
LD\u预加载
。使用static关键字,您只需硬编码自己的私有版本的
func\u 1
。它的灵活性与较小的运行时开销相比。

正如@Miroslav所写的,这就是允许插入。如果不想将
func1
的使用限制为单个文件(翻译单元),但仍然不想导出符号,请查看