2013-06-18 25 views
7

最近、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(); 
} 

私の意見では、b、d、fはbssセグメントに属していますが、a、c、eはデータセグメントに属していますが、グローバル変数変数とグローバル変数はelfファイル内にあります。

答えて

11

あなたは、シンボルテーブルを表示する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 

は、あなたは正しいcaながらbd、およびf.bssしていることであり、e.dataです。シンボルが静的であるかどうかは、シンボルテーブルの別のフラグに記録されます。これは、第2列のlまたはgフラグです。

elf(5) man pageには、シンボルテーブルのst_infoの値にSTB_LOCALSTB_GLOBALの値を使用して記録されていると記載されています。 /usr/include/elf.hは、STB_GLOBALが1であり、STB_LOCALが0であると示しています。st_infoフィールドのバインディングビットを取得するためのマクロST_BINDがあります。


man page -see objdumpのための他のフラグのトンがあります。 objdumpはすべてのアーキテクチャーで動作しますが、elfdumpツールもあり、elf固有のものを表示するのに少し良い仕事をします。 objdumpとその下にあるBFDライブラリは、ファイル形式固有のデータを表示することができません。

7

一般に、実行可能ファイルのデータセグメントには初期化されたグローバル/静的変数が含まれ、BSSセグメントには初期化されていないグローバル/静的変数が含まれます。

ローダーがプログラムをメモリにロードすると、ユニバーサル化されたグローバル/静的変数は自動的にゼロで埋められます。

Cでは、関数内の静的変数(初期化されているかどうか)は、変数がローカル/関数スコープ(内部静的とも呼ばれることもあります)を持つことを意味しますが、それらは初期化されます。

したがって、fun()が呼び出された回数に関係なく、静的変数は、プログラムのロード時に1回だけ初期化されます。

staticと定義された変数は、まだデータセグメントまたは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) | 
+------------------------+ 
+0

私は輸出list.Isそれシンボルテーブルであるかを理解できないのですか? – CrystalJake

+0

要するに、各.o(オブジェクトファイル)の一部は、他のオブジェクトファイルに見えるエクスポートリスト(外部シンボルのリスト - グローバル変数/関数)です。また、オブジェクトファイル内で参照されていても別の場所で定義されているシンボルであるインポートリスト(グローバル変数/関数)があります。コンパイルのリンクフェーズでは、リンケージエディタはこれらのリストを使用してシンボルを結合します。 – ffhaddad

関連する問題