1/*******************************************************************\
5Author: Daniel Kroening, kroening@kroening.com
7\*******************************************************************/
48 object_factory_parameters,
60 bool has_return_value =
67 // record return value
75 for(
const auto &p : parameters)
77 if(p.get_identifier().empty())
80 irep_idt identifier=p.get_identifier();
110 // check if entry point is already there
113 return false;
// silently ignore
117 // find main symbol, if any is given
122 for(
auto it = matches.begin(); it != matches.end();)
// no ++it
124 if((*it)->second.type.id() !=
ID_code || (*it)->second.is_property)
125 it = matches.erase(it);
133 message.
error() <<
"main symbol '" <<
config.
main.value() <<
"' not found"
135 return true;
// give up
138 if(matches.size()>=2)
146 main_symbol = matches.front()->first;
152 symbol_table_baset::symbolst::const_iterator
s_it =
153 symbol_table.
symbols.find(main_symbol);
156 return false;
// give up silently
160 // check if it has a body
166 return false;
// give up
172 symbol, symbol_table, message_handler, object_factory_parameters);
196 // build call to initialization function
199 symbol_table_baset::symbolst::const_iterator
init_it =
216 // build call to main function
240 if(parameters.empty())
244 // The C standard (and any related architecture descriptions) enforces an
245 // order of parameters. The user, however, may supply arbitrary
246 // (syntactically valid) C code, even one that does not respect the calling
247 // conventions set out in the C standard. If the user does supply such code,
248 // then we can only tell them that they got it wrong, which is what we do
249 // via the error message in the else branch of this code.
251 parameters.size() >= 2 && parameters[1].type().id() ==
ID_pointer &&
252 (parameters.size() == 2 ||
253 (parameters.size() == 3 && parameters[2].type().id() ==
ID_pointer)))
267 message.
error() <<
"argc already exists but is not usable"
276 // we make the type of this thing an array of pointers
277 // need to add one to the size -- the array is terminated
292 message.
error() <<
"argv already exists but is not usable"
302 // Assume argc is at least zero. Note that we don't assume it's
303 // at least one, since this isn't guaranteed, as exemplified by
304 // https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt
305 // The C standard only guarantees "The value of argc shall be
306 // nonnegative." and "argv[argc] shall be a null pointer."
326 // record argc as an input
329 if(parameters.size()==3)
364 // assume envp_size is INTMAX-1
377 /* zero_string doesn't work yet */
380 exprt zero_string(ID_zero_string, array_typet());
381 zero_string.type().subtype()=char_type();
382 zero_string.type().set(ID_size, "infinity");
383 const index_exprt index(zero_string, from_integer(0, uint_type()));
385 typecast_exprt::conditional_cast(
386 address_of_exprt(index, pointer_type(char_type())),
387 argv_symbol.type.subtype());
389 // assign argv[*] to the address of a string-object
390 array_of_exprt array_of(address_of, argv_symbol.type);
392 init_code.copy_to_operands(
393 code_assignt(argv_symbol.symbol_expr(), array_of));
398 // assign argv[argc] to NULL
408 // disable bounds check on that one
409 init_code.statements().back().add_source_location().add_pragma(
410 "disable:bounds-check");
413 if(parameters.size()==3)
419 // assume envp[envp_size] is NULL
431 // disable bounds check on that one
432 init_code.statements().back().add_source_location().add_pragma(
433 "disable:bounds-check");
439 if(parameters.size()==3)
444 exprt &op0=operands[0];
445 exprt &op1=operands[1];
454 // disable bounds check on that one
455 index_expr.add_source_location().add_pragma(
"disable:bounds-check");
465 if(parameters.size()==3)
490 <<
" but expecting one of:\n"
491 <<
" int main(void)\n"
492 <<
" int main(int argc, char *argv[])\n"
493 <<
" int main(int argc, char *argv[], char *envp[])\n"
494 <<
"If this is a non-standard main entry point please "
496 <<
"entry function and use --function instead"
503 // produce nondet arguments
505 parameters,
init_code, symbol_table, object_factory_parameters);
510 // TODO: add read/modified (recursively in call graph) globals as INPUT/OUTPUT
514 // now call destructor functions (a GCC extension)
534 // add the entry point symbol
540 if(!symbol_table.
insert(std::move(new_symbol)).second)
@ AUTOMATIC_LOCAL
Allocate local objects with automatic lifetime.
bool generate_ansi_c_start_function(const symbolt &symbol, symbol_table_baset &symbol_table, message_handlert &message_handler, const c_object_factory_parameterst &object_factory_parameters)
Generate a _start function for a specific function.
exprt::operandst build_function_environment(const code_typet::parameterst ¶meters, code_blockt &init_code, symbol_table_baset &symbol_table, const c_object_factory_parameterst &object_factory_parameters)
void record_function_outputs(const symbolt &function, code_blockt &init_code, symbol_table_baset &symbol_table)
bool ansi_c_entry_point(symbol_table_baset &symbol_table, message_handlert &message_handler, const c_object_factory_parameterst &object_factory_parameters)
const integer_bitvector_typet & to_integer_bitvector_type(const typet &type)
Cast a typet to an integer_bitvector_typet.
symbol_exprt c_nondet_symbol_factory(code_blockt &init_code, symbol_table_baset &symbol_table, const irep_idt base_name, const typet &type, const source_locationt &loc, const c_object_factory_parameterst &object_factory_parameters, const lifetimet lifetime)
Creates a symbol and generates code so that it can vary over all possible values for its type.
signedbv_typet signed_int_type()
pointer_typet pointer_type(const typet &subtype)
bitvector_typet char_type()
Operator to return the address of an object.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Internally generated symbol table entryThis is a symbol generated as part of translation to or modifi...
A base class for relations, i.e., binary predicates whose two operands have the same type.
An assumption, which must hold in subsequent code.
A codet representing sequential composition of program statements.
A codet representing an assignment in the program.
goto_instruction_codet representation of a function call statement.
codet representation of a label for branch targets.
A goto_instruction_codet representing the declaration that an output of a particular description has ...
A codet representing a skip statement.
const irep_idt & get_base_name() const
std::vector< parametert > parameterst
Data structure for representing an arbitrary statement in a program.
std::optional< std::string > main
struct configt::ansi_ct ansi_c
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Base class for all expressions.
std::vector< exprt > operandst
typet & type()
Return the type of the expression.
const source_locationt & source_location() const
source_locationt & add_source_location()
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
const irep_idt & id() const
source_locationt source_location
Class that provides messages with a built-in verbosity 'level'.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
The null pointer constant.
The plus expression Associativity is not specified.
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
The symbol table base class interface.
const symbolt * lookup(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
virtual std::pair< symbolt &, bool > insert(symbolt symbol)=0
Move or copy a new symbol to the symbol table.
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.
const symbolst & symbols
Read-only field, used to look up symbols given their names.
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
source_locationt location
Source code location of definition of symbol.
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
typet type
Type of symbol.
irep_idt name
The unique identifier.
irep_idt irep_idt base_name
Name of module the symbol belongs to.
exprt value
Initial value of symbol.
irep_idt mode
Language mode.
static exprt conditional_cast(const exprt &expr, const typet &type)
std::string type2c(const typet &type, const namespacet &ns, const expr2c_configurationt &configuration)
Goto Programs with Functions.
const std::string & id2string(const irep_idt &d)
API to expression classes for Pointers.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
#define PRECONDITION(CONDITION)
static std::optional< codet > static_lifetime_init(const irep_idt &identifier, symbol_table_baset &symbol_table)
#define INITIALIZE_FUNCTION
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
const array_typet & to_array_type(const typet &type)
Cast a typet to an array_typet.