CBMC
Loading...
Searching...
No Matches
interrupt.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Interrupt Instrumentation
4
5Author: Daniel Kroening
6
7Date: September 2011
8
9\*******************************************************************/
10
13
14#include "interrupt.h"
15
16#include <util/range.h>
17#include <util/std_code.h>
18
20
21#ifdef LOCAL_MAY
23#endif
24
25#include "rw_set.h"
26
30{
31 // R/W race?
32 for(const auto &r_entry : code_rw_set.r_entries)
33 {
34 if(isr_rw_set.has_w_entry(r_entry.first))
35 return true;
36 }
37
38 return false;
39}
40
44{
45 // W/R or W/W?
46 for(const auto &w_entry : code_rw_set.w_entries)
47 {
48 if(isr_rw_set.has_r_entry(w_entry.first))
49 return true;
50
51 if(isr_rw_set.has_w_entry(w_entry.first))
52 return true;
53 }
54
55 return false;
56}
57
58static void interrupt(
59 value_setst &value_sets,
60 const symbol_tablet &symbol_table,
61 const irep_idt &function_id,
63 const goto_functionst::goto_functiont &goto_function,
64#endif
65 goto_programt &goto_program,
68 message_handlert &message_handler)
69{
70 namespacet ns(symbol_table);
71
73 {
75
76#ifdef LOCAL_MAY
77 local_may_aliast local_may(goto_function);
78#endif
80 ns,
81 value_sets,
82 function_id,
83 i_it,
86#endif
87 message_handler); // NOLINT(whitespace/parens)
88
89 // potential race?
92
94 continue;
95
96 // Insert the call to the ISR.
97 // We do before for races on Read, and before and after
98 // for races on Write.
99
101 {
103 original_instruction.swap(instruction);
104
105 const source_locationt &source_location =
106 original_instruction.source_location();
107
109 isr_call.add_source_location()=source_location;
110
112 goto_programt::targett t_call=goto_program.insert_after(t_goto);
113 goto_programt::targett t_orig=goto_program.insert_after(t_call);
114
116 t_orig,
117 side_effect_expr_nondett(bool_typet(), source_location),
118 source_location);
119
121
123
124 i_it=t_orig; // the for loop already counts us up
125 }
126
127 if(race_on_write)
128 {
129 // insert _after_ the instruction with race
131 t_orig++;
132
133 const source_locationt &source_location = i_it->source_location();
134
136 isr_call.add_source_location()=source_location;
137
138 goto_programt::targett t_goto = goto_program.insert_after(
139 i_it,
141 t_orig,
142 side_effect_expr_nondett(bool_typet(), source_location),
143 source_location));
144
145 goto_programt::targett t_call = goto_program.insert_after(
147
148 i_it=t_call; // the for loop already counts us up
149 }
150 }
151}
152
153static symbol_exprt
155{
156 std::list<symbol_exprt> matches;
157
158 for(const auto &symbol_name_entry :
160 {
161 // look it up
162 symbol_tablet::symbolst::const_iterator s_it =
163 symbol_table.symbols.find(symbol_name_entry.second);
164
165 if(s_it==symbol_table.symbols.end())
166 continue;
167
168 if(s_it->second.type.id() == ID_code && !s_it->second.is_property)
169 matches.push_back(s_it->second.symbol_expr());
170 }
171
172 if(matches.empty())
173 throw "interrupt handler '" + id2string(interrupt_handler) + "' not found";
174
175 if(matches.size()>=2)
176 throw "interrupt handler '" + id2string(interrupt_handler) +
177 "' is ambiguous";
178
179 symbol_exprt isr=matches.front();
180
181 if(!to_code_type(isr.type()).parameters().empty())
182 throw "interrupt handler '" + id2string(interrupt_handler) +
183 "' must not have parameters";
184
185 return isr;
186}
187
189 value_setst &value_sets,
190 goto_modelt &goto_model,
192 message_handlert &message_handler)
193{
194 // look up the ISR
197
198 // we first figure out which objects are read/written by the ISR
199 rw_set_functiont isr_rw_set(value_sets, goto_model, isr, message_handler);
200
201 // now instrument
202
203 for(auto &gf_entry : goto_model.goto_functions.function_map)
204 {
205 if(
206 gf_entry.first != INITIALIZE_FUNCTION &&
208 gf_entry.first != isr.get_identifier())
209 {
210 interrupt(
211 value_sets,
212 goto_model.symbol_table,
213 gf_entry.first,
215 gf_entry.second,
216#endif
217 gf_entry.second.body,
218 isr,
220 message_handler);
221 }
222 }
223
224 goto_model.goto_functions.update();
225}
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
The Boolean type.
Definition std_types.h:36
goto_instruction_codet representation of a function call statement.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
function_mapt function_map
::goto_functiont goto_functiont
static irep_idt entry_point()
Get the identifier of the entry point to a goto model.
symbol_tablet symbol_table
Symbol table.
Definition goto_model.h:31
goto_functionst goto_functions
GOTO functions.
Definition goto_model.h:34
This class represents an instruction in the GOTO intermediate representation.
A generic container class for the GOTO intermediate representation of one function.
instructionst::iterator targett
static instructiont make_function_call(const code_function_callt &_code, const source_locationt &l=source_locationt::nil())
Create a function call instruction.
static instructiont make_goto(targett _target, const source_locationt &l=source_locationt::nil())
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
Definition namespace.h:91
A side_effect_exprt that returns a non-deterministically chosen value.
Definition std_code.h:1520
Expression to hold a symbol (variable)
Definition std_expr.h:131
const symbol_base_mapt & symbol_base_map
Read-only field, used to look up symbol names given their base names.
const symbolst & symbols
Read-only field, used to look up symbols given their names.
The symbol table.
#define Forall_goto_program_instructions(it, program)
static bool potential_race_on_read(const rw_set_baset &code_rw_set, const rw_set_baset &isr_rw_set)
Definition interrupt.cpp:27
static bool potential_race_on_write(const rw_set_baset &code_rw_set, const rw_set_baset &isr_rw_set)
Definition interrupt.cpp:41
static void interrupt(value_setst &value_sets, const symbol_tablet &symbol_table, const irep_idt &function_id, goto_programt &goto_program, const symbol_exprt &interrupt_handler, const rw_set_baset &isr_rw_set, message_handlert &message_handler)
Definition interrupt.cpp:58
static symbol_exprt get_isr(const symbol_tablet &symbol_table, const irep_idt &interrupt_handler)
Interrupt Instrumentation for Goto Programs.
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
Field-insensitive, location-sensitive may-alias analysis.
Ranges: pair of begin and end iterators, which can be initialized from containers,...
ranget< typename multimapt::const_iterator > equal_range(const multimapt &multimap, const typename multimapt::key_type &key)
Utility function to make equal_range method of multimap easier to use by returning a ranget object.
Definition range.h:539
Race Detection for Threaded Goto Programs.
#define INITIALIZE_FUNCTION
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
Definition std_types.h:788