BDB je jeden soubor, který se logicky skládá z několika dílčích souborů, tzv. streamů. Je navržen tak, aby optimalizoval proces provádění změn v PDB, který se provádí kompilací a přírůstkovými odkazy. Streamy lze odebírat, přidávat nebo nahrazovat, aniž by se přepisovaly jiné streamy, a minimalizují se také změny metadat, která popisují streamy.
PDB je uspořádán do stránek s pevnou velikostí, obvykle 1K, 2K nebo 4K, číslovaných postupně od 0.
Poznámka: Předpokládá se, že všechny číselné informace (např, čísla toků a stránek) jsou uloženy ve tvaru little-endian, což je nativní tvar pro procesory Intel x86. Kód pdbparse v jazyce Python vychází z tohoto předpokladu.
StreamEdit
Každý stream v PDB zabírá několik stránek, které nemusí být nutně postupně číslovány. Proud má číslo a délku. Obsah streamu je spojením jeho stránek, zkrácených na délku streamu.
Metadata formatEdit
Úkolem metadat PDB je identifikovat všechny složky streamu a uvést délku a pořadí stránek pro každý stream. Streamy jsou číslovány postupně od 0. Existuje také kořenový stream, nečíslovaný, který obsahuje některá metadata.
ZáhlavíEdit
PDB začíná záhlavím, které se skládá z:
- Podpisu, který slouží k identifikaci a ověření konkrétního formátu. Délka signatury se liší podle konkrétního formátu.
- Zbytek záhlaví se liší podle formátu identifikovaného signaturou.
Záhlaví může být delší než jedna strana.
Nástroje společnosti Microsoft používají dva formáty PDB:
Verze 7Edit
Signatura je "Microsoft C/C++ MSF 7.00\r\n\x1ADS"
(32 bajtů).
Zbytek záhlaví tvoří:
- Velikost stránky, 4 bajty.
- Ukazatel na alokační tabulku, 4 bajty. Význam tohoto údaje není znám. Zdá se, že existuje alokační tabulka, pole 65 536 bitů (8 192 bajtů), které se nachází na konci PDB, a 1 bit znamená nepoužívanou stránku.
- Počet stránek souboru, 4 bajty.
- Velikost kořenového toku, 4 bajty.
- rezervováno, 4 bajty.
- Číslo stránky seznamu čísel stránek kořenového toku. Neuvádí umístění samotného Root streamu, pouze stránky obsahující strukturu, která ukazuje na jeho stránky. Na této stránce seznam čísel stránek Root streamu označuje stránky, na kterých je Root stream uložen. Obsahuje 4 bajty na stránku, což stačí k pokrytí výše uvedené velikosti kořenového toku.
Kořenový tokEdit
Kořenový tok popisuje všechny toky PDB počínaje tokem 0. Jeho obsah se liší podle verze formátu PDB.
Verze 2Edit
Kořenový stream obsahuje:
- Počet streamů, 2 bajty.
- Rezervace, 2 bajty.
- Pro každý stream:
- Velikost streamu, 4 bajty.
- Rezervace, 4 bajty.
- Pro každý proud:
- Seznam čísel stránek proudu, 2 bajty na stránku, dost na to, aby pokryl výše uvedenou velikost proudu.
Verze 7Edit
Kořenový proud se skládá z:
- Počet proudů, 4 bajty.
- Pro každý proud:
- Velikost proudu, 4 bajty.
- Pro každý proud:
- Seznam čísel stránek proudu, 4 bajty na stránku, což stačí k pokrytí výše uvedené velikosti proudu.
Obsah prouduEdit
Nástroje společnosti Microsoft ukládají různé druhy informací do různě očíslovaných proudů. Některá čísla proudů mají přiřazen pevný typ informace a jiné proudy jsou identifikovány ve výše uvedených proudech s pevným typem.
Proud 1 slouží k ověření, že PDB je stejný soubor, na který odkazuje spustitelný nebo objektový proud souboru.
- Verze, 4 bajty.
- Časové razítko data, 4 bajty.
- Věk, 4 bajty. Jedná se o počet změn tohoto PDB od jeho vytvoření.
- GUID, 16 bajtů.
- Celková délka následujících názvů, 4 bajty. Následují řetězce znaků ukončené nulou.
Stream 2 a stream 4 obsahují informace o typech. Aktuální typové záznamy definují typy používané v programu. Strukturu těchto záznamů naleznete v souboru cvinfo.h poskytnutém společností Microsoft. Existují dvě varianty záznamů, každá s vlastní sadou indexových čísel: ID typu a typy; v proudu 2 jsou uloženy pouze typy a v proudu 4 pouze ID typu. Indexy se používají k odkazování na tyto záznamy uvnitř záznamů symbolů a jiných záznamů typů.
- Záhlaví:
- Verze, 4 bajty.
- Velikost záhlaví, 4 bajty.
- Minimální a maximální (poslední + 1) index pro záznamy typů (každý 4 bajty).
- Velikost následujících dat, 4 bajty, do konce proudu.
- Hash informace:
- Číslo streamu, 2 bajty s výplní 2 bajty.
- Hash klíč, 4 bajty.
- Kufry, 4 bajty.
- HashVals, TiOff a HashAdj, každý složený z offsetu a délky, každý 4 bajty.
- Záznamy typu, proměnná délka, počet = (maximum – minimum) z výše uvedeného záhlaví.
Stream 3 je adresář pro ostatní streamy. Všimněte si, že není přítomen ve verzi 2 ani v PDB vytvořeném kompilátorem. Stream začíná hlavičkou, která je doplněna tak, aby měla celkem 64 bajtů
Offset | Size | Name | Description |
---|---|---|---|
0 | 4 | Signature | Identifikátor hlavičky, == 0xFFFFFFFFFF |
4 | 4 | HeaderVersion | Verze hlavičky |
8 | 4 | Age | |
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 | build verze pdb dll, která naposledy sestavila tuto pdb |
20 | 2 | snSymRecs | |
22 | 2 | VerPdbDllRBld | rbld verze pdb dll, která naposledy sestavila tuto pdb |
24 | 4 | cbGpModi | velikost podproudu rgmodi |
28 | 4 | cbSC | velikost podproudu Section Contribution |
32 | 4 | cbSecMap | velikost mapy sekcí |
36 | 4 | cbFileInfo | velikost proudu informací o souboru |
40 | 4 | cbTSMap | velikost podproudu Type Server Map |
44 | 4 | iMFC | MFC Index |
48 | 4 | cbDbgHdr | velikost nepovinné informace DbgHdr připojené na konec proudu |
52 | 4 | cbECInfo | počet bajtů v podproudu EC, nebo 0, pokud není EC povoleno 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 | identifikátor stroje, stejný jako se používá ve formátu objektu COFF, např.g., hex 8664 pro Intel x86 64-bit |
60 | 4 | RESERVED | budoucí rozšíření, pad na 64 bytů |
- Informace o modulu, proměnná délka. Celková velikost ve výše uvedeném záhlaví. Pro každý objektový modul používaný linkerem je jeden z nich
- Otevřeno, 4 bajty.
- Informace o symbolu.
- Číslo sekce, 2 bajty + 2 bajty padding.
- Odsazení a velikost, každá 4 bajty.
- Vlajky, 4 bajty.
- Číslo modulu, 2 bajty + 2 bajty padding.
- CRC pro data sekce a data relokace, každý 4 bajty.
- Příznaky, 2 bajty.
- Číslo proudu, 2 bajty.
- Velikost symbolů, 4 bajty.
- Velikost informací o starém a novém čísle řádku, po 4 bajtech.
- Počet zdrojových souborů, 2 bajty + 2 bajty výplň.
- Offsety, 4 bajty.
- niSource a niCompiler, po 4 bajtech.
- Název modulu, nulou ukončený řetězec bajtů.
- Název objektu, nulou ukončený řetězec bajtů.
- Padding na násobek 4 bajtů.
- Příspěvky sekcí, hlavičky sekcí, informace o souboru, mapa ts a informace o EC. Jejich velikosti se nacházejí ve výše uvedeném záhlaví.
- Záhlaví chyb,
- Čísla proudů pro vynechání ukazatele starého rámce, výjimky, opravy, mapy objektů do a ze zdroje, záhlaví sekcí, ID tokenringu, Xdata, Pdata, vynechání ukazatele nového rámce a původ záhlaví sekcí. Po 2 bajtech.