全局变量位于elf文件中的哪个位置

时间:2013-06-18 02:25:43

标签: c linux elf

我想学习elf文件,但是当我想到全局变量,全局静态变量和范围静态变量时, 我有些困惑。例如:

int a = 2;
int b;

static int c = 4;
static int d;

void fun(){
  static int e = 6;
  static int f;
}


int main(void){
   fun();
}

谁能告诉每个变量属于哪个细分?在我看来, bdf属于.bss段,ace属于数据段,但我不知道全局静态变量和elf文件中的全局变量之间的区别。

2 个答案:

答案 0 :(得分:13)

您可以使用objdump -t查看符号表:

$ objdump -t foo | grep -P '      \b(a|b|c|d|e|f)\b'
0000000000601034 l     O .data  0000000000000004              c
0000000000601040 l     O .bss   0000000000000004              d
0000000000601044 l     O .bss   0000000000000004              f.1710
0000000000601038 l     O .data  0000000000000004              e.1709
0000000000601048 g     O .bss   0000000000000004              b
0000000000601030 g     O .data  0000000000000004              a

bdf .bss ace,你是对的。是.data。符号是否为静态记录在符号表的单独标志中 - 即第二列中的lg标志。

elf(5) man page表示这些是使用符号表的STB_LOCAL成员的STB_GLOBALst_info值记录的。 /usr/include/elf.h表示STB_GLOBAL为1,而STB_LOCAL为0.有一个宏ST_BIND可以检索st_info字段的绑定位。


objdump还有很多其他标志 - 请参阅man pageobjdump适用于所有体系结构,但还有一个elfdump工具可以更好地显示特定于elf的内容。 objdump和基础BFD库在显示某些特定于文件格式的数据方面做得不好。

答案 1 :(得分:7)

通常,可执行文件的数据段包含初始化的全局/静态变量,BSS段包含未初始化的全局/静态变量。

当加载程序将程序加载到内存中时,单位化的全局/静态变量将自动填零。

在C中,函数内部的静态变量(初始化或未初始化)只是意味着变量具有局部/函数范围(有时称为内部静态),但它们仍然存在于Data / BSS段中,具体取决于它们是否存在已初始化。

因此,无论fun()被调用多少次,静态变量只在程序加载时启动一次。

定义为静态且在任何函数之外的变量仍然存在于数据段或bss段中,但仅具有文件范围。

编译代码时,会有一个导入和导出列表,它是每个目标文件的一部分,由链接编辑器使用。您的静态变量不在导出列表中,因此无法访问其他目标文件。

通过排除static关键字,您的全局变量将被放置在导出列表中,并且可以被其他对象模块引用,并且链接编辑器将能够在创建可执行文件时找到符号。

对于图片视图:

+--------- TEXT ---------+  Low memory
| main()                 |
| fun()                  |
+--------- DATA ---------+
| int a (global scope)   |
| int c (file scope)     |
| int e (function scope) |
+---------- BSS ---------+
| int b (global scope)   |
| int d (file scope)     |
| int f (function scope) |
+------------------------+