如何强制内存位置在ACSL中有效?

时间:2017-07-20 18:33:28

标签: frama-c 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(struct 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;
}

使用

运行
  

frama -c-wp -wp-rte -wp-init-const -wp-model Typed test.c

2 个答案:

答案 0 :(得分:2)

我认为证明断言的唯一方法是放置形式的公理块

/*@ 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.mlwglobal(0) base 0 shiftoffset(仅修改valid_rw)。 base的定义强加了\valid,因此存在矛盾。

这必须在WP的水平上修复。但是,在等待新的Frama-C版本时,有一些可用的解决方法:

  • 如果您不需要写入实际位置,则可以在公理中用\valid_read替换\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.vglobal中修补内存模型,具体取决于您选择的投标人)。最简单的方法可能是让Incident Identifier: C25BD8DF-FAA9-4A5F-B3D2-6E1CE81F1D17 CrashReporter Key: 798f7dee81117ed0f05b3f19dc4bbc2874eefaf6 Hardware Model: iPhone9,2 Process: My app [1936] Path: /private/var/containers/Bundle/Application/757D7BE6-4F91-4B74-BA64-09FA53AE3E16/My app.app/My app Identifier: com.app.Myapp Version: 12 (1.1) Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd [1] Coalition: com.app.Myapp [701] Date/Time: 2017-06-27 20:05:28.7901 -0400 Launch Time: 2017-06-27 16:38:23.0376 -0400 OS Version: iPhone OS 10.3.2 (14F89) Report Version: 104 Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000010 Termination Signal: Segmentation fault: 11 Termination Reason: Namespace SIGNAL, Code 0xb Terminating Process: exc handler [0] Triggered by Thread: 0 Thread 0 name: Thread 0 Crashed: 0 UIKit 0x0000000190ee4264 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 444 (UIPresentationController.m:731) 1 UIKit 0x0000000190ee4260 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 440 (UIPresentationController.m:731) 2 UIKit 0x0000000190e20950 _runAfterCACommitDeferredBlocks + 292 (UIApplication.m:2469) 3 UIKit 0x0000000190e129ec _cleanUpAfterCAFlushAndRunDeferredBlocks + 528 (UIApplication.m:2447) 4 UIKit 0x0000000190b86648 _afterCACommitHandler + 132 (UIApplication.m:2499) 5 CoreFoundation 0x000000018aa109a8 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32 (CFRunLoop.c:1802) 6 CoreFoundation 0x000000018aa0e630 __CFRunLoopDoObservers + 372 (CFRunLoop.c:1898) 7 CoreFoundation 0x000000018aa0ea7c __CFRunLoopRun + 956 (CFRunLoop.c:2849) 8 CoreFoundation 0x000000018a93eda4 CFRunLoopRunSpecific + 424 (CFRunLoop.c:3113) 9 GraphicsServices 0x000000018c3a8074 GSEventRunModal + 100 (GSEvent.c:2245) 10 UIKit 0x0000000190bf9058 UIApplicationMain + 208 (UIApplication.m:4089) 11 My app 0x000000010005a8b4 main + 56 (Database.swift:17) 12 libdyld.dylib 0x000000018994d59c start + 4 依赖于抽象基础,如:
logic global_base: int

function global(b: int) : addr = { base = global_base + b; offset = 0 }

(当然注意,这个答案并不能保证这不会在模型中引入其他问题)。

答案 1 :(得分:0)

不是我知道的(我也经常尝试过)。

我找到的唯一解决方法是:

struct mydevice MY_DEVICE_STRUCT;
volatile struct mydevice * const dev = & MY_DEVICE_STRUCT;

你需要&#34;实例化&#34;内存,因为这是底层LLVM所期望的。肯定通过ACSL表示法强制执行此操作会很好。