Ejemplo n.º 1
0
void goto_symext::symex_free(const expr2tc &expr)
{
  const code_free2t &code = to_code_free2t(expr);

  // Trigger 'free'-mode dereference of this pointer. Should generate various
  // dereference failure callbacks.
  expr2tc tmp = code.operand;
  dereference(tmp, dereferencet::FREE);

  // Don't rely on the output of dereference in free mode; instead fetch all
  // the internal dereference state for pointed at objects, and creates claims
  // that if pointed at, their offset is zero.
  internal_deref_items.clear();
  tmp = code.operand;

  // Create temporary, dummy, dereference
  tmp = dereference2tc(get_uint8_type(), tmp);
  dereference(tmp, dereferencet::INTERNAL);

  // Only add assertions to check pointer offset if pointer check is enabled
  if(!options.get_bool_option("no-pointer-check"))
  {
    for(auto const &item : internal_deref_items)
    {
      guardt g = cur_state->guard;
      g.add(item.guard);
      expr2tc offset = item.offset;
      expr2tc eq = equality2tc(offset, gen_ulong(0));
      g.guard_expr(eq);
      claim(eq, "Operand of free must have zero pointer offset");
    }
  }

  // Clear the alloc bit, and set the deallocated bit.
  type2tc sym_type =
    type2tc(new array_type2t(get_bool_type(), expr2tc(), true));
  expr2tc ptr_obj = pointer_object2tc(pointer_type2(), code.operand);
  dereference(ptr_obj, dereferencet::READ);

  symbol2tc dealloc_sym(sym_type, deallocd_arr_name);
  index2tc dealloc_index_expr(get_bool_type(), dealloc_sym, ptr_obj);
  expr2tc truth = gen_true_expr();
  symex_assign(code_assign2tc(dealloc_index_expr, truth), true);

  symbol2tc valid_sym(sym_type, valid_ptr_arr_name);
  index2tc valid_index_expr(get_bool_type(), valid_sym, ptr_obj);
  expr2tc falsity = gen_false_expr();
  symex_assign(code_assign2tc(valid_index_expr, falsity), true);
}
Ejemplo n.º 2
0
void goto_symext::symex_free(const expr2tc &expr)
{
  const code_free2t &code = to_code_free2t(expr);

  // Trigger 'free'-mode dereference of this pointer. Should generate various
  // dereference failure callbacks.
  expr2tc tmp = code.operand;
  dereference(tmp, false, true);

  // Don't rely on the output of dereference in free mode; instead fetch all
  // the internal dereference state for pointed at objects, and creates claims
  // that if pointed at, their offset is zero.
  internal_deref_items.clear();
  tmp = code.operand;
  // Create temporary, dummy, dereference
  tmp = dereference2tc(get_uint8_type(), tmp);
  dereference(tmp, false, false, true); // 'internal' dereference
  for (const auto &item : internal_deref_items) {
    guardt g = cur_state->guard;
    g.add(item.guard);
    expr2tc offset = item.offset;
    expr2tc eq = equality2tc(offset, zero_ulong);
    g.guard_expr(eq);
    claim(eq, "Operand of free must have zero pointer offset");
  }

  // Clear the alloc bit, and set the deallocated bit.
  guardt guard;
  type2tc sym_type = type2tc(new array_type2t(get_bool_type(),
                                              expr2tc(), true));
  pointer_object2tc ptr_obj(pointer_type2(), code.operand);

  symbol2tc dealloc_sym(sym_type, deallocd_arr_name);
  index2tc dealloc_index_expr(get_bool_type(), dealloc_sym, ptr_obj);
  expr2tc truth = true_expr;
  symex_assign_rec(dealloc_index_expr, truth, guard);

  symbol2tc valid_sym(sym_type, valid_ptr_arr_name);
  index2tc valid_index_expr(get_bool_type(), valid_sym, ptr_obj);
  expr2tc falsity = false_expr;
  symex_assign_rec(valid_index_expr, falsity, guard);
}
Ejemplo n.º 3
0
smt_astt 
smt_convt::convert_byte_extract(const expr2tc &expr)
{
  const byte_extract2t &data = to_byte_extract2t(expr);

  assert(is_scalar_type(data.source_value) && "Byte extract now only works on "
         "scalar variables");
  if (!is_constant_int2t(data.source_offset)) {
    expr2tc source = data.source_value;
    unsigned int src_width = source->type->get_width();
    if (!is_bv_type(source)) {
      source = typecast2tc(get_uint_type(src_width), source);
    }

    // The approach: the argument is now a bitvector. Just shift it the
    // appropriate amount, according to the source offset, and select out the
    // bottom byte.
    expr2tc offs = data.source_offset;

    // Endian-ness: if we're in non-"native" endian-ness mode, then flip the
    // offset distance. The rest of these calculations will still apply.
    if (data.big_endian) {
      auto data_size = type_byte_size(*source->type);
      constant_int2tc data_size_expr(source->type, data_size - 1);
      sub2tc sub(source->type, data_size_expr, offs);
      offs = sub;
    }

    if (offs->type->get_width() != src_width)
      // Z3 requires these two arguments to be the same width
      offs = typecast2tc(source->type, data.source_offset);

    lshr2tc shr(source->type, source, offs);
    smt_astt ext = convert_ast(shr);
    smt_astt res = mk_extract(ext, 7, 0, convert_sort(get_uint8_type()));
    return res;
  }

  const constant_int2t &intref = to_constant_int2t(data.source_offset);

  unsigned width;
  width = data.source_value->type->get_width();

  uint64_t upper, lower;
  if (!data.big_endian) {
    upper = ((intref.constant_value.to_long() + 1) * 8) - 1; //((i+1)*w)-1;
    lower = intref.constant_value.to_long() * 8; //i*w;
  } else {
    uint64_t max = width - 1;
    upper = max - (intref.constant_value.to_long() * 8); //max-(i*w);
    lower = max - ((intref.constant_value.to_long() + 1) * 8 - 1); //max-((i+1)*w-1);
  }

  smt_astt source = convert_ast(data.source_value);;

  if (int_encoding) {
    std::cerr << "Refusing to byte extract in integer mode; re-run in "
                 "bitvector mode" << std::endl;
    abort();
  } else {
    if (is_bv_type(data.source_value)) {
      ;
    } else if (is_fixedbv_type(data.source_value)) {
      ;
    } else if (is_bool_type(data.source_value)) {
      // We cdan extract a byte from a bool -- zero or one.
      typecast2tc cast(get_uint8_type(), data.source_value);
      source = convert_ast(cast);
    } else {
      std::cerr << "Unrecognized type in operand to byte extract." << std::endl;
      data.dump();
      abort();
    }

    unsigned int sort_sz = data.source_value->type->get_width();
    if (sort_sz <= upper) {
      smt_sortt s = mk_sort(SMT_SORT_BV, 8, false);
      return mk_smt_symbol("out_of_bounds_byte_extract", s);
    } else {
      return mk_extract(source, upper, lower, convert_sort(expr->type));
    }
  }
}