0
votes

I am trying to copy a function from one file to another. The file that I wanted to copy the function into contains a function with the same name and the same number of instructions. I decided to just replace the instructions with those of the other function. I am doing all of this from within a function pass.

  1. I created a function pass in which I extract a function using "llvm-extract" from within the pass.

  2. Then I read the (.ll) file created by the "llvm-extract" tool using:

SMDiagnostic Err;
LLVMContext Context;

std::unique_ptr<Module> ParsedMod(parseIRFile("add.ll", Err, Context));
Module &M = dynamic_cast<Module&>(*ParsedMod);
Module* Mod_ptr = &M;
  1. Then I read the (.ll) file into which I want to copy the function using:
std::unique_ptr<Module> ParsedMod2(parseIRFile("server.ll", Err, Context));
Module &M2 = dynamic_cast<Module&>(*ParsedMod2);
Module* Mod_ptr2 = &M2;
  1. I keep two iterators to save the points from where i have to start replacing instructions as:
Module::iterator F1;
Module::iterator F2;
  1. Assign them values so that F1 points to the first function and F2 to the second function:
    for(Module::iterator func = Mod_ptr->begin(), Lfunc = Mod_ptr->end(); func!=Lfunc; ++func)
        {
          F1 = func;
        }

    for(Module::iterator func2 = Mod_ptr2->begin(), Lfunc2 = Mod_ptr2->end(); func2!=Lfunc2; ++func2)
        {
          if(func2->getName() == F.getName()) //F.getName() gives the same name as the function that was extracted
          {
            F2 = func2;
          }
        }
  1. Replacing each instruction of F2 with instruction from F1 using:
    for(Function::iterator bb = F1->begin(), Lbb = F1->end(), bb2 = F2->begin(), Lbb2 = F2->end(); bb2!=Lbb2; ++bb, ++bb2)
        {
          for(BasicBlock::iterator inst = bb->begin(), Linst = bb->end(), inst2 = bb2->begin(), Linst2 = bb2->end(); inst2 != Linst2; ++inst, ++inst2)
          {
            Instruction* I = &*inst;
            Instruction* I2 = &*inst2;

            //errs() << "F1's instruction: " << *I << "\n";
            //errs() << "F2's instruction: " << *I2 << "\n";

            ReplaceInstWithInst(I, I2);
          }
        }

If I comment the ReplaceInstWithInst instruction and uncomment the instructions printing the instructions from two functions, correct instructions are printed.

I get Segmentation Fault if I use ReplaceInstWithInst instruction.

1

1 Answers

0
votes

I can guess what's happening, and the answer is to verify early and often. The verifier will detect a lot of trivial errors such as having an instruction in one function refer to a function or global variable in a different module. Verify every function you change, it'll catch errors early.

(You may also want to look at llvm/lib/Transforms/Utils/CloneFunction.cpp and its callers; perhaps either the functions there or the callers can help you.)