Пример #1
0
void simulator_loop_detectiont::get_fresh_induction_parameter(
    exprt &parameter)
{
  symbol_exprt parameter_expr(uint_type());

  bool found;
  do 
  {
    parameter_index++;
    parameter_expr.set_identifier("c::N$"+i2string(parameter_index));
    parameter_expr.set("induction_symbol", true);

    try 
    {
      concrete_model.ns.lookup(parameter_expr);
      found = true;
    }
    catch (std::string ex) 
    {
      found = false;
    }
  }
  while (found);

  symbolt sym;

  sym.name = parameter_expr.get_identifier();
  sym.base_name = "N$"+i2string(parameter_index);
  sym.module = ID_C;

  shadow_context.add (sym);

  parameter = parameter_expr;
}
Пример #2
0
const exprt qbf_squolem_coret::f_get(literalt l)
{
  if(squolem->isUniversal(l.var_no()))
  {
    assert(l.var_no()!=0);
    variable_mapt::const_iterator it=variable_map.find(l.var_no());

    if(it==variable_map.end())
      throw "Variable map error";

    const exprt &sym=it->second.first;
    unsigned index=it->second.second;

    exprt extract_expr(ID_extractbit, typet(ID_bool));
    extract_expr.copy_to_operands(sym);
    typet uint_type(ID_unsignedbv);
    uint_type.set(ID_width, 32);
    extract_expr.copy_to_operands(from_integer(index, uint_type));

    if(l.sign()) extract_expr.negate();

    return extract_expr;
  }

  function_cachet::const_iterator it=function_cache.find(l.var_no());
  if(it!=function_cache.end())
  {
    #if 0
    std::cout << "CACHE HIT for " << l.dimacs() << std::endl;
    #endif

    if(l.sign())
      return not_exprt(it->second);
    else
      return it->second;
  }
  else
  {
    WitnessStack *wsp = squolem->getModelFunction(Literal(l.dimacs()));
    exprt res;

    if(wsp==NULL || wsp->empty())
    {
//      res=exprt(ID_nondet_bool, typet(ID_bool));
      res=false_exprt(); // just set it to zero
    }
    else if(wsp->pSize<=wsp->nSize)
      res=f_get_cnf(wsp);
    else
      res=f_get_dnf(wsp);

    function_cache[l.var_no()] = res;

    if(l.sign())
      return not_exprt(res);
    else
      return res;
  }
}
Пример #3
0
void ranking_synthesis_satt::adjust_type(typet &type) const
{
  if(type.id()=="bool")
  {
    type=uint_type();
    type.set("width", 1);
  }
}
Пример #4
0
 exprt zero_string_length(
   const exprt &what,
   bool write=false)
 {
   exprt result("zero_string_length", uint_type());
   result.copy_to_operands(what);
   result.set("lhs", write);
   return result;
 }
Пример #5
0
void c_typecastt::implicit_typecast_arithmetic(
  exprt &expr,
  c_typet c_type)
{
  typet new_type;
  
  const typet &expr_type=ns.follow(expr.type());
  
  switch(c_type)
  {
  case PTR:
    if(expr_type.id()==ID_array)
    {
      new_type.id(ID_pointer);
      new_type.subtype()=expr_type.subtype();
      break;
    }
    return;

  case BOOL:       new_type=bool_typet(); break;
  case CHAR:       assert(false); // should always be promoted to int
  case UCHAR:      assert(false); // should always be promoted to int
  case SHORT:      assert(false); // should always be promoted to int
  case USHORT:     assert(false); // should always be promoted to int
  case INT:        new_type=int_type(); break;
  case UINT:       new_type=uint_type(); break;
  case LONG:       new_type=long_int_type(); break;
  case ULONG:      new_type=long_uint_type(); break;
  case LONGLONG:   new_type=long_long_int_type(); break;
  case ULONGLONG:  new_type=long_long_uint_type(); break;
  case SINGLE:     new_type=float_type(); break;
  case DOUBLE:     new_type=double_type(); break;
  case LONGDOUBLE: new_type=long_double_type(); break;
  case RATIONAL:   new_type=rational_typet(); break;
  case REAL:       new_type=real_typet(); break;
  case INTEGER:    new_type=integer_typet(); break;
  case COMPLEX: return; // do nothing
  default: return;
  }

  if(new_type!=expr_type)
  {
    if(new_type.id()==ID_pointer &&
       expr_type.id()==ID_array)
    {
      exprt index_expr(ID_index, expr_type.subtype());
      index_expr.reserve_operands(2);
      index_expr.move_to_operands(expr);
      index_expr.copy_to_operands(gen_zero(index_type()));
      expr=exprt(ID_address_of, new_type);
      expr.move_to_operands(index_expr);
    }
    else
      do_typecast(expr, new_type);
  }
}
Пример #6
0
void string_instrumentationt::do_strerror(
  goto_programt &dest,
  goto_programt::targett it,
  code_function_callt &call)
{
  if(call.lhs().is_nil())
  {
    it->make_skip();
    return;
  }

  irep_idt identifier_buf="c::__strerror_buffer";
  irep_idt identifier_size="c::__strerror_buffer_size";

  if(context.symbols.find(identifier_buf)==context.symbols.end())
  {
    symbolt new_symbol_size;
    new_symbol_size.base_name="__strerror_buffer_size";
    new_symbol_size.pretty_name=new_symbol_size.base_name;
    new_symbol_size.name=identifier_size;
    new_symbol_size.mode="C";
    new_symbol_size.type=uint_type();
    new_symbol_size.is_statevar=true;
    new_symbol_size.lvalue=true;
    new_symbol_size.static_lifetime=true;

    array_typet type;
    type.subtype()=char_type();
    type.size()=symbol_expr(new_symbol_size);
    symbolt new_symbol_buf;
    new_symbol_buf.mode="C";
    new_symbol_buf.type=type;
    new_symbol_buf.is_statevar=true;
    new_symbol_buf.lvalue=true;
    new_symbol_buf.static_lifetime=true;
    new_symbol_buf.base_name="__strerror_buffer";
    new_symbol_buf.pretty_name=new_symbol_buf.base_name;
    new_symbol_buf.name="c::"+id2string(new_symbol_buf.base_name);

    context.move(new_symbol_buf);
    context.move(new_symbol_size);
  }

  const symbolt &symbol_size=ns.lookup(identifier_size);
  const symbolt &symbol_buf=ns.lookup(identifier_buf);

  goto_programt tmp;

  {  
    goto_programt::targett assignment1=tmp.add_instruction(ASSIGN);
    exprt nondet_size=side_effect_expr_nondett(uint_type());

    assignment1->code=code_assignt(symbol_expr(symbol_size), nondet_size);
    assignment1->location=it->location;
    
    goto_programt::targett assumption1=tmp.add_instruction();

    assumption1->make_assumption(binary_relation_exprt(
      symbol_expr(symbol_size), "notequal",
      gen_zero(symbol_size.type)));

    assumption1->location=it->location;
  }

  // return a pointer to some magic buffer
  exprt index=exprt("index", char_type());
  index.copy_to_operands(symbol_expr(symbol_buf), gen_zero(uint_type()));

  exprt ptr=exprt("address_of", pointer_typet());
  ptr.type().subtype()=char_type();
  ptr.copy_to_operands(index);

  // make that zero-terminated
  {
    goto_programt::targett assignment2=tmp.add_instruction(ASSIGN);
    assignment2->code=code_assignt(is_zero_string(ptr, true), true_exprt());
    assignment2->location=it->location;
  }

  // assign address
  {
    goto_programt::targett assignment3=tmp.add_instruction(ASSIGN);
    exprt rhs=ptr;
    make_type(rhs, call.lhs().type());
    assignment3->code=code_assignt(call.lhs(), rhs);
    assignment3->location=it->location;
  }

  it->make_skip();
  dest.insert_before_swap(it, tmp);
}
Пример #7
0
 exprt buffer_size(const exprt &what)
 {
   exprt result("buffer_size", uint_type());
   result.copy_to_operands(what);
   return result;
 }
Пример #8
0
void string_instrumentationt::do_format_string_write(
  goto_programt &dest,
  goto_programt::const_targett target,
  const code_function_callt::argumentst &arguments,
  unsigned format_string_inx,
  unsigned argument_start_inx,
  const std::string &function_name)
{
  const exprt &format_arg = arguments[format_string_inx];
    
  if(format_arg.id()=="address_of" &&
     format_arg.op0().id()=="index" &&
     format_arg.op0().op0().id()==ID_string_constant) // constant format
  {
    format_token_listt token_list;
    parse_format_string(format_arg.op0().op0(), token_list);
    
    unsigned args=0;
    
    for(format_token_listt::const_iterator it=token_list.begin();
        it!=token_list.end();
        it++)
    {
      if(find(it->flags.begin(), it->flags.end(), format_tokent::ASTERISK)!=
         it->flags.end()) 
        continue; // asterisk means `ignore this'
      
      switch(it->type)
      {
        case format_tokent::STRING:
        {
            
          const exprt &argument=arguments[argument_start_inx+args];
          const typet &arg_type=ns.follow(argument.type());
          
          goto_programt::targett assertion=dest.add_instruction();
          assertion->location=target->location;
          assertion->location.set("property", "string");
          std::string comment("format string buffer overflow in ");
          comment += function_name;
          assertion->location.set("comment", comment);
          
          if(it->field_width!=0)
          {
            exprt fwidth = from_integer(it->field_width, uint_type());
            exprt fw_1("+", uint_type());
            exprt one = gen_one(uint_type());
            fw_1.move_to_operands(fwidth);
            fw_1.move_to_operands(one); // +1 for 0-char
            
            exprt fw_lt_bs;
            
            if(arg_type.id()=="pointer")
              fw_lt_bs=binary_relation_exprt(fw_1, "<=", buffer_size(argument));
            else
            {
              index_exprt index;
              index.array()=argument;
              index.index()=gen_zero(uint_type());
              address_of_exprt aof(index);
              fw_lt_bs=binary_relation_exprt(fw_1, "<=", buffer_size(aof));
            }
            
            assertion->make_assertion(fw_lt_bs);
          }
          else
          {
            // this is a possible overflow.
            assertion->make_assertion(false_exprt());
          }
          
          // now kill the contents
          invalidate_buffer(dest, target, argument, arg_type, it->field_width);
          
          args++;
          break;
        }
        case format_tokent::TEXT:
        case format_tokent::UNKNOWN:
        {          
          // nothing
          break;
        }
        default: // everything else
        {
          const exprt &argument=arguments[argument_start_inx+args];
          const typet &arg_type=ns.follow(argument.type());
          
          goto_programt::targett assignment=dest.add_instruction(ASSIGN);
          assignment->location=target->location;
          
          exprt lhs("dereference", arg_type.subtype());
          lhs.copy_to_operands(argument);
          
          exprt rhs=side_effect_expr_nondett(lhs.type());
          rhs.location()=target->location;
           
          assignment->code=code_assignt(lhs, rhs);
          
          args++;
          break;
        }
      }
    }
  }
  else // non-const format string
  {    
    for(unsigned i=argument_start_inx; i<arguments.size(); i++)
    {    
      const typet &arg_type=ns.follow(arguments[i].type());
      
      // Note: is_string_type() is a `good guess' here. Actually
      // any of the pointers could point into an array. But it
      // would suck if we had to invalidate all variables.
      // Luckily this case isn't needed too often.
      if(is_string_type(arg_type))
      {
        goto_programt::targett assertion=dest.add_instruction();
        assertion->location=target->location;
        assertion->location.set("property", "string");
        std::string comment("format string buffer overflow in ");
        comment += function_name;
        assertion->location.set("comment", comment);

        // as we don't know any field width for the %s that 
        // should be here during runtime, we just report a 
        // possibly false positive
        assertion->make_assertion(false_exprt());
        
        invalidate_buffer(dest, target, arguments[i], arg_type, 0);
      }
      else
      {
        goto_programt::targett assignment = dest.add_instruction(ASSIGN);
        assignment->location=target->location;
        
        exprt lhs("dereference", arg_type.subtype());
        lhs.copy_to_operands(arguments[i]);
        
        exprt rhs=side_effect_expr_nondett(lhs.type());
        rhs.location()=target->location;
         
        assignment->code=code_assignt(lhs, rhs);
      }
    }
  }
}
Пример #9
0
void string_instrumentationt::do_format_string_read(
  goto_programt &dest,
  goto_programt::const_targett target,
  const code_function_callt::argumentst &arguments,
  unsigned format_string_inx,
  unsigned argument_start_inx,
  const std::string &function_name)
{
  const exprt &format_arg = arguments[format_string_inx];
  
  if(format_arg.id()=="address_of" &&
     format_arg.op0().id()=="index" &&
     format_arg.op0().op0().id()==ID_string_constant)
  {
    format_token_listt token_list;
    parse_format_string(format_arg.op0().op0(), token_list);
    
    unsigned args=0;
    
    for(format_token_listt::const_iterator it=token_list.begin();
        it!=token_list.end();
        it++)
    {
      if(it->type==format_tokent::STRING)
      {
        const exprt &arg = arguments[argument_start_inx+args];
        const typet &arg_type = ns.follow(arg.type());
        
        if(arg.id()!=ID_string_constant) // we don't need to check constants
        {
          goto_programt::targett assertion=dest.add_instruction();
          assertion->location=target->location;
          assertion->location.set("property", "string");
          std::string comment("zero-termination of string argument of ");
          comment += function_name;
          assertion->location.set("comment", comment);
          
          exprt temp(arg);
          
          if(arg_type.id()!="pointer")
          {
            index_exprt index;
            index.array()=temp;
            index.index()=gen_zero(uint_type());
            index.type()=arg_type.subtype();            
            temp=address_of_exprt(index);            
          }
          
          assertion->make_assertion(is_zero_string(temp));
        }
      }
      
      if(it->type!=format_tokent::TEXT && 
         it->type!=format_tokent::UNKNOWN) args++;
      
      if(find(it->flags.begin(), it->flags.end(), format_tokent::ASTERISK)!=
         it->flags.end())
        args++; // just eat the additional argument          
    }
  }
  else // non-const format string
  {
    goto_programt::targett format_ass=dest.add_instruction();
    format_ass->make_assertion(is_zero_string(arguments[1]));
    format_ass->location=target->location;
    format_ass->location.set("property", "string");
    std::string comment("zero-termination of format string of ");
    comment += function_name;
    format_ass->location.set("comment", comment);
    
    for(unsigned i=2; i<arguments.size(); i++)
    {
      const exprt &arg = arguments[i];
      const typet &arg_type=ns.follow(arguments[i].type());
      
      if(arguments[i].id()!=ID_string_constant &&
         is_string_type(arg_type))
      {
        goto_programt::targett assertion=dest.add_instruction();        
        assertion->location=target->location;
        assertion->location.set("property", "string");
        std::string comment("zero-termination of string argument of ");
        comment += function_name;
        assertion->location.set("comment", comment);
        
        exprt temp(arg);
                  
        if(arg_type.id()!="pointer")
        {
          index_exprt index;
          index.array()=temp;
          index.index()=gen_zero(uint_type());
          index.type()=arg_type.subtype();            
          temp=address_of_exprt(index);            
        }
        
        assertion->make_assertion(is_zero_string(temp));
      }
    }
  }
}
Пример #10
0
void string_instrumentationt::invalidate_buffer(
  goto_programt &dest,
  goto_programt::const_targett target,
  const exprt &buffer,
  const typet &buf_type,
  const mp_integer &limit)
{
  irep_idt cntr_id="string_instrumentation::$counter";
  
  if(context.symbols.find(cntr_id)==context.symbols.end())
  {
    symbolt new_symbol;
    new_symbol.base_name="$counter";
    new_symbol.pretty_name=new_symbol.base_name;
    new_symbol.name=cntr_id;
    new_symbol.mode="C";
    new_symbol.type=uint_type();
    new_symbol.is_statevar=true;
    new_symbol.lvalue=true;
    new_symbol.static_lifetime=true;
    
    context.move(new_symbol);
  }
  
  const symbolt &cntr_sym=ns.lookup(cntr_id);
  
  // create a loop that runs over the buffer
  // and invalidates every element
  
  goto_programt::targett init=dest.add_instruction(ASSIGN);
  init->location=target->location;  
  init->code=code_assignt(symbol_expr(cntr_sym), gen_zero(cntr_sym.type));
  
  goto_programt::targett check=dest.add_instruction();
  check->location=target->location;  
  
  goto_programt::targett invalidate=dest.add_instruction(ASSIGN);
  invalidate->location=target->location;  
  
  goto_programt::targett increment=dest.add_instruction(ASSIGN);
  increment->location=target->location;  
  
  exprt plus("+", uint_type());
  plus.copy_to_operands(symbol_expr(cntr_sym));
  plus.copy_to_operands(gen_one(uint_type()));
  
  increment->code=code_assignt(symbol_expr(cntr_sym), plus);
  
  goto_programt::targett back=dest.add_instruction();
  back->location=target->location;  
  back->make_goto(check);
  back->guard=true_exprt();
  
  goto_programt::targett exit=dest.add_instruction();
  exit->location=target->location;  
  exit->make_skip();  
  
  exprt cnt_bs, bufp;
  
  if(buf_type.id()=="pointer")
    bufp = buffer;
  else
  {
    index_exprt index;
    index.array()=buffer;
    index.index()=gen_zero(uint_type());
    index.type()=buf_type.subtype();
    bufp = address_of_exprt(index);
  }
  
  exprt deref("dereference", buf_type.subtype());
  exprt b_plus_i("+", bufp.type());
  b_plus_i.copy_to_operands(bufp);
  b_plus_i.copy_to_operands(symbol_expr(cntr_sym));
  deref.copy_to_operands(b_plus_i);
  
  check->make_goto(exit);
  
  if(limit==0)
    check->guard=
          binary_relation_exprt(symbol_expr(cntr_sym), ">=", 
                                buffer_size(bufp));
  else
    check->guard=
          binary_relation_exprt(symbol_expr(cntr_sym), ">", 
                                from_integer(limit, uint_type()));
  
  exprt nondet=side_effect_expr_nondett(buf_type.subtype());
  invalidate->code=code_assignt(deref, nondet);
}
void printf_formattert::process_format(std::ostream &out)
{
  exprt tmp;
  format_constantt format_constant;

  format_constant.precision=6;
  format_constant.min_width=0;
  format_constant.zero_padding=false;

  char ch=next();

  if(ch=='0') // leading zeros
  {
    format_constant.zero_padding=true;
    ch=next();
  }

  while(isdigit(ch)) // width
  {
    format_constant.min_width*=10;
    format_constant.min_width+=ch-'0';
    ch=next();
  }

  if(ch=='.') // precision
  {
    format_constant.precision=0;
    ch=next();

    while(isdigit(ch))
    {
      format_constant.precision*=10;
      format_constant.precision+=ch-'0';
      ch=next();
    }
  }

  switch(ch)
  {
  case '%':
    out << ch;
    break;

  case 'f':
  case 'F':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), double_type()));
    break;

  case 'g':
  case 'G':
    if(format_constant.precision==0) format_constant.precision=1;
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), double_type()));
    break;

  case 's':
    {
      if(next_operand==operands.end()) break;
      // this is the address of a string
      const exprt &op=*(next_operand++);
      if(op.id()==ID_address_of &&
         op.operands().size()==1 &&
         op.op0().id()==ID_index &&
         op.op0().operands().size()==2 &&
         op.op0().op0().id()==ID_string_constant)
        out << format_constant(op.op0().op0());
    }
    break;

  case 'd':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), int_type()));
    break;

  case 'D':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), long_int_type()));
    break;

  case 'u':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), uint_type()));
    break;

  case 'U':
    if(next_operand==operands.end()) break;
    out << format_constant(
      make_type(*(next_operand++), long_uint_type()));
    break;

  default:
    out << '%' << ch;
  }
}
Пример #12
0
 static void
 call(Iterator const& first, Iterator const& last, unsigned int& attr)
 {
     Iterator first_ = first;
     qi::parse(first_, last, uint_type(), attr);
 }