2012-03-13 15 views
0

__data_startシンボルのアドレスをプログラマティックに取得したいと考えています。 _GLOBAL_OFFSET_TABLE_の場合は、extern void* _GLOBAL_OFFSET_TABLE_を使用しました(例hereを参照)。しかし、同じテクニックは__data_startでは機能しません。コンパイラはプログラムを正常にコンパイルしますが、プログラムによって返される値は偽です。どのようにこの問題を解決できるか考えてみましょう。__data_startシンボルのアドレスを取得

+2

動作しませんでした。あなたの他の質問に対する私のコメントを見てください。 '__data_start'を'&__ data_start'に変更します。 –

+0

@R ..素晴らしい!その作品は今!ありがとう!たぶんあなたはこれを答えに入れることができるので、私はそれを受け入れることができます。 – MetallicPriest

答えて

3

__data_startなどのマジックシンボルは、値が目的のアドレスであるポインタ変数ではありません。あなたが望むシンボルののアドレスです。したがって、&__data_startのように&演算子が必要です。

+0

'__data_start'はどこに定義されていますか? 'etext'とは異なり、' ld -verbose'で与えられたリンカスクリプトにはありません。しかし、それは 'ld'の土地に現れるように定義するのは間違いなくリンカーです。他のリンカスクリプトの中には '__data_start__'を定義していますが、' __data_start'は定義していません。 –

+0

実際、私は考えていません。リンカのソースを調べて調べるか、GNU ldの専門家に尋ねる必要があります。 –

+0

確かに、それは明らかだった:-)私が知っている場合は、私は返信します。 –

1

あなたは

extern char _GLOBAL_OFFSET_TABLE_[]; 
extern char __data_start[]; 

(これは、配列のではなく、ポインタの宣言です!)

を試してみて、あなたのコードで&__data_startを使用することができます。

+0

この場合、 '&'は必要ではありません。なぜなら、配列の名前が最初の要素へのポインタを評価するからです。 –

+0

合意。しかし、読みやすくするために役立つ可能性があります。 –

+0

不完全な型(未知のサイズ)で宣言された配列に対しても '&'は有効ですか?通常、 'T [N]'型の配列に適用される '&'の型は 'T(*)[N]'型ですが、ここには 'N'はありません... –

1

このコードは問題なく動作します。

extern void *data_start; 
int main() { 
fprintf(stdout,">%p\n", &data_start); 
return 0; 
} 

atom :: » nm test | grep "data_start" ; ./test 
0804a00c D __data_start 
0804a00c W data_start 
>0x804a00 
+0

私はそれがすべきであると確信していません。私の答えを見てください。 –