Hi all,<br><br>Sorry for the inconvenient about the previous post. The files were not attached. So I put them here again.<br><br>I am a newbie in LLVM and I am trying to replace the function like:<br><br>old function               ||            new function<br>
==============================<div id=":r">=========<br><div>int haha(int a) {                        int haha(int a, char* ID) {<br>

                          <br>                            ===>    <br>
<br><br>}                                            }            <br><div><br>Of course in the newly replaced function "int haha(int, char*ID)", I want to insert some instrumentation code.<br><br>
Here is my code that I am working on till now and it generates 
segmentation fault in the place I comment with "//////////////////////"<br>
Can you help me? Any advice will be helpful because I am a beginner in llvm.<br><br><br>Thank you in advance.<br>Shawn.<br><br><br>duplicateFunction.cpp<br>=============================================================================<br>
<br>//===- duplicateFunction.cpp - Writing an LLVM Pass -----------------------===//<br>


//<br>//                     The LLVM Compiler Infrastructure<br>//<br>//===----------------------------------------------------------------------===//<br>//<br>// This file implements the LLVM duplicating function pass.<br>



// It starts by computing a new prototype for the function,<br>// which is the same as the old function, but has an extra argument.<br>//<br>//===----------------------------------------------------------------------===//<br>



#include "llvm/Transforms/Utils/Cloning.h"<br>#include "llvm/Pass.h"<br>#include "llvm/Function.h"<br>#include "llvm/Module.h"<br>#include "llvm/CallingConv.h"<br>#include "llvm/DerivedTypes.h"<br>



#include "llvm/InstrTypes.h"<br>#include "llvm/Constants.h"<br>#include "llvm/Instructions.h"<br>#include "llvm/Support/raw_ostream.h"<br>#include "llvm/Transforms/Utils/BasicBlockUtils.h"<br>



#include "llvm/BasicBlock.h"<br>#include "llvm/Support/Debug.h"<br>#include "llvm/Support/CallSite.h"<br>using namespace llvm;<br><br>namespace {<br>    Constant *f;<br>    Function *Fn;<br>


    FunctionType *FTy;<br>
    Type *RetTy;<br>    std::vector<Type*> Params;<br>    class DP : public FunctionPass {<br><br>      public:<br>        static char ID;<br><br>        DP() : FunctionPass(ID) {}<br><br>        virtual bool doInitialization(Module &M);<br>



        virtual bool runOnFunction(Function &F);<br>        virtual bool doFinalization(Module &mdl) {<br>            mdl.dump();<br>            return true;<br>        }<br>    }; /* class */<br>}<br><br>char DP::ID = 0;<br>
static RegisterPass<DP> IC("duplicateFunction", "Duplicate Function Pass");<br><br><br>bool DP::doInitialization(Module &M) {<br>

<br>
    // find the function that we want to change.<br>    Fn = M.getFunction("haha");<br>   <br>    // Start by computing a new prototype for the function, which is the same as<br>


    // the old function, but has an extra argument.<br>    FTy = Fn->getFunctionType();<br><br>    // Find out the return value.<br>    RetTy = FTy->getReturnType();<br><br>    // set the calling convention to C.<br>
    // so, we interoperate with C Code properly.<br>    Function *tmp = cast<Function>(Fn);<br>


    tmp->setCallingConv(CallingConv::C);<br><br>    return true;<br>}<br><br>bool DP::runOnFunction(Function &F) {<br>#if 0<br>    Value *param;<br> <br>    // Find the instruction before which you want to insert the function call<br>



    Instruction *nextInstr = F.back().getTerminator();<br> <br>    // Create the actual parameter for the function call<br>    param = ConstantInt::get(Type::getInt32Ty(F.getContext()), 333);<br> <br>    // create and insert the function call<br>



    //CallInst::Create(f, param, "", nextInstr);<br>    CallInst::Create(Fn, param, "", nextInstr);<br><br>    // indicates that we changed the code<br>    //return true;<br>#endif<br>    Type *NRetTy;<br>



<br>    std::vector<Type*> Params(FTy->param_begin(), FTy->param_end());<br>    FunctionType *NFTy = FunctionType::get(FTy->getReturnType(), Params, false);<br><br>    // Create the new function body and insert it into the module...<br>



    Function *NF = Function::Create(NFTy, Fn->getLinkage());<br>    NF->copyAttributesFrom(Fn);<br>    Fn->getParent()->getFunctionList().insert(Fn, NF);<br>    NF->takeName(Fn);<br><br>    for (Function::arg_iterator AI=F.arg_begin(), AE=F.arg_end(), NAI=NF->arg_begin();<br>



         AI != AE; ++AI, ++NAI) {<br>        NAI->takeName(AI);<br>    }<br><br>    // Since we have now create the new function, splice the body of the old<br>    // function right into the new function, leaving the old rotting hulk of the<br>



    // function empty.<br>    NF->getBasicBlockList().splice(NF->begin(), F.getBasicBlockList());<br><br>    llvm::Value *Globals = --NF->arg_end();<br>    Globals->setName("IOCallIDs");<br><br>    // Now, exploit all return instructions.<br>



    for (Function::iterator BI = NF->begin(), BE = NF->end(); BI != BE; ++BI) {<br>        if (ReturnInst *RI = llvm::dyn_cast<llvm::ReturnInst>(BI->getTerminator())) {<br>            // Don't support functions that have multiple return values.<br>



            assert(RI->getNumOperands() < 2);<br><br>            // Insert a new load instruction to return.<br>            ///////////////////////////////////////////////////////////////////////////////////// HERE, GENERATE ERROR<br>

            /////////////////////////////////////////////////////////////////////////////////////<br>

            Value *Load = new llvm::LoadInst(Globals, "globalsret", RI);<br>            /////////////////////////////////////////////////////////////////////////////////////<br><div>          </div>            // Return type is void<br>

            if ( RetTy->isVoidTy() ) {<br>//                ReturnInst::Create(Load, 0, RI); // Return void<br>

                ReturnInst::Create(F.getContext(), 0, RI); // Return void<br>                RI->getParent()->getInstList().erase(RI);<br>            } else {<br>                // Start with an empty struct.<br>                Value *Return = ConstantAggregateZero::get(NRetTy);<br>



                DEBUG(errs() << "Return: " << *Return->getType() << '\n');<br><br>                // Insert the original return value in field 0<br>                Return = InsertValueInst::Create(Return, RI->getOperand(0), 0, "ret", RI);<br>



                DEBUG(errs() << "Return: " << *Return->getType() << '\n');<br><br>                // Insert the globals return value in field 1   <br>                Return = InsertValueInst::Create(Return, Load, 1, "ret", RI); // <- maybe useless<br>



                DEBUG(errs() << "Return: " << *Return->getType() << '\n');<br><br>                // Update the return instruction<br>                RI->setOperand(0, Return);<br>



            }<br>        } // if <br>    } // for<br><br>    // Replace all uses of the old arguments with the new arguments.<br>    for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(), NI = NF->arg_begin();<br>



         I != E; ++I, ++NI) {<br>        I->replaceAllUsesWith(NI);<br>    }<br><br>#if 1<br>    // Replace all callers<br>    while ( !F.use_empty() ) {<br>        CallSite CS(F.use_back());<br>        Instruction *Call = CS.getInstruction();<br>



//        Function *CallingF = Call->getParent()->getParent();<br><br>        // Get the global struct in our caller.<br>        //Value* CallerGlobals = ModifyFunctionRecursive(CallingF).first;<br>        Value* CallerGlobals = NULL; // <- This should be modified later.<br>



<br>        // Copy the existing arguments<br>        std::vector<Value*> Args;<br>        Args.reserve(CS.arg_size());<br>        CallSite::arg_iterator AI = CS.arg_begin(), AE = CS.arg_end();<br><br>        // First, copy regular arguments<br>



        for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++AI) {<br>            Args.push_back(*AI);<br>        }<br>        // Then, insert the new argument<br>        Args.push_back(CallerGlobals);<br>        // Lastly, copy any remaining varargs<br>



        for (; AI != AE; ++AI) {<br>            Args.push_back(*AI);<br>        }<br><br>        Instruction *New;<br>        Instruction *Before = Call;<br>        if ( InvokeInst *II = dyn_cast<InvokeInst>(Call) ) {<br>



            New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(), Args, "", Before);<br>            cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());<br>//          cast<InvokeInst>(New)->setParamAttrs(CS.getParamAttrs());<br>



            cast<InvokeInst>(New)->setAttributes(CS.getAttributes());<br>        } else {<br>            New = CallInst::Create(NF, Args, "", Before);<br>            cast<CallInst>(New)->setCallingConv(CS.getCallingConv());<br>



//          cast<CallInst>(New)->setParamAttrs(CS.getParamAttrs());<br>            cast<CallInst>(New)->setAttributes(CS.getAttributes());<br>            if ( cast<CallInst>(Call)->isTailCall() ) {<br>



                cast<CallInst>(New)->setTailCall();<br>            }<br>        }<br><br>        if (Call->hasName()) {<br>            New->takeName(Call);<br>        } else { <br>            New->setName(NF->getName() + ".ret");<br>



        }<br><br>        Value *GlobalsRet;<br>        if ( Call->getType()->isVoidTy() ) {<br>            // The original function returned nothing, so the new function returns<br>            // only the globals<br>



            GlobalsRet = New;<br>        } else {<br>            // Split the values<br>            Value *OrigRet = ExtractValueInst::Create(New, 0, "origret", Before);<br>            GlobalsRet     = ExtractValueInst::Create(New, 1, "globalsret", Before);<br>



            // Replace all the uses of the original result<br>            Call->replaceAllUsesWith(OrigRet);<br>        }<br>        <br>        // Now, store the globals back<br>        new StoreInst(GlobalsRet, CallerGlobals, Before);<br>



<br>        DEBUG(errs() << "Call " << *Call << " 
replaced, function is now " << 
*Call->getParent()->getParent() << "\n");<br><br>        // Finally, remove the old call from the program, reducing the use-count of F.<br>
        Call->eraseFromParent();<br><br>    } // while<br>#endif<br>    return true;<br>}<br><br><br>test.c<br>====================================================================================<br>#include <stdio.h><br>
#include <stdlib.h><br><br>int v[200];<br>int haha(int);<br><br>int main()<br>{<br>    int i;<br>    int n=100;<br><br>    if ( !haha(n) )<br>        exit(-1);<br><br>    return 1;<br>}<br><br>int haha(int n)<br>//int haha(int n, char* IOCallIDs)<br>
{<br>    int i;<br>    for (i=1; i<n; i++)<br>        v[i] = v[i-1] + v[i];<br><br>    printf ("hahaha\n");<br>    return 1;<br>}<br><br>Makefile<br>
====================================================================================<br>LLVM_CONFIG?=llvm-config<br><br># location of the source<br># useful if you want separate source and object directories.<br>SRC_DIR?=$(PWD)<br>
<br>#ifndef VERBOSE<br>#    QUIET:=@<br>#endif<br><br>COMMON_FLAGS=-Wall -Wextra #-fvisibility=hidden<br>CFLAGS+=$(COMMON_FLAGS) $(shell $(LLVM_CONFIG) --cflags)<br>CXXFLAGS+=$(COMMON_FLAGS) $(shell $(LLVM_CONFIG) --cxxflags)<br>
<br>#ifeq ($(shell uname),Darwin)<br>#LOADABLE_MODULE_OPTIONS=-bundle -undefined dynamic_lookup<br>#else<br>LOADABLE_MODULE_OPTIONS=-shared -Wl,-O1<br>#endif<br><br>TEST_C=test.c<br>TEST_FILE=$(subst .c,.s, $(TEST_C))<br>
PLUGIN=duplicateFunction.so<br>PLUGIN_OBJECTS=duplicateFunction.o <br><br>ALL_OBJECTS=$(PLUGIN_OBJECTS)<br>ALL_TARGETS=$(PLUGIN) $(TEST_FILE)<br><br>CPP_OPTIONS+=$(CPPFLAGS) $(shell $(LLVM_CONFIG) --cppflags) -MD -MP -I$(SRC_DIR)<br>
<br>LD_OPTIONS+=$(LDFLAGS) $(shell $(LLVM_CONFIG) --ldflags)<br><br>all: $(ALL_TARGETS)<br><br>%.o : $(SRC_DIR)/%.cpp<br>    @echo Compiling $*.cpp<br>    $(QUIET)$(CXX) -c $(CPP_OPTIONS) $(CXXFLAGS) $<<br><br>$(PLUGIN): $(PLUGIN_OBJECTS)<br>
    @echo Linking $@<br>    $(QUIET)$(CXX) -o $@ $(LOADABLE_MODULE_OPTIONS) $(CXXFLAGS) $(LD_OPTIONS) $(PLUGIN_OBJECTS)<br><br>RUN_FLAGS=-duplicateFunction<br><br>$(TEST_FILE): $(TEST_C)<br>    clang -g -O3 -S -emit-llvm $^<br>
#    clang -g -O0 -S -emit-llvm $^<br>#     clang -O0 -S -emit-llvm $^<br>run: <br>    opt -load ./$(PLUGIN) $(RUN_FLAGS) < $(TEST_FILE) > /dev/null 2> after.s<br>#    opt -load ./$(PLUGIN) $(RUN_FLAGS) < $(TEST_FILE) > /dev/null<br>
<br>clean:<br>    $(QUIET)rm -f $(ALL_OBJECTS) *.d $(PLUGIN) $(TEST_FILE)<br><br><br>-include $(ALL_OBJECTS:.o=.d)<br><br><br><br><br>
<br></div></div></div>