Database del programma

Il PDB è un singolo file che è logicamente composto da diversi sotto-file, chiamati stream. È progettato per ottimizzare il processo di apportare modifiche al PDB, come eseguito da compilazioni e collegamenti incrementali. I flussi possono essere rimossi, aggiunti o sostituiti senza riscrivere nessun altro flusso, e anche i cambiamenti ai metadati che descrivono i flussi sono ridotti al minimo.

Il PDB è organizzato in pagine di dimensione fissa, tipicamente 1K, 2K, o 4K, numerate consecutivamente a partire da 0.

Nota: Si presume che tutte le informazioni numeriche (es, stream e numeri di pagina) siano memorizzate in forma little-endian, la forma nativa per i processori Intel x86. Il codice Python di pdbparse fa questa assunzione.

StreamEdit

Ogni flusso nel PDB occupa diverse pagine, che non sono necessariamente numerate consecutivamente. Il flusso ha un numero e una lunghezza. Il contenuto del flusso è la concatenazione delle sue pagine, troncate alla lunghezza del flusso.

Formato dei metadatiEdit

La funzione dei metadati PDB è di identificare tutti i flussi componenti, dando la lunghezza e la sequenza delle pagine per ogni flusso. I flussi sono numerati consecutivamente a partire da 0. C’è anche un flusso principale, non numerato, che contiene alcuni dei metadati.

HeaderEdit

Il PDB inizia con un header, composto da:

  • Signature, usato per identificare e validare il formato specifico. La lunghezza della firma varia con il formato specifico.
  • Il resto dell’intestazione varia con il formato identificato dalla firma.

L’intestazione può essere più lunga di una singola pagina.

Gli strumenti Microsoft usano due formati PDB:

Versione 7Edit

La firma è "Microsoft C/C++ MSF 7.00\r\n\x1ADS"(32 byte).

Il resto dell’intestazione consiste in:

  • Dimensione della pagina, 4 byte.
  • Puntatore alla tabella di assegnazione, 4 byte. Il significato di questo è sconosciuto. Sembra che ci sia una tabella di allocazione, una matrice di 65.536 bit (8.192 byte), situata alla fine del PDB, e un bit 1 significa una pagina non utilizzata.
  • Numero di pagine del file, 4 byte.
  • Dimensione del flusso principale, 4 byte.
  • riservato, 4 byte.
  • Numero di pagina della lista del numero di pagina del flusso principale. Non indica la posizione del Root stream stesso, ma solo della pagina contenente la struttura che punta alle sue pagine. In quella pagina, l’elenco dei numeri di pagina del flusso radice indica le pagine in cui è memorizzato il flusso radice. Contiene 4 byte per pagina, sufficienti a coprire la dimensione del Root stream di cui sopra.

Root streamEdit

Il root stream descrive tutti i flussi PDB a partire dal flusso 0. Il suo contenuto varia con la versione del formato PDB.

Versione 2Modifica

Il root stream consiste in:

  • Numero di stream, 2 byte.
  • Riservato, 2 byte.
  • Per ogni stream:
    • Dimensione stream, 4 byte.
    • Riservato, 4 byte.
  • Per ogni flusso:
    • Lista numero di pagina del flusso, 2 byte per pagina, abbastanza per coprire le dimensioni del flusso.

Versione 7Edit

Il root stream consiste in:

  • Numero di stream, 4 byte.
  • Per ogni stream:
    • Dimensione stream, 4 byte.
  • Per ogni flusso:
    • Elenco dei numeri di pagina del flusso, 4 byte per pagina, abbastanza per coprire le dimensioni del flusso.

Contenuto del flussoEdit

Gli strumenti Microsoft memorizzano diversi tipi di informazioni in diversi flussi numerati. Alcuni numeri di stream hanno un tipo di informazione fisso associato ad essi, e altri stream sono identificati nei suddetti stream di tipo fisso.

Stream 1 è usato per verificare che il PDB è lo stesso file a cui si fa riferimento in uno stream di file eseguibile o oggetto.

  • Versione, 4 byte.
  • Time date stamp, 4 byte.
  • Age, 4 byte. Questo è il numero di volte che questo PDB è stato modificato dalla sua creazione.
  • GUID, 16 byte.
  • Lunghezza totale dei nomi seguenti, 4 byte. Seguiti da stringhe di caratteri null-terminati.

Il flusso 2 e il flusso 4 contengono informazioni sui tipi. I record dei tipi effettivi definiscono i tipi usati nel programma. La struttura di questi record può essere trovata nel file cvinfo.h fornito da Microsoft. Ci sono due tipi di record, ognuno con il proprio set di numeri di indice: ID dei tipi e tipi; solo i tipi sono memorizzati nel flusso 2 e solo gli ID dei tipi sono memorizzati nel flusso 4. Gli indici sono usati per riferirsi a questi record dall’interno di record di simboli e altri record di tipi.

  • Un’intestazione:
    • Versione, 4 byte.
    • Dimensione dell’intestazione, 4 byte.
    • Indice minimo e massimo (ultimo + 1) per i record di tipi (4 byte ciascuno).
    • Dimensione dei dati seguenti, 4 byte, alla fine del flusso.
  • Informazioni Hash:
    • Numero del flusso, 2 byte con 2 byte di padding.
    • Chiave Hash, 4 byte.
    • Bucket, 4 byte.
    • HashVals, TiOff, e HashAdj, ciascuno composto da un offset e lunghezza, ciascuno 4 byte.
  • Registri di tipo, lunghezza variabile, conteggio = (massimo – minimo) dall’intestazione precedente.

Stream 3 è una directory per altri flussi. Da notare che non è presente nella versione 2, né in un PDB prodotto da un compilatore. Il flusso inizia con un’intestazione che è imbottita per essere 64 byte in totale

PDB Stream 3 Header (struct NewDBIHdr)
Offset Size Nome Descrizione
0 4 Signature Header identifier, == 0xFFFFFFFF
4 4 HeaderVersion Versione dell’intestazione
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 versione della dll pdb che ha costruito questo pdb per ultima
20 2 snSymRecs
22 2 VerPdbDllRBld rbld versione della dll pdb che ha costruito questo pdb per ultimo
24 4 cbGpModi dimensione del substream rgmodi
28 4 cbSC dimensione del substream Section Contribution
32 4 cbSecMap dimensione della mappa delle sezioni
36 4 cbFileInfo dimensione del flusso di informazioni sui file
40 4 cbTSMap dimensione del substream Type Server Map
44 4 iMFC MFC Index
48 4 cbDbgHdr dimensione delle informazioni opzionali DbgHdr aggiunte alla fine del flusso
52 4 cbECInfo numero di byte nel substream EC, o 0 se nessun EC abilitato 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 identificatore di macchina, lo stesso usato nel formato oggetto COFF, es.g., hex 8664 per Intel x86 64-bit
60 4 RESERVED espansione futura, pad a 64 byte
  • Informazioni sul modulo, lunghezza variabile. Dimensione totale nell’intestazione di cui sopra. Ce n’è uno per ogni modulo oggetto usato dal linker
    • Aperto, 4 byte.
    • Informazioni sul simbolo.
      • Numero sezione, 2 byte + 2 byte padding.
      • Offset e dimensione, 4 byte ciascuno.
      • Flags, 4 byte.
      • Numero di modulo, 2 byte + 2 byte di padding.
      • CRC per dati di sezione e dati di rilocazione, 4 byte ciascuno.
    • Flags, 2 byte.
    • Numero di stream, 2 byte.
    • Dimensione simboli, 4 byte.
    • Dimensioni info vecchio e nuovo numero di linea, 4 byte ciascuno.
    • Numero di file sorgente, 2 byte + 2 byte padding.
    • Offset, 4 byte.
    • niSource e niCompiler, 4 byte ciascuno.
    • Nome del modulo, stringa di byte con terminazione nulla.
    • Nome dell’oggetto, stringa di byte con terminazione nulla.
    • Padding a multipli di 4 byte.
  • Contributi alle sezioni, intestazioni di sezione, informazioni sul file, mappa ts e informazioni EC. Le loro dimensioni si trovano nell’intestazione di cui sopra.
  • Intestazione di debug,
    • Numeri di stream per Old Frame Pointer Omission, Exceptions, Fixups, Object Maps to and from Source, Section Headers, Token Ring IDs, Xdata, Pdata, New Frame Pointer Omission, e Section Header Origin. 2 byte ciascuno.