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 | LazyValueInfo *LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI(); |
可以参考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 | In file included from ~/CLion_code/llvm-pass-tutorial/skeleton/Skeleton.cpp:1: |
适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/b9439cc117d77e11d687ecfca002900e9387b7e4
变化2:CryptoUtils宏定义S冲突
表现:编译Pass时报错
1 | In file included from /Users/leadroyal/pllvm/r10/include/llvm/Support/CommandLine.h:34: |
这个 S 不能被乱用,改名成__S。适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/0a75aeff3d6180b8f6476d68e1691fe9746ffc4e
变化 3:SetAlign参数变化
表现:编译Pass时提示类型错误,代码飘红。
1 | /Users/leadroyal/CLion_code/llvm-pass-tutorial/Hikari/StringEncryption.cpp:298:22: error: no viable conversion from 'int' to 'llvm::MaybeAlign' |
各种 Instruction 的 setAlignment参数从 int 变为 MaybeAlign。适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/0a75aeff3d6180b8f6476d68e1691fe9746ffc4e
变化 4:Intrinsic::ID 命名空间变化
表现:编译Pass时提示类型错误,代码飘红。
1 | /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 |
命名空间变了,适配commit:https://github.com/LeadroyaL/llvm-pass-tutorial/commit/0a75aeff3d6180b8f6476d68e1691fe9746ffc4e
四、总结
代码见:https://github.com/LeadroyaL/llvm-pass-tutorial 的dev分支。
欢迎提意见。