Ejemplo n.º 1
0
Constant *LLVMFormula::getGlobalVariableFor (double *ptr)
{
	// Thanks to the unladen-swallow project for this snippet, which was almost
	// impossible to figure out from the LLVM docs!

	// See if the JIT already knows about this global
	GlobalVariable *result = const_cast<GlobalVariable *>(
		cast_or_null<GlobalVariable>(
			engine->getGlobalValueAtAddress (ptr)));
	if (result && result->hasInitializer ())
		return result;
	
	Constant *initializer = ConstantFP::get (Type::getDoubleTy (getGlobalContext ()), *ptr);
	if (result == NULL)
	{
		// Make a global variable
		result = new GlobalVariable (*module, initializer->getType (),
		                             false, GlobalVariable::InternalLinkage,
		                             NULL, "");
		
		// Link the global variable to the right address
		engine->addGlobalMapping (result, ptr);
	}
	assert (!result->hasInitializer ());
		
	// Add the initial value
	result->setInitializer (initializer);

	return result;
}
Ejemplo n.º 2
0
void ClassHierarchyUtils::findClassHierarchy(Module& M) {
  // Extract class hierarchy using std::type_info structures rather than debug
  // info. The former works even for when there are anonymous namespaces.
  // (for more info, see http://mentorembedded.github.io/cxx-abi/abi.html)
  // 
  // Class names are usually global, except in the case of anonymous namespaces, in which case
  // they may be renamed during linking. This renaming is not consistent across type_info and
  // vtables. For example, the following are for the same class:
  // _ZTIN7content12_GLOBAL__N_115HeaderFlattenerE60908 and
  // _ZTVN7content12_GLOBAL__N_115HeaderFlattenerE60906.
  // 
  // (renamed from
  // _ZTVN7content12_GLOBAL__N_115HeaderFlattenerE and
  // _ZTIN7content12_GLOBAL__N_115HeaderFlattenerE).
  //
  // VTables give us the corresponding type_info, so we process them first and store
  // the VT <-> TI mappings, as this will be useful later.
  for (Module::global_iterator I=M.global_begin(), E=M.global_end(); I != E; I++) {
    GlobalVariable* VT = &*I;
    if (VT->getName().startswith("_ZTV")) {
      SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found vtable: " << VT->getName() << "\n");
      if (VT->hasInitializer()) {
        ConstantStruct* VTinit = cast<ConstantStruct>(VT->getInitializer());
        // all occurrences of a type_info object refer to this class's type_info, so we
        // can pick the first array
        ConstantArray* VTinitElem = cast<ConstantArray>(VTinit->getOperand(0));
        for (int i=0; i<VTinitElem->getNumOperands(); i++) {
          // type_info will be the first global variable in the array.
          // It's not always at a fixed index so we have to search for it...
          // The first one corresponds to the primary vtable, all others
          // correspond to secondary vtables. All type_info occurrences will
          // be the same.
          if (GlobalVariable* TI = dyn_cast<GlobalVariable>(VTinitElem->getOperand(i)->stripPointerCasts())) {
            if (typeInfoToVTable.find(TI) != typeInfoToVTable.end()) {
              report_fatal_error(TI->getName() + " <-> " + VT->getName() + " mapping already exists!");
            }
            // Record TI <-> VT mappings, as they will be useful later
            typeInfoToVTable[TI] = VT;
            vTableToTypeInfo[VT] = TI;
            break;  // we only need to process the first one
          }
        }
      }
      else {
        SDEBUG("soaap.util.classhierarchy", 1, dbgs() << "WARNING: VTable " << VT->getName() << " does not have initializer\n");
      }
    }
  }

  // Process type_info structures, recording class-hierarchy information and base offsets
  for (Module::global_iterator I=M.global_begin(), E=M.global_end(); I != E; I++) {
    GlobalVariable* G = &*I;
    if (G->getName().startswith("_ZTI")) {
      SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found type_info: " << G->getName() << "\n");
      processTypeInfo(G, M);
    }
  }

  SDEBUG("soaap.util.classhierarchy", 3, ppClassHierarchy(classToSubclasses));
}
Ejemplo n.º 3
0
Value *DbgStopPointInst::getDirectory() const {
  // Once the operand indices are verified, update this assert
  assert(LLVMDebugVersion == (7 << 16) && "Verify operand indices");
  GlobalVariable *GV = cast<GlobalVariable>(getContext());
  if (!GV->hasInitializer()) return NULL;
  ConstantStruct *CS = cast<ConstantStruct>(GV->getInitializer());
  return CS->getOperand(4);
}
Ejemplo n.º 4
0
void ClassHierarchyUtils::findClassHierarchy(Module& M) {
  // extract call hierarchy using std::type_info structures rather
  // than debug info. The former works even for when there are anonymous
  // namespaces. type_info structs can be obtained from vtable globals.
  // (for more info, see http://mentorembedded.github.io/cxx-abi/abi.html)
  for (Module::global_iterator I=M.global_begin(), E=M.global_end(); I != E; I++) {
    GlobalVariable* G = &*I;
    if (G->getName().startswith("_ZTV")) {
      if (G->hasInitializer()) {
        SDEBUG("soaap.util.classhierarchy", 3, G->dump());
        ConstantArray* Ginit = cast<ConstantArray>(G->getInitializer());
        // Ginit[1] is the type_info global for this vtable's type
        bool typeInfoFound = false;
        bool primaryVTable = true;
        for (int i=0; i<Ginit->getNumOperands(); i++) {
          // typeinfo will be the first global variable in the array.
          // It's not always at a fixed index so we have to search for it...
          if (GlobalVariable* TI = dyn_cast<GlobalVariable>(Ginit->getOperand(i)->stripPointerCasts())) {
            //TI->dump();
            typeInfoToVTable[TI] = G;
            vTableToTypeInfo[G] = TI;
            processTypeInfo(TI); // process TI recursively (it contains refs to super-class TIs)
            typeInfoFound = true;
            if (primaryVTable) {
              primaryVTable = false;
              vTableToSecondaryVTableMaps[G][0] = i+1;  // i+1 is also the size of the vtable header            
            }
            else {
              // offset_to_top is at the previous index 
              ConstantExpr* offsetValCast = cast<ConstantExpr>(Ginit->getOperand(i-1)->stripPointerCasts());
              ConstantInt* offsetVal = cast<ConstantInt>(offsetValCast->getOperand(0)); 
              int offsetToTop = offsetVal->getSExtValue();
              if (offsetToTop > 0) {
                dbgs() << "ERROR: offsetToTop is positive!\n";
                G->dump();
              }
              else {
                offsetToTop *= -1;
              }
              
              SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "offsetToTop: " << offsetToTop << "\n");
              vTableToSecondaryVTableMaps[G][offsetToTop] = i+1;
            }
          }
        }

        if (!typeInfoFound) {
          dbgs() << "ERROR: vtable initializer is not a global variable...\n";
          dbgs() << *G << " = " << *Ginit << "\n";
        }
      }
    }
  }
  
  SDEBUG("soaap.util.classhierarchy", 3, ppClassHierarchy(classToSubclasses));
}
Ejemplo n.º 5
0
GlobalVariable *llvm::collectUsedGlobalVariables(
    const Module &M, SmallPtrSetImpl<GlobalValue *> &Set, bool CompilerUsed) {
  const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used";
  GlobalVariable *GV = M.getGlobalVariable(Name);
  if (!GV || !GV->hasInitializer())
    return GV;

  const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer());
  for (Value *Op : Init->operands()) {
    GlobalValue *G = cast<GlobalValue>(Op->stripPointerCastsNoFollowAliases());
    Set.insert(G);
  }
  return GV;
}
Ejemplo n.º 6
0
/// AnalyzeModule - Scan the module for global debug information.
///
void MachineModuleInfo::AnalyzeModule(Module &M) {
  // Insert functions in the llvm.used array (but not llvm.compiler.used) into
  // UsedFunctions.
  GlobalVariable *GV = M.getGlobalVariable("llvm.used");
  if (!GV || !GV->hasInitializer()) return;

  // Should be an array of 'i8*'.
  ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
  if (InitList == 0) return;

  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i)
    if (Function *F =
          dyn_cast<Function>(InitList->getOperand(i)->stripPointerCasts()))
      UsedFunctions.insert(F);
}
Ejemplo n.º 7
0
/// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
GlobalVariable *llvm::ExtractTypeInfo(Value *V) {
  V = V->stripPointerCasts();
  GlobalVariable *GV = dyn_cast<GlobalVariable>(V);

  if (GV && GV->getName() == "llvm.eh.catch.all.value") {
    assert(GV->hasInitializer() &&
           "The EH catch-all value must have an initializer");
    Value *Init = GV->getInitializer();
    GV = dyn_cast<GlobalVariable>(Init);
    if (!GV) V = cast<ConstantPointerNull>(Init);
  }

  assert((GV || isa<ConstantPointerNull>(V)) &&
         "TypeInfo must be a global variable or NULL");
  return GV;
}
Ejemplo n.º 8
0
void moveGlobalVariableInitializer(GlobalVariable &OrigGV,
                                   ValueToValueMapTy &VMap,
                                   ValueMaterializer *Materializer,
                                   GlobalVariable *NewGV) {
  assert(OrigGV.hasInitializer() && "Nothing to move");
  if (!NewGV)
    NewGV = cast<GlobalVariable>(VMap[&OrigGV]);
  else
    assert(VMap[&OrigGV] == NewGV &&
           "Incorrect global variable mapping in VMap.");
  assert(NewGV->getParent() != OrigGV.getParent() &&
         "moveGlobalVariableInitializer should only be used to move "
         "initializers between modules");

  NewGV->setInitializer(MapValue(OrigGV.getInitializer(), VMap, RF_None,
                                 nullptr, Materializer));
}
Ejemplo n.º 9
0
static void setGlobalVariableValue(Module &M, const char *Name,
                                   Constant *Value) {
  GlobalVariable *Var = M.getNamedGlobal(Name);
  if (!Var) {
    // This warning can happen in a program that does not use a libc
    // and does not initialize TLS variables.  Such a program might be
    // linked with "-nostdlib".
    errs() << "Warning: Variable " << Name << " not referenced\n";
  } else {
    if (Var->hasInitializer()) {
      report_fatal_error(std::string("Variable ") + Name +
                         " already has an initializer");
    }
    Var->replaceAllUsesWith(ConstantExpr::getBitCast(Value, Var->getType()));
    Var->eraseFromParent();
  }
}
Ejemplo n.º 10
0
/// GetConstantStringInfo - This function computes the length of a
/// null-terminated C string pointed to by V.  If successful, it returns true
/// and returns the string in Str.  If unsuccessful, it returns false.
bool llvm::GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset,
                                 bool StopAtNul) {
  // If V is NULL then return false;
  if (V == NULL) return false;

  // Look through bitcast instructions.
  if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
    return GetConstantStringInfo(BCI->getOperand(0), Str, Offset, StopAtNul);
  
  // If the value is not a GEP instruction nor a constant expression with a
  // GEP instruction, then return false because ConstantArray can't occur
  // any other way
  User *GEP = 0;
  if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
    GEP = GEPI;
  } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
    if (CE->getOpcode() == Instruction::BitCast)
      return GetConstantStringInfo(CE->getOperand(0), Str, Offset, StopAtNul);
    if (CE->getOpcode() != Instruction::GetElementPtr)
      return false;
    GEP = CE;
  }
  
  if (GEP) {
    // Make sure the GEP has exactly three arguments.
    if (GEP->getNumOperands() != 3)
      return false;
    
    // Make sure the index-ee is a pointer to array of i8.
    const PointerType *PT = cast<PointerType>(GEP->getOperand(0)->getType());
    const ArrayType *AT = dyn_cast<ArrayType>(PT->getElementType());
    if (AT == 0 || AT->getElementType() != Type::Int8Ty)
      return false;
    
    // Check to make sure that the first operand of the GEP is an integer and
    // has value 0 so that we are sure we're indexing into the initializer.
    ConstantInt *FirstIdx = dyn_cast<ConstantInt>(GEP->getOperand(1));
    if (FirstIdx == 0 || !FirstIdx->isZero())
      return false;
    
    // If the second index isn't a ConstantInt, then this is a variable index
    // into the array.  If this occurs, we can't say anything meaningful about
    // the string.
    uint64_t StartIdx = 0;
    if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
      StartIdx = CI->getZExtValue();
    else
      return false;
    return GetConstantStringInfo(GEP->getOperand(0), Str, StartIdx+Offset,
                                 StopAtNul);
  }
  
  // The GEP instruction, constant or instruction, must reference a global
  // variable that is a constant and is initialized. The referenced constant
  // initializer is the array that we'll use for optimization.
  GlobalVariable* GV = dyn_cast<GlobalVariable>(V);
  if (!GV || !GV->isConstant() || !GV->hasInitializer())
    return false;
  Constant *GlobalInit = GV->getInitializer();
  
  // Handle the ConstantAggregateZero case
  if (isa<ConstantAggregateZero>(GlobalInit)) {
    // This is a degenerate case. The initializer is constant zero so the
    // length of the string must be zero.
    Str.clear();
    return true;
  }
  
  // Must be a Constant Array
  ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
  if (Array == 0 || Array->getType()->getElementType() != Type::Int8Ty)
    return false;
  
  // Get the number of elements in the array
  uint64_t NumElts = Array->getType()->getNumElements();
  
  if (Offset > NumElts)
    return false;
  
  // Traverse the constant array from 'Offset' which is the place the GEP refers
  // to in the array.
  Str.reserve(NumElts-Offset);
  for (unsigned i = Offset; i != NumElts; ++i) {
    Constant *Elt = Array->getOperand(i);
    ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
    if (!CI) // This array isn't suitable, non-int initializer.
      return false;
    if (StopAtNul && CI->isZero())
      return true; // we found end of string, success!
    Str += (char)CI->getZExtValue();
  }
  
  // The array isn't null terminated, but maybe this is a memcpy, not a strcpy.
  return true;
}
Ejemplo n.º 11
0
bool GenericToNVVM::runOnModule(Module &M) {
  // Create a clone of each global variable that has the default address space.
  // The clone is created with the global address space  specifier, and the pair
  // of original global variable and its clone is placed in the GVMap for later
  // use.

  for (Module::global_iterator I = M.global_begin(), E = M.global_end();
       I != E;) {
    GlobalVariable *GV = &*I++;
    if (GV->getType()->getAddressSpace() == llvm::ADDRESS_SPACE_GENERIC &&
        !llvm::isTexture(*GV) && !llvm::isSurface(*GV) &&
        !llvm::isSampler(*GV) && !GV->getName().startswith("llvm.")) {
      GlobalVariable *NewGV = new GlobalVariable(
          M, GV->getValueType(), GV->isConstant(),
          GV->getLinkage(),
          GV->hasInitializer() ? GV->getInitializer() : nullptr,
          "", GV, GV->getThreadLocalMode(), llvm::ADDRESS_SPACE_GLOBAL);
      NewGV->copyAttributesFrom(GV);
      GVMap[GV] = NewGV;
    }
  }

  // Return immediately, if every global variable has a specific address space
  // specifier.
  if (GVMap.empty()) {
    return false;
  }

  // Walk through the instructions in function defitinions, and replace any use
  // of original global variables in GVMap with a use of the corresponding
  // copies in GVMap.  If necessary, promote constants to instructions.
  for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
    if (I->isDeclaration()) {
      continue;
    }
    IRBuilder<> Builder(I->getEntryBlock().getFirstNonPHIOrDbg());
    for (Function::iterator BBI = I->begin(), BBE = I->end(); BBI != BBE;
         ++BBI) {
      for (BasicBlock::iterator II = BBI->begin(), IE = BBI->end(); II != IE;
           ++II) {
        for (unsigned i = 0, e = II->getNumOperands(); i < e; ++i) {
          Value *Operand = II->getOperand(i);
          if (isa<Constant>(Operand)) {
            II->setOperand(
                i, remapConstant(&M, &*I, cast<Constant>(Operand), Builder));
          }
        }
      }
    }
    ConstantToValueMap.clear();
  }

  // Copy GVMap over to a standard value map.
  ValueToValueMapTy VM;
  for (auto I = GVMap.begin(), E = GVMap.end(); I != E; ++I)
    VM[I->first] = I->second;

  // Walk through the metadata section and update the debug information
  // associated with the global variables in the default address space.
  for (NamedMDNode &I : M.named_metadata()) {
    remapNamedMDNode(VM, &I);
  }

  // Walk through the global variable  initializers, and replace any use of
  // original global variables in GVMap with a use of the corresponding copies
  // in GVMap.  The copies need to be bitcast to the original global variable
  // types, as we cannot use cvta in global variable initializers.
  for (GVMapTy::iterator I = GVMap.begin(), E = GVMap.end(); I != E;) {
    GlobalVariable *GV = I->first;
    GlobalVariable *NewGV = I->second;

    // Remove GV from the map so that it can be RAUWed.  Note that
    // DenseMap::erase() won't invalidate any iterators but this one.
    auto Next = std::next(I);
    GVMap.erase(I);
    I = Next;

    Constant *BitCastNewGV = ConstantExpr::getPointerCast(NewGV, GV->getType());
    // At this point, the remaining uses of GV should be found only in global
    // variable initializers, as other uses have been already been removed
    // while walking through the instructions in function definitions.
    GV->replaceAllUsesWith(BitCastNewGV);
    std::string Name = GV->getName();
    GV->eraseFromParent();
    NewGV->setName(Name);
  }
  assert(GVMap.empty() && "Expected it to be empty by now");

  return true;
}
Ejemplo n.º 12
0
void llvm::copyGVInitializer(GlobalVariable &New, const GlobalVariable &Orig,
                             ValueToValueMapTy &VMap) {
  if (Orig.hasInitializer())
    New.setInitializer(MapValue(Orig.getInitializer(), VMap));
}
Ejemplo n.º 13
0
bool SpDefUseInstrumenter::runOnModule(Module &M) {

  cerr << "instrument: --- Def-Use pair Spectrum ---\n";

  Function *Main = M.getFunction("main");
  LLVMContext &C = M.getContext();
  
  if (Main == 0) {
    cerr << "WARNING: cannot insert def-use instrumentation into a module"
         << " with no main function!\n";
    return false;  // No main, no instrumentation!
  }

  // Add library function prototype
  Constant *SpFn = M.getOrInsertFunction("_updateSpectrum", 
                          Type::getVoidTy(C), 
                          Type::getInt32Ty(C),  // spectrum index
                          Type::getInt32Ty(C),  // component index
                          NULL);


  unsigned spectrumIndex = IndexManager::getSpectrumIndex();
  unsigned nDefs = 0;
  unsigned nUses = 0;

  // Loop through all functions within module
  for (Module::iterator F = M.begin(), ME = M.end(); F != ME; ++F) {

    // skip function declarations
    if(F->isDeclaration()) 
      continue;

    // skip the _registerAll function
    if(F->getName()=="_registerAll")
      continue;
    
    // Loop through all basic blocks within function
    for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) {
      //skip dead blocks
      //is this really safe??
      BasicBlock *bb = B;
      if (B!=F->begin() && (pred_begin(bb)==pred_end(bb))) continue; //skip dead blocks

      // Loop through all instructions within basic block
      for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) {
    
        if(isa<DbgDeclareInst>(*I)) {

          // extract source file information from debug intrinsic
          DbgDeclareInst &DDI = cast<DbgDeclareInst>(*I);
          std::string file, dir;
          std::string name;
          GlobalVariable *gv = cast<GlobalVariable>(DDI.getVariable());
          if(!gv->hasInitializer()) continue;
          ConstantStruct *cs = cast<ConstantStruct>(gv->getInitializer());
          llvm::GetConstantStringInfo(cs->getOperand(2), name);
          unsigned int line = unsigned(cast<ConstantInt>(cs->getOperand(4))->getZExtValue());
          Value *V = cast<Value>(cs->getOperand(3));
          GlobalVariable *gv2 = cast<GlobalVariable>(cast<ConstantExpr>(V)->getOperand(0));
          if(!gv2->hasInitializer()) continue;
          ConstantStruct *cs2 = cast<ConstantStruct>(gv2->getInitializer());
          llvm::GetConstantStringInfo(cs2->getOperand(3), file);
          llvm::GetConstantStringInfo(cs2->getOperand(4), dir);

          // get the allocation instruction of the variable definition
          AllocaInst *AI;
          if(isa<AllocaInst>(DDI.getAddress())) {
            AI = cast<AllocaInst>(DDI.getAddress());
          } else if (isa<BitCastInst>(DDI.getAddress())) {
            AI = cast<AllocaInst>(cast<BitCastInst>(DDI.getAddress())->getOperand(0));
          } else {
            continue;
          }

          nDefs++;

          // add calls to lib function for each use of the variable
          int currUses = 0;
          for(AllocaInst::use_iterator U = AI->use_begin(), UE = AI->use_end(); U != UE; ++U) {
            if(isa<Instruction>(*U)) {

              User *user = *U;
              Instruction *insertInst = (Instruction*)user;

              // find most likely context location of use
              int useline = line;
              std::string usefile = file, usedir = dir;
              BasicBlock *parent = insertInst->getParent();
              BasicBlock::iterator inst = parent->begin();
              while(((Instruction *)inst) != insertInst  &&  inst != parent->end()) {
            	  /*TODO: solve DbgStopPointInst problem*/
            	/*if(isa<DbgStopPointInst>(*inst)) {
                  DbgStopPointInst &DSPI = cast<DbgStopPointInst>(*inst);
                  llvm::GetConstantStringInfo(DSPI.getDirectory(), usedir);
                  llvm::GetConstantStringInfo(DSPI.getFileName(), usefile);
                  useline = DSPI.getLine();
                }*/
                inst++;
              }

              std::stringstream usename;
              usename << name << "(use_" << currUses << ")";
              // add source context of this invariant to context file
              ContextManager::addSpectrumContext(
                spectrumIndex,  // spectrumIndex
                nUses,          // componentIndex
                usedir,         // path
                usefile,        // file
                useline,        // line
                usename.str()); // name
              currUses++;

              std::vector<Value*> Args(2);
              Args[0] = ConstantInt::get(Type::getInt32Ty(C), spectrumIndex);
              Args[1] = ConstantInt::get(Type::getInt32Ty(C), nUses++);

              CallInst::Create(SpFn, Args.begin(), Args.end(), "", insertInst);
            }
          }
        }
      }
    }
  }

  // add the registration of the instrumented spectrum points in the _registerAll() function
  addSpectrumRegistration(M, spectrumIndex, nUses, "Def-Use_Pairs");
  
  std::cerr << "instrument: " << nDefs << " defines with a total number of " << nUses << " uses instrumented\n";

  // notify change of program 
  return true;
}
Ejemplo n.º 14
0
DyckVertex* AAAnalyzer::wrapValue(Value * v) {
    // if the vertex of v exists, return it, otherwise create one
    pair < DyckVertex*, bool> retpair = dgraph->retrieveDyckVertex(v);
    if (retpair.second) {
        return retpair.first;
    }
    DyckVertex* vdv = retpair.first;
    // constantTy are handled as below.
    if (isa<ConstantExpr>(v)) {
        // constant expr should be handled like a assignment instruction
        if (isa<GEPOperator>(v)) {
            DyckVertex * got = handle_gep((GEPOperator*) v);
            makeAlias(vdv, got);
        } else if (((ConstantExpr*) v)->isCast()) {
            // errs() << *v << "\n";
            DyckVertex * got = wrapValue(((ConstantExpr*) v)->getOperand(0));
            makeAlias(vdv, got);
        } else {
            unsigned opcode = ((ConstantExpr*) v)->getOpcode();
            switch (opcode) {
                case 23: // BinaryConstantExpr "and"
                case 24: // BinaryConstantExpr "or"
                {
                    // do nothing
                }
                    break;
                default:
                {
                    errs() << "ERROR when handle the following constant expression\n";
                    errs() << *v << "\n";
                    errs() << ((ConstantExpr*) v)->getOpcode() << "\n";
                    errs() << ((ConstantExpr*) v)->getOpcodeName() << "\n";
                    errs().flush();
                    exit(-1);
                }
                    break;
            }
        }
    } else if (isa<ConstantArray>(v)) {
#ifndef ARRAY_SIMPLIFIED
        DyckVertex* ptr = addPtrTo(NULL, vdv, dgraph);
        DyckVertex* current = ptr;

        Constant * vAgg = (Constant*) v;
        int numElmt = vAgg->getNumOperands();
        for (int i = 0; i < numElmt; i++) {
            Value * vi = vAgg->getOperand(i);
            DyckVertex* viptr = addPtrOffset(current, i * dl.getTypeAllocSize(vi->getType()), dgraph);
            addPtrTo(viptr, wrapValue(vi, dgraph, dl), dgraph);
        }
#else
        Constant * vAgg = (Constant*) v;
        int numElmt = vAgg->getNumOperands();
        for (int i = 0; i < numElmt; i++) {
            Value * vi = vAgg->getOperand(i);
            makeAlias(vdv, wrapValue(vi));
        }
#endif
    } else if (isa<ConstantStruct>(v)) {
        //DyckVertex* ptr = addPtrTo(NULL, vdv);
        //DyckVertex* current = ptr;

        Constant * vAgg = (Constant*) v;
        int numElmt = vAgg->getNumOperands();
        for (int i = 0; i < numElmt; i++) {
            Value * vi = vAgg->getOperand(i);
            addField(vdv, -2 - i, wrapValue(vi));
        }
    } else if (isa<GlobalValue>(v)) {
        if (isa<GlobalVariable>(v)) {
            GlobalVariable * global = (GlobalVariable *) v;
            if (global->hasInitializer()) {
                Value * initializer = global->getInitializer();
                if (!isa<UndefValue>(initializer)) {
                    DyckVertex * initVer = wrapValue(initializer);
                    addPtrTo(vdv, initVer);
                }
            }
        } else if (isa<GlobalAlias>(v)) {
            GlobalAlias * global = (GlobalAlias *) v;
            Value * aliasee = global->getAliasee();
            makeAlias(vdv, wrapValue(aliasee));
        } else if (isa<Function>(v)) {
            // do nothing
        } // no else
    } else if (isa<ConstantInt>(v) || isa<ConstantFP>(v) || isa<ConstantPointerNull>(v) || isa<UndefValue>(v)) {
        // do nothing
    } else if (isa<ConstantDataArray>(v) || isa<ConstantAggregateZero>(v)) {
        // do nothing
    } else if (isa<BlockAddress>(v)) {
        // do nothing
    } else if (isa<ConstantDataVector>(v)) {
        errs() << "ERROR when handle the following ConstantDataSequential, ConstantDataVector\n";
        errs() << *v << "\n";
        errs().flush();
        exit(-1);
    } else if (isa<ConstantVector>(v)) {
        errs() << "ERROR when handle the following ConstantVector\n";
        errs() << *v << "\n";
        errs().flush();
        exit(-1);
    } else if (isa<Constant>(v)) {
        errs() << "ERROR when handle the following constant value\n";
        errs() << *v << "\n";
        errs().flush();
        exit(-1);
    }

    return vdv;
}
Ejemplo n.º 15
0
void SDBuildCHA::buildClouds(Module &M) {
  // this set is used for checking if a parent class is defined or not
  std::set<vtbl_t> build_undefinedVtables;

  for(auto itr = M.getNamedMDList().begin(); itr != M.getNamedMDList().end(); itr++) {
    NamedMDNode* md = itr;

    // check if this is a metadata that we've added
    if(! md->getName().startswith(SD_MD_CLASSINFO))
      continue;

    //sd_print("GOT METADATA: %s\n", md->getName().data());

    std::vector<nmd_t> infoVec = extractMetadata(md);

    for (const nmd_t& info : infoVec) {
      // record the old vtable array
      GlobalVariable* oldVtable = M.getGlobalVariable(info.className, true);

      //sd_print("class %s with %d subtables\n", info.className.c_str(), info.subVTables.size());

      /*
      sd_print("oldvtables: %p, %d, class %s\n",
               oldVtable,
               oldVtable ? oldVtable->hasInitializer() : -1,
               info.className.c_str());
      */

      if (oldVtable && oldVtable->hasInitializer()) {
        ConstantArray* vtable = dyn_cast<ConstantArray>(oldVtable->getInitializer());
        assert(vtable);
        oldVTables[info.className] = vtable;
      } else {
        undefinedVTables.insert(info.className);
      }

      for(unsigned ind = 0; ind < info.subVTables.size(); ind++) {
        const nmd_sub_t* subInfo = & info.subVTables[ind];
        vtbl_t name(info.className, ind);
        /*
        sd_print("SubVtable[%d] Order: %d Parents[%d]: %s [%d-%d] AddrPt: %d\n",
          ind, 
          subInfo->order,
          subInfo->parents.size(),
          "NYI",
          subInfo->start,
          subInfo->end,
          subInfo->addressPoint);
        */

        if (build_undefinedVtables.find(name) != build_undefinedVtables.end()) {
          //sd_print("Removing %s,%d from build_udnefinedVtables\n", name.first.c_str(), name.second);
          build_undefinedVtables.erase(name);
        }

        if (cloudMap.find(name) == cloudMap.end()){
          //sd_print("Inserting %s, %d in cloudMap\n", name.first.c_str(), name.second);
          cloudMap[name] = std::set<vtbl_t>();
        }

        vtbl_set_t parents;
        for (auto it : subInfo->parents) {
          if (it.first != "") {
            vtbl_t &parent = it;
            parents.insert(parent);

            // if the parent class is not defined yet, add it to the
            // undefined vtable set
            if (cloudMap.find(parent) == cloudMap.end()) {
              //sd_print("Inserting %s, %d in cloudMap - undefined parent\n", parent.first.c_str(), parent.second);
              cloudMap[parent] = std::set<vtbl_t>();
              build_undefinedVtables.insert(parent);
            }

            // add the current class to the parent's children set
            cloudMap[parent].insert(name);
          } else {
            assert(ind == 0); // make sure secondary vtables have a direct parent
            // add the class to the root set
            roots.insert(info.className);
          }
        }

        parentMap[info.className].push_back(parents);

        // record the original address points
        addrPtMap[info.className].push_back(subInfo->addressPoint);

        // record the sub-vtable ends
        rangeMap[info.className].push_back(range_t(subInfo->start, subInfo->end));
      }
    }
  }

  if (build_undefinedVtables.size() != 0) {
    sd_print("Build Undefined vtables:\n");
    for (auto n : build_undefinedVtables) {
      sd_print("%s,%d\n", n.first.c_str(), n.second);
    }
  }
  assert(build_undefinedVtables.size() == 0);

  for (auto rootName : roots) {
    vtbl_t root(rootName, 0);
    for (auto child : preorder(root)) {
      if (ancestorMap.find(child) == ancestorMap.end()) {
        ancestorMap[child] = rootName;
      }
    }
  }

  for (auto it : parentMap) {
    const vtbl_name_t &className = it.first;
    const std::vector<vtbl_set_t> &parentSetV = it.second;

    for (int ind = 0; ind < parentSetV.size(); ind++) {
      vtbl_name_t layoutClass = "none";

      // Check that all possible parents are in the same layout cloud
      for (auto ptIt : parentSetV[ind]) {
        if (layoutClass != "none")
          assert(layoutClass == ancestorMap[ptIt] &&
            "All parents of a primitive vtable should have the same root layout.");
        else
          layoutClass = ancestorMap[ptIt];
      }

      // No parents - then our "layout class" is ourselves.
      if (layoutClass == "none")
        layoutClass = className;
      
      // record the class name of the sub-object
      subObjNameMap[className].push_back(layoutClass);
    }
  }
}