A Basic Just-In-Time Compiler

查看原文

本文介绍如何写一个最基本的 JIT 编译器。

  • 第一个挑战是内存分配。在进程内存模型,只有页中有设置 execution bit, 页中的代码才能执行。为了运行时安全,我们要把 write bit 关掉,execution bit 打开,否则攻击者可以发动攻击,篡改代码。
  • 第二个挑战是指令缓存。Malloc 返回的内存只能读写不能运行,所以我们只能用 mmap。获得内存后,使用 mprotect 将内存数据设为 PROT_READ | PROT_EXEC. 销掉内存这用 munmap.
  • 第三个挑战是调用编译好的代码。基本思路是使用 rdi, rax, and rdx 这三个寄存器,设置它们三个的指令序列就能调函数了。记得在设置完 rax 后再编译个 ret 返回寄存器里的值。