[英]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.