1

Microsoft PE / COFF SPEC(v8、セクション5.4.4)は、シンボルに次の場合があると述べています。

  1. IMAGE_SYM_CLASS_EXTERNALのストレージクラス
  2. そしてセクション番号0(IMAGE_SYM_UNDEFINED)

「サイズを示す」のは(シンボルテーブル内の)「値」フィールドです。

これは私を混乱させます。特に、「何の大きさを示しているのか」と思っています。

通常、IMAGE_SYM_CLASS_EXTERNALおよびIMAGE_SYM_UNDEFINEDはCL(visual C ++)によってexternを表すために使用されます。

リンカがシンボルのサイズを知る必要がある、または気にする必要があるのはなぜですか?名前を知っているだけでなく、それが外部であり、適切な再配置エントリが設定されている必要がありますか?これはどれもサイズに依存するべきではありません。確かに、コンパイラはこれを知る必要がありますが、オブジェクトファイルからではなく、ヘッダーファイルからその情報を取得します。

CLによってコンパイルされたexternの簡単な例を見てきましたが、Valueフィールドは常にゼロのようです。したがって、フィールドのサイズをエンコードするために使用されていないことは明らかです。

スペックが何の「サイズ」を指しているのか誰か知っていますか?Visual Studioリンカーがそのフィールドを使用する可能性があるシナリオはありますか、それとも仕様の宣伝文句は意味がありませんか?私の限られた脳はそのようなシナリオを考えることができません。

アップデート:

少なくとも常にではないが、シンボルのサイズであるとは限らないことに注意してください。私が観察した場合、値は常に0であるため、質問があります。

4

4 に答える 4

4

Wisniewskiさん、私は答えを見つけたと思います。私は学生で、自分のリンカーを書こうとしました。その最初のバージョンでは、OBJファイルをリンクして、自分のバイナリ形式にダンプできます。しかし、すぐに私は多くのC++言語機能がLIBCMT.LIBなしではサポートされていないことに気づきました。したがって、最初はlibパーサーをコーディングしました...そしてCRTをリンクしようとしているときにスタックしました。ファイルLIBCMT.LIBの2番目のリンカーメンバーで、オブジェクトファイルcrt0.objlibcmt内)にシンボル__acmdlnが含まれていることが指定されました(コマンドラインへのグローバルポインタ)...しかし、そこで見つけることができませんでした!私は本当に欲求不満でした...シンボルにはIMAGE_SYM_CLASS_EXTERNALとセクションIMAGE_SYM_UNDEFINEDがありましたが、なぜですか?ソースファイルcrt0.cには、次の宣言があります。

#ifdef WPRFLAG
wchar_t *_wcmdln;           /* points to wide command line */
#else  /* WPRFLAG */
char *_acmdln;              /* points to command line */
#endif  /* WPRFLAG */

私の調査はかなり長く、結果はそうです:

C ++コンパイラは初期化されていないデータを.bssセクションに配置し、それをIMAGE_SCN_CNT_UNINITIALIZED_DATAでマークしますが、純粋なCコンパイラは異なる動作をします(libcmtはCで記述されています)。

初期化されていないデータをセクションに配置するのはリンカの義務です。Cコンパイラがセクション(0)なしでシンボルを発行し、外部としてマークされ、その値フィールドがゼロの場合、それは他の場所で宣言されますが、値フィールドがnullでない場合、指定されたOBJファイルには実際にそのシンボルが含まれていますが、初期化されていません。したがって、リンカは.bssセクションの場所を予約する必要があります。「値」サイズの場所。そして、これらの行を次のように変更すると、次のようになります。

#ifdef WPRFLAG
wchar_t *_wcmdln = 0xCCCCCCCC; /* points to wide command line */
#else  /* WPRFLAG */
char *_acmdln = 0xCCCCCCCC; /* points to command line */
#endif  /* WPRFLAG */

ゼロ値フィールドがあり、両方とも.dataセクションに配置されます。

頑張って、英語が下手でごめんなさい。

于 2010-12-13T20:42:48.677 に答える
1

サイズを宣言する配列のextern宣言はどうですか。

a.cpp:

 extern int example[42];

b.cpp:

 int example[13];

ただし、リンカがこの不一致をキャッチしないという事実は、Valueが使用されていないことを示しています。私にはそれを簡単に見る方法がありません。

于 2010-05-19T10:08:49.207 に答える
0

これは、シンボルによって参照されるデータ構造のサイズです。

基本的に、シンボルが定義されていない場合、リンカはデータ構造のサイズを見つけることができないため、リンク中にこれらの問題に対処できるように、インスタンス化されたときのサイズを事前に知る必要があります。

于 2010-05-17T15:16:03.333 に答える
0

非常にエキゾチックですが、興味深い質問があります。COFF内でシンボルテーブルを生成する唯一の可能性は、Visual C ++6.0までサポートされている/Zdコンパイラスイッチの使用であり、古いリンカースイッチ/ debugtype:coffを使用することです(http://www.debuginfo.com/を参照)。 articles / gendebuginfo.html#gendebuginfovc6)?少なくともVisualStudio2008でCOFF内にシンボルテーブルを作成する可能性はありますか?

私のアイデアは、ストレージクラスIMAGE_SYM_CLASS_EXTERNALのシンボルテーブルと、リンカースイッチ/ FORCE(/ FORCE:UNRESOLVEDまたは/ FORCE:MULTIPLE)に関するセクション番号0(IMAGE_SYM_UNDEFINED)、および/INCLUDEによる未解決のシンボルを使用してPEを作成することです。 :dummySymbolまたは/NODEFAULTLIBによって。私の問題は、COFF内でシンボルテーブルを作成するのは簡単ではないということです。テストPEはどこで受け取りますか?

于 2010-05-17T22:41:30.550 に答える