llvm学习(十三):0202年的混淆——llvm8/9/10的变更

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 时,控制流平坦化过程中出现错误:

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分支。

欢迎提意见。