Skip to content

Commit 86d36f6

Browse files
authored
Merge pull request #5111 from karkhaz/kk-static-documentation
Add docs for --export-file-local-symbols
2 parents d51243d + a3a7edb commit 86d36f6

File tree

5 files changed

+176
-7
lines changed

5 files changed

+176
-7
lines changed

doc/architectural/static-functions.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
\ingroup module_hidden
2+
\page modular-verification-static Modular Verification of Static Functions
3+
4+
\section verification-of-static Modular Verification of Static Functions
5+
6+
\author Kareem Khazem
7+
8+
This page describes how to use CBMC on static functions.
9+
10+
\tableofcontents
11+
12+
CBMC can check libraries and other codebases that expose several
13+
entry points. To do this, users typically write a *harness* that
14+
captures the entry points' API contract, and that calls into the API
15+
with unconstrained values. The example below shows such a library and
16+
harness:
17+
18+
\code{.c}
19+
void public_api_function(const int *a, int *b)
20+
{
21+
// ...
22+
private_function(a, b);
23+
// ...
24+
}
25+
26+
static void private_function(const int *a, int *b)
27+
{
28+
// ...
29+
}
30+
\endcode
31+
32+
The harness sets up some assumptions and then calls into the API:
33+
34+
\code{.c}
35+
void public_api_function(int *a, int *b);
36+
37+
void harness()
38+
{
39+
int a, b;
40+
__CPROVER_assume(a < 10);
41+
__CPROVER_assume(a >= 0);
42+
public_api_function(&a, &b);
43+
__CPROVER_assert(b != a);
44+
}
45+
\endcode
46+
47+
The following commands build and check this function:
48+
49+
\code{.sh}
50+
> goto-cc -c -o library.o library.c
51+
> goto-cc -c -o harness.o harness.c
52+
> goto-cc -o to_check.gb library.o harness.o
53+
> cbmc --function harness to_check.gb
54+
\endcode
55+
56+
\subsection stubbing-out-static Stubbing out static functions
57+
58+
For performance reasons, it might be desirable to analyze the API
59+
function independently of the static function. We can analyze the API
60+
function by "stubbing out" the static function, replacing it with a
61+
function that does nothing apart from asserting that its inputs satisfy
62+
the function's contract. ("Stubbing out" a function is sometimes known
63+
as "modelling" or "abstracting it out".) Add the following to
64+
`harness.c`:
65+
66+
\code{.c}
67+
static void private_function(const int *a, int *b)
68+
{
69+
__CPROVER_assert( private_function_precondition );
70+
__CPROVER_assume( private_function_postcondition );
71+
}
72+
\endcode
73+
74+
And build as follows, stripping the original static function out of its
75+
object file:
76+
77+
\code{.sh}
78+
> goto-cc -c -o library.o library.c
79+
> goto-instrument --remove-function-body private_function library.o library-no-private.o
80+
>
81+
> goto-cc -c -o harness.o harness.c
82+
>
83+
> # The stub in the harness overrides the implementation of
84+
> # private_function whose body has been removed
85+
> goto-cc -o to_check.gb library-no-private.o harness.o
86+
> cbmc --function harness to_check.gb
87+
\endcode
88+
89+
\subsection checking-static Separately checking static functions
90+
91+
We should now also write a harness for `private_function`. However,
92+
since that function is marked `static`, it is not possible for functions
93+
in external files to call it. We can write and link a harness by
94+
stripping the `static` attribute from `private_function` using goto-cc's
95+
`--export-file-local-symbols` flag.
96+
97+
\code{.sh}
98+
> goto-cc -c -o --export-file-local-symbols library_with_static.o library.c
99+
\endcode
100+
101+
`library_with_static.o` now contains an implementation of `private_function()`
102+
with a mangled name. We can display the mangled name with goto-instrument:
103+
104+
\code{.sh}
105+
> goto-instrument --show-symbol-table library_with_static.o | grep -B1 -A1 "Pretty name.: private_function"
106+
Symbol......: __CPROVER_file_local_library_c_private_function
107+
Pretty name.: private_function
108+
Module......: private_function
109+
\endcode
110+
111+
When we write a harness for the static function, we ensure that we call
112+
the mangled name:
113+
114+
\code{.c}
115+
void harness()
116+
{
117+
int a, b;
118+
119+
__CPROVER_assume( private_function_precondition );
120+
121+
// Call the static function
122+
__CPROVER_file_local_library_c_private_function(&a, &b);
123+
124+
__CPROVER_assert( private_function_postcondition );
125+
}
126+
\endcode
127+
128+
We can then link this harness to the object file with exported symbols
129+
and run CBMC as usual.
130+
131+
\code{.sh}
132+
> goto-cc -c -o private_harness.o private_harness.c
133+
> goto-cc -o to_test.gb private_harness.o library_with_static.o
134+
> cbmc --function harness to_test.gb
135+
\endcode
136+
137+
It is possible that CBMC will generate the same mangled name for two
138+
different static functions. This happens when the functions have the
139+
same name and are written in same-named files that live in different
140+
directories. In the following codebase, the two `qux` functions will
141+
both have their names mangled to `__CPROVER_file_local_b_c_qux`, and
142+
so any harness that requires both of those files will fail to link.
143+
144+
project
145+
|
146+
\_ foo
147+
| |
148+
| \_ a.c
149+
| \_ b.c <- contains static function "qux"
150+
|
151+
\_ bar
152+
|
153+
\_ c.c
154+
\_ b.c <- also contains static function "qux"
155+
156+
The solution is to use the `--mangle-suffix` option to goto-cc. This
157+
allows you to specify a different suffix for name-mangling. By
158+
specifying a custom, different suffix for each of the two files, the
159+
mangled names are unique and the files can be successfully linked.
160+
161+
More examples are in `regression/goto-cc-file-local`.

regression/goto-cc-file-local/chain.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ for src in ${SRC}; do
6363

6464
if [[ "${is_windows}" == "true" ]]; then
6565
"${goto_cc}" \
66-
--export-function-local-symbols \
66+
--export-file-local-symbols \
6767
--verbosity 10 \
6868
${wall} \
6969
${suffix} \
@@ -72,7 +72,7 @@ for src in ${SRC}; do
7272

7373
else
7474
"${goto_cc}" \
75-
--export-function-local-symbols \
75+
--export-file-local-symbols \
7676
--verbosity 10 \
7777
${wall} \
7878
${suffix} \
@@ -86,7 +86,7 @@ if is_in final-link "$ALL_ARGS"; then
8686
rm -f ${OUT_FILE}
8787
if [[ "${is_windows}" == "true" ]]; then
8888
"${goto_cc}" \
89-
--export-function-local-symbols \
89+
--export-file-local-symbols \
9090
--verbosity 10 \
9191
${wall} \
9292
${suffix} \
@@ -95,7 +95,7 @@ if is_in final-link "$ALL_ARGS"; then
9595

9696
else
9797
"${goto_cc}" \
98-
--export-function-local-symbols \
98+
--export-file-local-symbols \
9999
--verbosity 10 \
100100
${wall} \
101101
${suffix} \

src/goto-cc/compile.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,14 +626,22 @@ compilet::compilet(cmdlinet &_cmdline, message_handlert &mh, bool Werror)
626626
ns(goto_model.symbol_table),
627627
cmdline(_cmdline),
628628
warning_is_fatal(Werror),
629-
keep_file_local(cmdline.isset("export-function-local-symbols")),
629+
keep_file_local(
630+
// function-local is the old name and is still in use, but is misleading
631+
cmdline.isset("export-function-local-symbols") ||
632+
cmdline.isset("export-file-local-symbols")),
630633
file_local_mangle_suffix(
631634
cmdline.isset("mangle-suffix") ? cmdline.get_value("mangle-suffix") : "")
632635
{
633636
mode=COMPILE_LINK_EXECUTABLE;
634637
echo_file_name=false;
635638
wrote_object=false;
636639
working_directory=get_current_working_directory();
640+
641+
if(cmdline.isset("export-function-local-symbols"))
642+
warning() << "The `--export-function-local-symbols` flag is deprecated. "
643+
"Please use `--export-file-local-symbols` instead."
644+
<< eom;
637645
}
638646

639647
/// cleans up temporary files

src/goto-cc/gcc_cmdline.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const char *goto_cc_options_without_argument[]=
5252
"--partial-inlining",
5353
"--validate-goto-model",
5454
"-?",
55-
"--export-function-local-symbols",
55+
"--export-file-local-symbols",
5656
nullptr
5757
};
5858

src/goto-cc/ms_cl_cmdline.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const char *non_ms_cl_options[]=
4646
"--verbosity",
4747
"--function",
4848
"--validate-goto-model",
49-
"--export-function-local-symbols",
49+
"--export-file-local-symbols",
5050
"--mangle-suffix",
5151
nullptr
5252
};

0 commit comments

Comments
 (0)