SVFTools的约束图CG


SVFTools的约束图 C o n s t r a i n t G r a p h ConstraintGraph ConstraintGraph简称 CG,是用来做指针分析的。根据四条规则,在PAG的基础上建立。在这个过程中,PAG是不变的,而CG则是有可能改变的。

指针分析的Andersen规则与SVF中的规则

使用集合符号,令 p p p是一个指针,则 p t s ( p ) pts(p) pts(p) p p p所有可能指向的对象的集合。例如源代码

int o1, o2, *p;
p = &o1; p = &o2;

p t s ( p ) = { o 1 , o 2 } pts(p)=\{o1, o2\} pts(p)={o1,o2}
Andersen指针规则一共有4条,两条基本规则,两条扩展规则。

序号规则说明
1 x = & o , 则   o ∈ p t s ( x ) x={\&}o,则\ o\in pts(x) x=&o, opts(x)如果有 x = & o x={\&}o x=&o语句,则将 o o o加到 p t s ( x ) pts(x) pts(x)
2 x = y , 则   p t s ( x ) ⊇ p t s ( y ) x=y,则\ pts(x)\supseteq pts(y) x=y, pts(x)pts(y)如果有 x = y x=y x=y语句,则将 p t s ( y ) pts(y) pts(y)加到 p t s ( x ) pts(x) pts(x)
3 x = ∗ y , 则   p t s ( x ) ⊇ p t s ( o ) , 其 中 o ∈ p t s ( y ) x=*y,则\ pts(x)\supseteq pts(o),其中o\in pts(y) x=y, pts(x)pts(o),opts(y)如果有 x = ∗ y x=*y x=y语句,则将 p t s ( y ) pts(y) pts(y)中所有元素的 p t s pts pts集合加到 p t s ( x ) pts(x) pts(x)
4 ∗ x = y , 则   p t s ( o ) ⊇ p t s ( y ) , 其 中 o ∈ p t s ( x ) *x=y,则\ pts(o)\supseteq pts(y),其中o\in pts(x) x=y, pts(o)pts(y),opts(x)如果有 ∗ x = y *x=y x=y语句,则将 p t s ( y ) pts(y) pts(y)加到 p t s ( x ) pts(x) pts(x)中的每一个元素的 p t s pts pts集合中

有SVFTools操作的LLVMIR指令,并且将指令转变为了SVF的图数据结构,因此SVF中有不同的规则表现形式,其规则是

序号规则说明
1 s ⟶ a d d r t , 则 s ∈ p t s ( t ) s\stackrel{addr}{\longrightarrow}t,则s\in pts(t) saddrt,spts(t)如果s到t有一条addr边,则将s加到pts(t)中
2 s ⟶ c o p y t , 则 p t s ( s ) ∪ p t s ( t ) s\stackrel{copy}{\longrightarrow}t,则pts(s)\cup pts(t) scopyt,pts(s)pts(t)若s到t有一条copy边,则将pts(s)合并到pts(t)
3 s ⟶ l o a d t , 则 u ⟶ c o p y t , 其 中 u ∈ p t s ( s ) s\stackrel{load}{\longrightarrow}t,则u\stackrel{copy}{\longrightarrow}t,其中u\in pts(s) sloadt,ucopyt,upts(s)如果s到t有一条load边,则pts(s)中的所有节点到dst加一条copy边
4 s ⟶ s t o r e t , 则 s ⟶ c o p y u , 其 中 u ∈ p t s ( t ) s\stackrel{store}{\longrightarrow}t,则s\stackrel{copy}{\longrightarrow}u,其中u\in pts(t) sstoret,scopyu,upts(t)如果s到t有一条store边,则s到pts(t)中的所有节点加一条copy边
5 s ⟶ g e p t , 则 p t s ( u . m ) ∪ p t s ( t ) , 其 中 u ∈ p t s ( s ) , m 是 u 的 成 员 s\stackrel{gep}{\longrightarrow}t,则pts(u.m)\cup pts(t),其中u\in pts(s),m是u的成员 sgept,pts(u.m)pts(t),upts(s),mu若s到t有一条取成员边,则将所有的pts(u.m)合并到pts(t)

其中第一条规则可以称为基本规则,后面是扩展规则。其中第3条规则相当于 t = ∗ s t=*s t=s,第4条规则相当于 ∗ t = s *t=s t=s

第零个例子

源代码、IR代码和PAG图分别如下

void f(){
    int o;
}
define dso_local void @f() #0 !dbg !7 {
entry:
  %o = alloca i32, align 4
  call void @llvm.dbg.declare(metadata i32* %o, metadata !10, metadata !DIExpression()), !dbg !12
  ret void, !dbg !13
}

在这里插入图片描述SVFTools的PointTo分析结果如下

(4, f): (5, f (base object))
(11, llvm.dbg.declare): (12, llvm.dbg.declare (base object))
(7, o): (8, o (base object))

前两行是函数的,暂时忽略。这里有意义的结果就是第三行节点7的 p t s pts pts集合,其中只包含节点8。这是显然的。

第一个例子

源代码

void f(){
    int o1, o2, *x, **p;
    x = &o1;
    x = &o2;
    p = &x;
}
define dso_local void @f() #0 !dbg !7 {
entry:
  %o1 = alloca i32, align 4
  %o2 = alloca i32, align 4
  %x = alloca i32*, align 8
  %p = alloca i32**, align 8
  store i32* %o1, i32** %x, align 8, !dbg !21
  store i32* %o2, i32** %x, align 8, !dbg !22
  store i32** %x, i32*** %p, align 8, !dbg !23
  ret void, !dbg !24
}

PAG与CG的主要部分
在这里插入图片描述在这里插入图片描述
其PTA结果为

(9, o2): (10, o2 (base object))
(11, x): (12, x (base object))
(7, o1): (8, o1 (base object))
(13, p): (14, p (base object))
(14, p (base object)): (12, x (base object))
(12, x (base object)): (8, o1 (base object)) (10, o2 (base object))

由第1条规则可以得到前面4行。节点7到11有一条store边,所以7到pts(11)中的所有节点都要加一条copy边。而pts(11)={12},所以7到12加一条copy边。其他也是一样。

第二个例子

源代码

void f(){
    int o1,o2,*x,*y;
    y = &o1;
    x = y;
    y = &o2;
}
define dso_local void @f() #0 !dbg !7 {
entry:
  %o1 = alloca i32, align 4
  %o2 = alloca i32, align 4
  %x = alloca i32*, align 8
  %y = alloca i32*, align 8
  store i32* %o1, i32** %y, align 8, !dbg !20
  %0 = load i32*, i32** %y, align 8, !dbg !21
  store i32* %0, i32** %x, align 8, !dbg !22
  store i32* %o2, i32** %y, align 8, !dbg !23
  ret void, !dbg !24
}

PAG图和CG图

在这里插入图片描述
在这里插入图片描述
PTA的结果是

(11, x): (12, x (base object))
(7, o1): (8, o1 (base object))
(9, o2): (10, o2 (base object))
(13, y): (14, y (base object))
(14, y (base object)): (8, o1 (base object)) (10, o2 (base object))
(12, x (base object)): (8, o1 (base object)) (10, o2 (base object))

对照PAG图,可以看到前4行就是由基础规则生成的。而第5行的结果则是根据第3条store规则生成。再来看最后一行有关x的pts,节点20到节点11有一条store边,所以节点20到pts(11)中的每一个节点都有一条copy边,也就是20到12加一条copy边。再看节点13到节点20的load边,所以 所有pts(13)中的节点到节点20有一条copy边,也就是14到20加一条copy边。最后考虑copy边,由于copy边的存在,pts(14)要合并到pts(20),而pts(20)要合并到pts(12),所以pts(12)的最后结果也是 { o 1 , o 2 } \{o1, o2\} {o1,o2}

第三个例子

源代码

void f(){
    int o1,o2,o3,o4,*p1,*p2,**y,*x;
    x = *y;
    y = &p1;
    y = &p2;
    p1 = &o1;
    p2 = &o2;
    p1 = &o3;
    p2 = &o4;
}

IR代码

define dso_local void @f() #0 !dbg !7 {
entry:
  %o1 = alloca i32, align 4
  %o2 = alloca i32, align 4
  %o3 = alloca i32, align 4
  %o4 = alloca i32, align 4
  %p1 = alloca i32*, align 8
  %p2 = alloca i32*, align 8
  %y = alloca i32**, align 8
  %x = alloca i32*, align 8
  %0 = load i32**, i32*** %y, align 8, !dbg !29
  %1 = load i32*, i32** %0, align 8, !dbg !30
  store i32* %1, i32** %x, align 8, !dbg !31
  store i32** %p1, i32*** %y, align 8, !dbg !32
  store i32** %p2, i32*** %y, align 8, !dbg !33
  store i32* %o1, i32** %p1, align 8, !dbg !34
  store i32* %o2, i32** %p2, align 8, !dbg !35
  store i32* %o3, i32** %p1, align 8, !dbg !36
  store i32* %o4, i32** %p2, align 8, !dbg !37
  ret void, !dbg !38
}

PAG图
在这里插入图片描述PAG图上可以很容易看到o1o3指向p1o2o4指向p2,而p1p2指向yy l o a d load load两次,产生两个临时变量%0和%1,并且%1最后 s t o r e store storex

CG图
在这里插入图片描述PTA结果

(15, p1): (16, p1 (base object))
(13, o4): (14, o4 (base object))
(9, o2): (10, o2 (base object))
(7, o1): (8, o1 (base object))
(11, o3): (12, o3 (base object))
(17, p2): (18, p2 (base object))
(19, y): (20, y (base object))
(21, x): (22, x (base object))
(18, p2 (base object)): (10, o2 (base object)) (14, o4 (base object))
(16, p1 (base object)): (8, o1 (base object)) (12, o3 (base object))
(20, y (base object)): (16, p1 (base object)) (18, p2 (base object))
(22, x (base object)): (8, o1 (base object)) (10, o2 (base object)) (12, o3 (base object)) (14, o4 (base object))

其中,前8行由基础的addr规则生成。第9、10、11行的生成之前也有阐述,即利用store生成。关键是最后一行x的pts集合的生成过程。首先是19到31有一条load边,所以pts(19)的所有节点也就是20到31有一条copy边。既然是copy边,就要把pts(20)合并到pts(31)。而pts(20)是pts(15)和pts(17)的并集,也就是 { 16 , 18 } \{16, 18\} {16,18},分别代表p1和p2。
然后31到32有一条load边,也就是要把pts(31)的所有节点即16和18加一条到32的copy边,由于加了copy边,所以要把pts(16)和pts(18)合并到pts(32),所以pts(32)实际上等于 { o 1 , o 2 , o 3 , o 4 } \{o1,o2,o3,o4\} {o1,o2,o3,o4}。最后32到21有一条load边,所以32到22加一条copy边,所以最终得到了pts(22)。

第四个例子

源代码

void f(){
    int o1,o2,*y,**x,*p1,*p2;
    y = &o1;
    y = &o2;
    *x = y;
    x = &p1;
    x = &p2;
}
define dso_local void @f() #0 !dbg !7 {
entry:
  %o1 = alloca i32, align 4
  %o2 = alloca i32, align 4
  %y = alloca i32*, align 8
  %x = alloca i32**, align 8
  %p1 = alloca i32*, align 8
  %p2 = alloca i32*, align 8
  store i32* %o1, i32** %y, align 8, !dbg !25
  store i32* %o2, i32** %y, align 8, !dbg !26
  %0 = load i32*, i32** %y, align 8, !dbg !27
  %1 = load i32**, i32*** %x, align 8, !dbg !28
  store i32* %0, i32** %1, align 8, !dbg !29
  store i32** %p1, i32*** %x, align 8, !dbg !30
  store i32** %p2, i32*** %x, align 8, !dbg !31
  ret void, !dbg !32
}

在这里插入图片描述在这里插入图片描述其PTA的结果是

(15, p1): (16, p1 (base object))
(13, x): (14, x (base object))
(11, y): (12, y (base object))
(9, o2): (10, o2 (base object))
(7, o1): (8, o1 (base object))
(17, p2): (18, p2 (base object))
(14, x (base object)): (16, p1 (base object)) (18, p2 (base object))
(12, y (base object)): (8, o1 (base object)) (10, o2 (base object))
(27, ): (8, o1 (base object)) (10, o2 (base object))
(28, ): (16, p1 (base object)) (18, p2 (base object))
(18, p2 (base object)): (8, o1 (base object)) (10, o2 (base object))
(16, p1 (base object)): (8, o1 (base object)) (10, o2 (base object))

前六行是基本的 a d d r addr addr边生成PTA。第7、8行也是很简单的原则,生成的PTA结果。主要要考虑源代码 ∗ x = y *x=y x=y对PTA的影响。13到28有一条 l o a d load load边,所以 p t s ( 13 ) pts(13) pts(13)中的所有点也就是14到28有一条 c o p y copy copy边,所以 p t s ( 28 ) = { p 1 , p 2 } pts(28)=\{p1, p2\} pts(28)={p1,p2}。再考虑到27到28有一条 s t o r e store store边,所以27到p1和p2也就是16和18各有一条 c o p y copy copy边,于是pts(p1)和pts(P2)均为 { o 1 , o 2 } \{o1, o2\} {o1,o2}

第五个例子

struct _t{
    int *p;
};

void f(){
    int o1, o2;
    struct _t a, b, *x;
    x = &a;
    x = &b;
    x->p = &o1;
    x->p = &o2;
}
(15, x): (16, x (base object))
(13, b): (14, b (base object))
(11, a): (12, a (base object))
(9, o2): (10, o2 (base object))
(7, o1): (8, o1 (base object))
(25, p): (12, a (base object)) (14, b (base object))
(24, ): (12, a (base object)) (14, b (base object))
(27, ): (12, a (base object)) (14, b (base object))
(28, p1): (12, a (base object)) (14, b (base object))
(12, a (base object)): (8, o1 (base object)) (10, o2 (base object))
(14, b (base object)): (8, o1 (base object)) (10, o2 (base object))
(16, x (base object)): (12, a (base object)) (14, b (base object))

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值