C/C++ 変数へのポインターを使用できます。この変数が属するメモリのセグメントを正確に特定することは可能ですか? はいの場合、どのように?
注:私はこの変数のアドレスを持っているだけで、変数がローカル/グローバルなどの場合、それ以上の情報はありません.
C/C++ 変数へのポインターを使用できます。この変数が属するメモリのセグメントを正確に特定することは可能ですか? はいの場合、どのように?
注:私はこの変数のアドレスを持っているだけで、変数がローカル/グローバルなどの場合、それ以上の情報はありません.
Linux を使用している場合 (他のユニックスについては不明)、ファイル内の情報を見つけることができる場合があります。/proc/<pid>/maps
アーキテクチャにヒープ領域またはスタック領域へのポインタがあるかどうかを調べます。通常、いくつかのスタックポインタまたはフレームポインタがあります..
次に、実際の住所とそれらの住所を比較し、それらがどこに属しているかを判断します。
最初に、実行可能ファイル内のさまざまなセクションの最初と最後を特定できます。このためには、最終的に次のように各セクションの周りのリンカー スクリプトにいくつかの変数を追加する必要があります。
SECTIONS {
[...]
.data : {
data_start = .;
*(.data)
data_end = .;
}
[...]
}
次に、これらの変数を C/C++ コードで外部として宣言し、それらを直接使用して、識別したいアドレスを比較できます。
リンカー スクリプトを調整するのは簡単ではないかもしれません。gcc を使用すると、次のようにダンプできます。
gcc -Wl,-verbose whatever.c
次に、(乱雑な)出力ですでに定義されている変数を見つけようとします。
スタックの境界を取得するには、main() 関数の先頭でダミー変数をインスタンス化し、そのアドレスをスタックの一番上に保存してから、現在の位置で別の変数をインスタンス化すると、一番下になります。 . ただし、コンパイラはこのように正確に動作しない可能性があることに注意してください (C の変数のスタック順序は保証されず、スタックの使用も保証されません)。これは機能するはずですが、移植性はありません。
最後に、ヒープについては、私にはコツがありません。data/bss/derivated になく、スタックにない変数はヒープにあると推測します (レジスタを除くが、アドレスを取得できれば、コンパイラがレジスタのみのストレージを使用することは決してないと思います) )。
それがあなたの状況に合っているかどうかは正確にはわかりませんがobjdump -t
、elfファイルのシンボルテーブルを見てみることができます。必要なのは変数のアドレスだけです。そこで、各変数のセクションを示すフラグを見つけることができます。詳細については、manページを参照してobjdump
ください。
サンプル出力:
0804a020 g O .bss 00000004 var
それはvar
、住所、セクションのg
ローブの対象であると言いますO
0804a020
.bss