你将如何在 z3 中实现指针的取消引用
How would you implement dereferencing of pointers in z3
在 python 中尝试用 z3 分析一些 C 程序,但遇到了指针问题。我正在使用以下术语:
float * buffer = (float*)malloc(5*sizeof(float))
我将缓冲区解释为 BitVec(32)
值
所以 *buffer
应该是 Real()
。
那应该没问题,但是我应该为
这样的术语写什么断言
*(buffer+3) or *(buffer+i)
如果我像
一样索引出来,应该如何编写断言
*(buffer-1) or *(buffer+10)
一种解决方案是将程序堆编码为从位置到值的映射H
。在Z3中,数组理论可以用来对地图进行编码。
Pointers/addresses为整数位置,整数运算编码指针运算;这将在您的编码中允许诸如 H(buffer + i) > 0
之类的约束。如果您要对一种 OO 语言进行编码,则可以使用该对 (接收方、字段名称) 来对地址进行编码。例如。 H(r, f) > 0
将对应于 r.f > 0
。请注意,此地图编码自然会考虑别名,例如如果 buffer1 == buffer2
和 i == 3
那么 H(buffer1 + i) == H(buffer + 3)
.
有关基于映射的堆编码的有趣比较,请参阅论文 Heaps and Data Structures: A Challenge for Automated Provers。
Map-based encoding 通常由基于验证条件的工具使用,例如 Frama-C, Dafny and Boogie. Tools based on symbolic execution, such as Silicon (which is part of the Viper verification infrastructure) and VeriFast typically use a different encoding; see, e.g. Heap-Dependent expressions in separation logic .
在 python 中尝试用 z3 分析一些 C 程序,但遇到了指针问题。我正在使用以下术语:
float * buffer = (float*)malloc(5*sizeof(float))
我将缓冲区解释为 BitVec(32)
值
所以 *buffer
应该是 Real()
。
那应该没问题,但是我应该为
*(buffer+3) or *(buffer+i)
如果我像
一样索引出来,应该如何编写断言*(buffer-1) or *(buffer+10)
一种解决方案是将程序堆编码为从位置到值的映射H
。在Z3中,数组理论可以用来对地图进行编码。
Pointers/addresses为整数位置,整数运算编码指针运算;这将在您的编码中允许诸如 H(buffer + i) > 0
之类的约束。如果您要对一种 OO 语言进行编码,则可以使用该对 (接收方、字段名称) 来对地址进行编码。例如。 H(r, f) > 0
将对应于 r.f > 0
。请注意,此地图编码自然会考虑别名,例如如果 buffer1 == buffer2
和 i == 3
那么 H(buffer1 + i) == H(buffer + 3)
.
有关基于映射的堆编码的有趣比较,请参阅论文 Heaps and Data Structures: A Challenge for Automated Provers。
Map-based encoding 通常由基于验证条件的工具使用,例如 Frama-C, Dafny and Boogie. Tools based on symbolic execution, such as Silicon (which is part of the Viper verification infrastructure) and VeriFast typically use a different encoding; see, e.g. Heap-Dependent expressions in separation logic .