プログラムデータベース

PDBは、論理的にはストリームと呼ばれるいくつかのサブファイルから構成される1つのファイルである。 コンパイルやインクリメンタルリンクで行われるPDBへの変更処理を最適化するために設計されている。 ストリームは他のストリームを書き換えることなく削除、追加、置換することができ、ストリームを記述するメタデータの変更も最小限に抑えられます。 ストリーム番号やページ番号など)はリトルエンディアン形式で保存されているものと思われます。 pdbparse Pythonコードはこの仮定に基づいています。

StreamEdit

PDB内の各ストリームはいくつかのページを占め、それらは必ずしも連続した番号ではありません。 ストリームは番号と長さを持つ。

メタデータフォーマット編集

PDBメタデータの機能は、すべてのコンポーネントストリームを識別し、各ストリームの長さとページの順序を与えることです。 また、メタデータの一部を含むルートストリーム(番号なし)も存在します。

HeaderEdit

PDBはヘッダーから始まり、以下の項目で構成されます:

  • Signature 特定のフォーマットを識別し検証するために使われます。
  • ヘッダーの残りの部分は、署名によって識別されるフォーマットによって異なります。

ヘッダーは1ページより長くなることがあります。

Microsoft のツールは 2 つの PDB フォーマットを使用します:

Version 7Edit

Signature は "Microsoft C/C++ MSF 7.00\r\n\x1ADS"(32 バイト) です。

Remainder of the header consists of:

  • Page size, 4 bytes.
  • Allocation table pointer, 4 bytes.Allocation table pointer, 4 bytes.

    Remainder of the header consists of:

    • Page size, 4 bytes. この意味は不明である。 PDBの末尾に65,536ビット(8,192バイト)のアロケーションテーブルがあるようで、1ビットは使用されていないページを意味します。
    • Number of file pages, 4 bytes.
    • Root stream size, 4 bytes.
    • reserved, 4 bytes.
    • Root stream page number listのページナンバーです。 ルートストリーム自体の位置は示さず、そのページを指す構造体を含むページの位置のみを示す。 そのページで、ルートストリームページ番号リストは、ルートストリームが格納されているページを示す。

    ルートストリーム編集

    ルートストリームはストリーム0から始まる全てのPDBストリームを記述する。 その内容はPDBフォーマットのバージョンにより異なる。

    Version 2Edit

    ルートストリームの構成:

    • Number of streams, 2 bytes.
    • Reserved, 2 bytes.
    • For each stream:
      • Stream size, 4 bytes.
      • Reserved, 4 bytes.The roots stream consists of the PDB systems.
    • 各ストリームについて:
      • ストリームページ番号リスト、1ページあたり2バイト、上記のストリームサイズをカバーするのに十分なバイト数。

    Version 7Edit

    ルートストリームの構成:

    • ストリーム数、4バイト.
    • ストリームごとに:
      • ストリームサイズ、4バイト.ルートストリームは、

      で構成されます。

  • For each stream:
    • Stream page number list, 4 bytes per page, enough to cover above stream size.

    Stream contentsEdit

    Microsoft tools store different kinds of information in different numbered streams.The Stream contentsEditはストリームごとに異なる番号の情報を保存します。 いくつかのストリーム番号は、それらに関連する固定情報タイプを持ち、他のストリームは前述の固定タイプストリームで識別されます。

    Stream 1 は、PDB が実行ファイルまたはオブジェクト ファイルのストリームで参照される同じファイルであることを確認するために使用します。

    • バージョン、4 バイト。
    • タイム デート スタンプ、4 バイト。
    • Age 、4 バイト。 このPDBが作成されてから変更された回数です。
    • GUID, 16 bytes.
    • Total length of following names, 4 bytes.これは、このPDBが作成されてから何回変更されたかです。

    ストリーム2およびストリーム4は、タイプ情報を保持します。 実際の型レコードは、プログラムで使用される型を定義する。 これらのレコードの構造は、マイクロソフトが提供するファイルcvinfo.hに記載されている。 レコードには2種類あり、それぞれインデックス番号のセットを持っています。

    • ヘッダ:
      • バージョン、4バイト.
      • ヘッダサイズ、4バイト.
      • タイプレコードの最小および最大(最後+1)インデックス(各4バイト).
      • 続くデータのサイズ、4バイト、ストリーム末端まで.
      • ヘッダーサイズは4バイト.
      • タイプレコードの最小および最大インデックス、4バイト.
      • 続くデータのサイズ……com(ストリーム末端まで.com).
      • ヘッダーサイズは3バイト.com(ストリーム末端まで.
    • ハッシュ情報:
      • ストリーム番号、2バイトのパディング付き.
      • ハッシュキー、4バイト.
      • バケット、4バイト.
      • HashVals, TiOff, HashAdj、オフセットと長さからなり、各々4バイト.HashAdj、長さ、各々1バイト.
    • ストリーム番号、4バイト.
    • ハッシュキー、2バイト(2バイト.2.0)。

  • Type records, variable length, count = (maximum – minimum) from above header.
  • ストリーム3は他のストリーム用のディレクトリである。 なお、Version 2には存在せず、コンパイラが生成したPDBにも存在しない。 ストリームは合計64バイトになるようにパディングされたヘッダから始まります

    オフセット

    PDB Stream 3 Header (struct NewDBIHdr)
    サイズ 名前 説明
    0 4 署名 Header identifier, == 0xFFFFFF
    4 HeaderVersion ヘッダのバージョン
    8 4 年代 12 2 snGSSyms
    14 2 usVerAll
     union { struct { USHORT usVerPdbDllMin : 8; // minor version and USHORT usVerPdbDllMaj : 7; // major version and USHORT fNewVerFmt : 1; // flag telling us we have rbld stored elsewhere (high bit of original major version) } vernew; // that built this pdb last. struct { USHORT usVerPdbDllRbld: 4; USHORT usVerPdbDllMin : 7; USHORT usVerPdbDllMaj : 5; } verold; USHORT usVerAll; };
    16 2 snPSSyms
    18 2 usVerPdbDllBuild 最後にこのPdbを構築したPdb DLバージョン
    20 2 snSymRecs
    22 2 VerPdbDllRBld rbld version of pdb dll that build this pdb last
    24 4 cbGpModi rgmodiサブストリームのサイズ
    28 4 cbSC セクション貢献サブストリームのサイズ
    32 4 cbSecMap セクションマップのサイズ
    36 4 cbFileInfo ファイル情報のストリームサイズ
    40 4 cbTSMap size of Type Server Map substream
    44 4 iMFC MFCインデックス
    48 4 cbDbgHdr ストリームの最後に追加されるオプションのDbgHdr情報のサイズ
    52 4 cbECInfo ECサブストリームのバンド数。 ECが有効でない場合は0 Mods
    56 2 flags
     struct _flags { USHORT fIncLink:1; // true if linked incrmentally (really just if ilink thunks are present) USHORT fStripped:1; // true if PDB::CopyTo stripped the private data out USHORT fCTypes:1; // true if this PDB is using CTypes. USHORT unused:13; // reserved, must be 0. } flags;
    58 2 wMachine マシン識別子、COFFオブジェクトフォーマットで使用するものと同じ、例:Machine.It.D.g., Intel x86 64-bit
    60 4 RESERVED 将来の拡張、64バイトにパッド
    • モジュール情報、可変長。 上記ヘッダの合計サイズ。 3906>
    • Opened, 4 bytes.
    • Symbol info.
      • Section number, 2 bytes + 2 bytes padding.
      • Offset and size, each 4 bytes.
      • Flags, 4 bytes.
        • Opened, 3 bytes + 2 bytes padding.
        • Module number, 2 bytes + 2 bytes padding.
        • CRCs for section data and relocations data, each 4 bytes.
      • Flags, 2 bytes.
      • Stream number, 2 bytes.
      • Symbols size, 4 bytes.
      • Symbols data, 4 bytes.

    • Module number, 2 bytes + 2 bytes padding.

    • Old and new line number info sizes, 4 bytes each.
    • Number of source files, 2 bytes + 2 bytes padding.
    • Offsets, 4 bytes.
    • niSource and niCompiler, 4 bytes each.
    • ソースファイル数, 2 bytes + 4 bytes padding…。

    • Module name, null terminated byte string.
    • Object name, null terminated byte string.
    • Padding to multiple of 4 bytes.
  • Section contributions, section headers, file info, ts map, EC info.
  • Section informationは、それぞれ、4バイト。 8906>
  • Debug header,
    • 旧フレームポインタ省略、例外、修正、ソースとのオブジェクトマップ、セクションヘッダ、トークンリングID、Xdata、Pdata、新フレームポインタ省略、およびセクションヘッダの起源のストリームナンバー。 各2バイト