Programdatabase

PDB er en enkelt fil, som logisk set er sammensat af flere underfiler, kaldet streams. Den er designet til at optimere processen med at foretage ændringer i PDB’en, som udføres ved kompileringer og inkrementelle links. Streams kan fjernes, tilføjes eller udskiftes uden at omskrive andre streams, og ændringerne af de metadata, der beskriver streams, er ligeledes minimeret.

Den PDB er organiseret i sider af fast størrelse, typisk 1K, 2K eller 4K, der er nummereret fortløbende fra 0.

Bemærkning: Det antages, at alle numeriske oplysninger (f.eks, stream- og sidetal) er gemt i little-endian-form, den oprindelige form for Intel x86-baserede processorer. Python-koden pdbparse gør denne antagelse.

StreamEdit

Hver stream i PDB’en optager flere sider, som ikke nødvendigvis er fortløbende nummereret. Strømmen har et nummer og en længde. Streamens indhold er sammenkædningen af dens sider, afkortet til streamens længde.

Metadata formatEdit

Funktionen af PDB-metadata er at identificere alle komponentstreams og angive længden og rækkefølgen af sider for hver stream. Streams er nummereret fortløbende startende med 0. Der er også en rodstream, unummereret, som indeholder nogle af metadataene.

HeaderEdit

PDB’en begynder med en header, der består af:

  • Signatur, der bruges til at identificere og validere det specifikke format. Signaturens længde varierer med det specifikke format.
  • Resten af overskriften varierer med det format, der identificeres af signaturen.

Overskriften kan være længere end en enkelt side.

Microsoft-værktøjer bruger to PDB-formater:

Version 7Edit

Signaturen er "Microsoft C/C++ MSF 7.00\r\n\x1ADS"(32 byte).

Resten af overskriften består af:

  • Sidestørrelse, 4 bytes.
  • Allokeringstabellens pointer, 4 bytes. Betydningen af dette er ukendt. Der synes at være en allokeringstabel, et array på 65.536 bits (8.192 bytes), der er placeret i slutningen af PDB’en, og en 1-bit betyder en side, der ikke bruges.
  • Antal filsider, 4 bytes.
  • Root stream-størrelse, 4 bytes.
  • Reserved, 4 bytes.
  • Sidetal i listen over sidetal i Root stream-siden. Det angiver ikke placeringen af selve Root stream, men kun af den side, der indeholder den struktur, som peger på dens sider. På denne side angiver Root stream-sidenummerlisten de sider, hvor Root stream er gemt. Den indeholder 4 bytes pr. side, hvilket er nok til at dække ovenstående Root stream-størrelse.

Root streamEdit

Rot stream beskriver alle PDB streams startende med stream 0. Dens indhold varierer med PDB-formatversionen.

Version 2Rediger

Rodstrømmen består af:

  • Antal af strømme, 2 bytes.
  • Reserveret, 2 bytes.
  • For hver strøm:
    • Størrelse af strømmen, 4 bytes.
    • Reserveret, 4 bytes.
  • For hver stream:
    • Liste over streamens sidetal, 2 bytes pr. side, nok til at dække ovenstående streamstørrelse.

Version 7Edit

Rodstrømmen består af:

  • Antal af strømme, 4 bytes.
  • For hver strøm:
    • Størrelse af strømmen, 4 bytes.
  • For hver strøm:
    • Strømmenes sidetalsliste, 4 bytes pr. side, nok til at dække ovenstående strømstørrelse.

StrømindholdRedigér

Microsoft-værktøjer gemmer forskellige slags oplysninger i forskellige nummererede strømme. Nogle streamnumre har en fast informationstype tilknyttet, og andre streams identificeres i de førnævnte streams af fast type.

Stream 1 bruges til at verificere, at PDB’en er den samme fil, som der henvises til i en stream af en eksekverbar fil eller objektfil.

  • Version, 4 bytes.
  • Datostempel, 4 bytes.
  • Age, 4 bytes. Dette er antallet af gange, denne PDB er blevet ændret siden dens oprettelse.
  • GUID, 16 bytes.
  • Total længde af følgende navne, 4 bytes. Efterfulgt af null-terminerede tegnstrenge.

Stream 2 og stream 4 indeholder oplysninger om typer. De egentlige typeoptegnelser definerer de typer, der anvendes i programmet. Strukturen af disse poster findes i filen cvinfo.h, der leveres af Microsoft. Der er to slags poster med hver sit sæt indeksnumre: type-id’er og typer; kun typer gemmes i stream 2, og kun type-id’er gemmes i stream 4. Indeksene bruges til at henvise til disse poster fra symbolposter og andre typeposter.

  • En header:
    • Version, 4 bytes.
    • Hovedstørrelse, 4 bytes.
    • Minimum og maksimum (sidste + 1) indeks for typeposter (4 bytes hver).
    • Størrelse af følgende data, 4 bytes, til slutningen af strømmen.
  • Hash-informationer:
    • Streamnummer, 2 bytes med 2 bytes padding.
    • Hash-nøgle, 4 bytes.
    • Buckets, 4 bytes.
    • HashVals, TiOff og HashAdj, hver bestående af en offset og en længde, hver 4 bytes.
  • Type records, variabel længde, antal = (maksimum – minimum) fra ovenstående header.

Stream 3 er en mappe for andre streams. Bemærk, den er ikke til stede i version 2 og heller ikke i en PDB, der er produceret af en compiler. Strømmen starter med en header, som er polstret til at være 64 bytes i alt

PDB Stream 3 Header (struct NewDBIHdr)
Offset Size Name Description
0 4 Signature Header-identifikator, == 0xFFFFFFFFFFFF
4 4 HeaderVersion Version af 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 byggeversion af den pdb dll, der sidst byggede denne pdb
20 2 snSymRecs
22 2 VerPdbDllRBld rbld-version af den pdb dll, der sidst opbyggede denne pdb
24 4 cbGpModi størrelse af rgmodi-substream
28 4 cbSC størrelse af Section Contribution-substream
32 4 cbSecMap størrelse af sektionskort
36 4 cbFileInfo størrelse af filinformationsstrøm
40 4 cbTSMap størrelse af understrømmen til Type Server Map
44 4 iMFC MFC Index
48 4 4 cbDbgHdr størrelse af valgfri DbgHdr-info, der tilføjes til slutningen af strømmen
52 4 cbECInfo antal bytes i EC-substrømmen, eller 0, hvis ingen EC er aktiveret 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 Machineidentifikator, den samme som anvendes i COFF-objektformatet, f.eks.g., hex 8664 for Intel x86 64-bit
60 4 RESERVED future expansion, pad til 64 bytes
  • Modulinformation, variabel længde. Samlet størrelse i ovenstående header. Der er en af disse for hvert objektmodul, der anvendes af linkeren
    • Opened, 4 bytes.
    • Symbol info.
      • Sektionsnummer, 2 bytes + 2 bytes padding.
      • Offset og størrelse, 4 bytes hver.
      • Flags, 4 bytes.
      • Modulnummer, 2 bytes + 2 bytes padding.
      • CRC’er for sektionsdata og relokaliseringsdata, 4 bytes hver.
    • Flags, 2 bytes.
    • Streamnummer, 2 bytes.
    • Symbolstørrelse, 4 bytes.
    • 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.
    • Modulenavn, nul termineret byte-streng.
    • Objektnavn, nul termineret byte-streng.
    • Padding til et multiplum af 4 bytes.
  • Sektionsbidrag, sektionsoverskrifter, filinfo, ts map og EC-info. Deres størrelser findes i ovenstående header.
  • Debug header,
    • Streamnumre for Old Frame Pointer Omission, Exceptions, Fixups, Object Maps to and from Source, Section Headers, Token Ring IDs, Xdata, Pdata, New Frame Pointer Omission og Section Header Origin. 2 bytes hver.