ksco 的工作日志
年前在 DynamoRIO 遇到一个比较好玩的东西: 首先 RISC-V 直接跳转的范围只有 +/- 4 KiB,而 AArch64 则是 +/- 32 KiB,所以这个问题算是 RV 独有的。这个范围也直接决定了代码块的最大尺寸,也就是说,RV 中的一个代码块不能超过 4096 个字节(否则块内的直接跳转就有危险了)。 其次,DynamoRIO 有一个叫 clean call 的插桩机制,可以允许用户在任意的两条指令之间插入一个 C 函数的调用。 这个机制的实现方式是,在调用这个 C 函数之前,会保存…
想法很好,但是实际写代码发现 ldsp/sdsp 的 imm 不够长,迂回了一晚上终于可以工作了,FML
🥰2
ksco 的工作日志
box64 中的 CALL/RET 优化 这个优化基于一个假设:当一个 x86 程序执行 CALL 指令的时候,它大概是在做函数的调用;当执行 RET 指令的时候,它大概是在做函数的返回。 正常情况下,模拟 CALL / RET 的开销是比较大的,因为当 RET 的时候,需要从栈上获取到 return 的地址,然后去 jumptable 中查到该地址对应的代码块,再跳转过去。 但如果接受了上面的假设,则在 CALL 的时候可以把 guest x86 的返回地址以及下一个代码块的地址(CALL 指令会结束当前的代码块)同时压到…
给 RV64 后端加上了这个优化,做了个简单的 7z b,这个优化获得了 50% 以上的性能提升!https://ksco.cool/RdPW
刘阳
https://github.com/ptitSeb/box64/pull/1180
说起来之前就注意到这哥们总是时不时地给 box64 实现一些比较大的 feature,直到昨天才知道他是原作者的儿子 🤯
🤯8
开工大吉,今年希望可以把
1)DynamoRIO RV64 做到官方支持的程度;
2)dynarmic RV64 做好合进主线,Citra 和 yuzu 可以正常使用;
3)box64 Loongarch 做到能用的程度。
1)DynamoRIO RV64 做到官方支持的程度;
2)dynarmic RV64 做好合进主线,Citra 和 yuzu 可以正常使用;
3)box64 Loongarch 做到能用的程度。
昨天给 3A6000 装机然后安装了 AOSC OS,今天在上面做了一整天 box64 开发。不得不夸的是,不管是硬件还是系统,体验都是无可挑剔的。
🤔1
LoongArch 的 LBT 扩展也相当好玩,为了方便之后对比手动模拟 eflags 和直接使用 LBT 扩展的性能差距,我们同时实现了这两套方案。我已经等不及实现足够的指令后 benchmark 一下了
🤯1
LoongArch VSCode 折腾小计
最近因为需要在 LoongArch 上写一些 C 代码,所以折腾了一下 VSCode 环境。
本体下载:
https://github.com/Xiao-Tao/vscode-LA64/releases
在 Loongson 群里搜到的群友打包的 code-oss,解压就能用,版本是 1.80.1。
VSCode 插件:
因为没有 marketplace,所以需要手动下载 VSIX 文件来安装。
- GitLens:
https://github.com/gitkraken/vscode-gitlens/releases/tag/v13.0.0
需要下载旧版本,新版本不兼容。我用的是 13.0.0,再新一点的可能也能用,但我懒得试了。
- LoongArch Assembly:
https://github.com/FreeFlyingSheep/loongarch-assembly/releases
汇编语法高亮。
- C/C++ IntelliSense
https://github.com/microsoft/vscode-cpptools/releases
直接下载最新版的 cpptools-linux.vsix (x86_64)安装即可正常使用(需要安装 latx)。
最近因为需要在 LoongArch 上写一些 C 代码,所以折腾了一下 VSCode 环境。
本体下载:
https://github.com/Xiao-Tao/vscode-LA64/releases
在 Loongson 群里搜到的群友打包的 code-oss,解压就能用,版本是 1.80.1。
VSCode 插件:
因为没有 marketplace,所以需要手动下载 VSIX 文件来安装。
- GitLens:
https://github.com/gitkraken/vscode-gitlens/releases/tag/v13.0.0
需要下载旧版本,新版本不兼容。我用的是 13.0.0,再新一点的可能也能用,但我懒得试了。
- LoongArch Assembly:
https://github.com/FreeFlyingSheep/loongarch-assembly/releases
汇编语法高亮。
- C/C++ IntelliSense
https://github.com/microsoft/vscode-cpptools/releases
直接下载最新版的 cpptools-linux.vsix (x86_64)安装即可正常使用(需要安装 latx)。
box64 中对于 Self-Modifying Code™ 的处理:
所有的 guest 代码页都被设置为了 read-only,所以当有指令试图写入到 guest 代码页的时候,就会当场触发一个 SIGSEGV。
box64 的全局 signalhandler 接收到 SIGSEGV 信号后,首先会搜索出事的 pc 是否在某个 dynablock 中,如果确实是来自 dynablock,就会检查 si_addr 是否属于 guest 代码页,两者都吻合,就会 --
1. 把那个 dynaloblock 设置为 dirty;
2. 然后将相应的 guest 代码页设置为可写;
3. 从 ucontext 里面把 x86 状态恢复出来[1];
4. siglongjump 回
5. 解释器会尽快退出执行,跳转回 DynaRec。
对于任何标记为 dirty 的 dynablock,DynaRec 会检查 CRC 来确定是不是真的脏了,是的话就重建,否则就重新标记为 clean。
[1] box64 中每一个 x86 的寄存器都被一一映射到了 host 寄存器上,且 codegen 会保证对于每一条指令,生成的代码对于 x86 寄存器写入一定在内存写入之后,所以不用担心, ucontext 里面的状态一定是正确的。
这就是 x86 模拟器支持 SMC 所需要付出的代价。
RISC 则要容易得多,比如对于 RISC-V 模拟器来说,可以选择直接 intercept fence.i 和 __clear_cache() 然后更新相应的 dynablock 即可。
所有的 guest 代码页都被设置为了 read-only,所以当有指令试图写入到 guest 代码页的时候,就会当场触发一个 SIGSEGV。
box64 的全局 signalhandler 接收到 SIGSEGV 信号后,首先会搜索出事的 pc 是否在某个 dynablock 中,如果确实是来自 dynablock,就会检查 si_addr 是否属于 guest 代码页,两者都吻合,就会 --
1. 把那个 dynaloblock 设置为 dirty;
2. 然后将相应的 guest 代码页设置为可写;
3. 从 ucontext 里面把 x86 状态恢复出来[1];
4. siglongjump 回
run_code() ,使用解释器去执行 SMC 代码;5. 解释器会尽快退出执行,跳转回 DynaRec。
对于任何标记为 dirty 的 dynablock,DynaRec 会检查 CRC 来确定是不是真的脏了,是的话就重建,否则就重新标记为 clean。
[1] box64 中每一个 x86 的寄存器都被一一映射到了 host 寄存器上,且 codegen 会保证对于每一条指令,生成的代码对于 x86 寄存器写入一定在内存写入之后,所以不用担心, ucontext 里面的状态一定是正确的。
这就是 x86 模拟器支持 SMC 所需要付出的代价。
RISC 则要容易得多,比如对于 RISC-V 模拟器来说,可以选择直接 intercept fence.i 和 __clear_cache() 然后更新相应的 dynablock 即可。
👏2🎃1