Skip to content

goto-instrument: function pointer removal with value_set_fi #5436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <assert.h>

typedef void (*fp_t)();

void f()
{
}

void g()
{
}

int main(void)
{
fp_t fp = f;
fp();

// this would fool an analysis that looks for functions whose address is taken
fp_t other_fp = g;
}
12 changes: 12 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CORE
test.c
--value-set-fi-fp-removal
^EXIT=0$
^SIGNAL=0$
^ function: f$
--
^ function: g$
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Negative as well as positive tests are good.

--
This test checks that the value-set-fi-based function pointer removal
precisely identifies the function to call for a particular function pointer
call.
27 changes: 27 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal2/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

typedef void (*fp_t)(int, int);

void add(int a, int b)
{
}
void subtract(int a, int b)
{
}
void multiply(int a, int b)
{
}

int main()
{
// fun_ptr_arr is an array of function pointers
void (*fun_ptr_arr[])(int, int) = {add, subtract, add};

// Multiply should not be added into the value set
fp_t other_fp = multiply;
void (*fun_ptr_arr2[])(int, int) = {multiply, subtract, add};

// the fp removal over-approximates and assumes this could be any pointer in the array
(*fun_ptr_arr[0])(1, 1);

return 0;
}
13 changes: 13 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal2/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CORE
test.c
--value-set-fi-fp-removal
^EXIT=0$
^SIGNAL=0$
^ function: add$
^ function: subtract$
--
^ function: multiply$
--
This test checks that the value-set-fi-based function pointer removal
precisely identifies the function to call for a particular function pointer
call.
32 changes: 32 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal3/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
typedef void (*fp_t)(int, int);

void add(int a, int b)
{
}
void subtract(int a, int b)
{
}
void multiply(int a, int b)
{
}

int main()
{
// fun_ptr_arr is an array of function pointers
struct my_struct
{
fp_t first_pointer;
fp_t second_pointer;
} struct1;

struct1.first_pointer = add;

// Multiply and subtract should not be added into the value set
fp_t other_fp = multiply;
struct1.second_pointer = subtract;

// this pointer can only be "add"
struct1.first_pointer(1, 1);

return 0;
}
13 changes: 13 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal3/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CORE
test.c
--value-set-fi-fp-removal
^EXIT=0$
^SIGNAL=0$
^ function: add$
--
^ function: multiply$
^ function: subtract$
--
This test checks that the value-set-fi-based function pointer removal
precisely identifies the function to call for a particular function pointer
call.
21 changes: 21 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal4/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include <assert.h>

typedef void (*fp_t)();

void f()
{
}

void g()
{
}

int main(void)
{
// the value set for fp is empty, defaults to standard function pointer removal behaviour
fp_t other_fp = g;
other_fp = f;

fp_t fp;
fp();
}
10 changes: 10 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal4/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
test.c
--value-set-fi-fp-removal
^EXIT=0$
^SIGNAL=0$
^file test.c line 20 function main: replacing function pointer by 2 possible targets$
--
This test checks that the value-set-fi-based function pointer removal
precisely identifies the function to call for a particular function pointer
call.
20 changes: 20 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal5/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <assert.h>

typedef void (*fp_t)();

void f(int x)
{
}

void g(int y)
{
}

int main(void)
{
// the value set is empty, defaults to standard function pointer removal behaviour
fp_t other_fp = g;

fp_t fp;
fp();
}
10 changes: 10 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal5/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
CORE
test.c
--value-set-fi-fp-removal
^EXIT=0$
^SIGNAL=0$
^file test.c line 19 function main: replacing function pointer by 0 possible targets$
--
This test checks that the value-set-fi-based function pointer removal
precisely identifies the function to call for a particular function pointer
call.
19 changes: 19 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal6/test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include <assert.h>

typedef void (*fp_t)(void);

void f()
{
}

void g()
{
}

int main(void)
{
fp_t fp = f;
fp_t decoy_fp = g;
fp_t *ptr_to_func_ptr = &fp; // a pointer to a function pointer
(*ptr_to_func_ptr)();
}
12 changes: 12 additions & 0 deletions regression/goto-instrument/value-set-fi-fp-removal6/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CORE
test.c
--value-set-fi-fp-removal
^EXIT=0$
^SIGNAL=0$
^ function: f$
--
^ function: g$
--
This test checks that the value-set-fi-based function pointer removal
precisely identifies the function to call for a particular function pointer
call.
1 change: 1 addition & 0 deletions src/goto-instrument/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ SRC = accelerate/accelerate.cpp \
uninitialized.cpp \
unwind.cpp \
unwindset.cpp \
value_set_fi_fp_removal.cpp \
wmm/abstract_event.cpp \
wmm/cycle_collection.cpp \
wmm/data_dp.cpp \
Expand Down
11 changes: 11 additions & 0 deletions src/goto-instrument/goto_instrument_parse_options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Author: Daniel Kroening, [email protected]
#include <pointer-analysis/goto_program_dereference.h>
#include <pointer-analysis/show_value_sets.h>
#include <pointer-analysis/value_set_analysis.h>
#include <pointer-analysis/value_set_analysis_fi.h>

#include <analyses/call_graph.h>
#include <analyses/constant_propagator.h>
Expand Down Expand Up @@ -111,6 +112,7 @@ Author: Daniel Kroening, [email protected]
#include "undefined_functions.h"
#include "uninitialized.h"
#include "unwind.h"
#include "value_set_fi_fp_removal.h"
#include "wmm/weak_memory.h"

/// invoke main modules
Expand Down Expand Up @@ -1198,6 +1200,12 @@ void goto_instrument_parse_optionst::instrument_goto_program()
exit(CPROVER_EXIT_USAGE_ERROR);
}

if(cmdline.isset("value-set-fi-fp-removal"))
{
value_set_fi_fp_removal(goto_model, ui_message_handler);
do_indirect_call_and_rtti_removal();
}

// replace function pointers, if explicitly requested
if(cmdline.isset("remove-function-pointers"))
{
Expand Down Expand Up @@ -1867,6 +1875,9 @@ void goto_instrument_parse_optionst::help()
" --no-caching disable caching of intermediate results during transitive function inlining\n" // NOLINT(*)
" --log <file> log in json format which code segments were inlined, use with --function-inline\n" // NOLINT(*)
" --remove-function-pointers replace function pointers by case statement over function calls\n" // NOLINT(*)
" --value-set-fi-fp-removal build flow-insensitive value set and replace function pointers by a case statement\n" // NOLINT(*)
" over the possible assignments. If the set of possible assignments is empty the function pointer\n" // NOLINT(*)
" is removed using the standard remove-function-pointers pass. \n" // NOLINT(*)
HELP_RESTRICT_FUNCTION_POINTER
HELP_REMOVE_CALLS_NO_BODY
HELP_REMOVE_CONST_FUNCTION_POINTERS
Expand Down
1 change: 1 addition & 0 deletions src/goto-instrument/goto_instrument_parse_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Author: Daniel Kroening, [email protected]
"(full-slice)(reachability-slice)(slice-global-inits)" \
"(fp-reachability-slice):" \
"(inline)(partial-inline)(function-inline):(log):(no-caching)" \
"(value-set-fi-fp-removal)" \
OPT_REMOVE_CONST_FUNCTION_POINTERS \
"(print-internal-representation)" \
"(remove-function-pointers)" \
Expand Down
Loading