我想学习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();
}
Run Code Online (Sandbox Code Playgroud)
谁能告诉每个变量属于哪个细分?在我看来,
b,d和f属于.bss段和a,c以及e属于数据段,但我不知道全局静态变量和ELF文件的全局变量之间的差异.
and*_*otn 14
您可以使用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
Run Code Online (Sandbox Code Playgroud)
你是正确的b,d以及f是.bss同时a,c和e是.data.无论符号是静态的或不被记录在符号的独立标志表格,那就是l或g标志的第二列.
该小精灵(5)手册页说,这些正在使用的记录 STB_LOCAL和STB_GLOBAL值的st_info符号表的成员./usr/include/elf.h说STB_GLOBAL是1,STB_LOCAL而是0.有一个宏ST_BIND来检索st_info字段的绑定位.
还有很多其他标志objdump- 请参阅手册页.objdump适用于所有架构,但也有一个elfdump工具可以更好地显示精灵特定的东西.objdump并且底层BFD库可能会显示一些特定于文件格式的数据.
通常,可执行文件的数据段包含初始化的全局/静态变量,BSS段包含未初始化的全局/静态变量.
当加载程序将程序加载到内存中时,单位化的全局/静态变量将自动填充零.
在C中,函数内部的静态变量(初始化或未初始化)仅表示变量具有局部/函数范围(有时称为内部静态),但它们仍然存在于Data/BSS段中,具体取决于它们是否已初始化.
因此,无论fun()被调用多少次,静态变量只在程序加载时启动一次.
定义为静态且在任何函数外部的变量仍然存在于数据段或bss段中,但仅具有文件范围.
编译代码时,会有一个导入和导出列表,它是每个目标文件的一部分,由链接编辑器使用.您的静态变量不在导出列表中,因此无法访问其他目标文件.
通过排除static关键字,您的全局变量将放置在导出列表中,并可由其他对象模块引用,并且链接编辑器将能够在创建可执行文件时查找符号.
对于pictoral视图:
+--------- 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) |
+------------------------+
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13501 次 |
| 最近记录: |