如何在gem5中运行动态链接的可执行系统调用仿真模式se.py?

如何在gem5中运行动态链接的可执行系统调用仿真模式se.py?,gem5,Gem5,在我设法在特定条件下运行一个静态链接的hello world之后 但是,如果我尝试运行一个与stdlib动态链接的ARM,则: ./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.out 它失败于: fatal: Unable to open dynamic executable's interpreter. 如何让它找到翻译?希望不用在主机的根目录上复制cross’toolchain的解

在我设法在特定条件下运行一个静态链接的hello world之后

但是,如果我尝试运行一个与stdlib动态链接的ARM,则:

./out/common/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.out
它失败于:

fatal: Unable to open dynamic executable's interpreter.
如何让它找到翻译?希望不用在主机的根目录上复制cross’toolchain的解释器

对于x86_64,如果我使用我的本机编译器,它就可以工作,正如预期的那样,
strace
说它正在使用本机解释器,但是如果我使用交叉编译器,它就不工作了

当前的FAQ说不可能使用动态可执行文件:但我不相信它,然后这些演示文稿提到了它:

但不是如何实际使用它

QEMU用户模式具有该选项的
-L

在gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e中测试


2019年11月增加了对动态链接的支持

地址:

在那一点上它肯定能工作,但后来它在某一点上坏了,需要修理

  • arm 32位
  • arm 64位
例如,如果要使用根文件系统,可以执行以下操作:

./build/ARM/gem5.opt configs/example/se.py \
  --redirects /lib=/path/to/build/target/lib \
  --redirects /lib64=/path/to/build/target/lib64 \
  --redirects /usr/lib=/path/to/build/target/usr/lib \
  --redirects /usr/lib64=/path/to/build/target/usr/lib64 \
  --interp-dir /path/to/build/target \
  --cmd /path/to/build/target/bin/hello
或者,如果您正在使用Ubuntu交叉编译器工具链,例如在Ubuntu 18.04中:

sudo apt install gcc-aarch64-linux-gnu
aarch64-linux-gnu-gcc -o hello.out hello.c
./build/ARM/gem5.opt configs/example/se.py \
  --interp-dir /usr/aarch64-linux-gnu \
  --redirects /lib=/usr/aarch64-linux-gnu/lib \
  --cmd hello.out
您还必须添加任何可能包含动态库的路径作为单独的
--重定向
。这些对于C可执行文件来说已经足够了

--interp dir
根据表示加载程序路径的ELF元数据,设置将在其中搜索动态加载程序的根目录。例如,buildroot ELF文件将该路径设置为
/lib/ld-linux-aarch64.so.1
,加载程序是位于
/path/to/build/target/lib/ld-linux-aarch64.so.1
的文件。如Brandon所述,可通过以下方式找到此路径:

 readelf -a $bin_name | grep interp
系统调用仿真动态链接的主要困难在于,我们希望:

  • 链接器文件访问到一个魔法目录,在那里找到库
  • 从主应用程序访问其他文件以转到正常路径,例如读取当前工作目录中的输入文件
<> p>并且很难检测我们是否在加载器中,特别是因为这可以在程序中间通过<代码> dLOpen/<代码>发生。

--redirects
选项是一个简单的解决方案

例如,
/lib=/path/to/build/target/lib
使得如果来宾访问C标准库
/lib/libc.so.6
,那么gem5会看到它在
/lib
中,并将路径重定向到
/path/to/build/target/libc.so.6

稍微有点不好的地方是,实际上无法访问主机的
/lib
目录中的文件,但这并不常见,因此在大多数情况下都可以使用

如果您错过了任何
--重定向
,动态链接器可能会抱怨找不到包含以下类型消息的库:

hello.out: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
如果发生这种情况,您必须在目标文件系统/工具链中找到
libstdc++.so.6
库,并添加缺少的
--redirect

后来它在一点时坏了,但又修好了

动态链接的缺点

一旦我获得了工作的动态链接,我注意到它实际上有以下缺点,取决于应用程序,这些缺点可能会很大,也可能不会很大:

  • 动态链接器必须运行一些指令,如果您有一个非常小的userland测试可执行文件,并且运行在像O3这样的低CPU上,那么这个启动可以控制运行时,所以请注意这一点

  • ExecAll
    不显示stdlib函数的符号名,您只需从一些随机最近的符号(例如
    @\uuuuuu end\uuuuu+27487369228)获得偏移量即可。也许沿着这条思路做点什么会管用:但不确定

  • 第一次动态跳转到stdlib函数需要通过动态链接机制,如果您试图控制微边界,这可能会产生问题

    实际上我已经碰到过一次:程序的动态版本做了一些额外的事情,加上一个gem5错误破坏了我的实验,并花费了我几个小时的调试

Python和Java等解释器

Python和Java只是可执行文件,而执行可执行文件参数的脚本

因此,理论上,您可以在系统调用模拟模式下运行它们,例如:

build/ARM/gem5.opt configs/example/se.py--cmd/usr/bin/python--options='hello.py arg1 arg2'

实际上,考虑到截至2019年11月gem5的当前状态,尽管可执行文件(如解释器)非常复杂,但可能会有尚未实现的系统调用,另请参见:

不过,一般来说,实现/忽略非电话呼叫并不困难,所以不妨尝试一下。相关线程:

  • 爪哇:
  • Python:3.6.8 aarch64因“致命:系统调用未使用#278(#278)未实现”而失败
旧答案

我被告知,截至49f96e7b77925837aa5bc84d4c3453ab5f07408e(2018年5月),在系统调用仿真中运行动态链接的交叉可执行文件没有方便/经过良好测试的方法:


然而,我怀疑修补gem5以支持它并不困难。QEMU用户模式已经支持这一点,您只需使用
-L

指向根文件系统,我在交叉编译代码后遇到了这个问题。您可以尝试在命令后添加“-static”

交叉编译的二进制文件如果是动态可执行文件,则应具有.interp条目

使用readelf进行验证:

 readelf -a $bin_name | grep interp
模拟器被设置为在将可执行文件加载到模拟地址空间时在主可执行文件中查找此部分。如果存在此部分,则会设置一个c字符串来指向该文本(通常是somet)