Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 951b6ce

Browse files
committedAug 18, 2023
Permit re-setting --object-bits and malloc failure mode
Support choosing the number of object bits to be used by CBMC at runtime even with pre-compiled goto binaries. Equally, permit re-setting the malloc failure mode via --malloc-may-fail. Fixes: #5443
1 parent d84744f commit 951b6ce

30 files changed

+203
-168
lines changed
 

‎doc/man/goto-cc.1

-3
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,6 @@ files.
9696
.TP
9797
\fB\-\-print\-rejected\-preprocessed\-source\fR \fIfile\fR
9898
Copy failing (preprocessed) source to \fIfile\fR.
99-
.TP
100-
\fB\-\-object\-bits\fR \fIN\fR
101-
Configure the number of bits used for object numbering in CBMC's pointer encoding.
10299
.SH ENVIRONMENT
103100
All tools honor the TMPDIR environment variable when generating temporary
104101
files and directories.

‎regression/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ else()
6363
add_subdirectory(goto-cl)
6464
endif()
6565
add_subdirectory(goto-cc-cbmc)
66-
add_subdirectory(goto-cc-cbmc-shared-options)
6766
add_subdirectory(cbmc-cpp)
6867
add_subdirectory(goto-cc-goto-analyzer)
6968
add_subdirectory(goto-analyzer-simplify)

‎regression/Makefile

-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ DIRS = cbmc-shadow-memory \
3636
goto-gcc \
3737
goto-cl \
3838
goto-cc-cbmc \
39-
goto-cc-cbmc-shared-options \
4039
cbmc-cpp \
4140
goto-cc-goto-analyzer \
4241
goto-analyzer-simplify \

‎regression/cbmc/simplify_singleton_interval_7690/singleton_interval_in_assume_7690.c

-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <stdlib.h>
66
#include <stdint.h>
77

8-
extern size_t __CPROVER_max_malloc_size;
98
int __builtin_clzll(unsigned long long);
109

1110
#define __nof_symex_objects \

‎regression/goto-cc-cbmc-shared-options/CMakeLists.txt

-11
This file was deleted.

‎regression/goto-cc-cbmc-shared-options/Makefile

-30
This file was deleted.

‎regression/goto-cc-cbmc-shared-options/README.md

-4
This file was deleted.

‎regression/goto-cc-cbmc-shared-options/chain.sh

-20
This file was deleted.

‎regression/goto-cc-cbmc-shared-options/object-bits/fewer_bits.desc renamed to ‎regression/goto-cc-cbmc/object-bits/fewer_bits.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE winbug
1+
CORE
22
test.c
33
--function main --object-bits 6
44
^EXIT=10$

‎regression/goto-cc-cbmc-shared-options/object-bits/more_bits.desc renamed to ‎regression/goto-cc-cbmc/object-bits/more_bits.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE winbug
1+
CORE
22
test.c
33
--function main --object-bits 10
44
^EXIT=10$

‎src/ansi-c/ansi_c_internal_additions.cpp

+3-31
Original file line numberDiff line numberDiff line change
@@ -130,34 +130,6 @@ static std::string architecture_string(T value, const char *s)
130130
std::string(s) + "=" + std::to_string(value) + ";\n";
131131
}
132132

133-
/// The maximum allocation size is determined by the number of bits that
134-
/// are left in the pointer of width \p pointer_width.
135-
///
136-
/// The allocation size cannot exceed the number represented by the (signed)
137-
/// offset, otherwise it would not be possible to store a pointer into a
138-
/// valid bit of memory. Therefore, the max allocation size is
139-
/// 2^(offset_bits - 1), where the offset bits is the number of bits left in the
140-
/// pointer after the object bits.
141-
///
142-
/// The offset must be signed, as a pointer can point to the end of the memory
143-
/// block, and needs to be able to point back to the start.
144-
/// \param pointer_width: The width of the pointer
145-
/// \param object_bits : The number of bits used to represent the ID
146-
/// \return The size in bytes of the maximum allocation supported.
147-
static mp_integer
148-
max_malloc_size(std::size_t pointer_width, std::size_t object_bits)
149-
{
150-
PRECONDITION(pointer_width >= 1);
151-
PRECONDITION(object_bits < pointer_width);
152-
PRECONDITION(object_bits >= 1);
153-
const auto offset_bits = pointer_width - object_bits;
154-
// We require the offset to be able to express upto allocation_size - 1,
155-
// but also down to -allocation_size, therefore the size is allowable
156-
// is number of bits, less the signed bit.
157-
const auto bits_for_positive_offset = offset_bits - 1;
158-
return ((mp_integer)1) << (mp_integer)bits_for_positive_offset;
159-
}
160-
161133
void ansi_c_internal_additions(std::string &code)
162134
{
163135
// clang-format off
@@ -181,9 +153,9 @@ void ansi_c_internal_additions(std::string &code)
181153
CPROVER_PREFIX "size_t size, " CPROVER_PREFIX "bool zero);\n"
182154
"void " CPROVER_PREFIX "deallocate(void *);\n"
183155

184-
CPROVER_PREFIX "size_t " CPROVER_PREFIX "max_malloc_size="+
185-
integer2string(max_malloc_size(config.ansi_c.pointer_width, config
186-
.bv_encoding.object_bits))+";\n"
156+
CPROVER_PREFIX "thread_local " CPROVER_PREFIX "size_t "
157+
CPROVER_PREFIX "max_malloc_size="+
158+
integer2string(config.max_malloc_size())+";\n"
187159

188160
// this is ANSI-C
189161
"extern " CPROVER_PREFIX "thread_local const char __func__["

‎src/ansi-c/cprover_library.cpp

+1-6
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,14 @@ static std::string get_cprover_library_text(
2424
std::ostringstream library_text;
2525

2626
library_text << "#line 1 \"<built-in-additions>\"\n"
27-
"#define " CPROVER_PREFIX "malloc_failure_mode "
28-
<< std::to_string(config.ansi_c.malloc_failure_mode)
29-
<< "\n"
3027
"#define " CPROVER_PREFIX "malloc_failure_mode_return_null "
3128
<< std::to_string(config.ansi_c.malloc_failure_mode_return_null)
3229
<< "\n"
3330
"#define " CPROVER_PREFIX
3431
"malloc_failure_mode_assert_then_assume "
3532
<< std::to_string(
3633
config.ansi_c.malloc_failure_mode_assert_then_assume)
37-
<< "\n"
38-
"#define " CPROVER_PREFIX "malloc_may_fail "
39-
<< std::to_string(config.ansi_c.malloc_may_fail) << "\n";
34+
<< "\n";
4035

4136
library_text <<
4237
"#line 1 \"<builtin-library>\"\n"

‎src/ansi-c/cprover_library.h

+1
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,5 @@ void cprover_c_library_factory_force_load(
5252
const std::set<irep_idt> &functions,
5353
symbol_table_baset &symbol_table,
5454
message_handlert &message_handler);
55+
5556
#endif // CPROVER_ANSI_C_CPROVER_LIBRARY_H

‎src/ansi-c/library/cprover.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ void __CPROVER_deallocate(void *);
2525
extern const void *__CPROVER_deallocated;
2626
extern const void *__CPROVER_memory_leak;
2727

28-
extern int __CPROVER_malloc_failure_mode;
29-
extern __CPROVER_size_t __CPROVER_max_malloc_size;
30-
extern __CPROVER_bool __CPROVER_malloc_may_fail;
28+
extern __CPROVER_thread_local __CPROVER_size_t __CPROVER_max_malloc_size;
3129

3230
// malloc failure modes
3331
extern int __CPROVER_malloc_failure_mode_return_null;

‎src/ansi-c/library/cprover_contracts.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77
#define __CPROVER_contracts_library_defined
88

99
// external dependencies
10-
extern __CPROVER_size_t __CPROVER_max_malloc_size;
1110
const void *__CPROVER_alloca_object = 0;
1211
extern const void *__CPROVER_deallocated;
1312
const void *__CPROVER_new_object = 0;
1413
extern const void *__CPROVER_memory_leak;
1514
__CPROVER_bool __CPROVER_malloc_is_new_array = 0;
15+
extern __CPROVER_thread_local int __CPROVER_malloc_failure_mode;
1616
int __builtin_clzll(unsigned long long);
1717
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool(void);
1818
__CPROVER_size_t __VERIFIER_nondet_size(void);

‎src/ansi-c/library/stdlib.c

+4
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ __CPROVER_bool __VERIFIER_nondet___CPROVER_bool(void);
142142
_Bool __builtin_mul_overflow();
143143
#endif
144144
__CPROVER_bool __CPROVER_malloc_is_new_array = 0;
145+
__CPROVER_thread_local int __CPROVER_malloc_failure_mode = 0;
146+
__CPROVER_thread_local __CPROVER_bool __CPROVER_malloc_may_fail = 0;
145147

146148
void *calloc(__CPROVER_size_t nmemb, __CPROVER_size_t size)
147149
{
@@ -205,6 +207,8 @@ __CPROVER_HIDE:;
205207
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool(void);
206208
#ifndef LIBRARY_CHECK
207209
__CPROVER_bool __CPROVER_malloc_is_new_array = 0;
210+
__CPROVER_thread_local int __CPROVER_malloc_failure_mode = 0;
211+
__CPROVER_thread_local __CPROVER_bool __CPROVER_malloc_may_fail = 0;
208212
#endif
209213

210214
// malloc is marked "inline" for the benefit of goto-analyzer. Really,

‎src/cbmc/cbmc_parse_options.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Author: Daniel Kroening, kroening@kroening.com
1111

1212
#include "cbmc_parse_options.h"
1313

14+
#include <util/c_types.h>
1415
#include <util/config.h>
1516
#include <util/exit_codes.h>
1617
#include <util/help_formatter.h>
@@ -744,6 +745,8 @@ int cbmc_parse_optionst::get_goto_program(
744745

745746
goto_model = initialize_goto_model(cmdline.args, ui_message_handler, options);
746747

748+
update_max_malloc_size(goto_model, ui_message_handler);
749+
747750
if(cmdline.isset("show-symbol-table"))
748751
{
749752
show_symbol_table(goto_model, ui_message_handler);
@@ -830,6 +833,13 @@ bool cbmc_parse_optionst::process_goto_program(
830833
link_to_library(
831834
goto_model, log.get_message_handler(), cprover_c_library_factory);
832835

836+
if(
837+
config.ansi_c.malloc_failure_mode !=
838+
configt::ansi_ct::malloc_failure_mode_none)
839+
{
840+
update_malloc_configuration(goto_model, log.get_message_handler());
841+
}
842+
833843
// Common removal of types and complex constructs
834844
if(::process_goto_program(goto_model, options, log))
835845
return true;

‎src/goto-cc/gcc_cmdline.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ const char *goto_cc_options_with_separated_argument[]=
2929
"--native-linker",
3030
"--print-rejected-preprocessed-source",
3131
"--mangle-suffix",
32-
"--object-bits",
3332
nullptr
3433
};
3534

‎src/goto-cc/goto_cc_mode.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ void goto_cc_modet::help()
6969
" --mangle-suffix suffix append suffix to exported file-local symbols\n"
7070
" --print-rejected-preprocessed-source file\n"
7171
" copy failing (preprocessed) source to file\n"
72-
" --object-bits number of bits used for object addresses\n"
7372
"\n";
7473
// clang-format on
7574
}

‎src/goto-instrument/goto_instrument_parse_options.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Author: Daniel Kroening, kroening@kroening.com
3232
#include <goto-programs/ensure_one_backedge_per_target.h>
3333
#include <goto-programs/goto_check.h>
3434
#include <goto-programs/goto_inline.h>
35+
#include <goto-programs/initialize_goto_model.h>
3536
#include <goto-programs/interpreter.h>
3637
#include <goto-programs/label_function_pointer_call_sites.h>
3738
#include <goto-programs/link_to_library.h>
@@ -1086,6 +1087,13 @@ void goto_instrument_parse_optionst::instrument_goto_program()
10861087
link_to_library(
10871088
goto_model, ui_message_handler, cprover_cpp_library_factory);
10881089
link_to_library(goto_model, ui_message_handler, cprover_c_library_factory);
1090+
1091+
if(
1092+
config.ansi_c.malloc_failure_mode !=
1093+
configt::ansi_ct::malloc_failure_mode_none)
1094+
{
1095+
update_malloc_configuration(goto_model, log.get_message_handler());
1096+
}
10891097
}
10901098

10911099
{

‎src/goto-programs/initialize_goto_model.cpp

+71-5
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,27 @@ Author: Daniel Kroening, kroening@kroening.com
1111

1212
#include "initialize_goto_model.h"
1313

14-
#include <fstream>
15-
14+
#include <util/arith_tools.h>
15+
#include <util/c_types.h>
1616
#include <util/config.h>
17+
#include <util/expr_util.h>
1718
#include <util/message.h>
1819
#include <util/options.h>
1920

21+
#include <fstream>
22+
2023
#ifdef _MSC_VER
2124
# include <util/unicode.h>
2225
#endif
2326

27+
#include <util/exception_utils.h>
28+
29+
#include <goto-programs/rebuild_goto_start_function.h>
30+
2431
#include <langapi/language.h>
2532
#include <langapi/language_file.h>
2633
#include <langapi/mode.h>
27-
28-
#include <goto-programs/rebuild_goto_start_function.h>
29-
#include <util/exception_utils.h>
34+
#include <linking/static_lifetime_init.h>
3035

3136
#include "goto_convert_functions.h"
3237
#include "read_goto_binary.h"
@@ -245,3 +250,64 @@ goto_modelt initialize_goto_model(
245250

246251
return goto_model;
247252
}
253+
254+
void update_max_malloc_size(
255+
goto_modelt &goto_model,
256+
message_handlert &message_handler)
257+
{
258+
if(!goto_model.symbol_table.has_symbol(CPROVER_PREFIX "max_malloc_size"))
259+
return;
260+
261+
const auto previous_max_malloc_size_value = numeric_cast<mp_integer>(
262+
goto_model.symbol_table.lookup_ref(CPROVER_PREFIX "max_malloc_size").value);
263+
const mp_integer current_max_malloc_size = config.max_malloc_size();
264+
265+
if(
266+
!previous_max_malloc_size_value.has_value() ||
267+
*previous_max_malloc_size_value != current_max_malloc_size)
268+
{
269+
symbolt &max_malloc_size_sym = goto_model.symbol_table.get_writeable_ref(
270+
CPROVER_PREFIX "max_malloc_size");
271+
max_malloc_size_sym.value =
272+
from_integer(current_max_malloc_size, size_type());
273+
274+
if(goto_model.can_produce_function(INITIALIZE_FUNCTION))
275+
recreate_initialize_function(goto_model, message_handler);
276+
}
277+
}
278+
279+
void update_malloc_configuration(
280+
goto_modelt &goto_model,
281+
message_handlert &message_handler)
282+
{
283+
const symbolt *malloc_may_fail_ptr =
284+
goto_model.symbol_table.lookup(CPROVER_PREFIX "malloc_may_fail");
285+
if(!malloc_may_fail_ptr)
286+
return;
287+
288+
bool reinit_required = false;
289+
if(malloc_may_fail_ptr->value.is_true() != config.ansi_c.malloc_may_fail)
290+
{
291+
symbolt &malloc_may_fail_sym = goto_model.symbol_table.get_writeable_ref(
292+
CPROVER_PREFIX "malloc_may_fail");
293+
malloc_may_fail_sym.value =
294+
make_boolean_expr(config.ansi_c.malloc_may_fail);
295+
reinit_required = true;
296+
}
297+
298+
symbolt &malloc_failure_mode_sym = goto_model.symbol_table.get_writeable_ref(
299+
CPROVER_PREFIX "malloc_failure_mode");
300+
const auto previous_failure_mode =
301+
numeric_cast<mp_integer>(malloc_failure_mode_sym.value);
302+
if(
303+
!previous_failure_mode.has_value() ||
304+
*previous_failure_mode != config.ansi_c.malloc_failure_mode)
305+
{
306+
malloc_failure_mode_sym.value =
307+
from_integer(config.ansi_c.malloc_failure_mode, signed_int_type());
308+
reinit_required = true;
309+
}
310+
311+
if(reinit_required && goto_model.can_produce_function(INITIALIZE_FUNCTION))
312+
recreate_initialize_function(goto_model, message_handler);
313+
}

0 commit comments

Comments
 (0)
Please sign in to comment.