Reputation: 167
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:
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...
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
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