22
33## Restricting function pointers
44
5+ In this document, we describe the ` goto-instrument ` feature to replace calls
6+ through function pointers by case distinctions over calls to given sets of
7+ functions.
8+
59### Motivation
610
7- CBMC comes with a way to resolve calls to function pointers to direct function
8- calls. This is needed because symbolic execution itself can't handle calls to
9- function pointers. In practice, this looks something like this:
11+ The CPROVER framework includes a goto program transformation pass
12+ ` remove_function_pointers() ` to resolve calls to function pointers to direct
13+ function calls. The pass is needed by ` cbmc ` , as symbolic execution itself can't
14+ handle calls to function pointers. In practice, the transformation pass works as
15+ follows:
1016
1117Given that there are functions with these signatures available in the program:
1218
@@ -53,15 +59,16 @@ functions matching a particular signature, or if some of these functions are
5359expensive in symex (e.g. functions with lots of loops or recursion), then this
5460can be a bit cumbersome - especially if we, as a user, already know that a
5561particular function pointer will only resolve to a single function or a small
56- set of functions. This is what the ` --restrict-function-pointer ` option allows.
62+ set of functions. The ` goto-instrument ` option ` --restrict-function-pointer `
63+ allows to manually specify this set of functions.
5764
5865### Example
5966
60- Take the motivating example. Let us assume that we know for a fact that ` call `
61- will always receive pointers to either ` f ` or ` g ` during actual executions of
62- the program, and symbolic execution for ` h ` is too expensive to simply ignore
63- the cost of its branch. For this, we will label the places in each function
64- where function pointers are being called, to this pattern:
67+ Take the motivating example above . Let us assume that we know for a fact that
68+ ` call ` will always receive pointers to either ` f ` or ` g ` during actual
69+ executions of the program, and symbolic execution for ` h ` is too expensive to
70+ simply ignore the cost of its branch. For this, we will label the places in each
71+ function where function pointers are being called, to this pattern:
6572
6673```
6774<function-name>.function_pointer_call.<N>
@@ -70,14 +77,14 @@ where function pointers are being called, to this pattern:
7077where ` N ` is referring to which function call it is - so the first call to a
7178function pointer in a function will have ` N=1 ` , the 5th ` N=5 ` etc.
7279
73- We can call ` cbmc ` with ` --restrict-function-pointer
74- call.function_pointer_call.1/f,g`. This can be read as
80+ We can call `goto-instrument --restrict-function-pointer
81+ call.function_pointer_call.1/f,g in.gb out.gb `. This can be read as
7582
7683> For the first call to a function pointer in the function ` call ` , assume that
7784> it can only be a call to ` f ` or ` g `
7885
79- The resulting code looks similar to the original example, except now there will
80- not be a call to ` h ` :
86+ The resulting output (written to goto binary ` out.gb ` ) looks similar to the
87+ original example, except now there will not be a call to ` h ` :
8188
8289```
8390void call(fptr_t fptr) {
0 commit comments