Linux 为什么静态链接的可执行文件中有全局偏移表和过程链接表?

Linux 为什么静态链接的可执行文件中有全局偏移表和过程链接表?,linux,gcc,linker,Linux,Gcc,Linker,我读了很多关于动态链接器重定位和位置无关代码的书,包括过程链接表和全局偏移表。我不明白为什么静态链接的可执行文件需要PLT和GOT。我在我的ubuntu x86_64机器上编译了一个hello world程序,当我用readelf-S转储节头时,它会显示PLT和GET节 我还创建了一个共享库,其中包含一个简单的增量函数,我使用gcc-shared编译它,而不使用-fpic,我还看到了PLT和GOT部分。我也没想到会这样 我不明白为什么静态链接的可执行文件需要PLT和GOT 没有 我在我的ubun

我读了很多关于动态链接器重定位和位置无关代码的书,包括过程链接表和全局偏移表。我不明白为什么静态链接的可执行文件需要PLT和GOT。我在我的ubuntu x86_64机器上编译了一个hello world程序,当我用
readelf-S
转储节头时,它会显示PLT和GET节

我还创建了一个共享库,其中包含一个简单的增量函数,我使用
gcc-shared
编译它,而不使用
-fpic
,我还看到了PLT和GOT部分。我也没想到会这样

我不明白为什么静态链接的可执行文件需要PLT和GOT

没有

我在我的ubuntu x86_64机器上编译了一个hello world程序,当我用readelf-S转储节头时,它会显示PLT和GET节

这是执行的一个意外。这些部分来自
crt1.o
,并且没有一个单独的
crt1s.o
用于完全静态链接,因此您最终得到了
.plt
条目

您可以剥离这些部分,二进制文件仍然可以工作:

objcopy -R.got -R.plt a.out a.out2

注意:不要剥离
.rela.plt
,因为仍然需要该部分来实现
IFUNC
s。

还有一个
.get.plt
我可以删除,但可执行文件仍在运行。如您所述,如果我删除了
.rela.plt
可执行文件,则会出现故障。