Page 120 - 《软件学报》2024年第6期
P. 120
2696 软件学报 2024 年第 35 卷第 6 期
编译技术, 实现从高级语言或低级字节码到二进制代码的高效转换. Copy-and-Patch 系统包含 MetaVar 编译器和
Copy-and-Patch 代码生成器两部分. MetaVar 预先构造满足多种场景的架构无关模板库. Copy-and-Patch 代码生成
器根据用户输入的字节码或 AST (abstract syntax tree) 的程序特征利用模式匹配选择最高效的模板库, 最终生成高
效的二进制代码. Copy-and-Patch 技术在代码生成效率和质量上优势显著, 并且对不同的字节码和 AST 具有很强
的可扩展性. 二进制翻译作为具有特殊前端的编译器, 有理由相信 Copy-and-Patch 技术对二进制指令高效翻译同
样具有很强的借鉴意义.
2.4 指令翻译方法分析与对比
本节介绍了二进制指令翻译常用的 3 种翻译方法: 定制化中间表示的指令翻译、编译器框架辅助的指令翻译
和规则匹配的指令映射翻译. 我们从代表性方法、翻译效率、平台可扩展性、代码膨胀率、不足等 5 个方面对 3
种指令翻译方法进行对比, 结果如表 3 所示, 可以看出 3 种方法各有千秋. 然而, 设计一种高质量的指令翻译方法
是一项具有挑战性的工作, 既要求在功能上完全表达被翻译指令, 又要在翻译效率上足够高效. 当前的二进制翻译
系统设计, 普遍做法是将不同的指令翻译方法融合使用 [20,80,85] .
问题. 具体优化方法将在第
表 3 二进制指令翻译方法对比
类别 代表性方法 翻译效率 平台可扩展性 代码膨胀率 不足
定制化中间表示的指令翻译 TCG IR [13] 、VEX IR [16] 低 强 高 翻译工作量较大; 优化手段有限
编译框架辅助的指令翻译 LLVM IR [74] 高 强 中等 优化成本较高
指令覆盖率不足; 学习成本高; 对全
规则匹配的指令映射翻译 文献[72,80−82,84]等 高 弱 低
系统翻译支持不足
3 二进制翻译技术关键问题
二进制翻译的输入文件不再维护函数名、变量信息、数据类型等关键符号信息, 导致其相比编译器设计更具
挑战性. 根据表 1 典型二进制翻译系统, 我们梳理发现当前二进制翻译技术依旧存在大量热点关键问题. 引发这些
问题的主要原因有: (1) 冯诺依曼结构的指令/地址/数据混编混接、变长指令、间接跳转指令、代码自修改等特
性, 二进制程序解码和翻译难度大. (2) 基于虚拟环境模拟的执行方式, 会引入大量翻译和运行开销. (3) 不同处理
器平台在内存模型、指令集、存储单元等硬件差异, 对指令翻译和处理器状态模拟难度较大.
3.1 存储单元模拟
二进制翻译除了完成指令的基本翻译, 还需要在目标机器上部署对应的存储单元作为源机器平台中寄存器的
镜像, 实现源平台的寄存器和内存等存储单元的等价模拟. 除了对通用寄存器的镜像部署, 程序中专用寄存器的状
态同样需要在目标机器中对应部署. 例如在翻译 x86 的分段寄存器和标志位寄存器时, 在目标机器中也必须建立
对应的内存镜像. 当前镜像部署的解决方案主要有两种: 开辟一块内存空间做镜像映射 [13,16] 或者利用硬件支持寄
存器映射 [17,53,86] . 其中, 开辟内存空间的方法屏蔽了寄存器使用差异, 实现简单, 但会引发大量的访存代价. 硬件支
持的寄存器映射方法效率较高, 但不同处理器平台中寄存器数量和使用约定各异, 很难实现寄存器的全部映射. 尤
其是源平台寄存器数量多于目标平台时, 必然有部分源机器平台中的寄存器要被映射到内存单元中, 涉及寄存器
映射收益 [53] 和映射代价选择 [82,87] 4.3.1 节中进行讨论.
与存储单元模拟相关的另外一个难点是对内存地址的翻译. 系统级翻译时, 所有客户机访存操作需要经过两
级虚实地址转换, 即先把客户机的虚地址翻译成客户机的物理地址. 然后再将客户机的物理地址作为宿主机的虚
地址, 最终翻译成宿主机的物理地址. QEMU 采用软件模拟实现两级虚实地址转换翻译, 翻译效率较低. Wang 等
人 [88] 和 Faravelon 等人 [89] 提出将客户虚拟地址空间嵌入到主机地址空间中, 宿主机可无差别地直接访问客户机虚
地址. 然而, 该方法对于客户机和宿主机的虚拟地址空间大小有严格限制. BTMMU [90] 通过扩展内存单元部件, 在
内核模块中增加影子页表来实现内存地址翻译, 具有通用性. LAT [91] 采用硬件支持的方式实现客户机虚地址到宿