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); } }
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); }
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; }
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; }
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 = ∈ 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; }