2020年3月24日,llvm10终于release了,当天就体验了一下。前段时间想看看是否会对混淆有影响,发现变化还是挺大的,本文以ollvm/armariris/hikari为例,总结一下 llvm8、9、10的更替过程中,变了哪些 API,以及如何去适配它们。
一、适配到llvm8
变化1:TerminatorInst 被移除
表现:编译Pass时提示类型错误,代码飘红。
适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/317135231c4cdb16346a1176f345b811d5b838f9
TerminatorInst has been removed.(http://lists.llvm.org/pipermail/llvm-dev/2018-May/123407.html)
二、适配到llvm9
变化 1:getOrInsertFunction 的返回值从 Function 变为 FunctionCallee变化
表现:编译Pass时提示类型错误,代码飘红。
网上大量仓库也被迫进行修改
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=239175
https://github.com/AFLplusplus/AFLplusplus/issues/40
https://github.com/stanson-ch/beignet.SlackBuild/blob/master/patches/llvm9-support.patch
适配在这次commit中:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/e39c14206058a1b55c33a37e1b7e398df0d03960
变化2:PassManager变化
表现:加载 pass 时,控制流平坦化过程中出现错误:
1 |
Assertion failed: (Resolver && "Pass has not been inserted into a PassManager object!"), function getAnalysis |
根源是:llvm9的LowerSwitchPass里有了新的逻辑,依赖了一个 Analyze,而Analyze需要PassManager,不能凭空产生。这里其实我也不知道是为什么,反正表现出来确实是这样。
1 2 |
LazyValueInfo *LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI(); auto *ACT = getAnalysisIfAvailable<AssumptionCacheTracker>(); |
可以参考Zhang的这次提问:http://lists.llvm.org/pipermail/llvm-dev/2019-December/137766.html
方案一:
注册阶段,将LowerSwitchPass放到Flatten前,执行时按顺序执行即可。适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/e3acd12e46fbcc657d17007b02f0f3183527f9b8
方案二:
手动抄一份 llvm8 的LowerSwitchPass,代替来自llvm9的那份,经测试,也是可以正常运行的,没有测太多 case,不保证严谨。
三、适配到llvm10
变化1:需要使用c++14
表现:编译Pass时出错
1 2 3 4 5 6 7 8 |
In file included from ~/CLion_code/llvm-pass-tutorial/skeleton/Skeleton.cpp:1: In file included from ~/pllvm/r/include/llvm/Pass.h:31: In file included from ~/pllvm/r/include/llvm/ADT/StringRef.h:12: ~/pllvm/r/include/llvm/ADT/STLExtras.h:559:49: error: no template named 'index_sequence' in namespace 'std' template <size_t... Ns> value_type deref(std::index_sequence<Ns...>) const { ~~~~~^ ~/pllvm/r/include/llvm/ADT/STLExtras.h:564:36: error: no template named 'index_sequence' in namespace 'std' decltype(iterators) tup_inc(std::index_sequence<Ns...>) const { |
适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/b9439cc117d77e11d687ecfca002900e9387b7e4
变化2:CryptoUtils宏定义S冲突
表现:编译Pass时报错
1 2 3 |
In file included from /Users/leadroyal/pllvm/r10/include/llvm/Support/CommandLine.h:34: /Users/leadroyal/pllvm/r10/include/llvm/Support/VirtualFileSystem.h:599:25: error: too few arguments provided to function-like macro invocation S(std::move(S)) {} |
这个 S 不能被乱用,改名成__S。适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/0a75aeff3d6180b8f6476d68e1691fe9746ffc4e
变化 3:SetAlign参数变化
表现:编译Pass时提示类型错误,代码飘红。
1 2 |
/Users/leadroyal/CLion_code/llvm-pass-tutorial/Hikari/StringEncryption.cpp:298:22: error: no viable conversion from 'int' to 'llvm::MaybeAlign' SI->setAlignment(4); |
各种 Instruction 的 setAlignment参数从 int 变为 MaybeAlign。适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/0a75aeff3d6180b8f6476d68e1691fe9746ffc4e
变化 4:Intrinsic::ID 命名空间变化
表现:编译Pass时提示类型错误,代码飘红。
1 2 |
/Users/leadroyal/CLion_code/llvm-pass-tutorial/Hikari/FunctionWrapper.cpp:88:44: error: 'llvm::Intrinsic::ID' (aka 'unsigned int') is not a class, namespace, or enumeration CS->getIntrinsicID() != Intrinsic::ID::not_intrinsic) { |
命名空间变了,适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/0a75aeff3d6180b8f6476d68e1691fe9746ffc4e
四、总结
代码见:https://github.com/LeadroyaL/llvm-pass-tutorial 的dev分支。
欢迎提意见。