10

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 ファイルのグローバル静的変数とグローバル変数の違いがわかりません。

4

2 に答える 2

18

を使用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、、、であることは正しいです。シンボルが静的かどうかは、シンボル テーブルの別のフラグ ( 2 列目のorフラグ) に記録されます。df.bssace.datalg

elf(5)のマニュアル ページによると、これらは シンボル テーブルのメンバーのSTB_LOCALおよびのSTB_GLOBAL値を使用して記録されます。フィールドのバインディング ビットを取得するマクロがあります。st_info/usr/include/elf.hSTB_GLOBALSTB_LOCALST_BINDst_info


他にもたくさんのフラグがありますobjdump— manページを参照してください。objdumpすべてのアーキテクチャで動作しますが、elfdumpelf 固有のものを表示するのに少し優れたツールもあります。objdumpまた、基礎となるBFDライブラリは、ファイル形式固有のデータを表示するという悪い仕事をする可能性があります。

于 2013-06-18T02:51:06.707 に答える
9

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

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

C では、関数内の静的変数 (初期化されているかどうかに関係なく) は、変数がローカル/関数スコープ (内部静的と呼ばれることもあります) を持っていることを意味しますが、初期化されているかどうかに応じて、データ/BSS セグメントに残ります。

したがって、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) |
+------------------------+
于 2013-06-18T05:23:24.823 に答える