[英]Where are global variables located in the elf file
我想了解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();
}
谁能区分每个变量属于哪个细分市场? 在我看来, b
, d
和f
属于.bss
段,而a
, c
和e
属于数据段,但我不知道elf文件中的全局静态变量和全局变量之间的区别。
您可以使用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
没错, b
, d
和f
是.bss
而a
, c
和e
是.data
。 符号是否是静态的都记录在符号表的单独标志中,即第二列中的l
或g
标志。
elf(5)手册页指出,这些是使用符号表的st_info
成员的STB_LOCAL
和STB_GLOBAL
值记录的。 /usr/include/elf.h
表示STB_GLOBAL
为1,而STB_LOCAL
为0。存在一个宏ST_BIND
用于检索st_info
字段的绑定位。
objdump
还有很多其他标志-请参见手册页 。 objdump
适用于所有体系结构,但是还有一个elfdump
工具,可以更好地显示特定于elf的内容。 objdump
和基础BFD
库在显示某些特定于文件格式的数据方面可能做得不好。
通常,可执行文件的数据段包含初始化的全局/静态变量,而BSS段包含未初始化的全局/静态变量。
当加载程序将程序加载到内存中时,统一的全局/静态变量将自动填充为零。
在C语言中,函数内部的静态变量(是否已初始化)仅表示变量具有局部/函数作用域(有时称为内部静态变量),但它们仍存在于Data / BSS段中,具体取决于是否已对其进行初始化。
因此,无论调用fun()多少次,加载程序时,静态变量只会初始化一次。
定义为静态且在任何函数之外的变量仍位于data或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) |
+------------------------+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.