Beispiel #1
0
void ClassHierarchyUtils::cacheAllCalleesForVirtualCalls(Module& M) {
  if (!cachingDone) {
    for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
      if (F->isDeclaration()) continue;
      for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
        if (CallInst* C = dyn_cast<CallInst>(&*I)) {
          GlobalVariable* definingTypeVTableVar = NULL;
          GlobalVariable* staticTypeVTableVar = NULL;
          bool hasMetadata = false;
          if (MDNode* N = I->getMetadata("soaap_defining_vtable_var")) {
            definingTypeVTableVar = cast<GlobalVariable>(N->getOperand(0));
            hasMetadata = true;
          }
          else if (MDNode* N = I->getMetadata("soaap_defining_vtable_name")) {
            ConstantDataArray* definingTypeVTableConstant = cast<ConstantDataArray>(N->getOperand(0));
            string definingTypeVTableConstantStr = definingTypeVTableConstant->getAsString().str();
            //dbgs() << "definingTypeVTableConstantStr: " << definingTypeVTableConstantStr << "\n";
            definingTypeVTableVar = M.getGlobalVariable(definingTypeVTableConstantStr, true);
            hasMetadata = true;
          }
          if (MDNode* N = I->getMetadata("soaap_static_vtable_var")) {
            staticTypeVTableVar = cast<GlobalVariable>(N->getOperand(0));
            hasMetadata = true;
          }
          else if (MDNode* N = I->getMetadata("soaap_static_vtable_name")) {
            ConstantDataArray* staticTypeVTableConstant = cast<ConstantDataArray>(N->getOperand(0));
            string staticTypeVTableConstantStr = staticTypeVTableConstant->getAsString().str();
            //dbgs() << "staticTypeVTableConstantStr: " << staticTypeVTableConstantStr << "\n";
            staticTypeVTableVar = M.getGlobalVariable(staticTypeVTableConstantStr, true);
            hasMetadata = true;
          }
          if (definingTypeVTableVar != NULL) {
            SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "Found definingVTableVar: " << *definingTypeVTableVar << "\n");
            if (staticTypeVTableVar == NULL) {
              dbgs() << "definingVTableVar is not null, but staticTypeVTableVar is NULL\n";
              // This could be the case if no instance of the static type is ever created
              staticTypeVTableVar = definingTypeVTableVar;
            }
            callToCalleesCache[C] = findAllCalleesForVirtualCall(C, definingTypeVTableVar, staticTypeVTableVar, M);
          }
          else if (hasMetadata) {
            dbgs() << "Defining VTable is NULL!\n";
            I->dump();
          }
        }
      }
    }
    cachingDone = true;
  }
}
void AssertionSiteInstrumenter::ParseAssertionLocation(
  Location *Loc, CallInst *Call) {

  assert(Call->getCalledFunction()->getName() == INLINE_ASSERTION);

  if (Call->getNumArgOperands() < 4)
    panic("TESLA assertion must have at least 4 arguments");

  // The filename (argument 1) should be a global variable.
  GlobalVariable *NameVar =
    dyn_cast<GlobalVariable>(Call->getOperand(1)->stripPointerCasts());

  ConstantDataArray *A;
  if (!NameVar ||
      !(A = dyn_cast_or_null<ConstantDataArray>(NameVar->getInitializer()))) {
    Call->dump();
    panic("unable to parse filename from TESLA assertion");
  }

  *Loc->mutable_filename() = A->getAsString();


  // The line and counter values should be constant integers.
  ConstantInt *Line = dyn_cast<ConstantInt>(Call->getOperand(2));
  if (!Line) {
    Call->getOperand(2)->dump();
    panic("assertion line must be a constant int");
  }

  Loc->set_line(Line->getLimitedValue(INT_MAX));

  ConstantInt *Count = dyn_cast<ConstantInt>(Call->getOperand(3));
  if (!Count) {
    Call->getOperand(3)->dump();
    panic("assertion count must be a constant int");
  }

  Loc->set_counter(Count->getLimitedValue(INT_MAX));
}