【发布时间】:2017-12-11 06:36:03
【问题描述】:
假设我们有:
f1.c
#include <stdio.h>
static int x = 10;
void f1() {
printf("f1.c : %d\n", x);
}
main.c
extern void f1();
int main(int argc, char **argv) {
f1();
return 0;
}
我们将编译并读取两个 ELF 文件符号表(rel. ELF 和 exec ELF):
$> gcc -c *.c
$> readelf -s f1.o | grep x
Num: Value Size Type Bind Vis Ndx Name
5: 0000000000000000 4 OBJECT LOCAL DEFAULT 3 x
$> gcc *.o
$> readelf -s a.out | grep x
Num: Value Size Type Bind Vis Ndx Name
38: 0000000000601038 4 OBJECT LOCAL DEFAULT 25 x
通过读取可重定位目标文件f1.o,可以看到全局静态变量x为0000000000000000的Value(也称为地址)。
这意味着我们还没有初始化它,因为它仍然是一个 rel。 ELF 目标文件和链接器会处理这个问题。
那么我的问题是,如果链接器是在链接0000000000601038 后在已知地址将x 的值设置为10 的链接器,它是如何做到的?链接器从哪里获取信息以将值设置为 10 以及谁提供此信息 (f1.o?)?
【问题讨论】:
-
这里的Value是变量
x的地址,不是x的值 -
@ChrisDodd 是的,我已经注意到,在最初的问题中已经不是混淆了,我明白它听起来像是我的意思是因为它没有被初始化。跨度>
标签: c gcc linker symbol-table