1

我有这样的代码

// 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

例如,在我的程序中,sinceprintf是一个外部符号,由 my 引用test_printf.so。因此,当我查看test_printf.so的重定位表时,应该有一个条目名称printf。我检查了一下,条目存在。

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

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

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

4

1 回答 1

3

.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 (将静态库链接到动态库)

于 2020-12-09T10:42:52.440 回答