我想在我的程序中生成一些机器代码然后运行它。一种方法是写出一个 .so 文件,然后将其加载到程序中,但这似乎太昂贵了。
linux中有没有办法让我在我的数据页中写出代码,然后在那里设置我的函数指针并调用它?我在 Windows 上看到过类似的东西,您可以在该页面上分配一个关闭 NX 保护的页面,但我找不到类似的 Linux 操作系统调用。
我想在我的程序中生成一些机器代码然后运行它。一种方法是写出一个 .so 文件,然后将其加载到程序中,但这似乎太昂贵了。
linux中有没有办法让我在我的数据页中写出代码,然后在那里设置我的函数指针并调用它?我在 Windows 上看到过类似的东西,您可以在该页面上分配一个关闭 NX 保护的页面,但我找不到类似的 Linux 操作系统调用。
mmap(2) (with munmap(2)
) 和mprotect(2)系统调用是执行此操作的基本操作。回想一下,从应用程序的角度来看,系统调用是基本操作。你要PROT_EXEC
您可以strace
使用任何动态链接的可执行文件来了解如何调用它们,因为动态链接器ld.so
正在使用它们。
生成共享对象可能比您想象的要便宜。实际上,生成 C 代码,运行编译器,然后dlopen
-ing 生成的共享对象是有一定意义的,即使您以交互方式工作也是如此。我的MELT领域特定语言(用于扩展 GCC)正在执行此操作。回想一下,您可以毫无问题地做很多dlopen
-s 。
如果你想在内存中生成机器码,你可以使用GNU Lightning(快速生成慢速机器码),libjit
来自dotgnu(生成较少错误的机器码),LuaJit,asmjit(特定于 x86 或 amd64),LLVM(缓慢生成优化机器代码)。顺便说一句,SBCL Common Lisp 实现是动态编译到内存并在运行时生成良好的机器代码(并且还有用于 JVM 的所有 JIT 执行此操作)。