PDB 文件格式¶
简介¶
PDB(程序数据库)是由 Microsoft 发明的一种文件格式,其中包含可供调试器和其他工具使用的调试信息。由于 Windows 上存在官方支持的 API,即使在用户不了解文件格式内部结构的情况下,也可以从 PDB 查询调试信息,因此已经为 Windows 构建了一个庞大的工具生态系统来使用此格式。为了使 Clang 能够生成可以与这些工具互操作的程序,我们有必要自行生成 PDB 文件。
与此同时,LLVM 在从任何平台交叉编译到任何平台方面有着悠久的历史,我们希望在这里也能如此。因此,我们有必要在字节级别上理解 PDB 文件格式,以便我们完全自主地生成 PDB 文件。
本手册描述了我们今天所知的关于 PDB 文件格式的信息。包括文件的布局、其中包含的各种流、流中各个记录的格式等等。
我们要衷心感谢 Microsoft,没有他们,我们就不会有今天的成就。本手册中包含的大部分知识是通过阅读 Microsoft 在其 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 类型记录 的页面。