I'm trying to prove some C code with the WP plugin of Frama-C and have problem with example below:
typedef unsigned char uint8_t;
const uint8_t globalStringArray[] = "demo";
const int STRING_LEN = 5;
/*@ requires \valid(src) && \valid(dest) && len < 32 ; */
void copyMemory(uint8_t * src, uint8_t * dest, unsigned int len);
/*@ requires \valid(arrayParam) && len < 32 ; */
uint8_t func(uint8_t * arrayParam, unsigned int len)
{
uint8_t arrayBig[512] = { 0 };
uint8_t * array_ptr = arrayBig;
copyMemory(array_ptr, arrayParam, len);
array_ptr = array_ptr + len;
copyMemory(array_ptr, globalStringArray, STRING_LEN);
array_ptr = array_ptr + STRING_LEN;
return array_ptr[0];
}
Command:
frama-c -wp -wp-rte test.c
My frama-c has Version: Sodium-20150201, and alt-ergo is 0.95.2
The result is
[kernel] warning: No code nor implicit assigns clause for function copyMemory, generating default assigns from the prototype
[rte] annotating function func
[wp] 4 goals scheduled
[wp] [Qed] Goal typed_func_assert_rte_mem_access : Valid
[wp] [Qed] Goal typed_func_call_Frama_C_bzero_pre : Valid
[wp] [Alt-Ergo] Goal typed_func_call_copyMemory_pre : Valid (275ms) (209)
[wp] [Alt-Ergo] Goal typed_func_call_copyMemory_pre_2 : Unknown (907ms)
I have noticed that when I will change
const uint8_t globalStringArray[] = "demo";
const int STRING_LEN = 5;
to
uint8_t globalStringArray[] = "demo";
int STRING_LEN = 5;
and
/*@ requires \valid(arrayParam) && len < 32 && \valid(globalStringArray);
requires STRING_LEN == 5;*/
uint8_t func(uint8_t * arrayParam, unsigned int len)
{
the result is
[wp] Proved goals: 4 / 4
but I don't want to rely on 'requires STRING_LEN == 5;' and prove first example with 'const'. How to achieve that?
Option
-wp-init-constwill instruct WP to consider thatconstglobals indeed have keep their initial value throughout program execution (this is not the default, as, although this invokes undefined behavior at some point, some C code seems to consider thatconstis more an advice than a binding rule).However, in that case, you still won't be able to prove your pre-condition, as it is indeed false:
&globalStringArray[0]is not valid, since it is an array ofconst. If you modify the contract ofcopyMemoryto say\valid_read(dest), then everything will be proved with the-wp-init-constoption.A few additional notes on your specification, even though they are not directly related to your question:
requiresclause ofcopyMemorydoes not requiresrcanddestto point to a valid block of length at leastlen. Presumably you want to write something like\valid(src+(0 .. length - 1))srcanddest, since it is a bit weird to pass aconstarray as thedestination of a copy function.copyMemoryhere) must come with anassignsclause indicating which memory locations might be modified by the callee