llvm-pdbutil - PDB 文件取证和诊断

摘要

llvm-pdbutil [子命令] [选项]

描述

显示 PDB 文件中的类型、符号、CodeView 记录和其他信息,以及操作和创建 PDB 文件。llvm-pdbutil 通常由基于 FileCheck 的测试用于测试 LLVM 的 PDB 读取和写入功能,但也可用于一般的 PDB 文件调查和取证,或作为 cvdump 的替代品。

子命令

llvm-pdbutil 被分成几个子命令,每个子命令都针对不同的目的。下面简要概述了每个命令,并在后续部分详细介绍。

  • pretty - 以尽可能接近原始源代码的格式转储符号和类型信息。

  • dump - 转储 PDB 文件中的低级类型和结构,包括 CodeView 记录、哈希表、PDB 流等。

  • bytes - 将 PDB 文件的流、记录、类型、符号等中的数据作为原始字节转储。

  • yaml2pdb - 给定 PDB 文件的 yaml 描述,生成一个与该描述匹配的有效 PDB 文件。

  • pdb2yaml - 对于给定的 PDB 文件,以可以重建 PDB 的方式生成文件部分或全部的 YAML 描述。

  • merge - 给定两个 PDB,生成第三个 PDB,它是合并这两个输入 PDB 的结果。

pretty

重要

pretty 子命令构建在 Windows DIA SDK 上,因此在非 Windows 平台上不受支持。

用法:llvm-pdbutil pretty [选项] <输入 PDB 文件>

概述

pretty 子命令显示程序调试信息的非常高级别的表示形式。由于它构建在 Windows DIA SDK 上,而 DIA SDK 是 Windows 工具和调试器查询调试信息的标准 API,因此它提供了关于调试器如何解释调试信息的更权威的视图,而不是显示低级 CodeView 记录的模式。

选项

过滤和排序选项

注意

exclude 过滤器优先于 include 过滤器。因此,如果一个过滤器同时匹配包含和排除规则,则它将被排除。

-exclude-compilands=<字符串>

在转储编译单元、编译单元源文件贡献或每个编译单元的符号时,此选项指示 llvm-pdbutil 忽略与指定正则表达式匹配的任何编译单元。

-exclude-symbols=<字符串>

在转储全局、公共或每个编译单元的符号时,此选项指示 llvm-pdbutil 忽略与指定正则表达式匹配的任何符号。

-exclude-types=<字符串>

在转储类型时,此选项指示 llvm-pdbutil 忽略与指定正则表达式匹配的任何类型。

-include-compilands=<字符串>

在转储编译单元、编译单元源文件贡献或每个编译单元的符号时,将初始搜索限制为仅与指定正则表达式匹配的那些编译单元。

-include-symbols=<字符串>

在转储全局、公共或每个编译单元的符号时,将初始搜索限制为仅与指定正则表达式匹配的那些符号。

-include-types=<字符串>

在转储类型时,将初始搜索限制为仅与指定正则表达式匹配的那些类型。

-min-class-padding=<无符号整数>

仅显示至少具有指定对齐填充量的类型,考虑基类和聚合字段成员中的填充。

-min-class-padding-imm=<无符号整数>

仅显示至少具有指定对齐填充量的类型,忽略基类和聚合字段成员中的填充。

-min-type-size=<无符号整数>

仅显示类型 T,其中 sizeof(T) 大于或等于指定数量。

-no-compiler-generated

不显示编译器生成的类型和符号

-no-enum-definitions

在转储枚举时,不显示完整的枚举(例如,各个枚举值)。

-no-system-libs

不显示来自系统库的符号

符号类型选项
-all

隐含此类别中的所有其他选项。

-class-definitions=<格式>

以指定的格式显示类定义。

=all      - Display all class members including data, constants, typedefs, functions, etc (default)
=layout   - Only display members that contribute to class size.
=none     - Don't display class definitions (e.g. only display the name and base list)
-class-order

以指定的顺序显示类。

=none            - Undefined / no particular sort order (default)
=name            - Sort classes by name
=size            - Sort classes by size
=padding         - Sort classes by amount of padding
=padding-pct     - Sort classes by percentage of space consumed by padding
=padding-imm     - Sort classes by amount of immediate padding
=padding-pct-imm - Sort classes by percentage of space consumed by immediate padding
-class-recurse-depth=<无符号整数>

在转储类定义时,在递归指定次数后停止。默认为 0,表示没有限制。

-classes

显示类

-compilands

显示编译单元(例如,目标文件)

-enums

显示枚举

-externals

转储外部(例如,导出)符号

-globals

转储全局符号

-lines

转储源代码行和代码地址之间的映射。

-module-syms

显示每个编译单元的符号(变量、函数等)

-sym-types=<类型>

指定 -globals、-externals 或 -module-syms 时要转储的符号类型。(默认为全部)

=thunks - Display thunk symbols
=data   - Display data symbols
=funcs  - Display function symbols
=all    - Display all symbols (default)
-symbol-order=<顺序>

对于通过 -module-syms、-globals 或 -externals 选项转储的符号,按指定顺序对结果进行排序。

=none - Undefined / no particular sort order
=name - Sort symbols by name
=size - Sort symbols by size
-typedefs

显示 typedef 类型

-types

显示所有类型(隐含 -classes、-enums、-typedefs)

其他选项
-color-output

强制开启或关闭彩色输出。默认情况下,如果输出到终端,则使用颜色。

-load-address=<uint>

在显示相对虚拟地址时,假设进程加载到给定地址,并显示绝对地址。

dump

用法:llvm-pdbutil dump [选项] <输入 PDB 文件>

摘要

dump 子命令显示有关 PDB 文件结构的低级信息。LLVM 的测试基础设施大量使用它,但也可以用于 PDB 取证。它扮演的角色类似于 Microsoft 的 cvdump 工具。

注意

dump 子命令公开了文件格式的内部细节。因此,读者在使用此命令之前应该熟悉 PDB 文件格式

选项

MSF 容器选项
-streams

转储 PDB 文件中所有流的摘要。

-stream-blocks

-streams 结合使用,向输出中添加有关指定流占据哪些块的信息。

-summary

转储 MSF 和 PDB 头信息。

模块和文件选项
-modi=<uint>

对于所有从每个模块/编译单元转储信息选项,限制为指定的模块。

-files

转储有助于每个显示的模块的源文件。

-il

转储内联行信息(DEBUG_S_INLINEELINES CodeView 子节)

-l

转储行信息(DEBUG_S_LINES CodeView 子节)

-modules

转储编译单元信息

-xme

转储跨模块导出(DEBUG_S_CROSSSCOPEEXPORTS CodeView 子节)

-xmi

转储跨模块导入(DEBUG_S_CROSSSCOPEIMPORTS CodeView 子节)

符号选项
-globals

转储全局符号记录

-global-extras

转储有关全局变量的其他信息,例如哈希桶和哈希值。

-publics

转储公共符号记录

-public-extras

转储有关公共符号的其他信息,例如哈希桶和哈希值。

-symbols

转储每个转储模块的符号(函数、变量等)。

-sym-data

对于作为 -symbols 选项结果转储的每个符号记录,也以二进制形式显示记录的完整字节。

类型记录选项
-types

转储来自 TPI 流的 CodeView 类型记录

-type-extras

转储来自 TPI 流的其他信息,例如哈希和类型索引偏移数组。

-type-data

对于转储的每个类型记录,也以二进制形式显示记录的完整字节。

-type-index=<uint>

仅转储具有指定类型索引的类型。

-ids

转储来自 IPI 流的 CodeView 类型记录。

-id-extras

转储来自 IPI 流的其他信息,例如哈希和类型索引偏移数组。

-id-data

对于转储的每个 ID 记录,也以二进制形式显示记录的完整字节。

-id-index=<uint>

仅转储具有指定十六进制类型索引的 ID 记录。

-dependents

-type-index-id-index 结合使用时,转储指定索引的整个依赖关系图,而不仅仅是具有指定索引的单个记录。例如,如果类型索引 0x4000 是一个函数,其返回值类型索引为 0x3000,并且您指定 -dependents=0x4000,则这将转储这两个记录(以及树中的任何其他依赖项)。

其他选项
-all

隐含大多数其他选项。

-section-contribs

转储节贡献。

-section-headers

转储映像节标头。

-section-map

转储节映射。

-string-table

转储 PDB 字符串表。

bytes

用法:llvm-pdbutil bytes [选项] <输入 PDB 文件>

摘要

dump 子命令类似,bytes 子命令显示有关 PDB 文件结构的低级信息,但它用于更深入的取证。bytes 子命令根据指定的命令行选项在 PDB 文件中查找各种结构,并以十六进制格式转储它们。例如,从事 PDB 发射支持工作的人员会大量使用它,以比较一个 PDB 与另一个 PDB,以确保字节级兼容性。仅仅比较整个文件或整个流的字节是不够的,因为相同结构存在于两个不同 PDB 中的不同位置是完全可以的,“查找”结构是成功的一半。

选项

MSF 文件选项
-block-range=<start[-end]>

转储来自指定 MSF 文件块范围的二进制数据。

-byte-range=<start[-end]>

转储来自文件中指定字节范围的二进制数据。

-fpm

转储 MSF 空闲页面映射。

-stream-data=<string>

转储指定流中的二进制数据。格式为 SN[:Start][@Size]。例如,-stream-data=7:3@12 从流 7 中转储 12 个字节,从流中的偏移量 3 开始。

PDB 流选项
-name-map

转储 PDB 名称映射的字节。

DBI 流选项
-ec

转储 DBI 流的编辑和继续映射子流。

-files

转储 DBI 流的文件信息子流。

-modi

转储 DBI 流的 modi 子流。

-sc

转储 DBI 流的节贡献子流。

-sm

转储 DBI 流中的节映射。

-type-server

转储 DBI 流中的类型服务器映射。

模块选项
-mod=<uint>

将此类别中的所有选项限制为指定的模块索引。默认情况下,此类别中的选项将从所有模块转储字节。

-chunks

转储每个模块的 C13 调试子部分的字节。

-split-chunks

当与 -chunks 一起指定时,将 C13 调试子部分拆分为每个子部分类型的单独块,并分别转储它们。

-syms

转储每个模块的符号记录子流。

类型记录选项
-id=<uint>

转储 IPI 流中具有给定类型索引的记录。

-type=<uint>

转储 TPI 流中具有给定类型索引的记录。

pdb2yaml

用法:llvm-pdbutil pdb2yaml [选项] <输入 PDB 文件>

摘要

选项

yaml2pdb

用法:llvm-pdbutil yaml2pdb [选项] <输入 YAML 文件>

摘要

从 YAML 描述生成 PDB 文件。YAML 语法此处未作描述。而是使用 llvm-pdbutil pdb2yaml 并检查输出以获取示例起点。

选项

-pdb=<file-name>

将生成的 PDB 写入指定的文件。

合并

用法:llvm-pdbutil merge [选项] <输入 PDB 文件 1> <输入 PDB 文件 2>

摘要

将两个 PDB 文件合并到一个文件中。

选项

-pdb=<file-name>

将生成的 PDB 写入指定的文件。