PDB 文件格式¶
简介¶
PDB(程序数据库)是微软发明的一种文件格式,其中包含调试器和其他工具可以使用的调试信息。由于 Windows 上存在官方支持的 API 用于从 PDB 中查询调试信息,即使用户不了解文件格式的内部细节,也构建了一个庞大的 Windows 工具生态系统来使用这种格式。为了让 Clang 能够生成可以与这些工具互操作的程序,我们需要自己生成 PDB 文件。
同时,LLVM 长期以来一直能够从任何平台交叉编译到任何平台,我们希望在这里也能做到这一点。因此,我们需要在字节级别上了解 PDB 文件格式,以便我们能够完全独立地生成 PDB 文件。
本手册描述了我们今天对 PDB 文件格式的了解。文件布局、其中包含的各种流、各个记录的格式等等。
我们要衷心感谢微软,没有他们,我们就不会取得今天的成就。本手册中的许多知识都来自于阅读微软在其 GitHub 代码库 上发布的代码。
文件布局¶
重要提示
除非另有说明,否则所有数值均以小端序编码。如果您看到诸如 uint16_t
或 uint64_t
之类的类型,请始终假设它是小端序!
MSF 容器¶
PDB 文件是 MSF(多流格式)文件。MSF 文件是“文件中的文件系统”。它包含多个流(也称为文件),这些流可以表示任意数据,并且这些流被划分为块,这些块在 MSF 容器文件中不一定连续布局。此外,MSF 包含一个流目录(也称为 MFT),它描述了流(文件)如何在 MSF 中布局。
有关 MSF 容器格式、流目录和块布局的更多信息,请参阅 MSF 文件格式。
流¶
PDB 格式包含许多流,这些流描述了程序的各种信息,例如类型、符号、源文件和编译单元(例如目标文件),以及一些包含哈希表的其他流,这些流由调试器和其他工具用于提供按名称快速查找记录和类型,以及有关程序编译方式的其他各种信息,例如使用的特定工具链等等。PDB 文件中包含的流摘要如下
名称 |
流索引 |
内容 |
---|---|---|
旧目录 |
|
|
PDB 流 |
|
|
TPI 流 |
|
|
DBI 流 |
|
|
IPI 流 |
|
|
/LinkInfo |
|
|
/src/headerblock |
|
|
/names |
|
|
模块信息流 |
|
|
公共流 |
|
|
全局流 |
|
|
TPI 哈希流 |
|
|
IPI 哈希流 |
|
|
可以在以下页面找到有关每个页面结构的更多信息
- PDB 信息流(也称为 PDB 流)
有关 PDB 信息流以及如何使用它将 PDB 与 EXE 匹配的信息。
- PDB TPI 和 IPI 流
有关 TPI 流以及其中包含的 CodeView 记录的信息。
- PDB DBI(调试信息)流
有关 DBI 流以及相关子流的信息,包括其中包含的模块子流、源文件信息和 CodeView 符号记录。
- 模块信息流
有关模块信息流的信息,每个编译单元一个,以及其中包含的符号格式。
- PDB 公共符号流
有关公共符号流的信息。
- PDB 全局符号流
有关全局符号流的信息。
- PDB 序列化哈希表格式
有关内部用于表示命名流映射和 TPI/IPI 流 中的哈希调整器的序列化哈希表格式的信息。
CodeView¶
CodeView 是另一种参与其中的格式。虽然 MSF 定义了整个文件的结构,PDB 定义了出现在 MSF 文件中的流集以及这些流的格式,但 CodeView 定义了出现在特定流中的**符号和类型记录**的格式。有关 CodeView 格式的更多信息,请参阅有关 CodeView 符号记录 和 CodeView 类型记录 的页面。