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 <util/config.h>
15 #include <util/exception_utils.h>
16 #include <util/message.h>
17 #include <util/options.h>
18 #include <util/unicode.h>
19 
21 
22 #include <langapi/language.h>
23 #include <langapi/language_file.h>
24 #include <langapi/mode.h>
25 
26 #include "goto_convert_functions.h"
27 #include "read_goto_binary.h"
28 
29 #include <fstream>
30 
34  const optionst &options,
35  symbol_tablet &symbol_table,
36  message_handlert &message_handler)
37 {
38  const irep_idt &entry_function_name = options.get_option("function");
39  CHECK_RETURN(!entry_function_name.empty());
40  auto matches = symbol_table.match_name_or_base_name(entry_function_name);
41  // it's ok if this is ambiguous at this point, we just need to get a mode, the
42  // actual entry point generator will take care of resolving (or rejecting)
43  // ambiguity
44  if(matches.empty())
45  {
47  std::string("couldn't find entry with name '") +
48  id2string(entry_function_name) + "' in symbol table",
49  "--function"};
50  }
51  const auto &entry_point_mode = matches.front()->second.mode;
52  PRECONDITION(!entry_point_mode.empty());
53  auto const entry_language = get_language_from_mode(entry_point_mode);
54  CHECK_RETURN(entry_language != nullptr);
55  entry_language->set_language_options(options, message_handler);
56  return entry_language->generate_support_functions(
57  symbol_table, message_handler);
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  std::ifstream infile(widen_if_needed(filename));
75 
76  if(!infile)
77  {
78  throw system_exceptiont("Failed to open input file '" + filename + '\'');
79  }
80 
81  language_filet &lf = language_files.add_file(filename);
82  lf.language = get_language_from_filename(filename);
83 
84  if(lf.language == nullptr)
85  {
87  "Failed to figure out type of file", filename};
88  }
89 
90  languaget &language = *lf.language;
91  language.set_language_options(options, message_handler);
92 
93  msg.status() << "Parsing " << filename << messaget::eom;
94 
95  if(language.parse(infile, filename, message_handler))
96  {
97  throw invalid_input_exceptiont("PARSING ERROR");
98  }
99 
100  lf.get_modules();
101  }
102 
103  msg.status() << "Converting" << messaget::eom;
104 
105  if(language_files.typecheck(symbol_table, message_handler))
106  {
107  throw invalid_input_exceptiont("CONVERSION ERROR");
108  }
109 }
110 
112  language_filest &language_files,
113  symbol_tablet &symbol_table,
114  const std::function<std::size_t(const irep_idt &)> &unload,
115  const optionst &options,
116  bool try_mode_lookup,
117  message_handlert &message_handler)
118 {
119  bool binaries_provided_start =
121 
122  bool entry_point_generation_failed=false;
123 
124  if(binaries_provided_start && options.is_set("function"))
125  {
126  // The goto binaries provided already contain a __CPROVER_start
127  // function that may be tied to a different entry point `function`.
128  // Hence, we will rebuild the __CPROVER_start function.
129 
130  // Get the language annotation of the existing __CPROVER_start function.
131  std::unique_ptr<languaget> language =
132  get_entry_point_language(symbol_table, options, message_handler);
133 
134  // To create a new entry point we must first remove the old one
135  remove_existing_entry_point(symbol_table);
136 
137  // Create the new entry-point
138  entry_point_generation_failed =
139  language->generate_support_functions(symbol_table, message_handler);
140 
141  // Remove the function from the goto functions so it is copied back in
142  // from the symbol table during goto_convert
143  if(!entry_point_generation_failed)
145  }
146  else if(!binaries_provided_start)
147  {
148  if(try_mode_lookup && options.is_set("function"))
149  {
150  // no entry point is present; Use the mode of the specified entry function
151  // to generate one
152  entry_point_generation_failed = generate_entry_point_for_function(
153  options, symbol_table, message_handler);
154  }
155  if(
156  !try_mode_lookup || entry_point_generation_failed ||
157  !options.is_set("function"))
158  {
159  // Allow all language front-ends to try to provide the user-specified
160  // (--function) entry-point, or some language-specific default:
161  entry_point_generation_failed = language_files.generate_support_functions(
162  symbol_table, message_handler);
163  }
164  }
165 
166  if(entry_point_generation_failed)
167  {
168  throw invalid_input_exceptiont("SUPPORT FUNCTION GENERATION ERROR");
169  }
170 }
171 
173  const std::vector<std::string> &files,
174  message_handlert &message_handler,
175  const optionst &options)
176 {
177  messaget msg(message_handler);
178  if(files.empty())
179  {
181  "missing program argument",
182  "filename",
183  "one or more paths to program files");
184  }
185 
186  std::list<std::string> binaries, sources;
187 
188  for(const auto &file : files)
189  {
190  if(is_goto_binary(file, message_handler))
191  binaries.push_back(file);
192  else
193  sources.push_back(file);
194  }
195 
196  language_filest language_files;
197  goto_modelt goto_model;
199  sources, options, language_files, goto_model.symbol_table, message_handler);
200 
201  if(read_objects_and_link(binaries, goto_model, message_handler))
202  throw incorrect_goto_program_exceptiont{"failed to read/link goto model"};
203 
205  language_files,
206  goto_model.symbol_table,
207  [&goto_model](const irep_idt &id) { return goto_model.unload(id); },
208  options,
209  true,
210  message_handler);
211 
212  if(language_files.final(goto_model.symbol_table))
213  {
214  throw invalid_input_exceptiont("FINAL STAGE CONVERSION ERROR");
215  }
216 
217  msg.status() << "Generating GOTO Program" << messaget::eom;
218 
219  goto_convert(
220  goto_model.symbol_table,
221  goto_model.goto_functions,
222  message_handler);
223 
224  if(options.is_set("validate-goto-model"))
225  {
226  goto_model_validation_optionst goto_model_validation_options{
227  goto_model_validation_optionst ::set_optionst::all_false};
228 
229  goto_model.validate(
230  validation_modet::INVARIANT, goto_model_validation_options);
231  }
232 
233  // stupid hack
235  goto_model.symbol_table);
236 
237  return goto_model;
238 }
configt config
Definition: config.cpp:25
void set_object_bits_from_symbol_table(const symbol_table_baset &)
Sets the number of bits used for object addresses.
Definition: config.cpp:1325
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:38
bool empty() const
Definition: dstring.h:89
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
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:105
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:31
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:34
Thrown when a goto program that's being processed is in an invalid format, for example passing the wr...
Thrown when users pass incorrect command line arguments, for example passing no files to analysis or ...
Thrown when user-provided input cannot be processed.
language_filet & add_file(const std::string &filename)
Definition: language_file.h:77
bool typecheck(symbol_table_baset &symbol_table, const bool keep_file_local, message_handlert &message_handler)
bool generate_support_functions(symbol_table_baset &symbol_table, message_handlert &message_handler)
bool final(symbol_table_baset &symbol_table)
std::unique_ptr< languaget > language
Definition: language_file.h:46
virtual bool parse(std::istream &instream, const std::string &path, message_handlert &message_handler)=0
virtual void set_language_options(const optionst &, message_handlert &)
Set language-specific options.
Definition: language.h:40
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:155
mstreamt & status() const
Definition: message.h:414
static eomt eom
Definition: message.h:297
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
const std::string get_option(const std::string &option) const
Definition: options.cpp:67
std::list< symbolst::const_iterator > match_name_or_base_name(const irep_idt &id) const
Collect all symbols the name of which matches id or the base name of which matches id.
bool has_symbol(const irep_idt &name) const
Check whether a symbol exists in the symbol table.
The symbol table.
Definition: symbol_table.h:14
Thrown when some external system fails unexpectedly.
void goto_convert(const codet &code, symbol_table_baset &symbol_table, goto_programt &dest, message_handlert &message_handler, const irep_idt &mode)
Goto Programs with Functions.
goto_modelt initialize_goto_model(const std::vector< std::string > &files, message_handlert &message_handler, const optionst &options)
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.
void set_up_custom_entry_point(language_filest &language_files, symbol_tablet &symbol_table, const std::function< std::size_t(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.
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...
Initialize a Goto Program.
const std::string & id2string(const irep_idt &d)
Definition: irep.h:40
Abstract interface to support a programming language.
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
std::unique_ptr< languaget > get_language_from_mode(const irep_idt &mode)
Get the language corresponding to the given mode.
Definition: mode.cpp:51
Options.
bool is_goto_binary(const std::string &filename, message_handlert &message_handler)
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.
Read Goto Programs.
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...
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.
Goto Programs Author: Thomas Kiley, thomas@diffblue.com.
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
#define PRECONDITION(CONDITION)
Definition: invariant.h:463
#define widen_if_needed(s)
Definition: unicode.h:28