最近要获取linux内核的llvm bitcode,以便后续进行分析,例如获取callgraph等等,尝试了很多提取llvm bitcode的方法(用build-bom, wllvm),过程中也出现了很多错误,最后用wllvm终于成功了,记录下报错与踩坑。
使用工具:wllvm(whole-program-llvm)
要求:clang+lllvm
clang+llvm下载地址:https://github.com/llvm/llvm-project/releases
wllvm安装方法:(具体信息看Readme)
pip install wllvm
wllvm使用之前运行:
export LLVM_COMPILER=clang
编译过程:
无废话纯享版:
make CC=clang defconfig # 默认配置
make menuconfig -> General setup -> 取消勾选"compile the kernel with warnings as errors" -> esc退出保存
make CC=wllvm LLVM=1 #开始编译
extract-bc vmlinux #提取bitcode
编译详细过程:
首先获取linux源码
两个途径,选择想要的版本下载即可:我用的是6.2.0版本
https://github.com/torvalds/linux
编译
解压源码后,进入到解压目录:
运行linux自带的默认配置,官方文档说默认配置最靠谱(X)。
make CC=clang defconfig #默认配置
但是!!默认配置后编译会报错编译器ld无法识别包含llvm_bitcode的orphan section(这里是用build-bom编译报的错,wllvm的报错与此类似,我忘记录了):
然后我换成了使用LLVM的编译器ld.lld(编译时加上LLVM=1)也会报错如下:
原因是默认配置开启了WERROR参数!!!
这个参数在./init/Kconfig中这样描述:
如果某些编译器有奇怪的警告的话,会直接报error,可能ld和ld.lld都不能很好的处理llvm_bc段,因此接下来要手动配置将WERROR取消。
Disable WERROR :
运行如下命令开启手动配置,进入 "General setup", 取消勾选"compile the kernel with warnings as errors",狂按esc退出并保存。
make menuconfig
make
make CC=wllvm LLVM=1 #指定编译器为wllvm,使用LLVM编译工具链
这里是用的wllvm能成功编译得到vmlinux,但是还有另一个提取llvm bitcode的好工具build-bom,也能成功编译,但是提取bitcode时会出错,如下,编译命令为:
build-bom generate-bitcode --bc-out bcdir -- make CC=clang LLVM=1
我实在找不出原因,因此就放弃了,不过其他wllvm会失败的项目build-bom却能够成功。
提取bitcode
extract-bc是wllvm自带的一个工具,当使用wllvm成功编译得到目标二进制文件后,就可以使用extract-bc来获取目标对应的.bc文件。
extract-bc vmlinux #提取bitcode
得到vmlinux.bc后,就可以使用opt工具对其进行分析啦,例如获取调用图:
opt -dot-callgraph vmlinux.bc
dot -Tsvg vmlinux.bc.callgraph.dot -O #转化为svg文件可视化