我已经阅读了大量关于动态链接器重新定位和位置独立代码的文章,包括过程链接表和全局偏移表。我不明白为什么静态链接的可执行文件需要PLT和GOT。我在我的ubuntu x86_64机器上编译了一个hello程序,当我用readelf -S
转储节头时,它会显示PLT和GOT节。
我还创建了一个共享库,其中包含一个简单的增量函数,我在没有gcc -shared
的情况下编译了这个库,我还看到了PLT和GOT部分。我也没想到会这样。
发布于 2016-01-18 11:59:54
我不明白为什么静态链接的可执行文件需要PLT和GOT。
事实并非如此。
我在我的ubuntu x86_64机器上编译了hello程序,当我用readelf转储节头时,它会显示PLT和GOT节。
这是一个执行上的意外。这些部分来自crt1.o
,并且没有一个用于完全静态链接的单独的crt1s.o
,因此您将从那里得到.plt
和.got
条目。
您可以剥离这些部分,二进制文件仍然可以工作:
objcopy -R.got -R.plt a.out a.out2
注意:不要剥夺.rela.plt
,因为该部分仍然需要实现IFUNC
的。
发布于 2022-04-01 04:31:41
我发现gcc在生成位置独立的代码并接受另一个源文件中定义的函数的地址时,会生成一个.got
和.got.lpt
。
我的测试文件是:
第1.c部分:
extern void afunc();
int _start()
{
return 0x55 & (__SIZE_TYPE__) afunc;
}
第2.c部分:
void afunc() {}
我的考试是(代替你自己的gcc版本):
for o in s 4 3 2 1 0
do
aarch64-linux-gnu-gcc-10 -fPIC part1.c part2.c -o static.elf -static -nostdlib -O$o &&
aarch64-linux-gnu-objdump -x static.elf | grep 'GLOBAL_OFFSET'
done
对于所有优化级别,我得到以下输出:
0000000000410fd8 l O .got 0000000000000000 _GLOBAL_OFFSET_TABLE_
用-fPIC
代替-fno-PIC
,段就会消失。
通过运行以下命令,可以判断编译器是否默认为-fPIC
:
aarch64-linux-gnu-gcc-10 -mcmodel=large -x c - < /dev/null
由此,我得到了错误,如果是这样的话:
cc1: sorry, unimplemented: code model ‘large’ with ‘-fPIC’
https://stackoverflow.com/questions/34850007
复制相似问题