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
返回寄存器里的值。