llvm学习(五):动态加载 pass 时问题汇总
昨天搞交叉编译,中间其实有些没解决的问题都跳过了,最近有小伙伴联系我说加载不上的问题,符号各种找不到。刚好今天在做选型的工作,必须要面对这个问题了。
一、Release 版的 clang 和 Debug 版的 clang 无法加载对方编译出来的pass
之前有个误区,相同版本号的 clang 可以加载相同版本号的 pass,但却不是这样的,操作如下:
- 编译 Release 版的 llvm+clang,安装在 /path/to/llvm/r 目录下
- 编译 Debug 版的 llvm+clang,安装在 /path/to/llvm/i 目录下
- 使用
$LLVM_HOME=/path/to/llvm/i
,编译出i/libSkeletonPass.so
- 使用
$LLVM_HOME=/path/to/llvm/r
,编译出r/libSkeletonPass.so
两个成功
Debug-clang + Debug-pass 成功
1 | ➜ ii bin/clang -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include -Xclang -load -Xclang /Users/leadroyal/CLion_code/llvm-pass-tutorial/ii/skeleton/libSkeletonPass.so -w /tmp/test.c -o test.bin |
Release-clang + Release-pass 成功
1 | ➜ r bin/clang -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include -Xclang -load -Xclang /Users/leadroyal/CLion_code/llvm-pass-tutorial/r/skeleton/libSkeletonPass.so -w /tmp/test.c -o test.bin |
两个失败的例子
Release-clang + Debug-pass 失败
1 | ➜ r clang -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include -Xclang -load -Xclang /Users/leadroyal/CLion_code/llvm-pass-tutorial/r/skeleton/libSkeletonPass.so -w /tmp/test.c -o test.bin |
Debug-clang + Release-pass 失败
1 | ➜ ii clang -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include -Xclang -load -Xclang /Users/leadroyal/CLion_code/llvm-pass-tutorial/ii/skeleton/libSkeletonPass.so -w /tmp/test.c -o test.bin |
稍微看一眼,这两个报错不是一模一样的报错么,都是找不到符号。但两个文件基本一模一样,源码一样,环境稍微有点区别,但符号为什么找不到。
在这里纠结了很久,突然想起来自己是个星际玩家,容易眼瞎,经过大量的思考后,发现有句话不一样。
1 | Symbol not found: __ZN4llvm24DisableABIBreakingChecksE |
一个是 Disable
一个是 Enable
,难道是这里的问题?
于是打开 IDA 和 010Editor 开始各种diff ,发现二者文件的导入函数个数、长度、文件大小基本都一模一样,只有一个细节不一致。
破案了,原来是 Release 版的 clang 和 Debug 版的 clang 符号表本来就不一致,能加载成功就奇怪了。
(2019.3.22更新,这里其实是 LLVM_ENABLE_ABI_BREAKING_CHECKS
的不一致导致的,详情看第九篇文章)
二、系统自带的clang加载编译出来的 Pass
这时候测一下系统自带的那个 clang,因为它是最辣鸡的那个,从来没有成功运行过。
1 | ➜ darwin-x86_64 /usr/bin/clang -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include -Xclang -load -Xclang /Users/leadroyal/CLion_code/llvm-pass-tutorial/ii/skeleton/libSkeletonPass.so -w /tmp/test.c -o test.bin |
哈哈,两个符号全都找不到,真丢人,赶紧退群吧。
1 | ➜ darwin-x86_64 /usr/bin/clang --version |
别想了,完全是两套体系。有大佬会的话,求教。
三、ndk的clang加载编译出来的 Pass
2019年11月15日16:08:34:可行,但需要条件请,阅读第十一篇文章。