在Linux上用C语言分配可执行RAM

13

我希望在 Linux 上使用 C 语言制作一个简单的即时编译器。

我该如何分配内存,以便将原始的 x86 代码写入其中并像执行其他函数一样执行它?

2个回答

18

请查看 mprotect() 函数。一旦您使用 mmap() 函数分配了一个大小为 n 页的内存区域并填充了代码,就可以更改其权限以禁止写入并允许执行。


@Ignacio:链接失效了,存档链接:http://web.archive.org/web/20090203055327/http://people.redhat.com/drepper/selinux-mem.html - ninjalj
这篇文章的新地址似乎是https://www.akkadia.org/drepper/selinux-mem.html。 - Per Mildner

8
除了正确使用mprotect以提供首先写入,然后执行权限外,在某些操作系统/硬件操作中,您可能需要清除I-cache。此时(2010年中期),所有最近的x86处理器都有专门的指令和数据级1缓存,必须确保如果您将新指令写入内存(这将更新D-cache),则不会尝试执行I-cache中的旧位。如何从用户空间刷新I-cache将取决于您的硬件和操作系统。我的建议是阅读Intel关于“自修改代码”的文档,适用于他们的IA-32多处理器。这应该足以帮助您完成任务。

2
x86不需要这个;x86 ISA规则要求I-cache与数据缓存一致,并且在新写入的字节被“看到”之前最多只需要一个jmp。但是这是一个好观点,因为其他架构没有一致的I-cache。 - Peter Cordes
但有趣的是,如果将数据存储到缓冲区中,然后将其转换为函数指针,在x86架构上仍然需要使用gcc的__builtin___clear_cache,否则gcc会将存储优化为死代码。请参见The repetitive byte counter以获取示例。 - Peter Cordes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接