Carlinho89
Carlinho89

Reputation: 167

LLVM - Rename Function inside a Module

I'm using llvm3.8 to make a ModulePass that, given a function name, it iterates through all the Modules's functions and searches for that name. Once the Function is found, it renames it with a String chosen randomly.

I need to run this pass on a iOS xcodeproject, so I am executing the pass by writing in the OTHER_C_FLAGS, in the project's build settings the command:

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

First thing I cannot figure out is the Extension Point that I should use in order to correctly rename the function:

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

I tried with the EP_EarlyAsPossible, EP_ModuleOptimizerEarly and EP_EnabledOnOptLevel0 but don't really know which one should be used in this case.

In order to rename the function I tried 2 different approaches, after finding the function:

  1. By following this answer: Simply calling the Function's setName() method, setting it to the string I wanted.

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

This doesn't compile for EP_ModuleOptimizerEarly. It compiles and runs for EP_EarlyAsPossible and EP_EnabledOnOptLevel0, but, by reverse engineering the app's binary, I noticed that the name didn't really change...

  1. I tried cloning the original function, renaming it, changing all the original function's usages with the new clone and erasing the original one.

    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();

This is failing with clang error: Running pass 'replaces function with a clone with a different name' on function.

Upvotes: 1

Views: 1082

Answers (1)

Ismail Badawi
Ismail Badawi

Reputation: 37177

The first approach is the correct one. Any issues you run into are likely because of how your pass is registered.

EP_EarlyAsPossible is for function passes. It'll compile with a module pass but will do weird things.

If your want your module pass to always run, you should register it for both EP_EnabledOnOptLevel0 and EP_ModuleOptimizerEarly.

Upvotes: 1

Related Questions