Holy Macroni! 渐进式语言增强方案
尽管Clang在代码重构和静态分析工具中广泛应用,但其AST存在重大缺陷:无法提供关于AST节点源自哪些CPP宏展开的溯源信息,也不将宏展开降级到LLVM IR代码。这使得构建宏感知的静态分析和转换工具极为困难,成为持续研究的课题。今年夏天在Trail of Bits,我开发了Macroni来解决这个问题。
Macroni允许开发者通过宏定义新的C语言构造语法,并用MLIR提供这些构造的语义。它使用VAST将C代码降级到MLIR,并通过PASTA获取宏到AST的溯源信息。开发者可以定义自定义MLIR转换器,将Macroni输出转换为领域特定的MLIR方言以进行更细致的分析。
强化类型定义
C语言的typedef虽然能为底层类型提供语义名称,但编译器仅检查底层类型。通过Macroni,我们可以使用宏定义强类型typedef语法,并用MLIR实现自定义类型检查:
|
|
Macroni会将这些typedef转换为自定义MLIR方言类型,实现严格的类型检查。相比使用struct实现强类型,这种方法保持了API和ABI兼容性。
增强Linux内核Sparse检查
Macroni可以挂钩到Sparse宏(如__user
)执行安全检查。与仅支持C的Sparse不同,Macroni适用于所有Clang可解析的代码(C/C++/Objective C)。例如:
|
|
Macroni将这类声明降级到MLIR时会将用户空间注解嵌入类型系统,实现自定义类型检查。
Rust风格不安全区域
为便于逐步采用强类型系统,Macroni实现了类似Rust的unsafe机制:
|
|
在unsafe区域外执行强类型检查,区域内则保持原有语义。
安全信号处理
Macroni可以确保信号处理器只执行信号安全代码:
|
|
通过标记信号处理器和安全函数,Macroni在MLIR层验证信号处理器只调用安全函数。
为什么选择Macroni?
Macroni将C代码和宏降级到MLIR,避免了Clang AST的限制,使开发者能够构建考虑宏的静态分析工具。它支持定义自定义分析、转换和优化,甚至可以结合宏和MLIR定义新的C语法和语义。
Macroni是免费开源工具,GitHub仓库提供了试用机会。特别感谢Trail of Bits团队的支持,特别是Peter Goodman的创意指导,以及Lukas Korencik的代码审查和改进建议。