void java_internal_additions(symbol_tablet &dest)
{
  // add __CPROVER_rounding_mode

  {
    symbolt symbol;
    symbol.base_name="__CPROVER_rounding_mode";
    symbol.name=CPROVER_PREFIX "rounding_mode";
    symbol.type=signed_int_type();
    symbol.mode=ID_C;
    symbol.is_lvalue=true;
    symbol.is_state_var=true;
    symbol.is_thread_local=true;
    dest.add(symbol);
  }

  // add __CPROVER_malloc_object

  {
    symbolt symbol;
    symbol.base_name="__CPROVER_malloc_object";
    symbol.name=CPROVER_PREFIX "malloc_object";
    symbol.type=pointer_type(empty_typet());
    symbol.mode=ID_C;
    symbol.is_lvalue=true;
    symbol.is_state_var=true;
    symbol.is_thread_local=true;
    dest.add(symbol);
  }
}
Beispiel #2
0
void java_record_outputs(
  const symbolt &function,
  const exprt::operandst &main_arguments,
  code_blockt &init_code,
  symbol_tablet &symbol_table)
{
  const code_typet::parameterst &parameters=
    to_code_type(function.type).parameters();

  exprt::operandst result;
  result.reserve(parameters.size()+1);

  bool has_return_value=
    to_code_type(function.type).return_type()!=empty_typet();

  if(has_return_value)
  {
    // record return value
    codet output(ID_output);
    output.operands().resize(2);

    const symbolt &return_symbol=symbol_table.lookup("return'");

    output.op0()=
      address_of_exprt(
        index_exprt(
          string_constantt(return_symbol.base_name),
          from_integer(0, index_type())));
    output.op1()=return_symbol.symbol_expr();
    output.add_source_location()=function.location;

    init_code.move_to_operands(output);
  }

  for(std::size_t param_number=0;
      param_number<parameters.size();
      param_number++)
  {
    const symbolt &p_symbol=
      symbol_table.lookup(parameters[param_number].get_identifier());

    if(p_symbol.type.id()==ID_pointer)
    {
      // record as an output
      codet output(ID_output);
      output.operands().resize(2);
      output.op0()=
        address_of_exprt(
          index_exprt(
            string_constantt(p_symbol.base_name),
            from_integer(0, index_type())));
      output.op1()=main_arguments[param_number];
      output.add_source_location()=function.location;

      init_code.move_to_operands(output);
    }
  }
}
Beispiel #3
0
/// Remove the body of function "identifier" such that an analysis will treat it
/// as a side-effect free function with non-deterministic return value.
/// \par parameters: symbol_table  Input symbol table to be modified
/// goto_functions  Input functions to be modified
/// identifier  Function to be removed
/// message_handler  Error/status output
void remove_function(
  symbol_tablet &symbol_table,
  goto_functionst &goto_functions,
  const irep_idt &identifier,
  message_handlert &message_handler)
{
  messaget message(message_handler);

  goto_functionst::function_mapt::iterator entry=
    goto_functions.function_map.find(identifier);

  if(entry==goto_functions.function_map.end())
  {
    message.error() << "No function " << identifier
                    << " in goto program" << messaget::eom;
    return;
  }
  else if(entry->second.is_inlined())
  {
    message.warning() << "Function " << identifier << " is inlined, "
                      << "instantiations will not be removed"
                      << messaget::eom;
  }

  if(entry->second.body_available())
  {
    message.status() << "Removing body of " << identifier
                     << messaget::eom;
    entry->second.clear();
    symbol_table.lookup(identifier).value.make_nil();
  }
}
Beispiel #4
0
goto_programt::targett cegis_assign_user_variable(const symbol_tablet &st,
    goto_functionst &gf, const goto_programt::targett &insert_after_pos,
    const irep_idt &name, const exprt &value)
{
  const symbol_exprt lhs(st.lookup(name).symbol_expr());
  return cegis_assign(st, gf, insert_after_pos, lhs, value);
}
Beispiel #5
0
void add_failed_symbol(symbolt &symbol, symbol_tablet &symbol_table)
{
  if(!symbol.is_lvalue) return;
  
  if(symbol.type.get(ID_C_failed_symbol)!="")
    return;

  if(symbol.type.id()==ID_pointer)
  {
    symbolt new_symbol;
    new_symbol.is_lvalue=true;
    new_symbol.module=symbol.module;
    new_symbol.mode=symbol.mode;
    new_symbol.base_name=failed_symbol_id(symbol.base_name);
    new_symbol.name=failed_symbol_id(symbol.name);
    new_symbol.type=symbol.type.subtype();
    new_symbol.value.make_nil();
    new_symbol.type.set(ID_C_is_failed_symbol, true);
    
    symbol.type.set(ID_C_failed_symbol, new_symbol.name);
    
    if(new_symbol.type.id()==ID_pointer)
      add_failed_symbol(new_symbol, symbol_table); // recursive call
        
    symbol_table.move(new_symbol);
  }
}
Beispiel #6
0
static void create_initialize(symbol_tablet &symbol_table)
{
  symbolt initialize;
  initialize.name=INITIALIZE;
  initialize.base_name=INITIALIZE;
  initialize.mode=ID_java;

  code_typet type;
  type.return_type()=empty_typet();
  initialize.type=type;

  code_blockt init_code;

  namespacet ns(symbol_table);

  symbol_exprt rounding_mode=
    ns.lookup(CPROVER_PREFIX "rounding_mode").symbol_expr();

  init_code.add(
    code_assignt(rounding_mode, from_integer(0, rounding_mode.type())));

  initialize.value=init_code;

  if(symbol_table.add(initialize))
    throw "failed to add "+std::string(INITIALIZE);
}
std::string get_prog_var_name(const symbol_tablet &st,
    const goto_programt::targett &decl)
{
  const irep_idt &base_id=st.lookup(get_affected_variable(*decl)).base_name;
  std::string base_name(id2string(base_id));
  return base_name+=PROG_SUFFIX;
}
Beispiel #8
0
dereference_exprt cegis_operand(const symbol_tablet &st,
    const std::string &func_name, const typet &type, const size_t op)
{
  const member_exprt operand_id(cegis_operand_id(st, func_name, op));
  const std::string array_name(cegis_operand_array_name(st, type));
  const symbol_exprt array(st.lookup(array_name).symbol_expr());
  return dereference_exprt(index_exprt(array, operand_id), type);
}
goto_programt::targett assign_jsa_meta_variable(const symbol_tablet &st,
    goto_functionst &gf, const goto_programt::targett &pos,
    const std::string &base_name, const exprt &expr_value)
{
  const std::string name(get_cegis_meta_name(base_name));
  const symbol_exprt lhs(st.lookup(name).symbol_expr());
  return jsa_assign(st, gf, pos, lhs, expr_value);
}
Beispiel #10
0
code_function_callt function_to_call(
  symbol_tablet &symbol_table,
  const irep_idt &id,
  const irep_idt &argument)
{
  // already there?

  symbol_tablet::symbolst::const_iterator s_it=
    symbol_table.symbols.find(id);

  if(s_it==symbol_table.symbols.end())
  {
    // not there
    pointer_typet p(char_type());
    p.subtype().set(ID_C_constant, true);

    code_typet function_type;
    function_type.return_type()=empty_typet();
    function_type.parameters().push_back(
      code_typet::parametert(p));

    symbolt new_symbol;
    new_symbol.name=id;
    new_symbol.base_name=id;
    new_symbol.type=function_type;

    symbol_table.move(new_symbol);

    s_it=symbol_table.symbols.find(id);
    assert(s_it!=symbol_table.symbols.end());
  }

  // signature is expected to be
  // (type *) -> ...
  if(s_it->second.type.id()!=ID_code ||
     to_code_type(s_it->second.type).parameters().size()!=1 ||
     to_code_type(s_it->second.type).parameters()[0].type().id()!=ID_pointer)
  {
    std::string error="function `"+id2string(id)+"' has wrong signature";
    throw error;
  }

  string_constantt function_id_string(argument);

  code_function_callt call;
  call.lhs().make_nil();
  call.function()=
    symbol_exprt(s_it->second.name, s_it->second.type);
  call.arguments().resize(1);
  call.arguments()[0]=
    typecast_exprt(
      address_of_exprt(
        index_exprt(
          function_id_string, from_integer(0, index_type()))),
      to_code_type(s_it->second.type).parameters()[0].type());

  return call;
}
void execute_inv_prog(const symbol_tablet &st, goto_functionst &gf,
    const size_t max_solution_size, const goto_programt::targett &decl,
    const std::string &prog_base_name)
{
  goto_programt &body=get_entry_body(gf);
  goto_programt::targett pos=decl;
  goto_programt::targett execution=body.insert_after(++pos);
  execution->type=goto_program_instruction_typet::FUNCTION_CALL;
  execution->source_location=default_cegis_source_location();
  code_function_callt call;
  call.function()=st.lookup(DANGER_EXECUTE).symbol_expr();
  const std::string prog_name(get_cegis_meta_name(prog_base_name));
  const symbol_exprt prog_symbol(st.lookup(prog_name).symbol_expr());
  const typet size_type(unsigned_int_type());
  const constant_exprt index(from_integer(0u, size_type));
  const index_exprt first_elem(prog_symbol, index);
  call.arguments().push_back(address_of_exprt(first_elem));
  const constant_exprt size(from_integer(max_solution_size, size_type));
  call.arguments().push_back(size);
  execution->code=call;
}
Beispiel #12
0
goto_programt::targett cegis_assign_local_variable(const symbol_tablet &st,
    goto_programt &body, const goto_programt::targett &insert_after_pos,
    const std::string &func_name, const std::string &var_name,
    const exprt &value)
{
  std::string name(func_name);
  name+=NS_SEP;
  name+=var_name;
  const symbol_exprt lhs(st.lookup(name).symbol_expr());
  const source_locationt loc(default_cegis_source_location());
  return cegis_assign(st, body, insert_after_pos, lhs, value, loc);
}
void propagate_controller_sizes(const symbol_tablet &st, goto_functionst &gf)
{
  const symbolt &symbol=st.lookup(CEGIS_CONTROL_SOLUTION_VAR_NAME);
  const struct_exprt &controller_value=to_struct_expr(symbol.value);
  const namespacet ns(st);
  const exprt &a_size=get_a_size(ns, controller_value);
  const exprt &b_size=get_b_size(ns, controller_value);
  replace_sizes_visitort visitor(a_size, b_size);
  goto_programt &body=get_entry_body(gf);
  for (goto_programt::instructiont &instr : body.instructions)
  {
    instr.code.visit(visitor);
    instr.guard.visit(visitor);
  }
}
bool java_static_lifetime_init(
  symbol_tablet &symbol_table,
  const source_locationt &source_location,
  message_handlert &message_handler)
{
  symbolt &initialize_symbol=symbol_table.lookup(INITIALIZE);
  code_blockt &code_block=to_code_block(to_code(initialize_symbol.value));
  
  // we need to zero out all static variables
  
  for(symbol_tablet::symbolst::const_iterator
      it=symbol_table.symbols.begin();
      it!=symbol_table.symbols.end();
      it++)
  {
    if(it->second.type.id()!=ID_code &&
       it->second.is_lvalue &&
       it->second.is_state_var &&
       it->second.is_static_lifetime &&
       it->second.value.is_not_nil() &&
       it->second.mode==ID_java)
    {
      code_assignt assignment(it->second.symbol_expr(), it->second.value);
      code_block.add(assignment);
    }
  }
  
  // we now need to run all the <clinit> methods

  for(symbol_tablet::symbolst::const_iterator
      it=symbol_table.symbols.begin();
      it!=symbol_table.symbols.end();
      it++)
  {
    if(it->second.base_name=="<clinit>" &&
       it->second.type.id()==ID_code &&
       it->second.mode==ID_java)
    {
      code_function_callt function_call;
      function_call.lhs()=nil_exprt();
      function_call.function()=it->second.symbol_expr();
      code_block.add(function_call);
    }
  }
  
  return false;
}
Beispiel #15
0
symbol_exprt add_stack_depth_symbol(symbol_tablet &symbol_table)
{
  const irep_idt identifier="$stack_depth";
  signedbv_typet type(sizeof(int)*8);

  symbolt new_symbol;
  new_symbol.name=identifier;
  new_symbol.base_name=identifier;
  new_symbol.pretty_name=identifier;
  new_symbol.type=type;
  new_symbol.is_static_lifetime=true;
  new_symbol.value=from_integer(0, type);
  new_symbol.mode=ID_C;
  new_symbol.is_thread_local=true;
  new_symbol.is_lvalue=true;

  symbol_table.move(new_symbol);

  return symbol_exprt(identifier, type);
}
bool java_bytecode_languaget::typecheck(
  symbol_tablet &symbol_table,
  const std::string &module)
{
  symbol_tablet new_symbol_table;

  if(java_bytecode_convert(
       parse_tree, new_symbol_table, module, get_message_handler()))
    return true;
  
  if(java_bytecode_typecheck(
       new_symbol_table, module, get_message_handler()))
    return true;

  symbol_table.swap(new_symbol_table);

//  if(linking(new_symbol_table, symbol_table, message_handler))
//    return true;
    
  return false;
}
Beispiel #17
0
bool read_goto_object(
  std::istream &in,
  const std::string &filename,
  symbol_tablet &symbol_table,
  goto_functionst &functions,
  message_handlert &message_handler)
{
  messaget message(message_handler);

  xml_parser.clear();
  xml_parser.filename = filename;
  xml_parser.in = &in;
  xml_parser.set_message_handler(message_handler);

  if (xml_parser.parse())
    return true;

  xmlt &top = xml_parser.parse_tree.element;

  if (top.get_attribute("version")!=XML_VERSION)
  {
    message.error() <<
      "The input was compiled with a different version of "
      "goto-cc, please recompile." << messaget::eom;
    return true;
  }

  xml_irep_convertt::ireps_containert ic;
  xml_irep_convertt irepconverter(ic);
  xml_symbol_convertt symbolconverter(ic);
  xml_goto_function_convertt gfconverter(ic);

  if(top.name.substr(0, 11)=="goto-object")
  {
    for(xmlt::elementst::const_iterator
        sec_it=top.elements.begin();
        sec_it != top.elements.end();
        sec_it++)
    {
      xmlt sec = *sec_it;
      if (sec.name=="irep_hash_map")
      {
        for(xmlt::elementst::const_iterator
            irep_it = sec.elements.begin();
            irep_it != sec.elements.end();
            irep_it++)
        {
          irept i;
          irepconverter.convert(*irep_it, i);
          irepconverter.insert(irep_it->get_attribute("id"), i);
        }
      }
      else if (sec.name=="symbols")
      {
        for(xmlt::elementst::const_iterator
            sym_it = sec.elements.begin();
            sym_it != sec.elements.end();
            sym_it++)
        {
          symbolt symbol;
          symbolconverter.convert(*sym_it, symbol);
          // std::cout << "Adding Symbol: " << symbol.name << std::endl;
          if(!symbol.is_type &&
             symbol.type.id()=="code")
          {
            // makes sure there is an empty function
            // for this symbol. if we got code for it,
            // it will be added lateron.
            functions.function_map[symbol.name].type=
              to_code_type(symbol.type);
          }
          symbol_table.add(symbol);
        }
      }
      else if (sec.name=="functions")
      {
        for(xmlt::elementst::const_iterator
            fun_it = sec.elements.begin();
            fun_it != sec.elements.end();
            fun_it++)
        {
          std::string fname = fun_it->get_attribute("name");
          //std::cout << "Adding function body: " << fname << std::endl;
          goto_functionst::goto_functiont &f = functions.function_map[fname];
          gfconverter.convert(*fun_it, f);
        }
      }
      else
      {
        message.error() << "Unknown Section '" << sec.name
                        << "' in object file." << messaget::eom;
        return true;
      }

    }
  }
  else
  {
    message.error() << "no goto-object" << messaget::eom;
    return true;
  }

  xml_parser.clear();
  return false;
}
bool java_entry_point(
  symbol_tablet &symbol_table,
  const irep_idt &main_class,
  message_handlert &message_handler)
{
  // check if the entry point is already there
  if(symbol_table.symbols.find(goto_functionst::entry_point())!=
     symbol_table.symbols.end())
    return false; // silently ignore

  messaget message(message_handler);

  symbolt symbol; // main function symbol

  // find main symbol
  if(config.main!="")
  {
    // Add java:: prefix
    std::string main_identifier="java::"+config.main;
    
    symbol_tablet::symbolst::const_iterator s_it;
    
    // Does it have a type signature? (':' suffix)
    if(config.main.rfind(':')==std::string::npos)
    {
      std::string prefix=main_identifier+':';
      std::set<irep_idt> matches;
      
      for(const auto & s : symbol_table.symbols)
        if(has_prefix(id2string(s.first), prefix) &&
           s.second.type.id()==ID_code)
          matches.insert(s.first);

      if(matches.empty())
      {
        message.error() << "main symbol `" << config.main
                        << "' not found" << messaget::eom;
        return true;
      }
      else if(matches.size()==1)
      {
        s_it=symbol_table.symbols.find(*matches.begin());
        assert(s_it!=symbol_table.symbols.end());
      }
      else
      {
        message.error() << "main symbol `" << config.main
                        << "' is ambiguous:\n";

        for(const auto & s : matches)
          message.error() << "  " << s << '\n';
        
        message.error() << messaget::eom;

        return true;
      }
    }
    else
    {
      // just look it up
      s_it=symbol_table.symbols.find(main_identifier);

      if(s_it==symbol_table.symbols.end())
      {
        message.error() << "main symbol `" << config.main
                        << "' not found" << messaget::eom;
        return true;
      }
    }

    // function symbol
    symbol=s_it->second;

    if(symbol.type.id()!=ID_code)
    {
      message.error() << "main symbol `" << config.main
                      << "' not a function" << messaget::eom;
      return true;
    }
    
    // check if it has a body
    if(symbol.value.is_nil())
    {
      message.error() << "main method `" << main_class
                      << "' has no body" << messaget::eom;
      return true;
    }
  }
  else
  {
    // no function given, we look for the main class
    assert(config.main=="");

    // are we given a main class?
    if(main_class.empty())
      return false; // silently ignore

    std::string entry_method=
      id2string(main_class)+".main";

    std::string prefix="java::"+entry_method+":";

    // look it up
    std::set<irep_idt> matches;

    for(symbol_tablet::symbolst::const_iterator
        s_it=symbol_table.symbols.begin();
        s_it!=symbol_table.symbols.end();
        s_it++)
    {
      if(s_it->second.type.id()==ID_code &&
         has_prefix(id2string(s_it->first), prefix))
        matches.insert(s_it->first);
    }

    if(matches.empty())
    {
      // Not found, silently ignore
      return false;
    }

    if(matches.size()>=2)
    {
      message.error() << "main method in `" << main_class
                      << "' is ambiguous" << messaget::eom;
      return true; // give up with error, no main
    }

    // function symbol
    symbol=symbol_table.symbols.find(*matches.begin())->second;
  
    // check if it has a body
    if(symbol.value.is_nil())
    {
      message.error() << "main method `" << main_class
                      << "' has no body" << messaget::eom;
      return true; // give up with error
    }
  }

  assert(!symbol.value.is_nil());
  assert(symbol.type.id()==ID_code);

  const code_typet &code_type=to_code_type(symbol.type);
    
  create_initialize(symbol_table);

  if(java_static_lifetime_init(symbol_table, symbol.location, message_handler))
    return true;

  code_blockt init_code;

  // build call to initialization function
  {
    symbol_tablet::symbolst::iterator init_it=
      symbol_table.symbols.find(INITIALIZE);

    if(init_it==symbol_table.symbols.end())
    {
      message.error() << "failed to find " INITIALIZE " symbol"
                      << messaget::eom;
      return true; // give up with error
    }

    code_function_callt call_init;
    call_init.lhs().make_nil();
    call_init.add_source_location()=symbol.location;
    call_init.function()=init_it->second.symbol_expr();

    init_code.move_to_operands(call_init);
  }

  // build call to the main method

  code_function_callt call_main;
  call_main.add_source_location()=symbol.location;
  call_main.function()=symbol.symbol_expr();

  const code_typet::parameterst &parameters=
    code_type.parameters();

  exprt::operandst main_arguments;
  main_arguments.resize(parameters.size());
  
  for(std::size_t param_number=0;
      param_number<parameters.size();
      param_number++)
  {
    bool is_this=param_number==0 &&
                 parameters[param_number].get_this();
    bool allow_null=config.main!="" && !is_this;
    
    main_arguments[param_number]=
      object_factory(parameters[param_number].type(), 
                     init_code, allow_null, symbol_table);
  }

  call_main.arguments()=main_arguments;

  init_code.move_to_operands(call_main);

  // add "main"
  symbolt new_symbol;

  code_typet main_type;
  main_type.return_type()=empty_typet();

  new_symbol.name=goto_functionst::entry_point();
  new_symbol.type.swap(main_type);
  new_symbol.value.swap(init_code);
  new_symbol.mode=ID_java;

  if(symbol_table.move(new_symbol))
  {
    message.error() << "failed to move main symbol" << messaget::eom;
    return true;
  }

  return false;
}
Beispiel #19
0
size_t get_size(const symbol_tablet &st, const char * const id)
{
  return to_size(to_array_type(st.lookup(id).type).size());
}
Beispiel #20
0
exprt::operandst java_build_arguments(
  const symbolt &function,
  code_blockt &init_code,
  symbol_tablet &symbol_table,
  bool assume_init_pointers_not_null,
  unsigned max_nondet_array_length,
  message_handlert &message_handler)
{
  const code_typet::parameterst &parameters=
    to_code_type(function.type).parameters();

  exprt::operandst main_arguments;
  main_arguments.resize(parameters.size());

  for(std::size_t param_number=0;
      param_number<parameters.size();
      param_number++)
  {
    bool is_this=(param_number==0) &&
                 parameters[param_number].get_this();
    bool is_default_entry_point(config.main.empty());
    bool is_main=is_default_entry_point;
    if(!is_main)
    {
      bool named_main=has_suffix(config.main, ".main");
      const typet &string_array_type=
        java_type_from_string("[Ljava.lang.String;");
      bool has_correct_type=
        to_code_type(function.type).return_type().id()==ID_empty &&
        (!to_code_type(function.type).has_this()) &&
        parameters.size()==1 &&
        parameters[0].type().full_eq(string_array_type);
      is_main=(named_main && has_correct_type);
    }

    bool allow_null=(!is_main) && (!is_this) && !assume_init_pointers_not_null;

    main_arguments[param_number]=
      object_factory(
        parameters[param_number].type(),
        init_code,
        allow_null,
        symbol_table,
        max_nondet_array_length,
        function.location,
        message_handler);

    const symbolt &p_symbol=
      symbol_table.lookup(parameters[param_number].get_identifier());

    // record as an input
    codet input(ID_input);
    input.operands().resize(2);
    input.op0()=
      address_of_exprt(
        index_exprt(
          string_constantt(p_symbol.base_name),
          from_integer(0, index_type())));
    input.op1()=main_arguments[param_number];
    input.add_source_location()=function.location;

    init_code.move_to_operands(input);
  }

  return main_arguments;
}
bool read_bin_goto_object_v3(
  std::istream &in,
  const std::string &filename,
  symbol_tablet &symbol_table,
  goto_functionst &functions,
  message_handlert &message_handler,
  irep_serializationt &irepconverter)
{
  std::size_t count = irepconverter.read_gb_word(in); // # of symbols

  for(std::size_t i=0; i<count; i++)
  {
    symbolt sym;

    irepconverter.reference_convert(in, sym.type);
    irepconverter.reference_convert(in, sym.value);
    irepconverter.reference_convert(in, sym.location);

    sym.name = irepconverter.read_string_ref(in);
    sym.module = irepconverter.read_string_ref(in);
    sym.base_name = irepconverter.read_string_ref(in);
    sym.mode = irepconverter.read_string_ref(in);
    sym.pretty_name = irepconverter.read_string_ref(in);

    // obsolete: symordering
    irepconverter.read_gb_word(in);

    std::size_t flags=irepconverter.read_gb_word(in);

    sym.is_weak = (flags &(1 << 16))!=0;
    sym.is_type = (flags &(1 << 15))!=0;
    sym.is_property = (flags &(1 << 14))!=0;
    sym.is_macro = (flags &(1 << 13))!=0;
    sym.is_exported = (flags &(1 << 12))!=0;
    sym.is_input = (flags &(1 << 11))!=0;
    sym.is_output = (flags &(1 << 10))!=0;
    sym.is_state_var = (flags &(1 << 9))!=0;
    sym.is_parameter = (flags &(1 << 8))!=0;
    sym.is_auxiliary = (flags &(1 << 7))!=0;
    // sym.binding = (flags &(1 << 6))!=0;
    sym.is_lvalue = (flags &(1 << 5))!=0;
    sym.is_static_lifetime = (flags &(1 << 4))!=0;
    sym.is_thread_local = (flags &(1 << 3))!=0;
    sym.is_file_local = (flags &(1 << 2))!=0;
    sym.is_extern = (flags &(1 << 1))!=0;
    sym.is_volatile = (flags &1)!=0;

    if(!sym.is_type && sym.type.id()==ID_code)
    {
      // makes sure there is an empty function
      // for every function symbol and fixes
      // the function types.
      functions.function_map[sym.name].type=to_code_type(sym.type);
    }

    symbol_table.add(sym);
  }

  count=irepconverter.read_gb_word(in); // # of functions

  for(std::size_t i=0; i<count; i++)
  {
    irep_idt fname=irepconverter.read_gb_string(in);
    goto_functionst::goto_functiont &f = functions.function_map[fname];

    typedef std::map<goto_programt::targett, std::list<unsigned> > target_mapt;
    target_mapt target_map;
    typedef std::map<unsigned, goto_programt::targett> rev_target_mapt;
    rev_target_mapt rev_target_map;

    bool hidden=false;

    std::size_t ins_count = irepconverter.read_gb_word(in); // # of instructions
    for(std::size_t i=0; i<ins_count; i++)
    {
      goto_programt::targett itarget = f.body.add_instruction();
      goto_programt::instructiont &instruction=*itarget;

      irepconverter.reference_convert(in, instruction.code);
      instruction.function = irepconverter.read_string_ref(in);
      irepconverter.reference_convert(in, instruction.source_location);
      instruction.type = (goto_program_instruction_typet)
                              irepconverter.read_gb_word(in);
      instruction.guard.make_nil();
      irepconverter.reference_convert(in, instruction.guard);
      irepconverter.read_string_ref(in); // former event
      instruction.target_number = irepconverter.read_gb_word(in);
      if(instruction.is_target() &&
         rev_target_map.insert(
           rev_target_map.end(),
           std::make_pair(instruction.target_number, itarget))->second!=itarget)
        assert(false);

      std::size_t t_count = irepconverter.read_gb_word(in); // # of targets
      for(std::size_t i=0; i<t_count; i++)
        // just save the target numbers
        target_map[itarget].push_back(irepconverter.read_gb_word(in));

      std::size_t l_count = irepconverter.read_gb_word(in); // # of labels

      for(std::size_t i=0; i<l_count; i++)
      {
        irep_idt label=irepconverter.read_string_ref(in);
        instruction.labels.push_back(label);
        if(label=="__CPROVER_HIDE")
          hidden=true;
        // The above info is normally in the type of the goto_functiont object,
        // which should likely be stored in the binary.
      }
    }

    // Resolve targets
    for(target_mapt::iterator tit = target_map.begin();
        tit!=target_map.end();
        tit++)
    {
      goto_programt::targett ins = tit->first;

      for(std::list<unsigned>::iterator nit = tit->second.begin();
          nit!=tit->second.end();
          nit++)
      {
        unsigned n=*nit;
        rev_target_mapt::const_iterator entry=rev_target_map.find(n);
        assert(entry!=rev_target_map.end());
        ins->targets.push_back(entry->second);
      }
    }

    f.body.update();

    if(hidden)
      f.make_hidden();
  }

  functions.compute_location_numbers();

  return false;
}
Beispiel #22
0
bool java_entry_point(
  symbol_tablet &symbol_table,
  const irep_idt &main_class,
  message_handlert &message_handler,
  bool assume_init_pointers_not_null,
  size_t max_nondet_array_length)
{
  // check if the entry point is already there
  if(symbol_table.symbols.find(goto_functionst::entry_point())!=
     symbol_table.symbols.end())
    return false; // silently ignore

  messaget message(message_handler);
  main_function_resultt res=
    get_main_symbol(symbol_table, main_class, message_handler);
  if(res.stop_convert)
    return res.stop_convert;
  symbolt symbol=res.main_function;

  assert(!symbol.value.is_nil());
  assert(symbol.type.id()==ID_code);

  create_initialize(symbol_table);

  if(java_static_lifetime_init(
       symbol_table,
       symbol.location,
       message_handler,
       assume_init_pointers_not_null,
       max_nondet_array_length))
    return true;

  code_blockt init_code;

  // build call to initialization function
  {
    symbol_tablet::symbolst::iterator init_it=
      symbol_table.symbols.find(INITIALIZE);

    if(init_it==symbol_table.symbols.end())
    {
      message.error() << "failed to find " INITIALIZE " symbol"
                      << messaget::eom;
      return true; // give up with error
    }

    code_function_callt call_init;
    call_init.lhs().make_nil();
    call_init.add_source_location()=symbol.location;
    call_init.function()=init_it->second.symbol_expr();

    init_code.move_to_operands(call_init);
  }

  // build call to the main method

  code_function_callt call_main;

  source_locationt loc=symbol.location;
  loc.set_function(symbol.name);
  source_locationt &dloc=loc;

  call_main.add_source_location()=dloc;
  call_main.function()=symbol.symbol_expr();
  call_main.function().add_source_location()=dloc;

  if(to_code_type(symbol.type).return_type()!=empty_typet())
  {
    auxiliary_symbolt return_symbol;
    return_symbol.mode=ID_C;
    return_symbol.is_static_lifetime=false;
    return_symbol.name="return'";
    return_symbol.base_name="return";
    return_symbol.type=to_code_type(symbol.type).return_type();

    symbol_table.add(return_symbol);
    call_main.lhs()=return_symbol.symbol_expr();
  }

  exprt::operandst main_arguments=
    java_build_arguments(
      symbol,
      init_code,
      symbol_table,
      assume_init_pointers_not_null,
      max_nondet_array_length,
      message_handler);
  call_main.arguments()=main_arguments;

  init_code.move_to_operands(call_main);

  java_record_outputs(symbol, main_arguments, init_code, symbol_table);

  // add "main"
  symbolt new_symbol;

  code_typet main_type;
  main_type.return_type()=empty_typet();

  new_symbol.name=goto_functionst::entry_point();
  new_symbol.type.swap(main_type);
  new_symbol.value.swap(init_code);
  new_symbol.mode=ID_java;

  if(symbol_table.move(new_symbol))
  {
    message.error() << "failed to move main symbol" << messaget::eom;
    return true;
  }

  return false;
}
Beispiel #23
0
bool java_static_lifetime_init(
  symbol_tablet &symbol_table,
  const source_locationt &source_location,
  message_handlert &message_handler,
  bool assume_init_pointers_not_null,
  unsigned max_nondet_array_length)
{
  symbolt &initialize_symbol=symbol_table.lookup(INITIALIZE);
  code_blockt &code_block=to_code_block(to_code(initialize_symbol.value));

  // We need to zero out all static variables, or nondet-initialize if they're
  // external. Iterate over a copy of the symtab, as its iterators are
  // invalidated by object_factory:

  std::list<irep_idt> symbol_names;
  for(const auto &entry : symbol_table.symbols)
    symbol_names.push_back(entry.first);

  for(const auto &symname : symbol_names)
  {
    const symbolt &sym=symbol_table.lookup(symname);
    if(should_init_symbol(sym))
    {
      if(sym.value.is_nil() && sym.type!=empty_typet())
      {
        bool allow_null=!assume_init_pointers_not_null;
        if(allow_null)
        {
          std::string namestr=id2string(sym.symbol_expr().get_identifier());
          const std::string suffix="@class_model";
          // Static '.class' fields are always non-null.
          if(has_suffix(namestr, suffix))
            allow_null=false;
          if(allow_null && has_prefix(
               namestr,
               "java::java.lang.String.Literal"))
            allow_null=false;
        }
        auto newsym=object_factory(
          sym.type,
          code_block,
          allow_null,
          symbol_table,
          max_nondet_array_length,
          source_location,
          message_handler);
        code_assignt assignment(sym.symbol_expr(), newsym);
        code_block.add(assignment);
      }
      else if(sym.value.is_not_nil())
      {
        code_assignt assignment(sym.symbol_expr(), sym.value);
        assignment.add_source_location()=source_location;
        code_block.add(assignment);
      }
    }
  }

  // we now need to run all the <clinit> methods

  for(symbol_tablet::symbolst::const_iterator
      it=symbol_table.symbols.begin();
      it!=symbol_table.symbols.end();
      it++)
  {
    if(it->second.base_name=="<clinit>" &&
       it->second.type.id()==ID_code &&
       it->second.mode==ID_java)
    {
      code_function_callt function_call;
      function_call.lhs()=nil_exprt();
      function_call.function()=it->second.symbol_expr();
      function_call.add_source_location()=source_location;
      code_block.add(function_call);
    }
  }

  return false;
}