Beispiel #1
0
	virtual bool runOnModule(Module &M) {

		LLVMContext &C = M.getContext();
		Function *printError_func = (Function*)M.getOrInsertFunction("printErrorMessage", Type::getVoidTy(C), NULL);

		BasicBlock* entryBlock = BasicBlock::Create(C, "", printError_func);
		IRBuilder<> builder(entryBlock);

		Constant *msg = ConstantArray::get(C, "ERROR!  Array Index Out of Bounds", true);

		Constant *zero_32 = Constant::getNullValue(IntegerType::getInt32Ty(C));
		Constant *gep_params[] = {zero_32, zero_32};


		GlobalVariable *errorMsg = new GlobalVariable(M, msg->getType(), true, GlobalValue::InternalLinkage, msg, "errorMsg");
		Function *puts_func = (Function*)(M.getOrInsertFunction("puts", IntegerType::getInt32Ty(C), PointerType::getUnqual(IntegerType::getInt8Ty(C)), NULL));
		Constant *msgptr = ConstantExpr::getGetElementPtr(errorMsg, gep_params);

		Value *puts_params[] = {msgptr};

		CallInst *puts_call = builder.CreateCall(puts_func, puts_params);
		puts_call->setTailCall(false);

		Function *exit_func = cast<Function>(M.getOrInsertFunction("exit", IntegerType::getVoidTy(C), Type::getInt32Ty(C),NULL));

		Value *exit_val = ConstantInt::get(IntegerType::getInt32Ty(C), 1);
		
		//create exit block.  This block prints the error and calls exit system function
		BasicBlock* exitBlock = BasicBlock::Create(C, "exitBlock", printError_func);
		builder.CreateBr(exitBlock);
		builder.SetInsertPoint(exitBlock);


		builder.CreateCall(exit_func,exit_val);
		builder.CreateBr(exitBlock);

		int checksInserted = 0;

		for (Module::iterator MI = M.begin(), ME = M.end(); MI != ME; ++MI)
		{
			//leave func defs alone
			if (!MI->isDeclaration()) 
			{
				for (inst_iterator I = inst_begin(*MI), E = inst_end(*MI); I != E; ++I)
				{
					Instruction *inst = &*I;
					
					if(GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>(inst))
					{
						if (const ArrayType *ar = dyn_cast<ArrayType>(gep->getPointerOperandType()->getElementType()))
						{           
							//increment checks inserted counter
							checksInserted++;
	
							//create split in basic block for function call insertion (branch)
							Instruction* next = inst->getNextNode();
							BasicBlock* oldBlock = inst->getParent();
							BasicBlock* newBlock = SplitBlock(oldBlock, next, this);

							//get upper limit and index used
							unsigned upperLim = ar->getNumElements();
							int index = gep->getNumOperands() - 1;
							Value *vIndexUsed = gep->getOperand(index);
							Value *vUpperLimit = ConstantInt::get(vIndexUsed->getType(), upperLim);

							BasicBlock* checkUpperBlock = BasicBlock::Create(C, "checkUpperBlock", MI, newBlock);
							BasicBlock* checkLowerBlock = BasicBlock::Create(C, "checkLowerBlock", MI, checkUpperBlock);
							
							builder.SetInsertPoint(oldBlock);
							
							//remove old terminator
							TerminatorInst* term = oldBlock->getTerminator();
							term->eraseFromParent();
							//insert new one
							builder.CreateBr(checkUpperBlock);
							
							//configure uppper bound test
							builder.SetInsertPoint(checkUpperBlock);
							Value* condUpperInst = builder.CreateICmpSLT(vIndexUsed, vUpperLimit, "checkUpperBounds");
							BasicBlock* errorBlock = BasicBlock::Create(C, "errorBlock", MI, newBlock);
							builder.CreateCondBr(condUpperInst, checkLowerBlock, errorBlock);

							//configure lower bound test
							builder.SetInsertPoint(checkLowerBlock);
							Value *vLowerLimit = ConstantInt::get(vIndexUsed->getType(), -1);
							Value *condLowerInst = builder.CreateICmpSGT(vIndexUsed, vLowerLimit, "checkLowerBounds");
							builder.CreateCondBr(condLowerInst, newBlock, errorBlock);

							//setup error block.  All this block does is call func to print error and exit
							builder.SetInsertPoint(errorBlock);
							builder.CreateCall(printError_func);
							builder.CreateBr(errorBlock);
						}
					}				
				}
			}
		}
		errs() << "This pass has inserted " << checksInserted << " checks\n";
      return true;
	}
Beispiel #2
0
bool SourceEntityWalker::walk(Module &Mod) {
  SemaAnnotator Annotator(*this);
  return Mod.walk(Annotator);
}
Beispiel #3
0
 static void output(const Module &Mod, void *Ctxt, raw_ostream &OS) {
   Mod.print(OS, nullptr);
 }
Beispiel #4
0
// run - Run the transformation on the program. We grab the function
// prototypes for longjmp and setjmp. If they are used in the program,
// then we can go directly to the places they're at and transform them.
bool LowerSetJmp::runOnModule(Module& M) {
  bool Changed = false;

  // These are what the functions are called.
  Function* SetJmp = M.getFunction("llvm.setjmp");
  Function* LongJmp = M.getFunction("llvm.longjmp");

  // This program doesn't have longjmp and setjmp calls.
  if ((!LongJmp || LongJmp->use_empty()) &&
        (!SetJmp || SetJmp->use_empty())) return false;

  // Initialize some values and functions we'll need to transform the
  // setjmp/longjmp functions.
  doInitialization(M);

  if (SetJmp) {
    for (Value::use_iterator B = SetJmp->use_begin(), E = SetJmp->use_end();
         B != E; ++B) {
      BasicBlock* BB = cast<Instruction>(*B)->getParent();
      for (df_ext_iterator<BasicBlock*> I = df_ext_begin(BB, DFSBlocks),
             E = df_ext_end(BB, DFSBlocks); I != E; ++I)
        /* empty */;
    }

    while (!SetJmp->use_empty()) {
      assert(isa<CallInst>(SetJmp->use_back()) &&
             "User of setjmp intrinsic not a call?");
      TransformSetJmpCall(cast<CallInst>(SetJmp->use_back()));
      Changed = true;
    }
  }

  if (LongJmp)
    while (!LongJmp->use_empty()) {
      assert(isa<CallInst>(LongJmp->use_back()) &&
             "User of longjmp intrinsic not a call?");
      TransformLongJmpCall(cast<CallInst>(LongJmp->use_back()));
      Changed = true;
    }

  // Now go through the affected functions and convert calls and invokes
  // to new invokes...
  for (std::map<Function*, AllocaInst*>::iterator
      B = SJMap.begin(), E = SJMap.end(); B != E; ++B) {
    Function* F = B->first;
    for (Function::iterator BB = F->begin(), BE = F->end(); BB != BE; ++BB)
      for (BasicBlock::iterator IB = BB->begin(), IE = BB->end(); IB != IE; ) {
        visit(*IB++);
        if (IB != BB->end() && IB->getParent() != BB)
          break;  // The next instruction got moved to a different block!
      }
  }

  DFSBlocks.clear();
  SJMap.clear();
  RethrowBBMap.clear();
  PrelimBBMap.clear();
  SwitchValMap.clear();
  SetJmpIDMap.clear();

  return Changed;
}
Beispiel #5
0
void compile_module_to_html(const Module &module, std::string filename) {
    if (filename.empty()) filename = module.name() + ".html";

    Internal::print_to_html(filename, module);
}
bool ReduceCrashingBlocks::TestBlocks(std::vector<const BasicBlock*> &BBs) {
  // Clone the program to try hacking it apart...
  Module *M = CloneModule(BD.getProgram());

  // Convert list to set for fast lookup...
  std::set<BasicBlock*> Blocks;
  for (unsigned i = 0, e = BBs.size(); i != e; ++i) {
    // Convert the basic block from the original module to the new module...
    const Function *F = BBs[i]->getParent();
    Function *CMF = M->getFunction(F->getName());
    assert(CMF && "Function not in module?!");
    assert(CMF->getFunctionType() == F->getFunctionType() && "wrong type?");

    // Get the mapped basic block...
    Function::iterator CBI = CMF->begin();
    std::advance(CBI, std::distance(F->begin(),
                                    Function::const_iterator(BBs[i])));
    Blocks.insert(CBI);
  }

  std::cout << "Checking for crash with only these blocks:";
  unsigned NumPrint = Blocks.size();
  if (NumPrint > 10) NumPrint = 10;
  for (unsigned i = 0, e = NumPrint; i != e; ++i)
    std::cout << " " << BBs[i]->getName();
  if (NumPrint < Blocks.size())
    std::cout << "... <" << Blocks.size() << " total>";
  std::cout << ": ";

  // Loop over and delete any hack up any blocks that are not listed...
  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
    for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB)
      if (!Blocks.count(BB) && BB->getTerminator()->getNumSuccessors()) {
        // Loop over all of the successors of this block, deleting any PHI nodes
        // that might include it.
        for (succ_iterator SI = succ_begin(BB), E = succ_end(BB); SI != E; ++SI)
          (*SI)->removePredecessor(BB);

        if (BB->getTerminator()->getType() != Type::VoidTy)
          BB->getTerminator()->replaceAllUsesWith(
                      Constant::getNullValue(BB->getTerminator()->getType()));

        // Delete the old terminator instruction...
        BB->getInstList().pop_back();

        // Add a new return instruction of the appropriate type...
        const Type *RetTy = BB->getParent()->getReturnType();
        new ReturnInst(RetTy == Type::VoidTy ? 0 :
                       Constant::getNullValue(RetTy), BB);
      }

  // The CFG Simplifier pass may delete one of the basic blocks we are
  // interested in.  If it does we need to take the block out of the list.  Make
  // a "persistent mapping" by turning basic blocks into <function, name> pairs.
  // This won't work well if blocks are unnamed, but that is just the risk we
  // have to take.
  std::vector<std::pair<Function*, std::string> > BlockInfo;

  for (std::set<BasicBlock*>::iterator I = Blocks.begin(), E = Blocks.end();
       I != E; ++I)
    BlockInfo.push_back(std::make_pair((*I)->getParent(), (*I)->getName()));

  // Now run the CFG simplify pass on the function...
  PassManager Passes;
  Passes.add(createCFGSimplificationPass());
  Passes.add(createVerifierPass());
  Passes.run(*M);

  // Try running on the hacked up program...
  if (TestFn(BD, M)) {
    BD.setNewProgram(M);      // It crashed, keep the trimmed version...

    // Make sure to use basic block pointers that point into the now-current
    // module, and that they don't include any deleted blocks.
    BBs.clear();
    for (unsigned i = 0, e = BlockInfo.size(); i != e; ++i) {
      ValueSymbolTable &ST = BlockInfo[i].first->getValueSymbolTable();
      Value* V = ST.lookup(BlockInfo[i].second);
      if (V && V->getType() == Type::LabelTy)
        BBs.push_back(cast<BasicBlock>(V));
    }
    return true;
  }
  delete M;  // It didn't crash, try something else.
  return false;
}
Beispiel #7
0
void SILGenFunction::emitArtificialTopLevel(ClassDecl *mainClass) {
  // Load argc and argv from the entry point arguments.
  SILValue argc = F.begin()->getBBArg(0);
  SILValue argv = F.begin()->getBBArg(1);

  switch (mainClass->getArtificialMainKind()) {
  case ArtificialMainKind::UIApplicationMain: {
    // Emit a UIKit main.
    // return UIApplicationMain(C_ARGC, C_ARGV, nil, ClassName);

    CanType NSStringTy = SGM.Types.getNSStringType();
    CanType OptNSStringTy
      = OptionalType::get(NSStringTy)->getCanonicalType();
    CanType IUOptNSStringTy
      = ImplicitlyUnwrappedOptionalType::get(NSStringTy)->getCanonicalType();

    // Look up UIApplicationMain.
    // FIXME: Doing an AST lookup here is gross and not entirely sound;
    // we're getting away with it because the types are guaranteed to already
    // be imported.
    ASTContext &ctx = getASTContext();
    Module *UIKit = ctx.getLoadedModule(ctx.getIdentifier("UIKit"));
    SmallVector<ValueDecl *, 1> results;
    UIKit->lookupQualified(UIKit->getDeclaredType(),
                           ctx.getIdentifier("UIApplicationMain"),
                           NL_QualifiedDefault,
                           /*resolver*/nullptr,
                           results);
    assert(!results.empty() && "couldn't find UIApplicationMain in UIKit");
    assert(results.size() == 1 && "more than one UIApplicationMain?");

    SILDeclRef mainRef{results.front(), ResilienceExpansion::Minimal,
                       SILDeclRef::ConstructAtNaturalUncurryLevel,
                       /*isForeign*/true};
    auto UIApplicationMainFn = SGM.M.getOrCreateFunction(mainClass, mainRef,
                                                         NotForDefinition);
    auto fnTy = UIApplicationMainFn->getLoweredFunctionType();

    // Get the class name as a string using NSStringFromClass.
    CanType mainClassTy = mainClass->getDeclaredTypeInContext()->getCanonicalType();
    CanType mainClassMetaty = CanMetatypeType::get(mainClassTy,
                                                   MetatypeRepresentation::ObjC);
    ProtocolDecl *anyObjectProtocol =
      ctx.getProtocol(KnownProtocolKind::AnyObject);
    auto mainClassAnyObjectConformance = ProtocolConformanceRef(
      *SGM.M.getSwiftModule()->lookupConformance(mainClassTy, anyObjectProtocol,
                                                nullptr));
    CanType anyObjectTy = anyObjectProtocol
      ->getDeclaredTypeInContext()
      ->getCanonicalType();
    CanType anyObjectMetaTy = CanExistentialMetatypeType::get(anyObjectTy,
                                                  MetatypeRepresentation::ObjC);

    auto NSStringFromClassType = SILFunctionType::get(nullptr,
                  SILFunctionType::ExtInfo()
                    .withRepresentation(SILFunctionType::Representation::
                                        CFunctionPointer),
                  ParameterConvention::Direct_Unowned,
                  SILParameterInfo(anyObjectMetaTy,
                                   ParameterConvention::Direct_Unowned),
                  SILResultInfo(OptNSStringTy,
                                ResultConvention::Autoreleased),
                  /*error result*/ None,
                  ctx);
    auto NSStringFromClassFn
      = SGM.M.getOrCreateFunction(mainClass, "NSStringFromClass",
                                  SILLinkage::PublicExternal,
                                  NSStringFromClassType,
                                  IsBare, IsTransparent, IsNotFragile);
    auto NSStringFromClass = B.createFunctionRef(mainClass, NSStringFromClassFn);
    SILValue metaTy = B.createMetatype(mainClass,
                             SILType::getPrimitiveObjectType(mainClassMetaty));
    metaTy = B.createInitExistentialMetatype(mainClass, metaTy,
                          SILType::getPrimitiveObjectType(anyObjectMetaTy),
                          ctx.AllocateCopy(
                            llvm::makeArrayRef(mainClassAnyObjectConformance)));
    SILValue optName = B.createApply(mainClass,
                               NSStringFromClass,
                               NSStringFromClass->getType(),
                               SILType::getPrimitiveObjectType(OptNSStringTy),
                               {}, metaTy);

    // Fix up the string parameters to have the right type.
    SILType nameArgTy = fnTy->getSILArgumentType(3);
    assert(nameArgTy == fnTy->getSILArgumentType(2));
    auto managedName = ManagedValue::forUnmanaged(optName);
    SILValue nilValue;
    if (optName->getType() == nameArgTy) {
      nilValue = getOptionalNoneValue(mainClass,
                                      getTypeLowering(OptNSStringTy));
    } else {
      assert(nameArgTy.getSwiftRValueType() == IUOptNSStringTy);
      nilValue = getOptionalNoneValue(mainClass,
                                      getTypeLowering(IUOptNSStringTy));
      managedName = emitOptionalToOptional(
          mainClass, managedName,
          SILType::getPrimitiveObjectType(IUOptNSStringTy),
          [](SILGenFunction &, SILLocation, ManagedValue input, SILType) {
        return input;
      });
    }

    // Fix up argv to have the right type.
    auto argvTy = fnTy->getSILArgumentType(1);

    SILType unwrappedTy = argvTy;
    if (Type innerTy = argvTy.getSwiftRValueType()->getAnyOptionalObjectType()){
      auto canInnerTy = innerTy->getCanonicalType();
      unwrappedTy = SILType::getPrimitiveObjectType(canInnerTy);
    }

    auto managedArgv = ManagedValue::forUnmanaged(argv);

    if (unwrappedTy != argv->getType()) {
      auto converted =
          emitPointerToPointer(mainClass, managedArgv,
                               argv->getType().getSwiftRValueType(),
                               unwrappedTy.getSwiftRValueType());
      managedArgv = std::move(converted).getAsSingleValue(*this, mainClass);
    }

    if (unwrappedTy != argvTy) {
      managedArgv = getOptionalSomeValue(mainClass, managedArgv,
                                         getTypeLowering(argvTy));
    }

    auto UIApplicationMain = B.createFunctionRef(mainClass, UIApplicationMainFn);

    SILValue args[] = {argc, managedArgv.getValue(), nilValue,
                       managedName.getValue()};

    B.createApply(mainClass, UIApplicationMain,
                  UIApplicationMain->getType(),
                  argc->getType(), {}, args);
    SILValue r = B.createIntegerLiteral(mainClass,
                        SILType::getBuiltinIntegerType(32, ctx), 0);
    auto rType = F.getLoweredFunctionType()->getSingleResult().getSILType();
    if (r->getType() != rType)
      r = B.createStruct(mainClass, rType, r);

    Cleanups.emitCleanupsForReturn(mainClass);
    B.createReturn(mainClass, r);
    return;
  }

  case ArtificialMainKind::NSApplicationMain: {
    // Emit an AppKit main.
    // return NSApplicationMain(C_ARGC, C_ARGV);

    SILParameterInfo argTypes[] = {
      SILParameterInfo(argc->getType().getSwiftRValueType(),
                       ParameterConvention::Direct_Unowned),
      SILParameterInfo(argv->getType().getSwiftRValueType(),
                       ParameterConvention::Direct_Unowned),
    };
    auto NSApplicationMainType = SILFunctionType::get(nullptr,
                  SILFunctionType::ExtInfo()
                    // Should be C calling convention, but NSApplicationMain
                    // has an overlay to fix the type of argv.
                    .withRepresentation(SILFunctionType::Representation::Thin),
                  ParameterConvention::Direct_Unowned,
                  argTypes,
                  SILResultInfo(argc->getType().getSwiftRValueType(),
                                ResultConvention::Unowned),
                  /*error result*/ None,
                  getASTContext());

    auto NSApplicationMainFn
      = SGM.M.getOrCreateFunction(mainClass, "NSApplicationMain",
                                  SILLinkage::PublicExternal,
                                  NSApplicationMainType,
                                  IsBare, IsTransparent, IsNotFragile);

    auto NSApplicationMain = B.createFunctionRef(mainClass, NSApplicationMainFn);
    SILValue args[] = { argc, argv };

    B.createApply(mainClass, NSApplicationMain,
                  NSApplicationMain->getType(),
                  argc->getType(), {}, args);
    SILValue r = B.createIntegerLiteral(mainClass,
                        SILType::getBuiltinIntegerType(32, getASTContext()), 0);
    auto rType = F.getLoweredFunctionType()->getSingleResult().getSILType();
    if (r->getType() != rType)
      r = B.createStruct(mainClass, rType, r);
    B.createReturn(mainClass, r);
    return;
  }
  }
}
Beispiel #8
0
static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
  if (I == M.alias_end())
    return 3;
  const GlobalValue *GV = &*I;
  return reinterpret_cast<uintptr_t>(GV) | 2;
}
Beispiel #9
0
static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
  if (I == M.end())
    return skipEmpty(M.global_begin(), M);
  const GlobalValue *GV = &*I;
  return reinterpret_cast<uintptr_t>(GV) | 0;
}
llvm::error_code ELFObjectWriter::writeObject(Module& pModule,
                                              MemoryArea& pOutput)
{
  bool is_dynobj = m_Config.codeGenType() == LinkerConfig::DynObj;
  bool is_exec = m_Config.codeGenType() == LinkerConfig::Exec;
  bool is_binary = m_Config.codeGenType() == LinkerConfig::Binary;
  bool is_object = m_Config.codeGenType() == LinkerConfig::Object;

  assert(is_dynobj || is_exec || is_binary || is_object);

  if (is_dynobj || is_exec) {
    // Allow backend to sort symbols before emitting
    target().orderSymbolTable(pModule);

    // Write out the interpreter section: .interp
    target().emitInterp(pOutput);

    // Write out name pool sections: .dynsym, .dynstr, .hash
    target().emitDynNamePools(pModule, pOutput);
  }

  if (is_object || is_dynobj || is_exec) {
    // Write out name pool sections: .symtab, .strtab
    target().emitRegNamePools(pModule, pOutput);
  }

  if (is_binary) {
    // Iterate over the loadable segments and write the corresponding sections
    ELFSegmentFactory::iterator seg, segEnd = target().elfSegmentTable().end();

    for (seg = target().elfSegmentTable().begin(); seg != segEnd; ++seg) {
      if (llvm::ELF::PT_LOAD == (*seg).type()) {
        ELFSegment::sect_iterator sect, sectEnd = (*seg).end();
        for (sect = (*seg).begin(); sect != sectEnd; ++sect)
          writeSection(pOutput, *sect);
      }
    }
  } else {
    // Write out regular ELF sections
    Module::iterator sect, sectEnd = pModule.end();
    for (sect = pModule.begin(); sect != sectEnd; ++sect)
      writeSection(pOutput, *sect);

    emitShStrTab(target().getOutputFormat()->getShStrTab(), pModule, pOutput);

    if (m_Config.targets().is32Bits()) {
      // Write out ELF header
      // Write out section header table
      writeELFHeader<32>(m_Config, pModule, pOutput);
      if (is_dynobj || is_exec)
        emitProgramHeader<32>(pOutput);

      emitSectionHeader<32>(pModule, m_Config, pOutput);
    }
    else if (m_Config.targets().is64Bits()) {
      // Write out ELF header
      // Write out section header table
      writeELFHeader<64>(m_Config, pModule, pOutput);
      if (is_dynobj || is_exec)
        emitProgramHeader<64>(pOutput);

      emitSectionHeader<64>(pModule, m_Config, pOutput);
    }
    else
      return make_error_code(errc::not_supported);
  }

  pOutput.clear();
  return llvm::make_error_code(llvm::errc::success);
}
uint64_t ELFObjectWriter::getLastStartOffset<64>(const Module& pModule) const
{
  const LDSection* lastSect = pModule.back();
  assert(lastSect != NULL);
  return Align<64>(lastSect->offset() + lastSect->size());
}
Beispiel #12
0
// Construct the lowerer base class and initialize its members.
coro::LowererBase::LowererBase(Module &M)
    : TheModule(M), Context(M.getContext()),
      ResumeFnType(FunctionType::get(Type::getVoidTy(Context),
                                     Type::getInt8PtrTy(Context),
                                     /*isVarArg=*/false)) {}
Beispiel #13
0
void			Manager::process_modules( const Tsk::Task< Manager >& task )
{
	

	Module*					next;
	Module*					current;
	Lst::Search< Module >	sh;

	Manager&	manager = task.GetData();

	if ( !manager.control_change )
	{
		return; // nothing to do
	}

	manager.control_change = false;
	
	next = sh.FirstItem( manager.module_list );

	while ( next )
	{
		current = next;
		next = sh.NextItem();			// get next item before excuting callback

		switch ( current->state )
		{
			case Module::vSTOPPED :
			{
				if (( current->command == Module::vSTART ) ||
					( current->command == Module::vRESTART ))
				{
#ifndef __PLAT_XBOX__
#ifndef __PLAT_NGC__
#ifdef __NOPT_DEBUG__
				Dbg_Notify ( "Starting module %s @ %d", current->GetName(), 
					Tmr::GetTime() ); // should use Game Clock not system clock
#endif
#endif
#endif
					current->v_start_cb();
					current->state = Module::vRUNNING;
					current->command = Module::vNONE;
				}
				
				break;
			}
			
			case Module::vRUNNING :
			{
				if ( current->command == Module::vSTOP )
				{
#ifndef __PLAT_XBOX__
#ifndef __PLAT_NGC__
#ifdef __NOPT_DEBUG__
					Dbg_Notify ( "Stopping module %s @ %d", current->GetName(), 
						 Tmr::GetTime() ); // should use Game Clock not system clock
#endif
#endif
#endif
					current->v_stop_cb();
					current->state = Module::vSTOPPED;
					current->command = Module::vNONE;
				}
				else if ( current->command == Module::vRESTART ) 
				{
#ifndef __PLAT_XBOX__
#ifndef __PLAT_NGC__
#ifdef __NOPT_DEBUG__
					Dbg_Notify ( "Restarting module %s @ %d", current->GetName(), 
						Tmr::GetTime() ); // should use Game Clock not system clock
#endif
#endif
#endif
					current->v_stop_cb();
					current->v_start_cb();               
					current->command = Module::vNONE;
				}

				break;
			}        

			default:
			{
				Dbg_MsgAssert( false,( "Invalid module control state" ));
			}
		}
	}
}
Beispiel #14
0
Module *Preprocessor::LeaveSubmodule(bool ForPragma) {
  if (BuildingSubmoduleStack.empty() ||
      BuildingSubmoduleStack.back().IsPragma != ForPragma) {
    assert(ForPragma && "non-pragma module enter/leave mismatch");
    return nullptr;
  }

  auto &Info = BuildingSubmoduleStack.back();

  Module *LeavingMod = Info.M;
  SourceLocation ImportLoc = Info.ImportLoc;

  if (!needModuleMacros() ||
      (!getLangOpts().ModulesLocalVisibility &&
       LeavingMod->getTopLevelModuleName() != getLangOpts().CurrentModule)) {
    // If we don't need module macros, or this is not a module for which we
    // are tracking macro visibility, don't build any, and preserve the list
    // of pending names for the surrounding submodule.
    BuildingSubmoduleStack.pop_back();
    makeModuleVisible(LeavingMod, ImportLoc);
    return LeavingMod;
  }

  // Create ModuleMacros for any macros defined in this submodule.
  llvm::SmallPtrSet<const IdentifierInfo*, 8> VisitedMacros;
  for (unsigned I = Info.OuterPendingModuleMacroNames;
       I != PendingModuleMacroNames.size(); ++I) {
    auto *II = const_cast<IdentifierInfo*>(PendingModuleMacroNames[I]);
    if (!VisitedMacros.insert(II).second)
      continue;

    auto MacroIt = CurSubmoduleState->Macros.find(II);
    if (MacroIt == CurSubmoduleState->Macros.end())
      continue;
    auto &Macro = MacroIt->second;

    // Find the starting point for the MacroDirective chain in this submodule.
    MacroDirective *OldMD = nullptr;
    auto *OldState = Info.OuterSubmoduleState;
    if (getLangOpts().ModulesLocalVisibility)
      OldState = &NullSubmoduleState;
    if (OldState && OldState != CurSubmoduleState) {
      // FIXME: It'd be better to start at the state from when we most recently
      // entered this submodule, but it doesn't really matter.
      auto &OldMacros = OldState->Macros;
      auto OldMacroIt = OldMacros.find(II);
      if (OldMacroIt == OldMacros.end())
        OldMD = nullptr;
      else
        OldMD = OldMacroIt->second.getLatest();
    }

    // This module may have exported a new macro. If so, create a ModuleMacro
    // representing that fact.
    bool ExplicitlyPublic = false;
    for (auto *MD = Macro.getLatest(); MD != OldMD; MD = MD->getPrevious()) {
      assert(MD && "broken macro directive chain");

      if (auto *VisMD = dyn_cast<VisibilityMacroDirective>(MD)) {
        // The latest visibility directive for a name in a submodule affects
        // all the directives that come before it.
        if (VisMD->isPublic())
          ExplicitlyPublic = true;
        else if (!ExplicitlyPublic)
          // Private with no following public directive: not exported.
          break;
      } else {
        MacroInfo *Def = nullptr;
        if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
          Def = DefMD->getInfo();

        // FIXME: Issue a warning if multiple headers for the same submodule
        // define a macro, rather than silently ignoring all but the first.
        bool IsNew;
        // Don't bother creating a module macro if it would represent a #undef
        // that doesn't override anything.
        if (Def || !Macro.getOverriddenMacros().empty())
          addModuleMacro(LeavingMod, II, Def,
                         Macro.getOverriddenMacros(), IsNew);

        if (!getLangOpts().ModulesLocalVisibility) {
          // This macro is exposed to the rest of this compilation as a
          // ModuleMacro; we don't need to track its MacroDirective any more.
          Macro.setLatest(nullptr);
          Macro.setOverriddenMacros(*this, {});
        }
        break;
      }
    }
  }
  PendingModuleMacroNames.resize(Info.OuterPendingModuleMacroNames);

  // FIXME: Before we leave this submodule, we should parse all the other
  // headers within it. Otherwise, we're left with an inconsistent state
  // where we've made the module visible but don't yet have its complete
  // contents.

  // Put back the outer module's state, if we're tracking it.
  if (getLangOpts().ModulesLocalVisibility)
    CurSubmoduleState = Info.OuterSubmoduleState;

  BuildingSubmoduleStack.pop_back();

  // A nested #include makes the included submodule visible.
  makeModuleVisible(LeavingMod, ImportLoc);
  return LeavingMod;
}
Beispiel #15
0
void InitializeSoftBound:: constructMetadataHandlers(Module & module){

  Type* VoidTy = Type::getVoidTy(module.getContext());
  Type* 
    VoidPtrTy = PointerType::getUnqual(Type::getInt8Ty(module.getContext()));
  Type* SizeTy = Type::getInt64Ty(module.getContext());
  
  Type* Int32Ty = Type::getInt32Ty(module.getContext());

  module.getOrInsertFunction("__softboundcets_introspect_metadata", 
                             VoidTy, VoidPtrTy, VoidPtrTy, Int32Ty, NULL);
  module.getOrInsertFunction("__softboundcets_copy_metadata", 
                             VoidTy, VoidPtrTy, VoidPtrTy, SizeTy, NULL);

  Type* PtrVoidPtrTy = PointerType::getUnqual(VoidPtrTy);
  Type* PtrSizeTy = PointerType::getUnqual(SizeTy);
  
  module.getOrInsertFunction("__softboundcets_metadata_load", 
                             VoidTy, VoidPtrTy, PtrVoidPtrTy, PtrVoidPtrTy, 
                             PtrSizeTy, PtrVoidPtrTy, NULL);

  module.getOrInsertFunction("__softboundcets_metadata_store", 
                             VoidTy, VoidPtrTy, VoidPtrTy, 
                             VoidPtrTy, SizeTy, VoidPtrTy, NULL);

  module.getOrInsertFunction("__softboundcets_get_global_lock", 
                             VoidPtrTy, NULL);

  module.getOrInsertFunction("__softboundcets_stack_memory_allocation", 
                             VoidTy, PtrVoidPtrTy, 
                             PtrSizeTy, NULL);

  module.getOrInsertFunction("__softboundcets_stack_memory_deallocation", 
                             VoidTy, SizeTy, NULL);

  module.getOrInsertFunction("__softboundcets_spatial_call_dereference_check",
                             VoidTy, VoidPtrTy, VoidPtrTy, VoidPtrTy, NULL);


}
Beispiel #16
0
void StatsTracker::writeIStats() {
  Module *m = executor.kmodule->module;
  uint64_t istatsMask = 0;
  llvm::raw_fd_ostream &of = *istatsFile;
  
  // We assume that we didn't move the file pointer
  unsigned istatsSize = of.tell();

  of.seek(0);

  of << "version: 1\n";
  of << "creator: klee\n";
  of << "pid: " << getpid() << "\n";
  of << "cmd: " << m->getModuleIdentifier() << "\n\n";
  of << "\n";
  
  StatisticManager &sm = *theStatisticManager;
  unsigned nStats = sm.getNumStatistics();

  // Max is 13, sadly
  istatsMask |= 1<<sm.getStatisticID("Queries");
  istatsMask |= 1<<sm.getStatisticID("QueriesValid");
  istatsMask |= 1<<sm.getStatisticID("QueriesInvalid");
  istatsMask |= 1<<sm.getStatisticID("QueryTime");
  istatsMask |= 1<<sm.getStatisticID("ResolveTime");
  istatsMask |= 1<<sm.getStatisticID("Instructions");
  istatsMask |= 1<<sm.getStatisticID("InstructionTimes");
  istatsMask |= 1<<sm.getStatisticID("InstructionRealTimes");
  istatsMask |= 1<<sm.getStatisticID("Forks");
  istatsMask |= 1<<sm.getStatisticID("CoveredInstructions");
  istatsMask |= 1<<sm.getStatisticID("UncoveredInstructions");
  istatsMask |= 1<<sm.getStatisticID("States");
  istatsMask |= 1<<sm.getStatisticID("MinDistToUncovered");

  of << "positions: instr line\n";

  for (unsigned i=0; i<nStats; i++) {
    if (istatsMask & (1<<i)) {
      Statistic &s = sm.getStatistic(i);
      of << "event: " << s.getShortName() << " : " 
         << s.getName() << "\n";
    }
  }

  of << "events: ";
  for (unsigned i=0; i<nStats; i++) {
    if (istatsMask & (1<<i))
      of << sm.getStatistic(i).getShortName() << " ";
  }
  of << "\n";
  
  // set state counts, decremented after we process so that we don't
  // have to zero all records each time.
  if (istatsMask & (1<<stats::states.getID()))
    updateStateStatistics(1);

  std::string sourceFile = "";

  CallSiteSummaryTable callSiteStats;
  if (UseCallPaths)
    callPathManager.getSummaryStatistics(callSiteStats);

  of << "ob=" << objectFilename << "\n";

  for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); 
       fnIt != fn_ie; ++fnIt) {
    if (!fnIt->isDeclaration()) {
      // Always try to write the filename before the function name, as otherwise
      // KCachegrind can create two entries for the function, one with an
      // unnamed file and one without.
      const InstructionInfo &ii = executor.kmodule->infos->getFunctionInfo(fnIt);
      if (ii.file != sourceFile) {
        of << "fl=" << ii.file << "\n";
        sourceFile = ii.file;
      }
      
      of << "fn=" << fnIt->getName().str() << "\n";
      for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
           bbIt != bb_ie; ++bbIt) {
        for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end(); 
             it != ie; ++it) {
          Instruction *instr = &*it;
          const InstructionInfo &ii = executor.kmodule->infos->getInfo(instr);
          unsigned index = ii.id;
          if (ii.file!=sourceFile) {
            of << "fl=" << ii.file << "\n";
            sourceFile = ii.file;
          }
          of << ii.assemblyLine << " ";
          of << ii.line << " ";
          for (unsigned i=0; i<nStats; i++)
            if (istatsMask&(1<<i))
              of << sm.getIndexedValue(sm.getStatistic(i), index) << " ";
          of << "\n";

          if (UseCallPaths && 
              (isa<CallInst>(instr) || isa<InvokeInst>(instr))) {
            CallSiteSummaryTable::iterator it = callSiteStats.find(instr);
            if (it!=callSiteStats.end()) {
              for (std::map<llvm::Function*, CallSiteInfo>::iterator
                     fit = it->second.begin(), fie = it->second.end(); 
                   fit != fie; ++fit) {
                Function *f = fit->first;
                CallSiteInfo &csi = fit->second;
                const InstructionInfo &fii = 
                  executor.kmodule->infos->getFunctionInfo(f);
  
                if (fii.file!="" && fii.file!=sourceFile)
                  of << "cfl=" << fii.file << "\n";
                of << "cfn=" << f->getName().str() << "\n";
                of << "calls=" << csi.count << " ";
                of << fii.assemblyLine << " ";
                of << fii.line << "\n";

                of << ii.assemblyLine << " ";
                of << ii.line << " ";
                for (unsigned i=0; i<nStats; i++) {
                  if (istatsMask&(1<<i)) {
                    Statistic &s = sm.getStatistic(i);
                    uint64_t value;

                    // Hack, ignore things that don't make sense on
                    // call paths.
                    if (&s == &stats::uncoveredInstructions) {
                      value = 0;
                    } else {
                      value = csi.statistics.getValue(s);
                    }

                    of << value << " ";
                  }
                }
                of << "\n";
              }
            }
          }
        }
      }
    }
  }

  if (istatsMask & (1<<stats::states.getID()))
    updateStateStatistics((uint64_t)-1);
  
  // Clear then end of the file if necessary (no truncate op?).
  unsigned pos = of.tell();
  for (unsigned i=pos; i<istatsSize; ++i)
    of << '\n';
  
  of.flush();
}
Beispiel #17
0
void sceNpTrophy_init()
{
	sceNpTrophy.AddFunc(0x079f0e87, sceNpTrophyGetGameProgress);
	sceNpTrophy.AddFunc(0x1197b52c, sceNpTrophyRegisterContext);
	sceNpTrophy.AddFunc(0x1c25470d, sceNpTrophyCreateHandle);
	sceNpTrophy.AddFunc(0x27deda93, sceNpTrophySetSoundLevel);
	sceNpTrophy.AddFunc(0x370136fe, sceNpTrophyGetRequiredDiskSpace);
	sceNpTrophy.AddFunc(0x3741ecc7, sceNpTrophyDestroyContext);
	sceNpTrophy.AddFunc(0x39567781, sceNpTrophyInit);
	sceNpTrophy.AddFunc(0x48bd97c7, sceNpTrophyAbortHandle);
	sceNpTrophy.AddFunc(0x49d18217, sceNpTrophyGetGameInfo);
	sceNpTrophy.AddFunc(0x623cd2dc, sceNpTrophyDestroyHandle);
	sceNpTrophy.AddFunc(0x8ceedd21, sceNpTrophyUnlockTrophy);
	sceNpTrophy.AddFunc(0xa7fabf4d, sceNpTrophyTerm);
	sceNpTrophy.AddFunc(0xb3ac3478, sceNpTrophyGetTrophyUnlockState);
	sceNpTrophy.AddFunc(0xbaedf689, sceNpTrophyGetTrophyIcon);
	sceNpTrophy.AddFunc(0xe3bf9a28, sceNpTrophyCreateContext);
	sceNpTrophy.AddFunc(0xfce6d30a, sceNpTrophyGetTrophyInfo);
	sceNpTrophy.AddFunc(0xff299e03, sceNpTrophyGetGameIcon);
}
Beispiel #18
0
void StatsTracker::computeReachableUncovered() {
  KModule *km = executor.kmodule;
  Module *m = km->module;
  static bool init = true;
  const InstructionInfoTable &infos = *km->infos;
  StatisticManager &sm = *theStatisticManager;
  
  if (init) {
    init = false;

    // Compute call targets. It would be nice to use alias information
    // instead of assuming all indirect calls hit all escaping
    // functions, eh?
    for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); 
         fnIt != fn_ie; ++fnIt) {
      for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
           bbIt != bb_ie; ++bbIt) {
        for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end(); 
             it != ie; ++it) {
          if (isa<CallInst>(it) || isa<InvokeInst>(it)) {
            CallSite cs(it);
            if (isa<InlineAsm>(cs.getCalledValue())) {
              // We can never call through here so assume no targets
              // (which should be correct anyhow).
              callTargets.insert(std::make_pair(it,
                                                std::vector<Function*>()));
            } else if (Function *target = getDirectCallTarget(cs)) {
              callTargets[it].push_back(target);
            } else {
              callTargets[it] = 
                std::vector<Function*>(km->escapingFunctions.begin(),
                                       km->escapingFunctions.end());
            }
          }
        }
      }
    }

    // Compute function callers as reflexion of callTargets.
    for (calltargets_ty::iterator it = callTargets.begin(), 
           ie = callTargets.end(); it != ie; ++it)
      for (std::vector<Function*>::iterator fit = it->second.begin(), 
             fie = it->second.end(); fit != fie; ++fit) 
        functionCallers[*fit].push_back(it->first);

    // Initialize minDistToReturn to shortest paths through
    // functions. 0 is unreachable.
    std::vector<Instruction *> instructions;
    for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); 
         fnIt != fn_ie; ++fnIt) {
      if (fnIt->isDeclaration()) {
        if (fnIt->doesNotReturn()) {
          functionShortestPath[fnIt] = 0;
        } else {
          functionShortestPath[fnIt] = 1; // whatever
        }
      } else {
        functionShortestPath[fnIt] = 0;
      }

      // Not sure if I should bother to preorder here. XXX I should.
      for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
           bbIt != bb_ie; ++bbIt) {
        for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end(); 
             it != ie; ++it) {
          instructions.push_back(it);
          unsigned id = infos.getInfo(it).id;
          sm.setIndexedValue(stats::minDistToReturn, 
                             id, 
                             isa<ReturnInst>(it)
#if LLVM_VERSION_CODE < LLVM_VERSION(3, 1)
                             || isa<UnwindInst>(it)
#endif
                             );
        }
      }
    }
  
    std::reverse(instructions.begin(), instructions.end());
    
    // I'm so lazy it's not even worklisted.
    bool changed;
    do {
      changed = false;
      for (std::vector<Instruction*>::iterator it = instructions.begin(),
             ie = instructions.end(); it != ie; ++it) {
        Instruction *inst = *it;
        unsigned bestThrough = 0;

        if (isa<CallInst>(inst) || isa<InvokeInst>(inst)) {
          std::vector<Function*> &targets = callTargets[inst];
          for (std::vector<Function*>::iterator fnIt = targets.begin(),
                 ie = targets.end(); fnIt != ie; ++fnIt) {
            uint64_t dist = functionShortestPath[*fnIt];
            if (dist) {
              dist = 1+dist; // count instruction itself
              if (bestThrough==0 || dist<bestThrough)
                bestThrough = dist;
            }
          }
        } else {
          bestThrough = 1;
        }
       
        if (bestThrough) {
          unsigned id = infos.getInfo(*it).id;
          uint64_t best, cur = best = sm.getIndexedValue(stats::minDistToReturn, id);
          std::vector<Instruction*> succs = getSuccs(*it);
          for (std::vector<Instruction*>::iterator it2 = succs.begin(),
                 ie = succs.end(); it2 != ie; ++it2) {
            uint64_t dist = sm.getIndexedValue(stats::minDistToReturn,
                                               infos.getInfo(*it2).id);
            if (dist) {
              uint64_t val = bestThrough + dist;
              if (best==0 || val<best)
                best = val;
            }
          }
          // there's a corner case here when a function only includes a single
          // instruction (a ret). in that case, we MUST update
          // functionShortestPath, or it will remain 0 (erroneously indicating
          // that no return instructions are reachable)
          Function *f = inst->getParent()->getParent();
          if (best != cur
              || (inst == f->begin()->begin()
                  && functionShortestPath[f] != best)) {
            sm.setIndexedValue(stats::minDistToReturn, id, best);
            changed = true;

            // Update shortest path if this is the entry point.
            if (inst==f->begin()->begin())
              functionShortestPath[f] = best;
          }
        }
      }
    } while (changed);
  }

  // compute minDistToUncovered, 0 is unreachable
  std::vector<Instruction *> instructions;
  for (Module::iterator fnIt = m->begin(), fn_ie = m->end(); 
       fnIt != fn_ie; ++fnIt) {
    // Not sure if I should bother to preorder here.
    for (Function::iterator bbIt = fnIt->begin(), bb_ie = fnIt->end(); 
         bbIt != bb_ie; ++bbIt) {
      for (BasicBlock::iterator it = bbIt->begin(), ie = bbIt->end(); 
           it != ie; ++it) {
        unsigned id = infos.getInfo(it).id;
        instructions.push_back(&*it);
        sm.setIndexedValue(stats::minDistToUncovered, 
                           id, 
                           sm.getIndexedValue(stats::uncoveredInstructions, id));
      }
    }
  }
  
  std::reverse(instructions.begin(), instructions.end());
  
  // I'm so lazy it's not even worklisted.
  bool changed;
  do {
    changed = false;
    for (std::vector<Instruction*>::iterator it = instructions.begin(),
           ie = instructions.end(); it != ie; ++it) {
      Instruction *inst = *it;
      uint64_t best, cur = best = sm.getIndexedValue(stats::minDistToUncovered, 
                                                     infos.getInfo(inst).id);
      unsigned bestThrough = 0;
      
      if (isa<CallInst>(inst) || isa<InvokeInst>(inst)) {
        std::vector<Function*> &targets = callTargets[inst];
        for (std::vector<Function*>::iterator fnIt = targets.begin(),
               ie = targets.end(); fnIt != ie; ++fnIt) {
          uint64_t dist = functionShortestPath[*fnIt];
          if (dist) {
            dist = 1+dist; // count instruction itself
            if (bestThrough==0 || dist<bestThrough)
              bestThrough = dist;
          }

          if (!(*fnIt)->isDeclaration()) {
            uint64_t calleeDist = sm.getIndexedValue(stats::minDistToUncovered,
                                                     infos.getFunctionInfo(*fnIt).id);
            if (calleeDist) {
              calleeDist = 1+calleeDist; // count instruction itself
              if (best==0 || calleeDist<best)
                best = calleeDist;
            }
          }
        }
      } else {
        bestThrough = 1;
      }
      
      if (bestThrough) {
        std::vector<Instruction*> succs = getSuccs(inst);
        for (std::vector<Instruction*>::iterator it2 = succs.begin(),
               ie = succs.end(); it2 != ie; ++it2) {
          uint64_t dist = sm.getIndexedValue(stats::minDistToUncovered,
                                             infos.getInfo(*it2).id);
          if (dist) {
            uint64_t val = bestThrough + dist;
            if (best==0 || val<best)
              best = val;
          }
        }
      }

      if (best != cur) {
        sm.setIndexedValue(stats::minDistToUncovered, 
                           infos.getInfo(inst).id, 
                           best);
        changed = true;
      }
    }
  } while (changed);

  for (std::set<ExecutionState*>::iterator it = executor.states.begin(),
         ie = executor.states.end(); it != ie; ++it) {
    ExecutionState *es = *it;
    uint64_t currentFrameMinDist = 0;
#if MULTITHREAD
	for (Thread::stack_ty::iterator sfIt = es->stack().begin(),
				sf_ie = es->stack().end(); sfIt != sf_ie; ++sfIt) {
		Thread::stack_ty::iterator next = sfIt + 1;
		KInstIterator kii;
		if (next==es->stack().end()) {
			kii = es->pc();
#else
	for (ExecutionState::stack_ty::iterator sfIt = es->stack.begin(),
           sf_ie = es->stack.end(); sfIt != sf_ie; ++sfIt) {
      ExecutionState::stack_ty::iterator next = sfIt + 1;
      KInstIterator kii;

      if (next==es->stack.end()) {
        kii = es->pc;
#endif
      } else {
        kii = next->caller;
        ++kii;
      }
      
      sfIt->minDistToUncoveredOnReturn = currentFrameMinDist;
      
      currentFrameMinDist = computeMinDistToUncovered(kii, currentFrameMinDist);
    }
  }
}
/// DebugACrash - Given a predicate that determines whether a component crashes
/// on a program, try to destructively reduce the program while still keeping
/// the predicate true.
static bool DebugACrash(BugDriver &BD,  bool (*TestFn)(BugDriver &, Module *)) {
  // See if we can get away with nuking some of the global variable initializers
  // in the program...
  if (BD.getProgram()->global_begin() != BD.getProgram()->global_end()) {
    // Now try to reduce the number of global variable initializers in the
    // module to something small.
    Module *M = CloneModule(BD.getProgram());
    bool DeletedInit = false;

    for (Module::global_iterator I = M->global_begin(), E = M->global_end();
         I != E; ++I)
      if (I->hasInitializer()) {
        I->setInitializer(0);
        I->setLinkage(GlobalValue::ExternalLinkage);
        DeletedInit = true;
      }

    if (!DeletedInit) {
      delete M;  // No change made...
    } else {
      // See if the program still causes a crash...
      std::cout << "\nChecking to see if we can delete global inits: ";

      if (TestFn(BD, M)) {      // Still crashes?
        BD.setNewProgram(M);
        std::cout << "\n*** Able to remove all global initializers!\n";
      } else {                  // No longer crashes?
        std::cout << "  - Removing all global inits hides problem!\n";
        delete M;

        std::vector<GlobalVariable*> GVs;

        for (Module::global_iterator I = BD.getProgram()->global_begin(),
               E = BD.getProgram()->global_end(); I != E; ++I)
          if (I->hasInitializer())
            GVs.push_back(I);

        if (GVs.size() > 1 && !BugpointIsInterrupted) {
          std::cout << "\n*** Attempting to reduce the number of global "
                    << "variables in the testcase\n";

          unsigned OldSize = GVs.size();
          ReduceCrashingGlobalVariables(BD, TestFn).reduceList(GVs);

          if (GVs.size() < OldSize)
            BD.EmitProgressBytecode("reduced-global-variables");
        }
      }
    }
  }

  // Now try to reduce the number of functions in the module to something small.
  std::vector<Function*> Functions;
  for (Module::iterator I = BD.getProgram()->begin(),
         E = BD.getProgram()->end(); I != E; ++I)
    if (!I->isDeclaration())
      Functions.push_back(I);

  if (Functions.size() > 1 && !BugpointIsInterrupted) {
    std::cout << "\n*** Attempting to reduce the number of functions "
      "in the testcase\n";

    unsigned OldSize = Functions.size();
    ReduceCrashingFunctions(BD, TestFn).reduceList(Functions);

    if (Functions.size() < OldSize)
      BD.EmitProgressBytecode("reduced-function");
  }

  // Attempt to delete entire basic blocks at a time to speed up
  // convergence... this actually works by setting the terminator of the blocks
  // to a return instruction then running simplifycfg, which can potentially
  // shrinks the code dramatically quickly
  //
  if (!DisableSimplifyCFG && !BugpointIsInterrupted) {
    std::vector<const BasicBlock*> Blocks;
    for (Module::const_iterator I = BD.getProgram()->begin(),
           E = BD.getProgram()->end(); I != E; ++I)
      for (Function::const_iterator FI = I->begin(), E = I->end(); FI !=E; ++FI)
        Blocks.push_back(FI);
    ReduceCrashingBlocks(BD, TestFn).reduceList(Blocks);
  }

  // FIXME: This should use the list reducer to converge faster by deleting
  // larger chunks of instructions at a time!
  unsigned Simplification = 2;
  do {
    if (BugpointIsInterrupted) break;
    --Simplification;
    std::cout << "\n*** Attempting to reduce testcase by deleting instruc"
              << "tions: Simplification Level #" << Simplification << '\n';

    // Now that we have deleted the functions that are unnecessary for the
    // program, try to remove instructions that are not necessary to cause the
    // crash.  To do this, we loop through all of the instructions in the
    // remaining functions, deleting them (replacing any values produced with
    // nulls), and then running ADCE and SimplifyCFG.  If the transformed input
    // still triggers failure, keep deleting until we cannot trigger failure
    // anymore.
    //
    unsigned InstructionsToSkipBeforeDeleting = 0;
  TryAgain:

    // Loop over all of the (non-terminator) instructions remaining in the
    // function, attempting to delete them.
    unsigned CurInstructionNum = 0;
    for (Module::const_iterator FI = BD.getProgram()->begin(),
           E = BD.getProgram()->end(); FI != E; ++FI)
      if (!FI->isDeclaration())
        for (Function::const_iterator BI = FI->begin(), E = FI->end(); BI != E;
             ++BI)
          for (BasicBlock::const_iterator I = BI->begin(), E = --BI->end();
               I != E; ++I, ++CurInstructionNum)
            if (InstructionsToSkipBeforeDeleting) {
              --InstructionsToSkipBeforeDeleting;
            } else {
              if (BugpointIsInterrupted) goto ExitLoops;

              std::cout << "Checking instruction '" << I->getName() << "': ";
              Module *M = BD.deleteInstructionFromProgram(I, Simplification);

              // Find out if the pass still crashes on this pass...
              if (TestFn(BD, M)) {
                // Yup, it does, we delete the old module, and continue trying
                // to reduce the testcase...
                BD.setNewProgram(M);
                InstructionsToSkipBeforeDeleting = CurInstructionNum;
                goto TryAgain;  // I wish I had a multi-level break here!
              }

              // This pass didn't crash without this instruction, try the next
              // one.
              delete M;
            }

    if (InstructionsToSkipBeforeDeleting) {
      InstructionsToSkipBeforeDeleting = 0;
      goto TryAgain;
    }

  } while (Simplification);
ExitLoops:

  // Try to clean up the testcase by running funcresolve and globaldce...
  if (!BugpointIsInterrupted) {
    std::cout << "\n*** Attempting to perform final cleanups: ";
    Module *M = CloneModule(BD.getProgram());
    M = BD.performFinalCleanups(M, true);

    // Find out if the pass still crashes on the cleaned up program...
    if (TestFn(BD, M)) {
      BD.setNewProgram(M);     // Yup, it does, keep the reduced version...
    } else {
      delete M;
    }
  }

  BD.EmitProgressBytecode("reduced-simplified");

  return false;
}
bool AMDGPURewriteOutArguments::doInitialization(Module &M) {
  DL = &M.getDataLayout();
  return false;
}
Beispiel #21
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->getType()->getElementType(), 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;
}
Beispiel #22
0
Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
{   Module *m;
    char *filename;

    //printf("Module::load(ident = '%s')\n", ident->toChars());

    // Build module filename by turning:
    //  foo.bar.baz
    // into:
    //  foo\bar\baz
    filename = ident->toChars();
    if (packages && packages->dim)
    {
        OutBuffer buf;

        for (size_t i = 0; i < packages->dim; i++)
        {   Identifier *pid = packages->tdata()[i];

            buf.writestring(pid->toChars());
#if _WIN32
            buf.writeByte('\\');
#else
            buf.writeByte('/');
#endif
        }
        buf.writestring(filename);
        buf.writeByte(0);
        filename = (char *)buf.extractData();
    }

    m = new Module(filename, ident, 0, 0);
    m->loc = loc;

    /* Search along global.path for .di file, then .d file.
     */
    char *result = NULL;
    FileName *fdi = FileName::forceExt(filename, global.hdr_ext);
    FileName *fd  = FileName::forceExt(filename, global.mars_ext);
    char *sdi = fdi->toChars();
    char *sd  = fd->toChars();

    if (FileName::exists(sdi))
        result = sdi;
    else if (FileName::exists(sd))
        result = sd;
    else if (FileName::absolute(filename))
        ;
    else if (!global.path)
        ;
    else
    {
        for (size_t i = 0; i < global.path->dim; i++)
        {
            char *p = (*global.path)[i];
            char *n = FileName::combine(p, sdi);
            if (FileName::exists(n))
            {   result = n;
                break;
            }
            mem.free(n);
            n = FileName::combine(p, sd);
            if (FileName::exists(n))
            {   result = n;
                break;
            }
            mem.free(n);
        }
    }
    if (result)
        m->srcfile = new File(result);

    if (global.params.verbose)
    {
        printf("import    ");
        if (packages)
        {
            for (size_t i = 0; i < packages->dim; i++)
            {   Identifier *pid = packages->tdata()[i];
                printf("%s.", pid->toChars());
            }
        }
        printf("%s\t(%s)\n", ident->toChars(), m->srcfile->toChars());
    }

    m->read(loc);
    m->parse();

#ifdef IN_GCC
    d_gcc_magic_module(m);
#endif

    return m;
}
Beispiel #23
0
// doInitialization - For the lower long/setjmp pass, this ensures that a
// module contains a declaration for the intrisic functions we are going
// to call to convert longjmp and setjmp calls.
//
// This function is always successful, unless it isn't.
bool LowerSetJmp::doInitialization(Module& M)
{
  const Type *SBPTy = Type::getInt8PtrTy(M.getContext());
  const Type *SBPPTy = PointerType::getUnqual(SBPTy);

  // N.B. See llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h for
  // a description of the following library functions.

  // void __llvm_sjljeh_init_setjmpmap(void**)
  InitSJMap = M.getOrInsertFunction("__llvm_sjljeh_init_setjmpmap",
                                    Type::getVoidTy(M.getContext()),
                                    SBPPTy, (Type *)0);
  // void __llvm_sjljeh_destroy_setjmpmap(void**)
  DestroySJMap = M.getOrInsertFunction("__llvm_sjljeh_destroy_setjmpmap",
                                       Type::getVoidTy(M.getContext()),
                                       SBPPTy, (Type *)0);

  // void __llvm_sjljeh_add_setjmp_to_map(void**, void*, unsigned)
  AddSJToMap = M.getOrInsertFunction("__llvm_sjljeh_add_setjmp_to_map",
                                     Type::getVoidTy(M.getContext()),
                                     SBPPTy, SBPTy,
                                     Type::getInt32Ty(M.getContext()),
                                     (Type *)0);

  // void __llvm_sjljeh_throw_longjmp(int*, int)
  ThrowLongJmp = M.getOrInsertFunction("__llvm_sjljeh_throw_longjmp",
                                       Type::getVoidTy(M.getContext()), SBPTy, 
                                       Type::getInt32Ty(M.getContext()),
                                       (Type *)0);

  // unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **)
  TryCatchLJ =
    M.getOrInsertFunction("__llvm_sjljeh_try_catching_longjmp_exception",
                          Type::getInt32Ty(M.getContext()), SBPPTy, (Type *)0);

  // bool __llvm_sjljeh_is_longjmp_exception()
  IsLJException = M.getOrInsertFunction("__llvm_sjljeh_is_longjmp_exception",
                                        Type::getInt1Ty(M.getContext()),
                                        (Type *)0);

  // int __llvm_sjljeh_get_longjmp_value()
  GetLJValue = M.getOrInsertFunction("__llvm_sjljeh_get_longjmp_value",
                                     Type::getInt32Ty(M.getContext()),
                                     (Type *)0);
  return true;
}
Beispiel #24
0
void Module::parse()
#endif
{   char *srcname;
    unsigned char *buf;
    unsigned buflen;
    unsigned le;
    unsigned bom;

    //printf("Module::parse()\n");

    srcname = srcfile->name->toChars();
    //printf("Module::parse(srcname = '%s')\n", srcname);

    buf = srcfile->buffer;
    buflen = srcfile->len;

    if (buflen >= 2)
    {
        /* Convert all non-UTF-8 formats to UTF-8.
         * BOM : http://www.unicode.org/faq/utf_bom.html
         * 00 00 FE FF  UTF-32BE, big-endian
         * FF FE 00 00  UTF-32LE, little-endian
         * FE FF        UTF-16BE, big-endian
         * FF FE        UTF-16LE, little-endian
         * EF BB BF     UTF-8
         */

        bom = 1;                // assume there's a BOM
        if (buf[0] == 0xFF && buf[1] == 0xFE)
        {
            if (buflen >= 4 && buf[2] == 0 && buf[3] == 0)
            {   // UTF-32LE
                le = 1;

            Lutf32:
                OutBuffer dbuf;
                unsigned *pu = (unsigned *)(buf);
                unsigned *pumax = &pu[buflen / 4];

                if (buflen & 3)
                {   error("odd length of UTF-32 char source %u", buflen);
                    fatal();
                }

                dbuf.reserve(buflen / 4);
                for (pu += bom; pu < pumax; pu++)
                {   unsigned u;

                    u = le ? readlongLE(pu) : readlongBE(pu);
                    if (u & ~0x7F)
                    {
                        if (u > 0x10FFFF)
                        {   error("UTF-32 value %08x greater than 0x10FFFF", u);
                            fatal();
                        }
                        dbuf.writeUTF8(u);
                    }
                    else
                        dbuf.writeByte(u);
                }
                dbuf.writeByte(0);              // add 0 as sentinel for scanner
                buflen = dbuf.offset - 1;       // don't include sentinel in count
                buf = (unsigned char *) dbuf.extractData();
            }
            else
            {   // UTF-16LE (X86)
                // Convert it to UTF-8
                le = 1;

            Lutf16:
                OutBuffer dbuf;
                unsigned short *pu = (unsigned short *)(buf);
                unsigned short *pumax = &pu[buflen / 2];

                if (buflen & 1)
                {   error("odd length of UTF-16 char source %u", buflen);
                    fatal();
                }

                dbuf.reserve(buflen / 2);
                for (pu += bom; pu < pumax; pu++)
                {   unsigned u;

                    u = le ? readwordLE(pu) : readwordBE(pu);
                    if (u & ~0x7F)
                    {   if (u >= 0xD800 && u <= 0xDBFF)
                        {   unsigned u2;

                            if (++pu > pumax)
                            {   error("surrogate UTF-16 high value %04x at EOF", u);
                                fatal();
                            }
                            u2 = le ? readwordLE(pu) : readwordBE(pu);
                            if (u2 < 0xDC00 || u2 > 0xDFFF)
                            {   error("surrogate UTF-16 low value %04x out of range", u2);
                                fatal();
                            }
                            u = (u - 0xD7C0) << 10;
                            u |= (u2 - 0xDC00);
                        }
                        else if (u >= 0xDC00 && u <= 0xDFFF)
                        {   error("unpaired surrogate UTF-16 value %04x", u);
                            fatal();
                        }
                        else if (u == 0xFFFE || u == 0xFFFF)
                        {   error("illegal UTF-16 value %04x", u);
                            fatal();
                        }
                        dbuf.writeUTF8(u);
                    }
                    else
                        dbuf.writeByte(u);
                }
                dbuf.writeByte(0);              // add 0 as sentinel for scanner
                buflen = dbuf.offset - 1;       // don't include sentinel in count
                buf = (unsigned char *) dbuf.extractData();
            }
        }
        else if (buf[0] == 0xFE && buf[1] == 0xFF)
        {   // UTF-16BE
            le = 0;
            goto Lutf16;
        }
        else if (buflen >= 4 && buf[0] == 0 && buf[1] == 0 && buf[2] == 0xFE && buf[3] == 0xFF)
        {   // UTF-32BE
            le = 0;
            goto Lutf32;
        }
        else if (buflen >= 3 && buf[0] == 0xEF && buf[1] == 0xBB && buf[2] == 0xBF)
        {   // UTF-8

            buf += 3;
            buflen -= 3;
        }
        else
        {
            /* There is no BOM. Make use of Arcane Jill's insight that
             * the first char of D source must be ASCII to
             * figure out the encoding.
             */

            bom = 0;
            if (buflen >= 4)
            {   if (buf[1] == 0 && buf[2] == 0 && buf[3] == 0)
                {   // UTF-32LE
                    le = 1;
                    goto Lutf32;
                }
                else if (buf[0] == 0 && buf[1] == 0 && buf[2] == 0)
                {   // UTF-32BE
                    le = 0;
                    goto Lutf32;
                }
            }
            if (buflen >= 2)
            {
                if (buf[1] == 0)
                {   // UTF-16LE
                    le = 1;
                    goto Lutf16;
                }
                else if (buf[0] == 0)
                {   // UTF-16BE
                    le = 0;
                    goto Lutf16;
                }
            }

            // It's UTF-8
            if (buf[0] >= 0x80)
            {   error("source file must start with BOM or ASCII character, not \\x%02X", buf[0]);
                fatal();
            }
        }
    }

#ifdef IN_GCC
    // dump utf-8 encoded source
    if (dump_source)
    {   // %% srcname could contain a path ...
        d_gcc_dump_source(srcname, "utf-8", buf, buflen);
    }
#endif

    /* If it starts with the string "Ddoc", then it's a documentation
     * source file.
     */
    if (buflen >= 4 && memcmp(buf, "Ddoc", 4) == 0)
    {
        comment = buf + 4;
        isDocFile = 1;
        if (!docfile)
            setDocfile();
        return;
    }
    if (isHtml)
    {
        OutBuffer *dbuf = new OutBuffer();
        Html h(srcname, buf, buflen);
        h.extractCode(dbuf);
        buf = dbuf->data;
        buflen = dbuf->offset;
#ifdef IN_GCC
        // dump extracted source
        if (dump_source)
            d_gcc_dump_source(srcname, "d.utf-8", buf, buflen);
#endif
    }
    Parser p(this, buf, buflen, docfile != NULL);
    p.nextToken();
    members = p.parseModule();

    ::free(srcfile->buffer);
    srcfile->buffer = NULL;
    srcfile->len = 0;

    md = p.md;
    numlines = p.loc.linnum;

    DsymbolTable *dst;

    if (md)
    {   this->ident = md->id;
        this->safe = md->safe;
        dst = Package::resolve(md->packages, &this->parent, NULL);
    }
    else
    {
        dst = modules;

        /* Check to see if module name is a valid identifier
         */
        if (!Lexer::isValidIdentifier(this->ident->toChars()))
            error("has non-identifier characters in filename, use module declaration instead");
    }

    // Update global list of modules
    if (!dst->insert(this))
    {
        Dsymbol *prev = dst->lookup(ident);
        assert(prev);
        Module *mprev = prev->isModule();
        if (mprev)
            error(loc, "from file %s conflicts with another module %s from file %s",
                srcname, mprev->toChars(), mprev->srcfile->toChars());
        else
        {
            Package *pkg = prev->isPackage();
            assert(pkg);
            error(loc, "from file %s conflicts with package name %s",
                srcname, pkg->toChars());
        }
    }
    else
    {
        amodules.push(this);
    }
}
Beispiel #25
0
void compile_module_to_text(const Module &module, std::string filename) {
    if (filename.empty()) filename = module.name() + ".stmt";

    std::ofstream file(filename.c_str());
    file << module;
}
Beispiel #26
0
void InitializeSoftBound:: constructCheckHandlers(Module & module){

  Type* void_ty = Type::getVoidTy(module.getContext());

  Type* void_ptr_ty = PointerType::getUnqual(Type::getInt8Ty(module.getContext()));
  Type* size_ty = Type::getInt64Ty(module.getContext());

  module.getOrInsertFunction("__softboundcets_spatial_load_dereference_check",
                             void_ty, void_ptr_ty, void_ptr_ty, 
                             void_ptr_ty, size_ty, NULL);

  module.getOrInsertFunction("__softboundcets_spatial_store_dereference_check", 
                             void_ty, void_ptr_ty, void_ptr_ty, 
                             void_ptr_ty, size_ty, NULL);

  module.getOrInsertFunction("__softboundcets_temporal_load_dereference_check", 
                             void_ty, void_ptr_ty, size_ty, 
                             void_ptr_ty, void_ptr_ty, NULL);

  module.getOrInsertFunction("__softboundcets_temporal_store_dereference_check", 
                             void_ty, void_ptr_ty, size_ty, 
                             void_ptr_ty, void_ptr_ty, NULL);


  Function* global_init = (Function *) module.getOrInsertFunction("__softboundcets_global_init", 
                                                                  void_ty, NULL);

  global_init->setDoesNotThrow();
  global_init->setLinkage(GlobalValue::InternalLinkage);

  BasicBlock* BB = BasicBlock::Create(module.getContext(), 
                                      "entry", global_init);
  
  Function* softboundcets_init = (Function*) module.getOrInsertFunction("__softboundcets_init", void_ty, Type::getInt32Ty(module.getContext()), NULL);

  
  SmallVector<Value*, 8> args;
  Constant * const_one = ConstantInt::get(Type::getInt32Ty(module.getContext()), 1);
  
  args.push_back(const_one);
  Instruction* ret = ReturnInst::Create(module.getContext(), BB);
  
  CallInst::Create(softboundcets_init, args, "", ret);



  Type * Int32Type = IntegerType::getInt32Ty(module.getContext());
  std::vector<Constant *> CtorInits;
  CtorInits.push_back(ConstantInt::get(Int32Type, 0));
  CtorInits.push_back(global_init);
  StructType * ST = ConstantStruct::getTypeForElements(CtorInits, false);
  Constant * RuntimeCtorInit = ConstantStruct::get(ST, CtorInits);

  //
  // Get the current set of static global constructors and add the new ctor
  // to the list.
  //
  std::vector<Constant *> CurrentCtors;
  GlobalVariable * GVCtor = module.getNamedGlobal ("llvm.global_ctors");
  if (GVCtor) {
    if (Constant * C = GVCtor->getInitializer()) {
      for (unsigned index = 0; index < C->getNumOperands(); ++index) {
        CurrentCtors.push_back (dyn_cast<Constant>(C->getOperand (index)));
      }
    }
  }
  CurrentCtors.push_back(RuntimeCtorInit);

  //
  // Create a new initializer.
  //
  ArrayType * AT = ArrayType::get (RuntimeCtorInit-> getType(),
                                   CurrentCtors.size());
  Constant * NewInit = ConstantArray::get (AT, CurrentCtors);

  //
  // Create the new llvm.global_ctors global variable and remove the old one
  // if it existed.
  //
  Value * newGVCtor = new GlobalVariable (module,
                                          NewInit->getType(),
                                          false,
                                          GlobalValue::AppendingLinkage,
                                          NewInit,
                                          "llvm.global_ctors");
  if (GVCtor) {
    newGVCtor->takeName (GVCtor);
    GVCtor->eraseFromParent ();
  }



}
Beispiel #27
0
/*
** Close an existing SQLite database
*/
int sqlite3_close(sqlite3 *db){
  HashElem *i;
  int j;

  if( !db ){
    return SQLITE_OK;
  }
  if( sqlite3SafetyCheck(db) ){
    return SQLITE_MISUSE;
  }

#ifdef SQLITE_SSE
  {
    extern void sqlite3SseCleanup(sqlite3*);
    sqlite3SseCleanup(db);
  }
#endif 

  sqlite3ResetInternalSchema(db, 0);

  /* If a transaction is open, the ResetInternalSchema() call above
  ** will not have called the xDisconnect() method on any virtual
  ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
  ** call will do so. We need to do this before the check for active
  ** SQL statements below, as the v-table implementation may be storing
  ** some prepared statements internally.
  */
  sqlite3VtabRollback(db);

  /* If there are any outstanding VMs, return SQLITE_BUSY. */
  if( db->pVdbe ){
    sqlite3Error(db, SQLITE_BUSY, 
        "Unable to close due to unfinalised statements");
    return SQLITE_BUSY;
  }
  assert( !sqlite3SafetyCheck(db) );

  /* FIX ME: db->magic may be set to SQLITE_MAGIC_CLOSED if the database
  ** cannot be opened for some reason. So this routine needs to run in
  ** that case. But maybe there should be an extra magic value for the
  ** "failed to open" state.
  **
  ** TODO: Coverage tests do not test the case where this condition is
  ** true. It's hard to see how to cause it without messing with threads.
  */
  if( db->magic!=SQLITE_MAGIC_CLOSED && sqlite3SafetyOn(db) ){
    /* printf("DID NOT CLOSE\n"); fflush(stdout); */
    return SQLITE_ERROR;
  }

  for(j=0; j<db->nDb; j++){
    struct Db *pDb = &db->aDb[j];
    if( pDb->pBt ){
      sqlite3BtreeClose(pDb->pBt);
      pDb->pBt = 0;
      if( j!=1 ){
        pDb->pSchema = 0;
      }
    }
  }
  sqlite3ResetInternalSchema(db, 0);
  assert( db->nDb<=2 );
  assert( db->aDb==db->aDbStatic );
  for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
    FuncDef *pFunc, *pNext;
    for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
      pNext = pFunc->pNext;
      sqliteFree(pFunc);
    }
  }

  for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){
    CollSeq *pColl = (CollSeq *)sqliteHashData(i);
    /* Invoke any destructors registered for collation sequence user data. */
    for(j=0; j<3; j++){
      if( pColl[j].xDel ){
        pColl[j].xDel(pColl[j].pUser);
      }
    }
    sqliteFree(pColl);
  }
  sqlite3HashClear(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){
    Module *pMod = (Module *)sqliteHashData(i);
    if( pMod->xDestroy ){
      pMod->xDestroy(pMod->pAux);
    }
    sqliteFree(pMod);
  }
  sqlite3HashClear(&db->aModule);
#endif

  sqlite3HashClear(&db->aFunc);
  sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
  if( db->pErr ){
    sqlite3ValueFree(db->pErr);
  }
  sqlite3CloseExtensions(db);

  db->magic = SQLITE_MAGIC_ERROR;

  /* The temp-database schema is allocated differently from the other schema
  ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()).
  ** So it needs to be freed here. Todo: Why not roll the temp schema into
  ** the same sqliteMalloc() as the one that allocates the database 
  ** structure?
  */
  sqliteFree(db->aDb[1].pSchema);
  sqliteFree(db);
  sqlite3ReleaseThreadData();
  return SQLITE_OK;
}
Beispiel #28
0
void InitializeSoftBound:: constructShadowStackHandlers(Module & module){

  Type* VoidTy = Type::getVoidTy(module.getContext());
  Type* 
    VoidPtrTy = PointerType::getUnqual(Type::getInt8Ty(module.getContext()));
  Type* SizeTy = Type::getInt64Ty(module.getContext());
  
  Type* Int32Ty = Type::getInt32Ty(module.getContext());
  module.getOrInsertFunction("__softboundcets_allocate_shadow_stack_space", 
                             VoidTy, Int32Ty, NULL);
  module.getOrInsertFunction("__softboundcets_deallocate_shadow_stack_space", 
                             VoidTy, NULL);
  module.getOrInsertFunction("__softboundcets_load_base_shadow_stack", 
                             VoidPtrTy, Int32Ty, NULL);
  module.getOrInsertFunction("__softboundcets_load_bound_shadow_stack", 
                             VoidPtrTy, Int32Ty, NULL);
  module.getOrInsertFunction("__softboundcets_load_key_shadow_stack", 
                             SizeTy, Int32Ty, NULL);
  module.getOrInsertFunction("__softboundcets_load_lock_shadow_stack", 
                             VoidPtrTy, Int32Ty, NULL);
  module.getOrInsertFunction("__softboundcets_store_base_shadow_stack", 
                             VoidTy, VoidPtrTy, Int32Ty, NULL);
  module.getOrInsertFunction("__softboundcets_store_bound_shadow_stack", 
                             VoidTy, VoidPtrTy, Int32Ty, NULL);
  module.getOrInsertFunction("__softboundcets_store_key_shadow_stack", 
                             VoidTy, SizeTy, Int32Ty, NULL);
  module.getOrInsertFunction("__softboundcets_store_lock_shadow_stack", 
                             VoidTy, VoidPtrTy, Int32Ty, NULL);

}
Beispiel #29
0
/// \brief Assign DWARF discriminators.
///
/// To assign discriminators, we examine the boundaries of every
/// basic block and its successors. Suppose there is a basic block B1
/// with successor B2. The last instruction I1 in B1 and the first
/// instruction I2 in B2 are located at the same file and line number.
/// This situation is illustrated in the following code snippet:
///
///       if (i < 10) x = i;
///
///     entry:
///       br i1 %cmp, label %if.then, label %if.end, !dbg !10
///     if.then:
///       %1 = load i32* %i.addr, align 4, !dbg !10
///       store i32 %1, i32* %x, align 4, !dbg !10
///       br label %if.end, !dbg !10
///     if.end:
///       ret void, !dbg !12
///
/// Notice how the branch instruction in block 'entry' and all the
/// instructions in block 'if.then' have the exact same debug location
/// information (!dbg !10).
///
/// To distinguish instructions in block 'entry' from instructions in
/// block 'if.then', we generate a new lexical block for all the
/// instruction in block 'if.then' that share the same file and line
/// location with the last instruction of block 'entry'.
///
/// This new lexical block will have the same location information as
/// the previous one, but with a new DWARF discriminator value.
///
/// One of the main uses of this discriminator value is in runtime
/// sample profilers. It allows the profiler to distinguish instructions
/// at location !dbg !10 that execute on different basic blocks. This is
/// important because while the predicate 'if (x < 10)' may have been
/// executed millions of times, the assignment 'x = i' may have only
/// executed a handful of times (meaning that the entry->if.then edge is
/// seldom taken).
///
/// If we did not have discriminator information, the profiler would
/// assign the same weight to both blocks 'entry' and 'if.then', which
/// in turn will make it conclude that the entry->if.then edge is very
/// hot.
///
/// To decide where to create new discriminator values, this function
/// traverses the CFG and examines instruction at basic block boundaries.
/// If the last instruction I1 of a block B1 is at the same file and line
/// location as instruction I2 of successor B2, then it creates a new
/// lexical block for I2 and all the instruction in B2 that share the same
/// file and line location as I2. This new lexical block will have a
/// different discriminator number than I1.
bool AddDiscriminators::runOnFunction(Function &F) {
  // If the function has debug information, but the user has disabled
  // discriminators, do nothing.
  // Simlarly, if the function has no debug info, do nothing.
  // Finally, if this module is built with dwarf versions earlier than 4,
  // do nothing (discriminator support is a DWARF 4 feature).
  if (NoDiscriminators ||
      !hasDebugInfo(F) ||
      F.getParent()->getDwarfVersion() < 4)
    return false;

  bool Changed = false;
  Module *M = F.getParent();
  LLVMContext &Ctx = M->getContext();
  DIBuilder Builder(*M, /*AllowUnresolved*/ false);

  // Traverse all the blocks looking for instructions in different
  // blocks that are at the same file:line location.
  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
    BasicBlock *B = I;
    TerminatorInst *Last = B->getTerminator();
    DILocation LastDIL = Last->getDebugLoc().get();
    if (!LastDIL)
      continue;

    for (unsigned I = 0; I < Last->getNumSuccessors(); ++I) {
      BasicBlock *Succ = Last->getSuccessor(I);
      Instruction *First = Succ->getFirstNonPHIOrDbgOrLifetime();
      DILocation FirstDIL = First->getDebugLoc().get();
      if (!FirstDIL)
        continue;

      // If the first instruction (First) of Succ is at the same file
      // location as B's last instruction (Last), add a new
      // discriminator for First's location and all the instructions
      // in Succ that share the same location with First.
      if (!FirstDIL->canDiscriminate(*LastDIL)) {
        // Create a new lexical scope and compute a new discriminator
        // number for it.
        StringRef Filename = FirstDIL->getFilename();
        auto *Scope = FirstDIL->getScope();
        auto *File = Builder.createFile(Filename, Scope->getDirectory());

        // FIXME: Calculate the discriminator here, based on local information,
        // and delete MDLocation::computeNewDiscriminator().  The current
        // solution gives different results depending on other modules in the
        // same context.  All we really need is to discriminate between
        // FirstDIL and LastDIL -- a local map would suffice.
        unsigned Discriminator = FirstDIL->computeNewDiscriminator();
        auto *NewScope =
            Builder.createLexicalBlockFile(Scope, File, Discriminator);
        auto *NewDIL =
            MDLocation::get(Ctx, FirstDIL->getLine(), FirstDIL->getColumn(),
                            NewScope, FirstDIL->getInlinedAt());
        DebugLoc newDebugLoc = NewDIL;

        // Attach this new debug location to First and every
        // instruction following First that shares the same location.
        for (BasicBlock::iterator I1(*First), E1 = Succ->end(); I1 != E1;
             ++I1) {
          if (I1->getDebugLoc().get() != FirstDIL)
            break;
          I1->setDebugLoc(newDebugLoc);
          DEBUG(dbgs() << NewDIL->getFilename() << ":" << NewDIL->getLine()
                       << ":" << NewDIL->getColumn() << ":"
                       << NewDIL->getDiscriminator() << *I1 << "\n");
        }
        DEBUG(dbgs() << "\n");
        Changed = true;
      }
    }
  }
  return Changed;
}
// Ensure ELF .symver aliases get the same binding as the defined symbol
// they alias with.
static void handleSymverAliases(const Module &M, RecordStreamer &Streamer) {
  if (Streamer.symverAliases().empty())
    return;

  // The name in the assembler will be mangled, but the name in the IR
  // might not, so we first compute a mapping from mangled name to GV.
  Mangler Mang;
  SmallString<64> MangledName;
  StringMap<const GlobalValue *> MangledNameMap;
  auto GetMangledName = [&](const GlobalValue &GV) {
    if (!GV.hasName())
      return;

    MangledName.clear();
    MangledName.reserve(GV.getName().size() + 1);
    Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
    MangledNameMap[MangledName] = &GV;
  };
  for (const Function &F : M)
    GetMangledName(F);
  for (const GlobalVariable &GV : M.globals())
    GetMangledName(GV);
  for (const GlobalAlias &GA : M.aliases())
    GetMangledName(GA);

  // Walk all the recorded .symver aliases, and set up the binding
  // for each alias.
  for (auto &Symver : Streamer.symverAliases()) {
    const MCSymbol *Aliasee = Symver.first;
    MCSymbolAttr Attr = MCSA_Invalid;

    // First check if the aliasee binding was recorded in the asm.
    RecordStreamer::State state = Streamer.getSymbolState(Aliasee);
    switch (state) {
    case RecordStreamer::Global:
    case RecordStreamer::DefinedGlobal:
      Attr = MCSA_Global;
      break;
    case RecordStreamer::UndefinedWeak:
    case RecordStreamer::DefinedWeak:
      Attr = MCSA_Weak;
      break;
    default:
      break;
    }

    // If we don't have a symbol attribute from assembly, then check if
    // the aliasee was defined in the IR.
    if (Attr == MCSA_Invalid) {
      const auto *GV = M.getNamedValue(Aliasee->getName());
      if (!GV) {
        auto MI = MangledNameMap.find(Aliasee->getName());
        if (MI != MangledNameMap.end())
          GV = MI->second;
        else
          continue;
      }
      if (GV->hasExternalLinkage())
        Attr = MCSA_Global;
      else if (GV->hasLocalLinkage())
        Attr = MCSA_Local;
      else if (GV->isWeakForLinker())
        Attr = MCSA_Weak;
    }
    if (Attr == MCSA_Invalid)
      continue;

    // Set the detected binding on each alias with this aliasee.
    for (auto &Alias : Symver.second)
      Streamer.EmitSymbolAttribute(Alias, Attr);
  }
}