CBMC
initialize_goto_model.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Get a Goto Program
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "initialize_goto_model.h"
13 
14 #include <fstream>
15 
16 #include <util/config.h>
17 #include <util/message.h>
18 #include <util/options.h>
19 
20 #ifdef _MSC_VER
21 # include <util/unicode.h>
22 #endif
23 
24 #include <langapi/language.h>
25 #include <langapi/language_file.h>
26 #include <langapi/mode.h>
27 
29 #include <util/exception_utils.h>
30 
31 #include "goto_convert_functions.h"
32 #include "read_goto_binary.h"
33 
37  const optionst &options,
38  symbol_tablet &symbol_table,
39  message_handlert &message_handler)
40 {
41  const irep_idt &entry_function_name = options.get_option("function");
42  CHECK_RETURN(!entry_function_name.empty());
43  auto const entry_function_sym = symbol_table.lookup(entry_function_name);
44  if(entry_function_sym == nullptr)
45  {
47  // NOLINTNEXTLINE(whitespace/braces)
48  std::string{"couldn't find function with name '"} +
49  id2string(entry_function_name) + "' in symbol table",
50  "--function"};
51  }
52  PRECONDITION(!entry_function_sym->mode.empty());
53  auto const entry_language = get_language_from_mode(entry_function_sym->mode);
54  CHECK_RETURN(entry_language != nullptr);
55  entry_language->set_message_handler(message_handler);
56  entry_language->set_language_options(options);
57  return entry_language->generate_support_functions(symbol_table);
58 }
59 
61  const std::list<std::string> &sources,
62  const optionst &options,
63  language_filest &language_files,
64  symbol_tablet &symbol_table,
65  message_handlert &message_handler)
66 {
67  if(sources.empty())
68  return;
69 
70  messaget msg(message_handler);
71 
72  for(const auto &filename : sources)
73  {
74  #ifdef _MSC_VER
75  std::ifstream infile(widen(filename));
76  #else
77  std::ifstream infile(filename);
78  #endif
79 
80  if(!infile)
81  {
82  throw system_exceptiont(
83  "Failed to open input file '" + filename + '\'');
84  }
85 
86  language_filet &lf=language_files.add_file(filename);
88 
89  if(lf.language==nullptr)
90  {
92  "Failed to figure out type of file", filename};
93  }
94 
95  languaget &language=*lf.language;
96  language.set_message_handler(message_handler);
97  language.set_language_options(options);
98 
99  msg.status() << "Parsing " << filename << messaget::eom;
100 
101  if(language.parse(infile, filename))
102  {
103  throw invalid_input_exceptiont("PARSING ERROR");
104  }
105 
106  lf.get_modules();
107  }
108 
109  msg.status() << "Converting" << messaget::eom;
110 
111  if(language_files.typecheck(symbol_table))
112  {
113  throw invalid_input_exceptiont("CONVERSION ERROR");
114  }
115 }
116 
118  language_filest &language_files,
119  symbol_tablet &symbol_table,
120  const std::function<void(const irep_idt &)> &unload,
121  const optionst &options,
122  bool try_mode_lookup,
123  message_handlert &message_handler)
124 {
125  bool binaries_provided_start =
127 
128  bool entry_point_generation_failed=false;
129 
130  if(binaries_provided_start && options.is_set("function"))
131  {
132  // The goto binaries provided already contain a __CPROVER_start
133  // function that may be tied to a different entry point `function`.
134  // Hence, we will rebuild the __CPROVER_start function.
135 
136  // Get the language annotation of the existing __CPROVER_start function.
137  std::unique_ptr<languaget> language =
138  get_entry_point_language(symbol_table, options, message_handler);
139 
140  // To create a new entry point we must first remove the old one
141  remove_existing_entry_point(symbol_table);
142 
143  // Create the new entry-point
144  entry_point_generation_failed =
145  language->generate_support_functions(symbol_table);
146 
147  // Remove the function from the goto functions so it is copied back in
148  // from the symbol table during goto_convert
149  if(!entry_point_generation_failed)
151  }
152  else if(!binaries_provided_start)
153  {
154  if(try_mode_lookup && options.is_set("function"))
155  {
156  // no entry point is present; Use the mode of the specified entry function
157  // to generate one
158  entry_point_generation_failed = generate_entry_point_for_function(
159  options, symbol_table, message_handler);
160  }
161  if(
162  !try_mode_lookup || entry_point_generation_failed ||
163  !options.is_set("function"))
164  {
165  // Allow all language front-ends to try to provide the user-specified
166  // (--function) entry-point, or some language-specific default:
167  entry_point_generation_failed =
168  language_files.generate_support_functions(symbol_table);
169  }
170  }
171 
172  if(entry_point_generation_failed)
173  {
174  throw invalid_input_exceptiont("SUPPORT FUNCTION GENERATION ERROR");
175  }
176 }
177 
179  const std::vector<std::string> &files,
180  message_handlert &message_handler,
181  const optionst &options)
182 {
183  messaget msg(message_handler);
184  if(files.empty())
185  {
187  "missing program argument",
188  "filename",
189  "one or more paths to program files");
190  }
191 
192  std::list<std::string> binaries, sources;
193 
194  for(const auto &file : files)
195  {
196  if(is_goto_binary(file, message_handler))
197  binaries.push_back(file);
198  else
199  sources.push_back(file);
200  }
201 
202  language_filest language_files;
203  language_files.set_message_handler(message_handler);
204 
205  goto_modelt goto_model;
206 
208  sources, options, language_files, goto_model.symbol_table, message_handler);
209 
210  if(read_objects_and_link(binaries, goto_model, message_handler))
211  throw incorrect_goto_program_exceptiont{"failed to read/link goto model"};
212 
214  language_files,
215  goto_model.symbol_table,
216  [&goto_model](const irep_idt &id) { goto_model.goto_functions.unload(id); },
217  options,
218  true,
219  message_handler);
220 
221  if(language_files.final(goto_model.symbol_table))
222  {
223  throw invalid_input_exceptiont("FINAL STAGE CONVERSION ERROR");
224  }
225 
226  msg.status() << "Generating GOTO Program" << messaget::eom;
227 
228  goto_convert(
229  goto_model.symbol_table,
230  goto_model.goto_functions,
231  message_handler);
232 
233  if(options.is_set("validate-goto-model"))
234  {
235  goto_model_validation_optionst goto_model_validation_options{
236  goto_model_validation_optionst ::set_optionst::all_false};
237 
238  goto_model.validate(
239  validation_modet::INVARIANT, goto_model_validation_options);
240  }
241 
242  // stupid hack
244  goto_model.symbol_table);
245 
246  return goto_model;
247 }
messaget
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:154
symbol_table_baset::has_symbol
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
Definition: symbol_table_base.h:87
exception_utils.h
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
symbol_tablet
The symbol table.
Definition: symbol_table.h:13
language_filet::get_modules
void get_modules()
Definition: language_file.cpp:33
get_entry_point_language
std::unique_ptr< languaget > get_entry_point_language(const symbol_table_baset &symbol_table, const optionst &options, message_handlert &message_handler)
Find the language corresponding to the __CPROVER_start function.
Definition: rebuild_goto_start_function.cpp:24
optionst
Definition: options.h:22
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
language_filest::typecheck
bool typecheck(symbol_tablet &symbol_table, const bool keep_file_local=false)
Definition: language_file.cpp:83
optionst::get_option
const std::string get_option(const std::string &option) const
Definition: options.cpp:67
messaget::status
mstreamt & status() const
Definition: message.h:414
generate_entry_point_for_function
static bool generate_entry_point_for_function(const optionst &options, symbol_tablet &symbol_table, message_handlert &message_handler)
Generate an entry point that calls a function with the given name, based on the functions language mo...
Definition: initialize_goto_model.cpp:36
invalid_input_exceptiont
Thrown when user-provided input cannot be processed.
Definition: exception_utils.h:162
language_filet
Definition: language_file.h:41
get_language_from_mode
std::unique_ptr< languaget > get_language_from_mode(const irep_idt &mode)
Get the language corresponding to the given mode.
Definition: mode.cpp:51
goto_model_validation_optionst
Definition: validate_goto_model.h:15
goto_modelt
Definition: goto_model.h:25
mode.h
options.h
messaget::eom
static eomt eom
Definition: message.h:297
language_filest::generate_support_functions
bool generate_support_functions(symbol_tablet &symbol_table)
Definition: language_file.cpp:163
languaget::set_language_options
virtual void set_language_options(const optionst &)
Set language-specific options.
Definition: language.h:41
incorrect_goto_program_exceptiont
Thrown when a goto program that's being processed is in an invalid format, for example passing the wr...
Definition: exception_utils.h:91
goto_convert
void goto_convert(const codet &code, symbol_table_baset &symbol_table, goto_programt &dest, message_handlert &message_handler, const irep_idt &mode)
Definition: goto_convert.cpp:1905
initialize_from_source_files
void initialize_from_source_files(const std::list< std::string > &sources, const optionst &options, language_filest &language_files, symbol_tablet &symbol_table, message_handlert &message_handler)
Populate symbol_table from sources by parsing and type checking via language_files.
Definition: initialize_goto_model.cpp:60
get_language_from_filename
std::unique_ptr< languaget > get_language_from_filename(const std::string &filename)
Get the language corresponding to the registered file name extensions.
Definition: mode.cpp:102
read_objects_and_link
bool read_objects_and_link(const std::list< std::string > &file_names, goto_modelt &dest, message_handlert &message_handler)
Reads object files and updates the config if any files were read.
Definition: read_goto_binary.cpp:291
initialize_goto_model.h
rebuild_goto_start_function.h
remove_existing_entry_point
void remove_existing_entry_point(symbol_table_baset &symbol_table)
Eliminate the existing entry point function symbol and any symbols created in that scope from the sym...
Definition: rebuild_goto_start_function.cpp:47
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
languaget::generate_support_functions
virtual bool generate_support_functions(symbol_tablet &symbol_table)=0
Create language-specific support functions, such as __CPROVER_start, __CPROVER_initialize and languag...
optionst::is_set
bool is_set(const std::string &option) const
N.B. opts.is_set("foo") does not imply opts.get_bool_option("foo")
Definition: options.cpp:62
PRECONDITION
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
system_exceptiont
Thrown when some external system fails unexpectedly.
Definition: exception_utils.h:71
languaget::parse
virtual bool parse(std::istream &instream, const std::string &path)=0
language.h
messaget::set_message_handler
virtual void set_message_handler(message_handlert &_message_handler)
Definition: message.h:179
language_filest::add_file
language_filet & add_file(const std::string &filename)
Definition: language_file.h:77
message_handlert
Definition: message.h:27
dstringt::empty
bool empty() const
Definition: dstring.h:88
language_filet::language
std::unique_ptr< languaget > language
Definition: language_file.h:47
widen
std::wstring widen(const char *s)
Definition: unicode.cpp:48
read_goto_binary.h
config
configt config
Definition: config.cpp:25
language_filest::final
bool final(symbol_table_baset &symbol_table)
Definition: language_file.cpp:178
goto_modelt::goto_functions
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:33
unicode.h
languaget
Definition: language.h:37
is_goto_binary
bool is_goto_binary(const std::string &filename, message_handlert &message_handler)
Definition: read_goto_binary.cpp:192
config.h
goto_modelt::validate
void validate(const validation_modet vm=validation_modet::INVARIANT, const goto_model_validation_optionst &goto_model_validation_options=goto_model_validation_optionst{}) const override
Check that the goto model is well-formed.
Definition: goto_model.h:98
symbol_table_baset::lookup
const symbolt * lookup(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
Definition: symbol_table_base.h:95
goto_functionst::entry_point
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
Definition: goto_functions.h:92
initialize_goto_model
goto_modelt initialize_goto_model(const std::vector< std::string > &files, message_handlert &message_handler, const optionst &options)
Definition: initialize_goto_model.cpp:178
goto_convert_functions.h
message.h
invalid_command_line_argument_exceptiont
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
Definition: exception_utils.h:50
configt::set_object_bits_from_symbol_table
void set_object_bits_from_symbol_table(const symbol_tablet &)
Sets the number of bits used for object addresses.
Definition: config.cpp:1314
goto_modelt::symbol_table
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:30
set_up_custom_entry_point
void set_up_custom_entry_point(language_filest &language_files, symbol_tablet &symbol_table, const std::function< void(const irep_idt &)> &unload, const optionst &options, bool try_mode_lookup, message_handlert &message_handler)
Process the "function" option in options to prepare a custom entry point to replace __CPROVER_start.
Definition: initialize_goto_model.cpp:117
validation_modet::INVARIANT
@ INVARIANT
language_file.h
language_filest
Definition: language_file.h:62