gem5 - 如何在 gem5 中运行动态链接的可执行系统调用仿真模式 se.py?
问题描述
在系统调用仿真 SE 模式下运行 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.
如何让它找到解释器?希望不要在主机的根目录上复制我的交叉工具链的解释器。
对于 x86_64,如果我使用本机编译器,它可以工作,并且正如预期的strace
那样,它正在使用本机解释器,但如果我使用交叉编译器,它就不起作用。
当前的常见问题解答说不可能使用动态可执行文件:http: //gem5.org/Frequently_Asked_Questions但我不相信它,然后这些演示文稿提到了它:
- http://www.gem5.org/wiki/images/0/0c/2015_ws_08_dynamic-linker.pdf
- http://research.cs.wisc.edu/multifacet/papers/learning_gem5_tutorial.pdf
但不是如何实际使用它。
QEMU 用户模式有这个-L
选项。
在 gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e 中测试
https://www.mail-archive.com/gem5-users@gem5.org/msg15582.html
解决方案
2019 年 11 月增加了对动态链接的支持
在:https ://gem5-review.googlesource.com/c/public/gem5/+/23066
那时它肯定可以工作,但后来它在某个时候坏了,需要修复.....
如果您有要使用的根文件系统,例如由 Buildroot 生成的文件系统,您可以执行以下操作:
./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
您还必须单独添加任何可能包含动态库的路径--redirect
。这些对于 C 可执行文件来说已经足够了。
--interp-dir
根据表示加载程序路径的 ELF 元数据设置将在其中搜索动态加载程序的根目录。例如, buildroot ELF 文件将该路径设置为/lib/ld-linux-aarch64.so.1
,并且加载程序是存在于/path/to/build/target/lib/ld-linux-aarch64.so.1
. 正如布兰登所提到的,这条路径可以通过以下方式找到:
readelf -a $bin_name | grep interp
系统调用仿真动态链接的主要困难是我们想要以某种方式:
- 链接器文件访问到一个魔法目录以在那里找到库
- 从主应用程序访问其他文件以转到正常路径,例如读取当前工作目录中的输入文件
并且很难检测我们是否在加载程序中,特别是因为这可能发生dlopen
在程序中间。
该--redirects
选项是一个简单的解决方案。
例如/lib=/path/to/build/target/lib
,如果来宾将访问 C 标准库/lib/libc.so.6
,则 gem5 会看到它在里面/lib
,并将路径重定向到/path/to/build/target/lib/libc.so.6
。
轻微的缺点是无法实际访问/lib
主机目录中的文件,但这并不常见,因此在大多数情况下都可以使用。
如果你错过了 any --redirect
,动态链接器可能会抱怨找不到库并带有以下类型的消息:
hello.out: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
如果发生这种情况,您必须在目标文件系统/工具链中找到该libstdc++.so.6
库并添加缺少的--redirect
.
它后来在https://gem5.atlassian.net/browse/GEM5-430上中断,但又被修复了。
动态链接的缺点
一旦我得到动态链接来工作,我注意到它实际上有以下缺点,根据应用程序的不同,这些缺点可能会很大,也可能不会:
动态链接器必须运行一些指令,如果你有一个非常小的用户态测试可执行文件,并且运行在像 O3 这样的低 CPU 上,那么这个启动可以支配运行时,所以要小心
ExecAll
不显示 stdlib 函数的符号名称,您只需从一些随机最近的符号(例如@__end__+274873692728
. 也许这些方面的东西会起作用:Debugging shared libraries with gdbserver but not sure第一次动态跳转到 stdlib 函数需要通过动态链接机制,如果您试图控制 microbench,这可能会产生问题。
实际上,我已经遇到过一次:程序的动态版本做了一些额外的事情,再加上 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 的当前状态,非常复杂的可执行文件(如解释器)可能具有尚未实现的系统调用,另请参阅:何时在 gem5 中将完整系统 FS 与系统调用仿真 SE 与用户态程序一起使用?
一般来说,实现/忽略不需要的调用并不难,所以试一试。相关话题:
- Java:以 gem5(或任何非 C 语言)运行 Java 程序
- Python:3.6.8 aarch64 失败并显示“致命:未实现的系统调用#278 (#278) 未实现。”,测试设置
旧答案
有人告诉我,截至 49f96e7b77925837aa5bc84d4c3453ab5f07408e(2018 年 5 月),在系统调用仿真中运行动态链接的跨拱可执行文件没有方便/经过良好测试的方法:https ://www.mail-archive.com/gem5-users@gem5.org /msg15585.html
然而,我怀疑修补 gem5 来支持它并不难。QEMU 用户模式已经支持这一点,您只需使用-L
.
推荐阅读
- c# - ChromeDriver 未记录
- django - 初始化 django CheckboxSelectMultiple 并取消选中所有内容?
- c# - 是否可以通过 Messenger 控制发送到我的机器人的附件的大小?
- elasticsearch - ElasticSearch - 字段类型时间范围?
- bash - ssh上的for循环得到未绑定的变量错误
- python - 在 HTML (Flask) 中与 Python 并行迭代多个列表
- asynchronous - WebSphere WorkManager Cluster 双重执行作业
- docker - 一个 ip,多个域 - 重定向到正确的容器
- javascript - 使用 Javascript 取消选中所有其他复选框
- reactjs - React Native DrawerLayout:动画子导致无限递归