LLVM 的可选富反汇编输出

简介

LLVM 的默认反汇编输出是原始文本。为了让使用者能够更好地内省指令的文本表示,或者为了更友好的用户显示而重新格式化,这里提供了一个可选的富反汇编输出。

这个可选的输出足以引用到指令文本的各个部分。这旨在为反汇编器、列表文件生成器和美化打印器等客户端提供服务,这些客户端需要的不仅仅是原始指令和打印它们的能力。

为了提供此功能,汇编文本使用注解进行标记。标记的语法足够简单,即使在消费者和生产者之间的版本不匹配的情况下也足够健壮。也就是说,该语法通常不携带超出“此文本具有注解”的语义,因此消费者可以简单地忽略他们不理解或不关心的注解。

在调用 LLVMCreateDisasm() 创建反汇编器上下文之后,可以通过以下调用启用可选输出

LLVMSetDisasmOptions(DC, LLVMDisassembler_Option_UseMarkup);

然后,后续对 LLVMDisasmInstruction() 的调用将返回带有标记注解的输出字符串。

指令注解

上下文标记

带注解的汇编显示将提供上下文标记,以帮助客户端更有效地实现诸如美化打印机之类的功能。大多数标记将是目标独立的,因此客户端可以有效地提供良好的显示,而无需任何特定于目标的知识。

带注解的汇编会通过正常的指令打印器,但可以选择在指令字符串的部分包含上下文标签。注解是任何由“<” “>”分隔的文本部分 (1)。

annotation: '<' tag-name tag-modifier-list ':' annotated-text '>'
tag-name: identifier
tag-modifier-list: comma delimited identifier list

tag-name 是一个标识符,它给出了注解的类型。对于第一遍,这将非常简单,内存引用、寄存器和立即数将分别具有标签名称“mem”、“reg”和“imm”。

tag-modifier-list 通常是额外的特定于目标的上下文,例如寄存器类。

客户端应接受并忽略他们不理解的任何 tag-name 或 tag-modifier,从而允许注解在丰富性方面增长而不会破坏旧的客户端。

例如,ARM 加载堆栈相关位置的可能注解可以注解为

ldr <reg gpr:r0>, <mem regoffset:[<reg gpr:sp>, <imm:#4>]>

1: 对于汇编方言,其中“<”和/或“>”是合法标记,文字标记通过紧跟字符的重复来转义。例如,文字“<”字符在带注解的汇编字符串中输出为“<<”。

C API 细节

此信息的预期使用者使用 C API,因此将添加新的 C API 函数用于反汇编器,以提供一个选项来生成带有注解的反汇编指令,LLVMSetDisasmOptions()LLVMDisassembler_Option_UseMarkup 选项(见上文)。