为什么动态 ELF 文件中没有 .rel.dyn/.got.plt 部分?

Why there are no .rel.dyn/.got.plt section in dynamic ELF files?

我有这样的代码

// test_printf.c
#include <stdio.h>

int f(){
    printf("aaa %d\n", 1);
}

然后我用下面的代码编译它

gcc -shared -fPIC -m32 -g -c -o test_printf.so test_printf.c

我想如果运行readelf -S test_printf.so,我会看到.rel.dyn.rel.plt。这是因为这两个部分的行为类似于静态链接程序中的 .rel.data.rel.text

比如在我的程序中,由于printf是一个外部符号,被我的test_printf.so引用了。所以当我查看 test_printf.so 的重定位 table 时,应该有一个条目名称 printf。我检查了一下,条目存在。

然后我想,既然printf是一个外部符号,那么它的位置应该是在运行的时候确定的。但是,我们必须为这个printf函数分配一个.got.plt段,并且该段应该在动态链接执行和动态库中(test_printf.so).

但是我运行readelf -S的时候没有.got.plt段,我对此很困惑。这部分在动态库(test_printf.so)中不是必需的吗?我不认为这是可能的。假设test_printf.so最终链接到执行程序a,那么a怎么知道printf.got.plt段在哪里呢?这个 .got.plt 最终是在 a 中生成的吗?

同时,我有一个问题2。如果有.got.got.plt.rel.dyn.rel.plt是否总是存在?

.rel.dyn.got.plt 可以出现在共享库中 .elf 这取决于库中函数的结构,这在 https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html

如果包含外部函数,则存在

.rela.dyn

$ cat test.c
extern int foo;

int function(void) {
    return foo;
}
$ gcc -shared -fPIC -o libtest.so test.c

另见 https://eli.thegreenplace.net/2011/08/25/load-time-relocation-of-shared-libraries/https://eli.thegreenplace.net/2011/11/03/position-independent-code-pic-in-shared-libraries

https://blog.ramdoot.in/how-can-i-link-a-static-library-to-a-dynamic-library-e1f25c8095ef(将静态库链接成动态库)