机器码下的多态类型推导-Polymorphic type inference for machine code-wcventure译

Polymorphic type inference for machine code

如上文讲的WYSINWYX现象,对于许多编译式的编程语言,经过编译优化后,有可能从类型安全的高级编程语言转换为类型不安全的机器码。而转换为机器码之后,源码的类型信息和类型抽象都已经被擦除,所以二进制代码恢复出源码的类型信息和类型抽象是一大难题。

《Polymorphic type inference for machine code》提出二进制代码的类型推导工具Retypd。Retypd参考了SecondWrite和TIE这些传统工具,并且支持递归类型,多态和子类型化。

EXAMPLE:

这里写图片描述

例子中的C语言的代码中,结构LL是一个递归结构类型,从最后的结果可以看出类型推导的准确度,确实恢复出了这个递归结构类型的抽象。

整体流程

CodeSurfer可以将机器码恢复成高水平的IR(Intermediate-Representation),类型约束就是直接从这个IR生成的。
Retypd就是使用CodeSurfer恢复的IR来确定每个过程的变量的数量和位置,并根据IR进行产生约束,简化约束和约束求解的过程。
最后一步是将Retypd推导出来的类型映射到可读性强的C语言的类型。

Retypd使用的类型系统

用V代表类型变量的集合。
用∑代表标签,用.加标签来说明类型变量具有的能力。Table 1有几个简单例子。
.函数的类型为∑⟶{⊕,⊙}。
⊕为covariant,⊙为contra variant,复合运算⊕•⊕=⊙•⊙=⊕,⊙•⊕=⊕•⊙=⊙。
形式为aw (a∈V,w∈∑)称为派生类型变量。
这里写图片描述
类型的表示为用一个类型变量加上一个以上的标签组成,这些标签说明了该类型具有的能力。最终阶段会将这些类型转换为C语言下的类型。

产生约束集

约束集中约束的表达形如下面两种,
VAR X(派生类型变量X存在)
X⊑Y(X是Y的子类型)
下面是约束集产生的例子,思想是高级语言层次的,在汇编码下略有不同。
1. 变量赋值x := y
保守的假设就是y可能是x的子类型。因为子类型可以赋值给父类型,只需要丢失一些信息,而父类型不能赋值给子类型。我们可以产生Y≦X这个约束形式。但指针类型的赋值略有不同,后面有例子,本文是有.load和.store解决的。
2. Loads 和stores
假定p是2位类型的指针,若有x := *p,我们可以产生约束P.load.σ32@0≦X,同理若有*q :=y,我们可以产生约束Y≦Q.store.σ32@0。为了简化表述,.σ@K经常被省略。
实际上,可以理解为store = write load = read,write <= read
3. 函数调用
假设函数调用有y := f(x)的形式,我们知道函数的参数可以接受参数的子类型,所以我们可以产生约束集X≦F.in,同理可以产生约束集F.out≦Y。
我们通过上下文可以产生相应的约束集,但约束与约束之间也具有一些关系,可以推导出新的约束,于是就有下面的演绎规则。

演绎规则

通过下面的演绎规则,由上一步产生的约束来产生更多的约束规则。
这里写图片描述

很多规则都是明显正确的,但仔细看得话,其实T-INHERITL和T-INHERITR还存在一些问题,子类型拥有父类型具有的功能,所以T-INHERITR是明显正确的。但子类型具有的功能父类型可能没有,所以T-INHERITL规则这么定义肯定会带来一些问题,但是作者认为这样定义的影响不大,假设子类型和父类型都有相同的功能,这样可以解决某些问题。例如下面的指针的例子。
这里写图片描述
这两个段代码是同一个程序的两种不同表示,但是按照传统的分析方法会产生不同的结果。
假设P = Ptr(a),Q = Ptr(b)
第一个程序我们可以产生约束集C1 ={Ptr(b) ⊑ Ptr(a), X ⊑ a, b ⊑ Y }
第二个程序我们可以产生约束集C2 ={Ptr(b) ⊑ Ptr(a), X ⊑ b, a ⊑ Y }
就结果而言,我们知道最后肯定有Ci ⊢ X ⊑ Y ,但是如果我们假设 Ptr 是covariant的,那么 Ptr(b) ⊑ Ptr(a) 即b⊑a,可以得到C2 ⊢ X ⊑ Y,C1 ⊬ X ⊑ Y,如果假设Ptr是contra variant的即a⊑b,可以得到C1 ⊢ X ⊑ Y,C2 ⊬ X ⊑ Y.总之就是约束求解的结果不同。
而一个简单的解决这个问题的方法就是令Ptr(b) ⊑ Ptr(a)⟶ b=a,但反过来这也意味着Ptr(b) = Ptr(a),所以最终才需要给类型变量加上store和load标签。
我们重新修改约束集,用Ci’表示
C1’={Q ⊑ P, X ⊑ P.store, Q.load ⊑ Y }
C2’={Q ⊑ P, X ⊑ Q.store, P.load ⊑ Y }
由演绎规则T-INHERIT,若存在P.store,则也有Q.store和X.store。
由演绎规则S-POINTER,有P.store ⊑ Q.store。
那么C1’可以得出X ⊑ P.store ⊑ Q.store ⊑ Q.load ⊑ Y
那么C2’可以得出X ⊑ Q.store ⊑ Q.load ⊑ P.load ⊑ Y
最后都能得到Ci ⊢ X ⊑ Y,也就跟我们期待的一样了。

简化约束

约束集C中的约束很多,但实际上,我们对某些约束感兴趣。那些对分析没有帮助的约束可以不去考虑,所以我们希望再产生一个简化的约束集C’,如果c是一条 “interesting” constraint,并且C⊢c,那么也有C’⊢c。
对于类型变量r,“interesting” constraint包括:
1) 具有VAR r.u形式的约束
2) 具有r.u ⊑ r.v形式的递归类型约束
3) 具有r.u ⊑к或者к⊑ r.u形式的子类型约束(к是类型常量)
因为C和C’都能表示对r的相同的约束集,所以用C’来替换C是合理的。

约束求解

(…)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值