Skip to content

Commit 7a4ed34

Browse files
Daniel Kroeningpolgreen
Daniel Kroening
authored andcommitted
goto-instrument: function pointer removal with value_set_fi
This adds a new option to goto-instrument for removing function pointers. The points-to analysis is done using flow-insensitive value sets, which is more precise than using the signature of the function to identify the points-to set.
1 parent f0e8739 commit 7a4ed34

File tree

7 files changed

+754
-1
lines changed

7 files changed

+754
-1
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <assert.h>
2+
3+
typedef void (*fp_t)();
4+
5+
void f()
6+
{
7+
}
8+
9+
void g()
10+
{
11+
}
12+
13+
int main(void)
14+
{
15+
fp_t fp = f;
16+
fp();
17+
18+
// this would fool an analysis that looks for functions whose address is taken
19+
fp_t other_fp = g;
20+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
CORE
2+
test.c
3+
--value-set-fi-fp-removal
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^ function: f$
7+
--
8+
^ function: g$
9+
--
10+
This test checks that the value-set-fi-based function pointer removal
11+
precisely identifies the function to call for a particular function pointer
12+
call.

src/goto-instrument/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ SRC = accelerate/accelerate.cpp \
6767
uninitialized.cpp \
6868
unwind.cpp \
6969
unwindset.cpp \
70+
value_set_fi_fp_removal.cpp \
7071
wmm/abstract_event.cpp \
7172
wmm/cycle_collection.cpp \
7273
wmm/data_dp.cpp \

src/goto-instrument/goto_instrument_parse_options.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Author: Daniel Kroening, [email protected]
5454
#include <pointer-analysis/goto_program_dereference.h>
5555
#include <pointer-analysis/show_value_sets.h>
5656
#include <pointer-analysis/value_set_analysis.h>
57+
#include <pointer-analysis/value_set_analysis_fi.h>
5758

5859
#include <analyses/call_graph.h>
5960
#include <analyses/constant_propagator.h>
@@ -111,6 +112,7 @@ Author: Daniel Kroening, [email protected]
111112
#include "undefined_functions.h"
112113
#include "uninitialized.h"
113114
#include "unwind.h"
115+
#include "value_set_fi_fp_removal.h"
114116
#include "wmm/weak_memory.h"
115117

116118
/// invoke main modules
@@ -293,6 +295,17 @@ int goto_instrument_parse_optionst::doit()
293295
return CPROVER_EXIT_SUCCESS;
294296
}
295297

298+
if(cmdline.isset("show-value-set-fi"))
299+
{
300+
namespacet ns(goto_model.symbol_table);
301+
value_set_analysis_fit value_set(
302+
ns, value_set_analysis_fit::track_optionst::TRACK_FUNCTION_POINTERS);
303+
304+
value_set(goto_model.goto_functions);
305+
value_set.output(goto_model.goto_functions, std::cout);
306+
return CPROVER_EXIT_SUCCESS;
307+
}
308+
296309
if(cmdline.isset("show-global-may-alias"))
297310
{
298311
do_indirect_call_and_rtti_removal();
@@ -906,7 +919,6 @@ int goto_instrument_parse_optionst::doit()
906919
"goto-instrument needs one input and one output file, aside from other "
907920
"flags");
908921
}
909-
910922
help();
911923
return CPROVER_EXIT_USAGE_ERROR;
912924
}
@@ -1198,6 +1210,12 @@ void goto_instrument_parse_optionst::instrument_goto_program()
11981210
exit(CPROVER_EXIT_USAGE_ERROR);
11991211
}
12001212

1213+
if(cmdline.isset("value-set-fi-fp-removal"))
1214+
{
1215+
value_set_fi_fp_removal(goto_model);
1216+
do_indirect_call_and_rtti_removal();
1217+
}
1218+
12011219
// replace function pointers, if explicitly requested
12021220
if(cmdline.isset("remove-function-pointers"))
12031221
{
@@ -1867,6 +1885,10 @@ void goto_instrument_parse_optionst::help()
18671885
" --no-caching disable caching of intermediate results during transitive function inlining\n" // NOLINT(*)
18681886
" --log <file> log in json format which code segments were inlined, use with --function-inline\n" // NOLINT(*)
18691887
" --remove-function-pointers replace function pointers by case statement over function calls\n" // NOLINT(*)
1888+
" --value-set-fi-fp-removal build flow-insensitive value set and replace function pointers by a case statement" // NOLINT(*)
1889+
" over the possible assignments. If the set of possible assignments is empty, the function pointer" // NOLINT(*)
1890+
" is not removed \n" // NOLINT(*)
1891+
" --remove-function-pointers replace function pointers by case statement over all function calls with same signature\n" // NOLINT(*)
18701892
HELP_RESTRICT_FUNCTION_POINTER
18711893
HELP_REMOVE_CALLS_NO_BODY
18721894
HELP_REMOVE_CONST_FUNCTION_POINTERS

src/goto-instrument/goto_instrument_parse_options.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Author: Daniel Kroening, [email protected]
7474
OPT_SHOW_PROPERTIES \
7575
"(drop-unused-functions)" \
7676
"(show-value-sets)" \
77+
"(show-value-set-fi)" \
7778
"(show-global-may-alias)" \
7879
"(show-local-bitvector-analysis)(show-custom-bitvector-analysis)" \
7980
"(show-escape-analysis)(escape-analysis)" \
@@ -83,6 +84,8 @@ Author: Daniel Kroening, [email protected]
8384
"(full-slice)(reachability-slice)(slice-global-inits)" \
8485
"(fp-reachability-slice):" \
8586
"(inline)(partial-inline)(function-inline):(log):(no-caching)" \
87+
"(value-set-fi-fp-removal)" \
88+
"(conservative-value-set-fi-fp-removal)" \
8689
OPT_REMOVE_CONST_FUNCTION_POINTERS \
8790
"(print-internal-representation)" \
8891
"(remove-function-pointers)" \

0 commit comments

Comments
 (0)