CBMC
mm_io.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: Perform Memory-mapped I/O instrumentation
4 
5 Author: Daniel Kroening
6 
7 Date: April 2017
8 
9 \*******************************************************************/
10 
13 
14 #include "mm_io.h"
15 
16 #include <util/fresh_symbol.h>
17 #include <util/pointer_expr.h>
20 #include <util/replace_expr.h>
21 
22 #include "goto_model.h"
23 #include "remove_returns.h"
24 
25 #include <set>
26 
28  const exprt &src,
29  std::set<dereference_exprt> &dest)
30 {
31  src.visit_pre([&dest](const exprt &e) {
32  if(e.id() == ID_dereference)
33  dest.insert(to_dereference_expr(e));
34  });
35 }
36 
37 void mm_io(
38  const exprt &mm_io_r,
39  const exprt &mm_io_r_value,
40  const exprt &mm_io_w,
41  goto_functionst::goto_functiont &goto_function,
42  const namespacet &ns)
43 {
44  for(goto_programt::instructionst::iterator it=
45  goto_function.body.instructions.begin();
46  it!=goto_function.body.instructions.end();
47  it++)
48  {
49  std::set<dereference_exprt> deref_expr_w, deref_expr_r;
50 
51  if(it->is_assign())
52  {
53  auto &a_lhs = it->assign_lhs();
54  auto &a_rhs = it->assign_rhs_nonconst();
55  collect_deref_expr(a_rhs, deref_expr_r);
56 
57  if(mm_io_r.is_not_nil())
58  {
59  if(deref_expr_r.size()==1)
60  {
61  const dereference_exprt &d=*deref_expr_r.begin();
62  source_locationt source_location = it->source_location();
63  const code_typet &ct=to_code_type(mm_io_r.type());
64 
65  if_exprt if_expr(
67  typecast_exprt::conditional_cast(mm_io_r_value, d.type()),
68  d);
69  replace_expr(d, if_expr, a_rhs);
70 
71  const typet &pt=ct.parameters()[0].type();
72  const typet &st=ct.parameters()[1].type();
73  auto size_opt = size_of_expr(d.type(), ns);
74  CHECK_RETURN(size_opt.has_value());
76  mm_io_r_value,
77  mm_io_r,
78  {typecast_exprt(d.pointer(), pt),
79  typecast_exprt(size_opt.value(), st)},
80  source_location);
81  goto_function.body.insert_before_swap(it, call);
82  it++;
83  }
84  }
85 
86  if(mm_io_w.is_not_nil())
87  {
88  if(a_lhs.id() == ID_dereference)
89  {
90  const dereference_exprt &d = to_dereference_expr(a_lhs);
91  source_locationt source_location = it->source_location();
92  const code_typet &ct=to_code_type(mm_io_w.type());
93  const typet &pt=ct.parameters()[0].type();
94  const typet &st=ct.parameters()[1].type();
95  const typet &vt=ct.parameters()[2].type();
96  auto size_opt = size_of_expr(d.type(), ns);
97  CHECK_RETURN(size_opt.has_value());
98  const code_function_callt fc(
99  mm_io_w,
100  {typecast_exprt(d.pointer(), pt),
101  typecast_exprt(size_opt.value(), st),
102  typecast_exprt(a_rhs, vt)});
103  goto_function.body.insert_before_swap(it);
104  *it = goto_programt::make_function_call(fc, source_location);
105  it++;
106  }
107  }
108  }
109  }
110 }
111 
112 void mm_io(symbol_tablet &symbol_table, goto_functionst &goto_functions)
113 {
114  const namespacet ns(symbol_table);
115  exprt mm_io_r = nil_exprt(), mm_io_r_value = nil_exprt(),
116  mm_io_w = nil_exprt();
117 
118  irep_idt id_r=CPROVER_PREFIX "mm_io_r";
119  irep_idt id_w=CPROVER_PREFIX "mm_io_w";
120 
121  auto maybe_symbol=symbol_table.lookup(id_r);
122  if(maybe_symbol)
123  {
124  mm_io_r=maybe_symbol->symbol_expr();
125 
126  const auto &value_symbol = get_fresh_aux_symbol(
127  to_code_type(mm_io_r.type()).return_type(),
128  id2string(id_r) + "$value",
129  id2string(id_r) + "$value",
130  maybe_symbol->location,
131  maybe_symbol->mode,
132  symbol_table);
133 
134  mm_io_r_value = value_symbol.symbol_expr();
135  }
136 
137  maybe_symbol=symbol_table.lookup(id_w);
138  if(maybe_symbol)
139  mm_io_w=maybe_symbol->symbol_expr();
140 
141  for(auto & f : goto_functions.function_map)
142  mm_io(mm_io_r, mm_io_r_value, mm_io_w, f.second, ns);
143 }
144 
145 void mm_io(goto_modelt &model)
146 {
147  mm_io(model.symbol_table, model.goto_functions);
148 }
mm_io
void mm_io(const exprt &mm_io_r, const exprt &mm_io_r_value, const exprt &mm_io_w, goto_functionst::goto_functiont &goto_function, const namespacet &ns)
Definition: mm_io.cpp:37
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
pointer_offset_size.h
typecast_exprt::conditional_cast
static exprt conditional_cast(const exprt &expr, const typet &type)
Definition: std_expr.h:2025
symbol_tablet
The symbol table.
Definition: symbol_table.h:13
to_dereference_expr
const dereference_exprt & to_dereference_expr(const exprt &expr)
Cast an exprt to a dereference_exprt.
Definition: pointer_expr.h:716
CHECK_RETURN
#define CHECK_RETURN(CONDITION)
Definition: invariant.h:495
typet
The type of an expression, extends irept.
Definition: type.h:28
fresh_symbol.h
dereference_exprt
Operator to dereference a pointer.
Definition: pointer_expr.h:659
if_exprt
The trinary if-then-else operator.
Definition: std_expr.h:2322
pointer_predicates.h
goto_model.h
exprt
Base class for all expressions.
Definition: expr.h:55
goto_modelt
Definition: goto_model.h:25
goto_functionst::function_map
function_mapt function_map
Definition: goto_functions.h:29
namespacet
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition: namespace.h:90
goto_programt::make_function_call
static instructiont make_function_call(const code_function_callt &_code, const source_locationt &l=source_locationt::nil())
Create a function call instruction.
Definition: goto_program.h:1081
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:84
code_function_callt
goto_instruction_codet representation of a function call statement.
Definition: goto_instruction_code.h:271
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:380
collect_deref_expr
void collect_deref_expr(const exprt &src, std::set< dereference_exprt > &dest)
Definition: mm_io.cpp:27
to_code_type
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition: std_types.h:744
mm_io.h
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
nil_exprt
The NIL expression.
Definition: std_expr.h:3025
dereference_exprt::pointer
exprt & pointer()
Definition: pointer_expr.h:673
symbolt::symbol_expr
class symbol_exprt symbol_expr() const
Produces a symbol_exprt for a symbol.
Definition: symbol.cpp:121
pointer_expr.h
integer_address
exprt integer_address(const exprt &pointer)
Definition: pointer_predicates.cpp:93
code_typet
Base type of functions.
Definition: std_types.h:538
irept::id
const irep_idt & id() const
Definition: irep.h:396
code_typet::parameters
const parameterst & parameters() const
Definition: std_types.h:655
remove_returns.h
source_locationt
Definition: source_location.h:18
goto_functionst::goto_functiont
::goto_functiont goto_functiont
Definition: goto_functions.h:27
goto_functionst
A collection of goto functions.
Definition: goto_functions.h:24
goto_modelt::goto_functions
goto_functionst goto_functions
GOTO functions.
Definition: goto_model.h:33
replace_expr
bool replace_expr(const exprt &what, const exprt &by, exprt &dest)
Definition: replace_expr.cpp:12
CPROVER_PREFIX
#define CPROVER_PREFIX
Definition: cprover_prefix.h:14
exprt::visit_pre
void visit_pre(std::function< void(exprt &)>)
Definition: expr.cpp:245
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
code_typet::return_type
const typet & return_type() const
Definition: std_types.h:645
size_of_expr
optionalt< exprt > size_of_expr(const typet &type, const namespacet &ns)
Definition: pointer_offset_size.cpp:280
replace_expr.h
typecast_exprt
Semantic type conversion.
Definition: std_expr.h:2016
goto_modelt::symbol_table
symbol_tablet symbol_table
Symbol table.
Definition: goto_model.h:30
get_fresh_aux_symbol
symbolt & get_fresh_aux_symbol(const typet &type, const std::string &name_prefix, const std::string &basename_prefix, const source_locationt &source_location, const irep_idt &symbol_mode, const namespacet &ns, symbol_table_baset &symbol_table)
Installs a fresh-named symbol with respect to the given namespace ns with the requested name pattern ...
Definition: fresh_symbol.cpp:32