首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么静态链接的可执行文件中存在全局偏移表和过程链接表?

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

Stack Overflow用户
提问于 2016-01-18 08:19:24
回答 2查看 965关注 0票数 5

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

我还创建了一个共享库,其中包含一个简单的增量函数,我在没有gcc -shared的情况下编译了这个库,我还看到了PLT和GOT部分。我也没想到会这样。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-18 19:59:54

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

事实并非如此。

我在我的ubuntu x86_64机器上编译了hello程序,当我用readelf转储节头时,它会显示PLT和GOT节。

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

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

代码语言:javascript
运行
复制
objcopy -R.got -R.plt a.out a.out2

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

票数 5
EN

Stack Overflow用户

发布于 2022-04-01 12:31:41

我发现gcc在生成位置独立的代码并接受另一个源文件中定义的函数的地址时,会生成一个.got.got.lpt

我的测试文件是:

第1.c部分:

代码语言:javascript
运行
复制
extern void afunc();

int _start()
{
  return 0x55 & (__SIZE_TYPE__) afunc;
}

第2.c部分:

代码语言:javascript
运行
复制
void afunc() {}

我的考试是(代替你自己的gcc版本):

代码语言:javascript
运行
复制
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

对于所有优化级别,我得到以下输出:

代码语言:javascript
运行
复制
0000000000410fd8 l     O .got   0000000000000000 _GLOBAL_OFFSET_TABLE_

-fPIC代替-fno-PIC,段就会消失。

通过运行以下命令,可以判断编译器是否默认为-fPIC

代码语言:javascript
运行
复制
aarch64-linux-gnu-gcc-10 -mcmodel=large -x c - < /dev/null 

由此,我得到了错误,如果是这样的话:

代码语言:javascript
运行
复制
cc1: sorry, unimplemented: code model ‘large’ with ‘-fPIC’
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34850007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档