LLVM - 重命名模块内的函数

LLVM - Rename Function inside a Module

我正在使用 llvm3.8 制作一个 ModulePass,给定一个函数名称,它会遍历所有模块的函数并搜索该名称。 找到函数后,它会使用随机选择的字符串重命名它。

我需要 运行 这个传递到 iOS xcode 项目,所以我通过在 OTHER_C_FLAGS 中写入来执行传递,在项目的构建设置中命令:

-Xclang -load -Xclang path/to/my/ModulePass/RenameFunction.dlyb -mllvm -funcName="functionName"

我想不通的第一件事是为了正确重命名函数我应该使用的扩展点:

static RegisterStandardPasses RegisterClangPass(PassManagerBuilder::EP_EarlyAsPossible, registerClangPass);

我试过 EP_EarlyAsPossibleEP_ModuleOptimizerEarlyEP_EnabledOnOptLevel0,但真的不知道在这种情况下应该使用哪一个。

为了重命名函数,我尝试了两种不同的方法,找到函数后:

  1. 按照: 只需调用Function 的setName() 方法,将其设置为我想要的字符串。

for (Module::iterator F = tmp->begin(), E = tmp->end(); F != E; F++) { Function *_F(F); if(checkName(_F->getName())){ _F->setName(newNameString); } }

这不会为 EP_ModuleOptimizerEarly 编译。它为 EP_EarlyAsPossibleEP_EnabledOnOptLevel0 编译和 运行s,但是,通过对应用程序的二进制文件进行逆向工程,我注意到名称并没有真正改变...

  1. 我尝试克隆原始函数,重命名它,用新的克隆更改所有原始函数的用法并删除原始函数。

    Function *clone = CloneFunction(_F, vMap, true); clone->setLinkage(GlobalValue::InternalLinkage); _F->getParent()->getFunctionList().push_back(clone); clone->setName(func_name); _F->replaceAllUsesWith(clone); _F->eraseFromParent();

失败并出现 clang 错误:Running pass 'replaces function with a clone with a different name' on function.

第一种方法是正确的。您 运行 遇到的任何问题都可能与您的通票注册方式有关。

EP_EarlyAsPossible 用于函数传递。它会通过模块传递进行编译,但会做一些奇怪的事情。

如果您希望您的模块始终传递给 运行,您应该同时为 EP_EnabledOnOptLevel0EP_ModuleOptimizerEarly 注册它。