Esempio n. 1
0
bool IDTagger::runOnModule(Module &M) {
	IntegerType *IntType = IntegerType::get(M.getContext(), 32);
	for (Module::iterator F = M.begin(); F != M.end(); ++F) {
		for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
			for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
				Constant *InsID = ConstantInt::get(IntType, NumInstructions);
				I->setMetadata("ins_id", MDNode::get(M.getContext(), InsID));
				++NumInstructions;
			}
		}
	}
	return true;
}
Esempio n. 2
0
Module *llvm::CloneModule(const Module *M,
                          ValueToValueMapTy &VMap) {
  // First off, we need to create the new module...
  Module *New = new Module(M->getModuleIdentifier(), M->getContext());
  New->setDataLayout(M->getDataLayout());
  New->setTargetTriple(M->getTargetTriple());
  New->setModuleInlineAsm(M->getModuleInlineAsm());

  // Copy all of the type symbol table entries over.
  const TypeSymbolTable &TST = M->getTypeSymbolTable();
  for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end(); 
       TI != TE; ++TI)
    New->addTypeName(TI->first, TI->second);
  
  // Copy all of the dependent libraries over.
  for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I)
    New->addLibrary(*I);

  // Loop over all of the global variables, making corresponding globals in the
  // new module.  Here we add them to the VMap and to the new Module.  We
  // don't worry about attributes or initializers, they will come later.
  //
  for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
       I != E; ++I) {
    GlobalVariable *GV = new GlobalVariable(*New, 
                                            I->getType()->getElementType(),
                                            false,
                                            GlobalValue::ExternalLinkage, 0,
                                            I->getName());
    GV->setAlignment(I->getAlignment());
    VMap[I] = GV;
  }

  // Loop over the functions in the module, making external functions as before
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
    Function *NF =
      Function::Create(cast<FunctionType>(I->getType()->getElementType()),
                       GlobalValue::ExternalLinkage, I->getName(), New);
    NF->copyAttributesFrom(I);
    VMap[I] = NF;
  }

  // Loop over the aliases in the module
  for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
       I != E; ++I)
    VMap[I] = new GlobalAlias(I->getType(), GlobalAlias::ExternalLinkage,
                                  I->getName(), NULL, New);
  
  // Now that all of the things that global variable initializer can refer to
  // have been created, loop through and copy the global variable referrers
  // over...  We also set the attributes on the global now.
  //
  for (Module::const_global_iterator I = M->global_begin(), E = M->global_end();
       I != E; ++I) {
    GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);
    if (I->hasInitializer())
      GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(),
                                                 VMap)));
    GV->setLinkage(I->getLinkage());
    GV->setThreadLocal(I->isThreadLocal());
    GV->setConstant(I->isConstant());
  }

  // Similarly, copy over function bodies now...
  //
  for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) {
    Function *F = cast<Function>(VMap[I]);
    if (!I->isDeclaration()) {
      Function::arg_iterator DestI = F->arg_begin();
      for (Function::const_arg_iterator J = I->arg_begin(); J != I->arg_end();
           ++J) {
        DestI->setName(J->getName());
        VMap[J] = DestI++;
      }

      SmallVector<ReturnInst*, 8> Returns;  // Ignore returns cloned.
      CloneFunctionInto(F, I, VMap, Returns);
    }

    F->setLinkage(I->getLinkage());
  }

  // And aliases
  for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end();
       I != E; ++I) {
    GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
    GA->setLinkage(I->getLinkage());
    if (const Constant* C = I->getAliasee())
      GA->setAliasee(cast<Constant>(MapValue(C, VMap)));
  }

  // And named metadata....
  for (Module::const_named_metadata_iterator I = M->named_metadata_begin(),
         E = M->named_metadata_end(); I != E; ++I) {
    const NamedMDNode &NMD = *I;
    SmallVector<MDNode*, 4> MDs;
    for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
      MDs.push_back(cast<MDNode>(MapValue(NMD.getOperand(i), VMap)));
    NamedMDNode::Create(New->getContext(), NMD.getName(),
                        MDs.data(), MDs.size(), New);
  }

  // Update metadata attach with instructions.
  for (Module::iterator MI = New->begin(), ME = New->end(); MI != ME; ++MI)   
    for (Function::iterator FI = MI->begin(), FE = MI->end(); 
         FI != FE; ++FI)
      for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); 
           BI != BE; ++BI) {
        SmallVector<std::pair<unsigned, MDNode *>, 4 > MDs;
        BI->getAllMetadata(MDs);
        for (SmallVector<std::pair<unsigned, MDNode *>, 4>::iterator 
               MDI = MDs.begin(), MDE = MDs.end(); MDI != MDE; ++MDI) {
          Value *MappedValue = MapValue(MDI->second, VMap);
          if (MDI->second != MappedValue && MappedValue)
            BI->setMetadata(MDI->first, cast<MDNode>(MappedValue));
        }
      }
  return New;
}
Esempio n. 3
0
/// CloneAndPruneFunctionInto - This works exactly like CloneFunctionInto,
/// except that it does some simple constant prop and DCE on the fly.  The
/// effect of this is to copy significantly less code in cases where (for
/// example) a function call with constant arguments is inlined, and those
/// constant arguments cause a significant amount of code in the callee to be
/// dead.  Since this doesn't produce an exact copy of the input, it can't be
/// used for things like CloneFunction or CloneModule.
void llvm::CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc,
                                     ValueToValueMapTy &VMap,
                                     SmallVectorImpl<ReturnInst*> &Returns,
                                     const char *NameSuffix, 
                                     ClonedCodeInfo *CodeInfo,
                                     const TargetData *TD,
                                     Instruction *TheCall) {
  assert(NameSuffix && "NameSuffix cannot be null!");
  
#ifndef NDEBUG
  for (Function::const_arg_iterator II = OldFunc->arg_begin(), 
       E = OldFunc->arg_end(); II != E; ++II)
    assert(VMap.count(II) && "No mapping from source argument specified!");
#endif

  PruningFunctionCloner PFC(NewFunc, OldFunc, VMap, Returns,
                            NameSuffix, CodeInfo, TD);

  // Clone the entry block, and anything recursively reachable from it.
  std::vector<const BasicBlock*> CloneWorklist;
  CloneWorklist.push_back(&OldFunc->getEntryBlock());
  while (!CloneWorklist.empty()) {
    const BasicBlock *BB = CloneWorklist.back();
    CloneWorklist.pop_back();
    PFC.CloneBlock(BB, CloneWorklist);
  }
  
  // Loop over all of the basic blocks in the old function.  If the block was
  // reachable, we have cloned it and the old block is now in the value map:
  // insert it into the new function in the right order.  If not, ignore it.
  //
  // Defer PHI resolution until rest of function is resolved.
  SmallVector<const PHINode*, 16> PHIToResolve;
  for (Function::const_iterator BI = OldFunc->begin(), BE = OldFunc->end();
       BI != BE; ++BI) {
    BasicBlock *NewBB = cast_or_null<BasicBlock>(VMap[BI]);
    if (NewBB == 0) continue;  // Dead block.

    // Add the new block to the new function.
    NewFunc->getBasicBlockList().push_back(NewBB);
    
    // Loop over all of the instructions in the block, fixing up operand
    // references as we go.  This uses VMap to do all the hard work.
    //
    BasicBlock::iterator I = NewBB->begin();

    unsigned DbgKind = OldFunc->getContext().getMDKindID("dbg");
    MDNode *TheCallMD = NULL;
    if (TheCall && TheCall->hasMetadata()) 
      TheCallMD = TheCall->getMetadata(DbgKind);
    
    // Handle PHI nodes specially, as we have to remove references to dead
    // blocks.
    if (PHINode *PN = dyn_cast<PHINode>(I)) {
      // Skip over all PHI nodes, remembering them for later.
      BasicBlock::const_iterator OldI = BI->begin();
      for (; (PN = dyn_cast<PHINode>(I)); ++I, ++OldI) {
        if (I->hasMetadata()) {
          if (TheCallMD) {
            if (MDNode *IMD = I->getMetadata(DbgKind)) {
              MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD);
              I->setMetadata(DbgKind, NewMD);
            }
          } else {
            // The cloned instruction has dbg info but the call instruction
            // does not have dbg info. Remove dbg info from cloned instruction.
            I->setMetadata(DbgKind, 0);
          }
        }
        PHIToResolve.push_back(cast<PHINode>(OldI));
      }
    }
    
    // FIXME:
    // FIXME:
    // FIXME: Unclone all this metadata stuff.
    // FIXME:
    // FIXME:
    
    // Otherwise, remap the rest of the instructions normally.
    for (; I != NewBB->end(); ++I) {
      if (I->hasMetadata()) {
        if (TheCallMD) {
          if (MDNode *IMD = I->getMetadata(DbgKind)) {
            MDNode *NewMD = UpdateInlinedAtInfo(IMD, TheCallMD);
            I->setMetadata(DbgKind, NewMD);
          }
        } else {
          // The cloned instruction has dbg info but the call instruction
          // does not have dbg info. Remove dbg info from cloned instruction.
          I->setMetadata(DbgKind, 0);
        }
      }
      RemapInstruction(I, VMap);
    }
  }
  
  // Defer PHI resolution until rest of function is resolved, PHI resolution
  // requires the CFG to be up-to-date.
  for (unsigned phino = 0, e = PHIToResolve.size(); phino != e; ) {
    const PHINode *OPN = PHIToResolve[phino];
    unsigned NumPreds = OPN->getNumIncomingValues();
    const BasicBlock *OldBB = OPN->getParent();
    BasicBlock *NewBB = cast<BasicBlock>(VMap[OldBB]);

    // Map operands for blocks that are live and remove operands for blocks
    // that are dead.
    for (; phino != PHIToResolve.size() &&
         PHIToResolve[phino]->getParent() == OldBB; ++phino) {
      OPN = PHIToResolve[phino];
      PHINode *PN = cast<PHINode>(VMap[OPN]);
      for (unsigned pred = 0, e = NumPreds; pred != e; ++pred) {
        if (BasicBlock *MappedBlock = 
            cast_or_null<BasicBlock>(VMap[PN->getIncomingBlock(pred)])) {
          Value *InVal = MapValue(PN->getIncomingValue(pred),
                                  VMap);
          assert(InVal && "Unknown input value?");
          PN->setIncomingValue(pred, InVal);
          PN->setIncomingBlock(pred, MappedBlock);
        } else {
          PN->removeIncomingValue(pred, false);
          --pred, --e;  // Revisit the next entry.
        }
      } 
    }
    
    // The loop above has removed PHI entries for those blocks that are dead
    // and has updated others.  However, if a block is live (i.e. copied over)
    // but its terminator has been changed to not go to this block, then our
    // phi nodes will have invalid entries.  Update the PHI nodes in this
    // case.
    PHINode *PN = cast<PHINode>(NewBB->begin());
    NumPreds = std::distance(pred_begin(NewBB), pred_end(NewBB));
    if (NumPreds != PN->getNumIncomingValues()) {
      assert(NumPreds < PN->getNumIncomingValues());
      // Count how many times each predecessor comes to this block.
      std::map<BasicBlock*, unsigned> PredCount;
      for (pred_iterator PI = pred_begin(NewBB), E = pred_end(NewBB);
           PI != E; ++PI)
        --PredCount[*PI];
      
      // Figure out how many entries to remove from each PHI.
      for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
        ++PredCount[PN->getIncomingBlock(i)];
      
      // At this point, the excess predecessor entries are positive in the
      // map.  Loop over all of the PHIs and remove excess predecessor
      // entries.
      BasicBlock::iterator I = NewBB->begin();
      for (; (PN = dyn_cast<PHINode>(I)); ++I) {
        for (std::map<BasicBlock*, unsigned>::iterator PCI =PredCount.begin(),
             E = PredCount.end(); PCI != E; ++PCI) {
          BasicBlock *Pred     = PCI->first;
          for (unsigned NumToRemove = PCI->second; NumToRemove; --NumToRemove)
            PN->removeIncomingValue(Pred, false);
        }
      }
    }
    
    // If the loops above have made these phi nodes have 0 or 1 operand,
    // replace them with undef or the input value.  We must do this for
    // correctness, because 0-operand phis are not valid.
    PN = cast<PHINode>(NewBB->begin());
    if (PN->getNumIncomingValues() == 0) {
      BasicBlock::iterator I = NewBB->begin();
      BasicBlock::const_iterator OldI = OldBB->begin();
      while ((PN = dyn_cast<PHINode>(I++))) {
        Value *NV = UndefValue::get(PN->getType());
        PN->replaceAllUsesWith(NV);
        assert(VMap[OldI] == PN && "VMap mismatch");
        VMap[OldI] = NV;
        PN->eraseFromParent();
        ++OldI;
      }
    }
    // NOTE: We cannot eliminate single entry phi nodes here, because of
    // VMap.  Single entry phi nodes can have multiple VMap entries
    // pointing at them.  Thus, deleting one would require scanning the VMap
    // to update any entries in it that would require that.  This would be
    // really slow.
  }
  
  // Now that the inlined function body has been fully constructed, go through
  // and zap unconditional fall-through branches.  This happen all the time when
  // specializing code: code specialization turns conditional branches into
  // uncond branches, and this code folds them.
  Function::iterator I = cast<BasicBlock>(VMap[&OldFunc->getEntryBlock()]);
  while (I != NewFunc->end()) {
    BranchInst *BI = dyn_cast<BranchInst>(I->getTerminator());
    if (!BI || BI->isConditional()) { ++I; continue; }
    
    // Note that we can't eliminate uncond branches if the destination has
    // single-entry PHI nodes.  Eliminating the single-entry phi nodes would
    // require scanning the VMap to update any entries that point to the phi
    // node.
    BasicBlock *Dest = BI->getSuccessor(0);
    if (!Dest->getSinglePredecessor() || isa<PHINode>(Dest->begin())) {
      ++I; continue;
    }
    
    // We know all single-entry PHI nodes in the inlined function have been
    // removed, so we just need to splice the blocks.
    BI->eraseFromParent();
    
    // Move all the instructions in the succ to the pred.
    I->getInstList().splice(I->end(), Dest->getInstList());
    
    // Make all PHI nodes that referred to Dest now refer to I as their source.
    Dest->replaceAllUsesWith(I);

    // Remove the dest block.
    Dest->eraseFromParent();
    
    // Do not increment I, iteratively merge all things this block branches to.
  }
}
Esempio n. 4
0
bool ComputeSSO::runOnModule(Module &M) {

    //Get the timing information for the analysis..done using -time-passes
//    if (Input.getValue() == llvm::cl::BOU_UNSET || Input.getValue()
//            == llvm::cl::BOU_TRUE) {
//        errs()<<"---getting from InputValues--------------\n";
//        InputValues &IV = getAnalysis<InputValues> ();
//        inputDepValues = IV.getInputDepValues();
//        //TODO:need to add the function to get the target functions here
//    } else {
        errs()<<"---getting from InputDep--------------\n";
        InputDep &IV = getAnalysis<InputDep> ();
        inputDepValues = IV.getInputDepValues();
        targetFunctions = IV.getTargetFunctions();
        targetBlocks = IV.getTargetBlock();
        sourceTypes = IV.getSourceTypes();
        ValLabelmap = IV.getValueLabelMap();
        mediatorFunctions = IV.getMediators();
        queryinputs = IV.getQueryVals();
        // targetVal = IV.getTargetValue();
        //  PostDominatorTree &pdt = getAnalysis<PostDominatorTree>();
        //   DominatorTree &DT = getAnalysis<DominatorTree>();
  //  }

    blockAssign &bssa = getAnalysis<blockAssign> ();
    depGraph = bssa.newGraph;
    //DEBUG( // display dependence graph
    string Error;
    std::string tmp = M.getModuleIdentifier();
    replace(tmp.begin(), tmp.end(), '\\', '_');
    std::string Filename = "/tmp/" + tmp + ".dot";

    //Print dependency graph (in dot format)
        depGraph->toDot(M.getModuleIdentifier(), "depGraphtest.dot");
    //	depGraph->toDotLines(M.getModuleIdentifier(), "depGraphtestlines.dot");
    //	sys::Path Filename_path(Filename);
    //	llvm::DisplayGraph(Filename_path, true, GraphProgram::DOT);
    //	);
    int inputDepVal_count = 0;
    std::string appendVal ="a";
    std::set<Value*> inputDepValuespart;
     set<Instruction*> LoopupInsts;
     set<Value*> SecSensitiveObjs;
    errs()<<"----------------------Taint Flow Analysis-----------------\n";
    for(std::set<Value*>::iterator tv = inputDepValues.begin(); tv != inputDepValues.end(); ++tv)
    {

        int branches = 0;
        errs()<<**tv <<"\n";
        //std::string appendVal = (**tv).getName();

        inputDepValuespart.clear();
        errs()<<"----------------------Input deps above-----------------\n";
        //tainted = depGraph->getDepValues(inputDepValues);

        Value* currentTaintVal = *tv;
        std::string appendVal = ValLabelmap[currentTaintVal];
        inputDepValuespart.insert(currentTaintVal);
        errs()<<"\n\nInputDep Values for "<<*currentTaintVal;
        tainted =  depGraph->getDepValues(inputDepValuespart);

        //Graph * subGraph = depGraph->generateSubGraph(currentTaintVal,)


        //To print strings used with this taint...
        std::string ErrorInfo;
        bool writeStrings = true;
        string stringfileName = tmp+"_"+ appendVal + ".txt";

        raw_fd_ostream FileS(stringfileName.c_str(), ErrorInfo,sys::fs::F_None);
        if (!ErrorInfo.empty()) {
            errs() << "Error opening file " << stringfileName
                   << " for writing! Error Info: " << ErrorInfo << " \n";
            writeStrings = false;
        }


        taintGraphMap[currentTaintVal] = tainted;



        // PrintTainted(tainted);
        errs()<<"\n---------------------\n";
        //TODO: Memory error in the insert... verify and solve...



        std::set<GraphNode *>::iterator G;
        std::set<GraphNode *>::iterator endG;
        //        for (G = tainted.begin(), endG = tainted.end(); G != endG; ++G)
        //        {
        //            //  errs()<<" The tainted graph node : "<<(*G)->getName()<<"\n";
        //        }

        // errs()<<" \n \n";




        //DEBUG( // If debug mode is enabled, add metadata to easily identify tainted values in the llvm IR
        for (Module::iterator F = M.begin(), endF = M.end(); F != endF; ++F) {
            for (Function::iterator BB = F->begin(), endBB = F->end(); BB != endBB; ++BB) {

                for (BasicBlock::iterator I = BB->begin(), endI = BB->end(); I
                     != endI; ++I) {
                    GraphNode* g = depGraph->findNode(I);
                    if (tainted.count(g)) {
                        g->taintSet.insert(appendVal);
                        if (BranchInst *BI = dyn_cast<BranchInst>(I))
                        {
                            //   errs()<<"Branch Inst tainted : ";
                              BI->dump();
                            branches++;
                        }
                        if(CallInst *CI = dyn_cast<CallInst>(I))
                        {

                            Function* func = CI->getCalledFunction();
                            if(func && !func->isDeclaration())
                            {


                                for(set<string>::iterator med = mediatorFunctions.begin(); med != mediatorFunctions.end();med++)
                                {
                                    string medfunc = (*med);
                                    string funcName = func->getName();

                                    if(strcmp(medfunc.c_str(),funcName.c_str())==0)
                                    {
                                        g->taintSet.erase(appendVal);
                                        errs()<<"\n+++++++++++ Med func  : function name :  "<<funcName;
                                        appendVal = appendVal+"_Med";
                                        g->taintSet.insert(appendVal);
                                    }
                                }
                            }

                        }

                        //Print all the lookup instructions with tainted values..:

                        if(GetElementPtrInst *GI = dyn_cast<GetElementPtrInst>(I))
                        {
                            moduleDepGraph* mdG = new  moduleDepGraph();
                            mdG->CheckifRelevantField(GI,depGraph);
                            LoopupInsts.insert(I);
                            Value* sensitiveObject = GI->getPointerOperand();
                            SecSensitiveObjs.insert(sensitiveObject);
                        }

                        //check if any operand is global string..
                        if(writeStrings)
                        {
                            for (unsigned int i = 0; i < cast<User> (I)->getNumOperands(); i++)
                            {
                                Value *v1 = cast<User> (I)->getOperand(i);
                                if(isa<GlobalVariable> (v1))
                                {
                                    if(isa<Constant> (v1))
                                    {
                                        //string sName = v1->getName()
                                        v1->print(FileS);
                                        (FileS) << "\n";
                                    }
                                }
                            }
                        }

                        LLVMContext& C = I->getContext();
                        MDNode* N = MDNode::get(C, MDString::get(C, "ComputeSSO"));
                        // char numstr[21]; // enough to hold all numbers up to 64-bits
                        //sprintf(numstr, "%d", inputDepVal_count);
                        //appendVal = ()
                          std::string taintVal = "TAINT_"+appendVal;
                        //    if(debug)	errs()<<"\nFunction : "<< F->getName()<<"  Tainted Val " << *I <<"  val: " << appendVal;

                        //For the given tainted Val try priniting all the uses of it.
                        // errs()<<"\nUsed in :: "<<I->getNumUses();

                      //  std::string taintVal = std::strcat("tainted",numstr);
                        I->setMetadata(taintVal, N);
                    }


                    /*	if (GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(&*I)) {
                    // Dump the GEP instruction
                //	gep->dump();
                    Value* firstOperand = gep->getOperand(0);
                    Type* type = firstOperand->getType();

                    // Figure out whether the first operand points to an array
                    if (PointerType *pointerType = dyn_cast<PointerType>(type)) {
                        Type* elementType = pointerType->getElementType();
                        //errs() << "The element type is: " << *elementType << "\n";

                        if (elementType->isArrayTy()) {

                            errs() << "\n  .. points to an array!\n";
                            errs()<< "First op  ..: "<< firstOperand <<"  full def :";
                            gep->dump();
                        }
                        else if(elementType->isStructTy ()) {
                            errs() << "\n  *** points to a Struct !\n";
                            errs()<< "First op  ..: "<< firstOperand <<"  full def :";
                            gep->dump();
                        }
                    }
               }  */
                }
            }
        }

        //Print how many source types added
        //errs()<<"\nSource Types added  :"<<sourceTypes.size();

        inputDepVal_count++;
        //appendVal = appendVal+ 1;
        errs()<<"\n Branch Inst tainted : "<<branches;
    } //closing the loop for inputdepVal

    errs()<<"\n\n --- toal loookup instss.------: "<<LoopupInsts.size()<<"\n";
      errs()<<"\n\n --- toal sensitve objects .------: "<<SecSensitiveObjs.size()<<"\n";
      for(set<Value*>::iterator secVal = SecSensitiveObjs.begin(); secVal != SecSensitiveObjs.end();++secVal)
      {
          (*secVal)->dump();
      }

    updateTaintLabels();

         tainted =  depGraph->getDepValues(inputDepValues);

        //Add taint labels in metadata:
        for (Module::iterator F = M.begin(), endF = M.end(); F != endF; ++F) {
            for (Function::iterator BB = F->begin(), endBB = F->end(); BB != endBB; ++BB) {
                for (BasicBlock::iterator I = BB->begin(), endI = BB->end(); I
                     != endI; ++I) {
                    GraphNode* g = depGraph->findNode(I);
                    if (tainted.count(g)) {
                        LLVMContext& C = I->getContext();
                        MDNode* N = MDNode::get(C, MDString::get(C, "ComputeSSO"));
                        for(set<string>::iterator label = g->taintSet.begin();label!=g->taintSet.end();++label)
                        {
                        std::string taintVal = *label;
                        I->setMetadata(taintVal, N);
                        }
                    }
                }
            }
        }

    //
    //  M.dump();

    //  getSinkSourceBlockDependence();
    // getSinkSourceDependence();
    //   getHookLocation();
    //testProcessing();

    //	);



   // HandleQueries(M);



    //errs()<<"\n\n\n\n*********  Source Types ******************";
    for(std::set<SourceType*>::iterator st = sourceTypes.begin(); st!=sourceTypes.end();++st)
    {
        (*st)->Print();
    }


    //errs()<<"\n\n\n\n*********  Derived Types ******************";
    for(std::set<SourceType*>::iterator st = sourceTypesDerived.begin(); st!=sourceTypesDerived.end();++st)
    {
        (*st)->Print();
    }

    return false;
}