1

我正在使用 QEMU 来模拟 ARM11 CPU。

我的程序太复杂,无法在这里解释,所以我将把这个问题投影到一个更简单的程序中。所以我的程序包含2个c文件:

  • 主程序
  • some_code.c

我正在编译 some_code.c(到 some_code.o),然后我将它转换为一个 HEX 数组变量,它代表 some_code.c 的代码。

现在我正在链接两个目标文件(main.o 和 some_code.o)。该变量(HEX 数组变量)位于 DATA 段。

现在我从 main.c 中的代码调用 HEX 数组变量(我的意图是此时 some_code.c 的代码将开始执行)。当程序计数器 (PC) 到达 HEX 数组变量时,它会出现异常(我没有关于异常的更多详细信息)。

如果我将这个 HEX 数组变量从 DATA 部分复制到 CODE 部分,现在当 PC 到达这一行时,它可以毫无例外地成功执行它。

所以我的问题是:

  • QEMU 对从 DATA 部分执行命令有限制吗?
  • 如果是这样,我该如何禁用此限制?

先谢谢了,

暗里

4

2 回答 2

1

它将是链接器和操作系统的组合。链接器很可能将数据部分标记为“数据”,然后加载程序将创建一个没有执行权限的内存区域来包含数据。这是 QEMU 正在模拟的硬件的一个特性,而不是 QEMU 本身,也就是说,如果你在真机上运行它,你会看到同样的问题。

可以将数据部分更改为可执行,但详细信息将取决于您正在运行的操作系统以及您使用的编译器工具链。任何具有 JIT 编译器的解释器都必须执行类似的操作。

请注意,通常认为使数据部分可执行是不好的做法,因为这可能导致各种安全漏洞。

于 2015-09-10T11:44:09.160 回答
1

如果我正确理解了您的描述,那么您并没有遇到 QEMU 的限制,而是遇到了它正在模拟的 CPU 的限制。QEMU 对数据段和代码段一无所知,但在 QEMU 中运行的操作系统却知道。

大多数操作系统对代码和数据部分设置了不同的权限:代码通常可读可执行但不可写,只读数据可读但不可执行或可写,可变数据可读写但不可执行。

CPU 通过 MMU 描述符中的标志强制执行读取、写入和执行权限。在 ARM 上,执行权限由页面描述符中的 XN 位控制,从 ARMv6 开始就存在。

如果您想拥有可执行数据(例如对于即时编译器或动态代码加载机制),您需要弄清楚如何指示您的操作系统使内存可执行。

于 2015-09-10T12:05:59.597 回答