将Linux内核模块编译为LLVM .bc bitcode

Kev*_*oos 10 makefile llvm clang linux-kernel

背景

我正在尝试编译Linux内核中的某些驱动程序:drm(drivers/gpu/drm/drm_drv.o)和radeon(drivers/gpu/drm/radeon/)gpu驱动程序.我正在使用LLVM进行静态分析(跟踪copy_to/from_user()调用中使用的参数).

到目前为止,我能够使用Makefile编译实际模块,如下所示:

make CC=clang CFLAGS=-emit-llvm drivers/gpu/drm/radeon/ 

但这实际上并没有发出任何llvm bitcode - 我需要.bc文件来运行我的传递opt.

我只知道如何.bc直接使用clang(如下所示)生成文件,但不能使用Makefile ...

clang -emit-llvm hello.c -c -o hello.bc 

由于这个工作,我抓住了GNU make操作的详细输出,更改gccclang,并运行它来创建.bc文件,这也起作用:

 clang -emit-llvm  [[tons of CFLAGS]]  -c -o drm_drv.bc drivers/gpu/drm/drm_drv.c 

唯一的问题是我一次只能处理内核模块中的单个C文件.这种做法也非常繁琐......

主要问题

这让我.bc想到了我的主要问题:如何使用内核的Makefile发布llvm bitcode文件?

或者,如果.bc必须在每个文件的基础上创建bitcode,那么我将如何将它们全部链接在一起,以便我可以在内核模块中opt的所有.bc文件的聚合上运行LLVM 传递?

Cha*_*uth 2

从 Clang 中获取位码形式的 LLVM IR 的最佳方法是使用-flto命令行标志执行 LTO。

如果您有多个翻译单元,您可以使用该工具将它们组合在一起llvm-lto以“链接”位码文件。通常它会生成代码,但您可以让它使用该标志删除合并的 LLVM IR 模块-save-merged-module

但这些都不是真正受支持的接口。如果这是一个非常有用的工作流程,您应该与 LLVM 开发人员讨论支持更类似于 ld 的东西-r