Het VOB is een enkel bestand dat logisch is opgebouwd uit verschillende subbestanden, streams genaamd. Het is ontworpen om het proces van het aanbrengen van wijzigingen in de VOB, zoals uitgevoerd door compilaties en incrementele koppelingen, te optimaliseren. Streams kunnen worden verwijderd, toegevoegd of vervangen zonder andere streams te herschrijven, en de veranderingen in de metadata die de streams beschrijven worden ook geminimaliseerd.
De VOB is georganiseerd in pagina’s met een vaste grootte, gewoonlijk 1K, 2K, of 4K, opeenvolgend genummerd beginnend bij 0.
Note: Er wordt aangenomen dat alle numerieke informatie (b.v, stream en pagina nummers) is opgeslagen in little-endian vorm, de native vorm voor Intel x86 gebaseerde processoren. De pdbparse Python code gaat uit van deze veronderstelling.
StreamEdit
Elke stream in de PDB beslaat meerdere pagina’s, die niet noodzakelijkerwijs opeenvolgend genummerd zijn. De stroom heeft een nummer en een lengte. De stream-inhoud is de aaneenschakeling van de pagina’s, afgekapt tot de lengte van de stream.
Metadata formaatEdit
De functie van de PDB metadata is het identificeren van alle samenstellende streams, met vermelding van de lengte, en de volgorde van de pagina’s voor elke stream. De streams zijn opeenvolgend genummerd, beginnend bij 0. Er is ook een basisstream, ongenummerd, die een deel van de metadata bevat.
HeaderEdit
Het PDB begint met een header, bestaande uit:
- Signature, gebruikt om het specifieke formaat te identificeren en te valideren. De lengte van de handtekening varieert met het specifieke formaat.
- De rest van de header varieert met het door de handtekening geïdentificeerde formaat.
De header kan langer zijn dan een enkele pagina.
Microsoft programma’s gebruiken twee PDB formaten:
Versie 7Edit
Handtekening is "Microsoft C/C++ MSF 7.00\r\n\x1ADS"
(32 bytes).
Het restant van de header bestaat uit:
- Paginagrootte, 4 bytes.
- Allocatietabel pointer, 4 bytes. De betekenis hiervan is onbekend. Er lijkt een toewijzingstabel te zijn, een array van 65.536 bits (8.192 bytes), aan het eind van de PDB, en een 1-bit betekent een pagina die niet wordt gebruikt.
- Aantal bestandspagina’s, 4 bytes.
- Root stream grootte, 4 bytes.
- gereserveerd, 4 bytes.
- Paginanummer van de Root stream paginanummerlijst. Het geeft niet de locatie van de Root stream zelf aan, maar alleen van de pagina die de structuur bevat die naar zijn pagina’s verwijst. Op die pagina geeft de Root stream paginanummerlijst de pagina’s aan waar de Root stream is opgeslagen. Het bevat 4 bytes per pagina, genoeg om de bovenstaande Root stream grootte te dekken.
Root streamEdit
De root stream beschrijft alle PDB streams beginnend met stream 0. De inhoud varieert met de PDB formaat versie.
Versie 2Edit
De root stream bestaat uit:
- Aantal streams, 2 bytes.
- Reserveerd, 2 bytes.
- Voor elke stream:
- Stream grootte, 4 bytes.
- Reserveerd, 4 bytes.
- Voor elke stream:
- Paginanummerlijst van de stream, 2 bytes per pagina, genoeg om bovenstaande streamgrootte te dekken.
Versie 7Edit
De root stream bestaat uit:
- Aantal streams, 4 bytes.
- Voor elke stream:
- Streamgrootte, 4 bytes.
- Voor elke stream:
- Stream-paginanummerlijst, 4 bytes per pagina, genoeg om bovenstaande streamgrootte te dekken.
StreaminhoudEdit
Microsoft-programma’s slaan verschillende soorten informatie op in verschillende genummerde streams. Aan sommige stream-nummers is een vast informatietype gekoppeld, en andere streams worden geïdentificeerd in de eerder genoemde streams van een vast type.
Stream 1 wordt gebruikt om te controleren of het PDB hetzelfde bestand is als waarnaar wordt verwezen in een uitvoerbaar bestand of objectbestandsstream.
- Versie, 4 bytes.
- Tijd-datumstempel, 4 bytes.
- Age, 4 bytes. Dit is het aantal keren dat deze PDB is gewijzigd sinds de creatie.
- GUID, 16 bytes.
- Totale lengte van de volgende namen, 4 bytes. Gevolgd door null-terminated tekenreeksen.
Stream 2 en stream 4 bevatten informatie over typen. De eigenlijke type-records definiëren de types die in het programma worden gebruikt. De structuur van deze records kan worden gevonden in het bestand cvinfo.h dat door Microsoft wordt geleverd. Er zijn twee soorten records, elk met zijn eigen set indexnummers: type ID’s en types; alleen types worden opgeslagen in stream 2 en alleen type ID’s worden opgeslagen in stream 4. De indexen worden gebruikt om naar deze records te verwijzen vanuit symboolrecords en andere type-records.
- Een header:
- Versie, 4 bytes.
- Grootte van de header, 4 bytes.
- Minimale en maximale (laatste + 1) index voor type-records (elk 4 bytes).
- Grootte van de volgende gegevens, 4 bytes, tot aan het einde van de stroom.
- Hash-informatie:
- Stream-nummer, 2 bytes met 2 bytes opvulling.
- Hash-sleutel, 4 bytes.
- Buckets, 4 bytes.
- HashVals, TiOff, en HashAdj, elk bestaande uit een offset en lengte, elk 4 bytes.
- Type records, variabele lengte, count = (maximum – minimum) van bovenstaande header.
Stream 3 is een directory voor andere streams. Merk op, dat deze niet aanwezig is in versie 2, noch in een door een compiler geproduceerde PDB. De stream begint met een header die is opgevuld tot 64 bytes in totaal
Offset | Size | Name | Description |
---|---|---|---|
0 | 4 | Signature | Header identifier, == 0xFFFFFF |
4 | 4 | HeaderVersion | Version of the Header |
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 | bouw versie van de pdb dll waarmee deze pdb het laatst is gebouwd |
20 | 2 | snSymRecs | |
22 | 2 | VerPdbDllRBld | rbld versie van de pdb dll die deze pdb het laatst gebouwd heeft |
24 | 4 | cbGpModi | grootte van rgmodi substroom |
28 | 4 | cbSC | grootte van Sectie Bijdrage substroom |
32 | 4 | cbSecMap | size of section map |
36 | 4 | cbFileInfo | size of file info stream |
40 | 4 | cbTSMap | grootte van de Type Server Map-substroom |
44 | 4 | iMFC | MFC Index |
48 | 4 | cbDbgHdr | grootte van optionele DbgHdr info toegevoegd aan het eind van de stream |
52 | 4 | cbECInfo | aantal bytes in EC-substroom, of 0 indien geen EC ingeschakeld 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 | Machine-identifier, dezelfde als gebruikt in COFF object format, bijv.g., hex 8664 voor Intel x86 64-bit |
60 | 4 | RESERVED | toekomstige uitbreiding, opvulling tot 64 bytes |
- Module-informatie, variabele lengte. Totale grootte in bovenstaande header. Er is een van deze voor elke object module gebruikt door de linker
- Opened, 4 bytes.
- Symbool info.
- Sectienummer, 2 bytes + 2 bytes padding.
- Offset en grootte, 4 bytes elk.
- Flags, 4 bytes.
- Modulenummer, 2 bytes + 2 bytes padding.
- CRCs voor sectiegegevens en relocatiegegevens, elk 4 bytes.
- Flags, 2 bytes.
- Streamnummer, 2 bytes.
- Symbolengrootte, 4 bytes.
- Old en new line number info sizes, elk 4 bytes.
- Aantal bronbestanden, 2 bytes + 2 bytes padding.
- Offsets, 4 bytes.
- niSource en niCompiler, elk 4 bytes.
- Modulenaam, bytestring met null-afsluiting.
- Objectnaam, bytestring met null-afsluiting.
- Padding tot een veelvoud van 4 bytes.
- Sectiebijdragen, sectieheaders, bestandsinfo, ts map, en EC info. Hun grootte staat in de bovenstaande header.
- Debug header,
- Stream nummers voor Old Frame Pointer Omission, Exceptions, Fixups, Object Maps to and from Source, Section Headers, Token Ring IDs, Xdata, Pdata, New Frame Pointer Omission, en Section Header Origin. Elk 2 bytes.