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 与用户态程序一起使用?
一般来说,实现/忽略不需要的调用并不难,所以试一试。相关话题:
旧答案
有人告诉我,截至 49f96e7b77925837aa5bc84d4c3453ab5f07408e(2018 年 5 月),在系统调用仿真中运行动态链接的跨拱可执行文件没有方便/经过良好测试的方法:https ://www.mail-archive.com/gem5-users@gem5.org /msg15585.html
然而,我怀疑修补 gem5 来支持它并不难。QEMU 用户模式已经支持这一点,您只需使用-L
.