Skip to content

Commit f20fef6

Browse files
authored
Merge pull request diffblue#132 from diffblue/marek/irept_instrumenter_PR
SEC-19: Introducing irept_instrumenter.
2 parents c933b0e + c7035a4 commit f20fef6

File tree

3 files changed

+214
-0
lines changed

3 files changed

+214
-0
lines changed

src/taint-slicer/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ SRC = slicer.cpp \
44
instrumentation_props.cpp \
55
instrumenter.cpp \
66
slicing_tasks_builder.cpp \
7+
irept_instrument.cpp \
78
# end of SRC
89

910
INCLUDES= -I .. -I ../../cbmc/src -I ../../boost

src/taint-slicer/irept_instrument.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*******************************************************************\
2+
3+
Module: irept_instrument
4+
5+
Author: Marek Trtik
6+
7+
Date: May 2017
8+
9+
10+
@ Copyright Diffblue, Ltd.
11+
12+
\*******************************************************************/
13+
14+
#include <taint-slicer/irept_instrument.h>
15+
16+
// WARNING: 'irept' does not support equality check and its explicit use
17+
// in functions below was not appreciated (see PR #132). Equivalence
18+
// checks are thus used. And so, in case of performance issues in the
19+
// instrumenter focus your attention also to profiling of these checks.
20+
21+
irept instrument(const irept irep, const instrumenter_fnt &instrumenter)
22+
{
23+
bool modified=false;
24+
25+
irept::subt new_sub;
26+
for(const irept &sub : irep.get_sub())
27+
{
28+
new_sub.push_back(instrument(sub, instrumenter));
29+
if(new_sub.back()!=sub)
30+
modified=true;
31+
}
32+
33+
irept::named_subt new_named_sub;
34+
for(const irept::named_subt::value_type &name_sub : irep.get_named_sub())
35+
{
36+
const auto it_bool=
37+
new_named_sub.insert(
38+
{
39+
name_sub.first,
40+
instrument(name_sub.second, instrumenter)
41+
});
42+
assert(it_bool.second);
43+
if(it_bool.first->second!=name_sub.second)
44+
modified=true;
45+
}
46+
47+
irept::named_subt new_comments;
48+
for(const irept::named_subt::value_type &name_sub : irep.get_comments())
49+
{
50+
const auto it_bool=
51+
new_comments.insert(
52+
{
53+
name_sub.first,
54+
instrument(name_sub.second, instrumenter)
55+
});
56+
assert(it_bool.second);
57+
if(it_bool.first->second!=name_sub.second)
58+
modified=true;
59+
}
60+
61+
if(modified)
62+
{
63+
irept result(irep.id());
64+
result.get_sub()=new_sub;
65+
result.get_named_sub()=new_named_sub;
66+
result.get_comments()=new_comments;
67+
return instrumenter(result);
68+
}
69+
return instrumenter(irep);
70+
}
71+
72+
irept instrument_using_guide(
73+
const irept pivot,
74+
const irept irep,
75+
const guide_instrumenter_fnt &instrumenter)
76+
{
77+
bool modified=false;
78+
79+
irept::subt new_sub;
80+
for(auto pit=pivot.get_sub().cbegin(), iit=irep.get_sub().cbegin();
81+
pit!=pivot.get_sub().cend() && iit!=irep.get_sub().cend(); ++pit, ++iit)
82+
{
83+
new_sub.push_back(instrument_using_guide(*pit, *iit, instrumenter));
84+
if(new_sub.back()!=*iit)
85+
modified=true;
86+
}
87+
88+
irept::named_subt new_named_sub;
89+
for(auto iit=irep.get_named_sub().cbegin();
90+
iit!=irep.get_named_sub().cend();
91+
++iit)
92+
{
93+
const auto pit=pivot.get_named_sub().find(iit->first);
94+
const auto it_bool=
95+
new_named_sub.insert(
96+
{
97+
iit->first,
98+
pit!=pivot.get_named_sub().cend() ?
99+
instrument_using_guide(pit->second, iit->second, instrumenter):
100+
iit->second
101+
});
102+
assert(it_bool.second);
103+
if(it_bool.first->second!=iit->second)
104+
modified=true;
105+
}
106+
107+
irept::named_subt new_comments;
108+
for(auto iit=irep.get_comments().cbegin();
109+
iit!=irep.get_comments().cend();
110+
++iit)
111+
{
112+
auto pit=pivot.get_comments().find(iit->first);
113+
const auto it_bool=
114+
new_comments.insert(
115+
{
116+
iit->first,
117+
pit!=pivot.get_comments().cend() ?
118+
instrument_using_guide(pit->second, iit->second, instrumenter):
119+
iit->second
120+
});
121+
assert(it_bool.second);
122+
if(it_bool.first->second!=iit->second)
123+
modified=true;
124+
}
125+
126+
if(modified)
127+
{
128+
irept result(irep.id());
129+
result.get_sub()=new_sub;
130+
result.get_named_sub()=new_named_sub;
131+
result.get_comments()=new_comments;
132+
return instrumenter(pivot, result);
133+
}
134+
return instrumenter(pivot, irep);
135+
}

src/taint-slicer/irept_instrument.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*******************************************************************\
2+
3+
Module: irept_instrument
4+
5+
Author: Marek Trtik
6+
7+
Date: May 2017
8+
9+
The module provides utility functuions simplifying the instrumentation
10+
proces of "irept" hierarchical and shared data structures.
11+
12+
@ Copyright Diffblue, Ltd.
13+
14+
\*******************************************************************/
15+
16+
#ifndef CPROVER_TAINT_SLICER_IREPT_INSTRUMENT_H
17+
#define CPROVER_TAINT_SLICER_IREPT_INSTRUMENT_H
18+
19+
#include <util/irep.h>
20+
#include <functional>
21+
22+
/// An instrumenter is any function returning from a passed instance of
23+
/// 'irept' its instrumented version. If the passed instance does not
24+
/// match the king of 'irept' to be instrumented, the function must return
25+
/// the same instance to indicate no instrumentation was performed.
26+
/// Due to performance reasons it is recomended to write instrumenter
27+
/// functions looking only into the passed instance (i.e. not into
28+
/// 'irept' hierarchy below the passed instance).
29+
typedef std::function<irept(irept)> instrumenter_fnt;
30+
typedef std::function<irept(irept, irept)> guide_instrumenter_fnt;
31+
32+
/*******************************************************************\
33+
34+
Function:
35+
36+
Inputs:
37+
38+
Outputs:
39+
40+
Purpose:
41+
The function accepts a hierarchy of 'irept's and for each node in
42+
the hierarchy it calls the passed instrumenter. The result of the
43+
function is a new 'irept' hierarchy constructed from the original
44+
one by traversing it bottom-up and by applying the instrumenter on
45+
each visited node.
46+
47+
\*******************************************************************/
48+
irept instrument(const irept irep, const instrumenter_fnt &instrumenter);
49+
50+
/*******************************************************************\
51+
52+
Function:
53+
54+
Inputs:
55+
56+
Outputs:
57+
58+
Purpose:
59+
Builds an instrumented copy of a passed hierarchy of
60+
'irept's in the same way as the function 'instrument' above. However,
61+
this version allows the user to also specify a 'guide' hierarchy of
62+
'irept's providing more refined instrumentation.
63+
The instrumenter is called only on that topological part of the hierarchy
64+
matching the topology of the guide. Positional and named operands not present
65+
in the guide irep are left unaltered. Also, the instrumenter called for
66+
some node may use the corresponding guide node to decide how the
67+
instrumentation will be performed. For example, imagine two nodes of
68+
the exactly the same kind of the instrumenter passed with the different
69+
kinds of guide nodes. The intrumenter may then return nodes of different
70+
kinds (according to kinds of guide nodes).
71+
72+
\*******************************************************************/
73+
irept instrument_using_guide(
74+
const irept guide,
75+
const irept irep,
76+
const guide_instrumenter_fnt &instrumenter);
77+
78+
#endif

0 commit comments

Comments
 (0)