如何强制内存位置在ACSL中有效?
我定义设备访问如从而如何强制内存位置在ACSL中有效?
volatile struct mydevice * const dev = (struct mydevice *)MY_DEVICE_ADDRESS;
我建模使用
@ volatile dev->somereg reads somereg_read writes somereg_write;
现在的问题是,当我使RTE检查,所产生的有效性检查不能证明
的访问/*@ assert rte: mem_access: \valid(dev->somereg); */
有什么办法来标注我的代码,这样MY_DEVICE_ADDRESS高达MY_DEVICE_ADDRESS +的sizeof(结构mydevice在)被认为是有效的?
编辑:下面是不起作用
#include <stdint.h>
#define MY_DEVICE_ADDRESS (0x80000000)
struct mydevice {
uint32_t somereg;
uint32_t someotherreg;
};
volatile struct mydevice * const dev = (struct mydevice *)MY_DEVICE_ADDRESS;
/*@ axiomatic Physical_Memory {
axiom Dev: \valid((struct mydevice*)MY_DEVICE_ADDRESS);
} */
int main(int argc, const char *argv[]) {
//@ assert \valid(dev);
//@ assert \false;
return 0;
}
运行与
邮资-C-WP -wp即食-wp-INIT const的-wp模型类型化试验的尝试。 c
我认为有断言的唯一办法证明是把形式
/*@ axiomatic Physical_Memory {
axiom Dev: \valid((struct mydevice*)MY_DEVICE_ADDRESS);
// add more if you have other physical memory accesses
} */
的公理块没有在内核-absolute-valid-range <min-max>
一个选项,以表明在给定区间内的解引用指针好吧,但只有EVA能够利用它(我认为这对WP的内存模型来说太低级了)。
另外还需要注意的是,您可以将选项-wp-init-const
传递给WP,表明它应该在其上下文中添加全局const
变量总是等于其初始值的事实。
编辑
正如在评论中提到的,所提出的公理与WP的内存模型确实不一致。问题的主要原因在于,在所述模型中,数字地址0xnnnn
显然被定义为shift(global(0),0xnnnn)
。从例如可以看出, $FRAMAC_SHARE/wp/ergo/Memory.mlw
,global(0)
具有0
一个base
,所以具有shift
(只修改offset
)。 valid_rw
的定义强加一个严格正数base
,因此是矛盾的。
这必须固定在WP的水平。不过,也有提供一些解决办法,同时等待新的邮资-C版本:
- ,如果你不需要写物理位置,则可以通过
\valid_read
在公理代替\valid
。模型中\valid_read
的定义没有base>0
的要求,因此公理不会导致矛盾。 - 如果你能负担得起修改源代码,使
dev
的extern
声明(或定义dev
为等于一个extern
声明abstract_dev
),并在公理使用抽象常数:这样,你不会有平等dev.base==0
在逻辑模型中,消除矛盾。 - 最后,您可以在
$FRAMAC_SHARE/wp/ergo/Memory.mlw
(和$FRAMAC_SHARE/wp/why3/Memory.why
和$FRAMAC_SHARE/wp/coq/Memory.v
取决于您选择的证明者)中修补内存模型。这样做很可能使global
最简单的方法依赖于一个抽象的基础,如:
logic global_base: int function global(b: int) : addr = { base = global_base + b; offset = 0 }
(当然,需要注意的是这个答案不会以任何方式保证,这不会引入其他问题模型)。
不是我所知道的(我也试过很多)。
我发现的唯一的解决方法是:
struct mydevice MY_DEVICE_STRUCT;
volatile struct mydevice * const dev = & MY_DEVICE_STRUCT;
你需要“实例”存储,因为这是底层LLVM所期待的。当然,通过ACSL表示强制这样做会很好。
问题是我需要将设备寄存器映射到特定的物理地址。我想我可以尝试一些链接技巧,看看是否可行。 – Yifan
我以某种方式怀疑你描述的问题与你的内存位置的volatile性质有关(尽管这确实是其他问题的根源)。从你所描述的,我怀疑'MY_DEVICE_ADDRESS'是一个绝对的物理地址(例如0xdeadbeef)。你可以提供一个MWE,并指明你打算使用哪个插件(再次,我想这是WP,我恐怕无法证明绝对内存地址的任何内容) – Virgile
是的,它是WP和是的它是一个绝对的物理地址。这就是我害怕的,我会看看开发者是否有解决方案。 – Yifan