예제 #1
0
   virtual void EndSourceFileAction()
   {
      llvm::errs() << __FUNCTION__ << "\n";

      *output_ << "}\n";
      output_->flush();
   }
예제 #2
0
// Write a module hierarchy to the given output stream.
bool Module::output(llvm::raw_fd_ostream &OS, int Indent) {
    // If this is not the nameless root module, start a module definition.
    if (Name.size() != 0) {
        OS.indent(Indent);
        OS << "module " << Name << " {\n";
        Indent += 2;
    }

    // Output submodules.
    for (std::vector<Module *>::iterator I = SubModules.begin(),
            E = SubModules.end();
            I != E; ++I) {
        if (!(*I)->output(OS, Indent))
            return false;
    }

    // Output header files.
    for (std::vector<std::string>::iterator I = HeaderFileNames.begin(),
            E = HeaderFileNames.end();
            I != E; ++I) {
        OS.indent(Indent);
        OS << "header \"" << *I << "\"\n";
    }

    // If this module has header files, output export directive.
    if (HeaderFileNames.size() != 0) {
        OS.indent(Indent);
        OS << "export *\n";
    }

    // If this is not the nameless root module, close the module definition.
    if (Name.size() != 0) {
        Indent -= 2;
        OS.indent(Indent);
        OS << "}\n";
    }

    return true;
}
예제 #3
0
// Write a module hierarchy to the given output stream.
bool Module::output(llvm::raw_fd_ostream &OS, int Indent) {
  // If this is not the nameless root module, start a module definition.
  if (Name.size() != 0) {
    OS.indent(Indent);
    OS << "module " << Name << " {\n";
    Indent += 2;
  }

  // Output submodules.
  for (auto I = SubModules.begin(), E = SubModules.end(); I != E; ++I) {
    if (!(*I)->output(OS, Indent))
      return false;
  }

  // Output header files.
  for (auto I = HeaderFileNames.begin(), E = HeaderFileNames.end(); I != E;
       ++I) {
    OS.indent(Indent);
    if (IsProblem || strstr((*I).c_str(), ".inl"))
      OS << "exclude header \"" << *I << "\"\n";
    else
      OS << "header \"" << *I << "\"\n";
  }

  // If this module has header files, output export directive.
  if (HeaderFileNames.size() != 0) {
    OS.indent(Indent);
    OS << "export *\n";
  }

  // If this is not the nameless root module, close the module definition.
  if (Name.size() != 0) {
    Indent -= 2;
    OS.indent(Indent);
    OS << "}\n";
  }

  return true;
}
예제 #4
0
bool Z3SolverImpl::internalRunSolver(
    const Query &query, const std::vector<const Array *> *objects,
    std::vector<std::vector<unsigned char> > *values, bool &hasSolution) {

  TimerStatIncrementer t(stats::queryTime);
  // NOTE: Z3 will switch to using a slower solver internally if push/pop are
  // used so for now it is likely that creating a new solver each time is the
  // right way to go until Z3 changes its behaviour.
  //
  // TODO: Investigate using a custom tactic as described in
  // https://github.com/klee/klee/issues/653
  Z3_solver theSolver = Z3_mk_solver(builder->ctx);
  Z3_solver_inc_ref(builder->ctx, theSolver);
  Z3_solver_set_params(builder->ctx, theSolver, solverParameters);

  runStatusCode = SOLVER_RUN_STATUS_FAILURE;

  for (ConstraintManager::const_iterator it = query.constraints.begin(),
                                         ie = query.constraints.end();
       it != ie; ++it) {
    Z3_solver_assert(builder->ctx, theSolver, builder->construct(*it));
  }
  ++stats::queries;
  if (objects)
    ++stats::queryCounterexamples;

  Z3ASTHandle z3QueryExpr =
      Z3ASTHandle(builder->construct(query.expr), builder->ctx);

  // KLEE Queries are validity queries i.e.
  // ∀ X Constraints(X) → query(X)
  // but Z3 works in terms of satisfiability so instead we ask the
  // negation of the equivalent i.e.
  // ∃ X Constraints(X) ∧ ¬ query(X)
  Z3_solver_assert(
      builder->ctx, theSolver,
      Z3ASTHandle(Z3_mk_not(builder->ctx, z3QueryExpr), builder->ctx));

  if (dumpedQueriesFile) {
    *dumpedQueriesFile << "; start Z3 query\n";
    *dumpedQueriesFile << Z3_solver_to_string(builder->ctx, theSolver);
    *dumpedQueriesFile << "(check-sat)\n";
    *dumpedQueriesFile << "(reset)\n";
    *dumpedQueriesFile << "; end Z3 query\n\n";
    dumpedQueriesFile->flush();
  }

  ::Z3_lbool satisfiable = Z3_solver_check(builder->ctx, theSolver);
  runStatusCode = handleSolverResponse(theSolver, satisfiable, objects, values,
                                       hasSolution);

  Z3_solver_dec_ref(builder->ctx, theSolver);
  // Clear the builder's cache to prevent memory usage exploding.
  // By using ``autoClearConstructCache=false`` and clearning now
  // we allow Z3_ast expressions to be shared from an entire
  // ``Query`` rather than only sharing within a single call to
  // ``builder->construct()``.
  builder->clearConstructCache();

  if (runStatusCode == SolverImpl::SOLVER_RUN_STATUS_SUCCESS_SOLVABLE ||
      runStatusCode == SolverImpl::SOLVER_RUN_STATUS_SUCCESS_UNSOLVABLE) {
    if (hasSolution) {
      ++stats::queriesInvalid;
    } else {
      ++stats::queriesValid;
    }
    return true; // success
  }
  return false; // failed
}
예제 #5
0
void
XdfObject::Output(llvm::raw_fd_ostream& os,
                  bool all_syms,
                  DebugFormat& dbgfmt,
                  Diagnostic& diags)
{
    all_syms = true;   // force all syms into symbol table

    // Get number of symbols and set symbol index in symbol data.
    unsigned long symtab_count = 0;
    for (Object::symbol_iterator sym = m_object.symbols_begin(),
         end = m_object.symbols_end(); sym != end; ++sym)
    {
        int vis = sym->getVisibility();
        if (vis & Symbol::COMMON)
        {
            diags.Report(sym->getDeclSource(),
                         diag::err_xdf_common_unsupported);
            continue;
        }
        if (all_syms || (vis != Symbol::LOCAL && !(vis & Symbol::DLOCAL)))
        {
            // Save index in symrec data
            sym->AddAssocData(
                std::auto_ptr<XdfSymbol>(new XdfSymbol(symtab_count)));

            ++symtab_count;
        }
    }

    // Number sections
    long scnum = 0;
    for (Object::section_iterator i = m_object.sections_begin(),
         end = m_object.sections_end(); i != end; ++i)
    {
        XdfSection* xsect = i->getAssocData<XdfSection>();
        assert(xsect != 0);
        xsect->scnum = scnum++;
    }

    // Allocate space for headers by seeking forward
    os.seek(FILEHEAD_SIZE+SECTHEAD_SIZE*scnum);
    if (os.has_error())
    {
        diags.Report(SourceLocation(), diag::err_file_output_seek);
        return;
    }

    XdfOutput out(os, m_object, diags);

    // Get file offset of start of string table
    unsigned long strtab_offset =
        FILEHEAD_SIZE + SECTHEAD_SIZE*scnum + SYMBOL_SIZE*symtab_count;

    // Output symbol table
    for (Object::const_symbol_iterator sym = m_object.symbols_begin(),
         end = m_object.symbols_end(); sym != end; ++sym)
    {
        out.OutputSymbol(*sym, all_syms, &strtab_offset);
    }

    // Output string table
    for (Object::const_symbol_iterator sym = m_object.symbols_begin(),
         end = m_object.symbols_end(); sym != end; ++sym)
    {
        if (all_syms || sym->getVisibility() != Symbol::LOCAL)
            os << sym->getName() << '\0';
    }

    // Output section data/relocs
    for (Object::section_iterator i=m_object.sections_begin(),
         end=m_object.sections_end(); i != end; ++i)
    {
        out.OutputSection(*i);
    }

    // Write headers
    os.seek(0);
    if (os.has_error())
    {
        diags.Report(SourceLocation(), diag::err_file_output_seek);
        return;
    }

    // Output object header
    Bytes& scratch = out.getScratch();
    scratch.setLittleEndian();
    Write32(scratch, XDF_MAGIC);        // magic number
    Write32(scratch, scnum);            // number of sects
    Write32(scratch, symtab_count);     // number of symtabs
    // size of sect headers + symbol table + strings
    Write32(scratch, strtab_offset-FILEHEAD_SIZE);
    assert(scratch.size() == FILEHEAD_SIZE);
    os << scratch;

    // Output section headers
    for (Object::const_section_iterator i=m_object.sections_begin(),
         end=m_object.sections_end(); i != end; ++i)
    {
        const XdfSection* xsect = i->getAssocData<XdfSection>();
        assert(xsect != 0);

        Bytes& scratch2 = out.getScratch();
        xsect->Write(scratch2, *i);
        assert(scratch2.size() == SECTHEAD_SIZE);
        os << scratch2;
    }
}