O PDB é um ficheiro único que é logicamente composto por vários sub-files, chamados streams. Ele é projetado para otimizar o processo de fazer alterações no PDB, conforme realizado através de compilações e links incrementais. Os fluxos podem ser removidos, adicionados ou substituídos sem reescrever quaisquer outros fluxos, e as alterações nos metadados que descrevem os fluxos também são minimizadas.
O PDB é organizado em páginas de tamanho fixo, tipicamente 1K, 2K, ou 4K, numeradas consecutivamente começando em 0.
Nota: Presume-se que toda a informação numérica (por exemplo e números de páginas) é armazenada na forma little-endian, a forma nativa para processadores baseados em Intel x86. O código pdbparse Python faz esta suposição.
StreamEdit
Cada stream no PDB ocupa várias páginas, que não são necessariamente numeradas consecutivamente. O fluxo tem um número e um comprimento. O conteúdo do fluxo é a concatenação das suas páginas, truncado ao comprimento do fluxo.
Metadata formatEdit
A função dos metadados do PDB é identificar todos os fluxos componentes, dando o comprimento, e a sequência de páginas para cada fluxo. Os fluxos são numerados consecutivamente começando por 0. Existe também um fluxo raiz, não numerado, que contém alguns dos metadados.
HeaderEdit
O PDB começa com um cabeçalho, consistindo em:
- Signature, usado para identificar e validar o formato específico. O comprimento da assinatura varia com o formato específico.
- O restante do cabeçalho varia com o formato identificado pela assinatura.
O cabeçalho pode ser maior que uma única página.
Ferramentas da Microsoft usam dois formatos PDB:
Versão 7Edit
Signatura é "Microsoft C/C++ MSF 7.00\r\n\x1ADS"
(32 bytes).
Remainder do cabeçalho consiste em:
- Página tamanho, 4 bytes.
- Ponteiro da tabela de alocação, 4 bytes. O significado disto é desconhecido. Parece haver uma tabela de alocação, um array de 65.536 bits (8.192 bytes), localizado no final do PDB, e um 1 bit significa uma página que não está sendo usada.
- Número de páginas de arquivo, 4 bytes.
- Tamanho do fluxo raiz, 4 bytes.
- reservado, 4 bytes.
- Número de página da lista de número de página do fluxo raiz. Não indica a localização do Root stream em si, apenas da página que contém a estrutura que aponta para as suas páginas. Nessa página, a lista de número de página Root stream indica as páginas onde o Root stream está armazenado. Ela contém 4 bytes por página, o suficiente para cobrir o tamanho do fluxo Raiz acima.
Root streamEdit
O fluxo raiz descreve todos os fluxos PDB que começam com o fluxo 0. Seu conteúdo varia com a versão em formato PDB.
Versão 2Editar
O fluxo raiz consiste em:
- Número de fluxos, 2 bytes.
- Reservado, 2 bytes.
- Para cada fluxo:
- Tamanho do fluxo, 4 bytes.
- Reservado, 4 bytes.
- Para cada stream:
- Lista de número de página do stream, 2 bytes por página, o suficiente para cobrir o tamanho do stream acima.
Versão 7Editar
O fluxo raiz consiste em:
- Número de fluxos, 4 bytes.
- Para cada fluxo:
- Tamanho do fluxo, 4 bytes.
- Para cada stream:
- Lista de números de página do stream, 4 bytes por página, o suficiente para cobrir o tamanho do stream acima.
Conteúdo do streamEditar
Ferramentas da Microsoft armazenam diferentes tipos de informação em diferentes streams numerados. Alguns números de stream têm um tipo de informação fixo associado a eles, e outros streams são identificados nos streams do tipo fixo acima mencionados.
Stream 1 é usado para verificar se o PDB é o mesmo arquivo referido em um stream executável ou objeto.
- Version, 4 bytes.
- Time date stamp, 4 bytes.
- Age, 4 bytes. Este é o número de vezes que este PDB foi modificado desde a sua criação.
- GUID, 16 bytes.
- Comprimento total dos seguintes nomes, 4 bytes. Seguido por cadeias de caracteres de terminação nula.
Tream 2 e stream 4 informação dos tipos de retenção. Os registros de tipos reais definem os tipos usados no programa. A estrutura desses registros pode ser encontrada no arquivo cvinfo.h fornecido pela Microsoft. Há dois sabores de registros, cada um com seu próprio conjunto de números de índice: tipo IDs e tipos; apenas tipos são armazenados no fluxo 2 e apenas tipos IDs são armazenados no fluxo 4. Os índices são usados para se referir a esses registros de dentro de registros de símbolos e outros tipos de registros.
- Cabeçalho:
- Versão, 4 bytes.
- Tamanho do cabeçalho, 4 bytes.
- Índice mínimo e máximo (último + 1) para registros de tipos (4 bytes cada).
- Tamanho dos seguintes dados, 4 bytes, até o final do fluxo.
- Informação de hash:
- Número do fluxo, 2 bytes com 2 bytes de preenchimento.
- Tecla de hash, 4 bytes.
- Buckets, 4 bytes.
- HashVals, TiOff, e HashAdj, cada um composto de um offset e comprimento, cada 4 bytes.
- Digite registros, comprimento variável, contagem = (máximo – mínimo) do cabeçalho acima.
Stream 3 é um diretório para outros streams. Nota, não está presente na Versão 2, nem num PDB produzido por um compilador. O stream começa com um cabeçalho que é acolchoado para ser 64 bytes no total
Configuração | Tamanho | Nome | Descrição |
---|---|---|---|
0 | 4 | Assinatura | Identificador do cabeçalho, == 0xFFFFFFFFFF |
4 | 4 | Versão do Cabeçalho | Versão do Cabeçalho |
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 version of the pdb dll that built this pdb last |
20 | 2 | snSymRecs | |
22 | 2 | VerPdbDllRBld | versão da dll da pdb que construiu esta última pdb |
24 | 4 | cbGpModi | tamanho do substrato rgmodi |
28 | 4 | cbSC | tamanho da Seção Substrato de contribuição |
32 | 4 | cbSecMap | tamanho do mapa de secção |
36 | 4 | cbFileInfo | tamanho do fluxo de informação do ficheiro |
40 | 4 | cbTSMap | tamanho do sub-grupo do Mapa do Servidor do Tipo |
44 | 4 | iMFC | Índice do MFC |
48 | 4 | cbDbgHdr | tamanho da informação opcional DbgHdr anexada ao final do fluxo |
52 | 4 | cbECInfo | número de bytes no sub-corrente CE, ou 0 se nenhum Mods activado pelo CE |
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 | Identificador da máquina, igual ao usado no formato de objecto COFF, e.g., hex 8664 para Intel x86 64-bit |
60 | 4 | RESERVADO | expansão futura, pad para 64 bytes |
- Informação do módulo, comprimento variável. Tamanho total no cabeçalho acima. Há um destes para cada módulo de objeto usado pelo linker
- Aberto, 4 bytes.
- Informação de símbolos.
- Número da seção, 2 bytes + 2 bytes de preenchimento.
- Deslocamento e tamanho, 4 bytes cada.
- Flags, 4 bytes.
- Número do módulo, 2 bytes + 2 bytes de preenchimento.
- CRCs para dados da seção e dados de realocação, 4 bytes cada.
- Flags, 2 bytes.
- Número do fluxo, 2 bytes.
- Tamanho dos símbolos, 4 bytes cada.
- Número de linhas novas e antigas, 4 bytes cada.
- Número de arquivos fonte, 2 bytes + 2 bytes de preenchimento.
- Offets, 4 bytes.
- niSource e niCompiler, 4 bytes cada.
- Nome do módulo, string de bytes terminada nula.
- Nome do objeto, string de bytes terminada nula.
- Padding para múltiplos de 4 bytes.
- Números de fluxo para Omissão do Ponteiro do Quadro Antigo, Exceções, Fixups, Mapas de Objetos de e para a Fonte, Cabeçalhos de Seção, IDs de Token Ring, Xdata, Pdata, Omissão do Ponteiro do Novo Quadro, e Origem do Cabeçalho de Seção. 2 bytes cada.