尝试使用qemu-arm运行arm二进制文件时,如何解决“加载共享库时出错”?

How to solve “error while loading shared libraries” when trying to run an arm binary with qemu-arm?

我正在使用qemu,qemu-user和gnueabi工具链运行Linux Mint 14。 我用arm-linux-gnueabi-gcc test.c -o test编译了test.c。

当我尝试运行qemu-arm /usr/arm-linux-gnueabi/lib/ld-linux.so.3 test

我收到一条错误消息:test: error while loading shared libraries: test: cannot open shared object file: No such file or directory。 正如我之前尝试过的那样,运行qemu-arm test会给出/lib/ld-linux.so.3: No such file or directory

但是,该文件确实存在并且可以访问。

1
2
3
4
5
6
7
8
9
$ stat /usr/arm-linux-gnueabi/lib/ld-linux.so.3
  File: `/usr/arm-linux-gnueabi/lib/ld-linux.so.3' -> `ld-2.15.so'
  Size: 10          Blocks: 0          IO Block: 4096   symbolic link
Device: 801h/2049d  Inode: 4083308     Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2013-04-22 16:19:48.090613901 -0700
Modify: 2012-09-21 08:31:29.000000000 -0700
Change: 2013-04-22 15:58:41.042542851 -0700
 Birth: -

有谁知道我如何让qemu运行arm程序而不必模拟整个arm Linux内核?

test.c是

1
2
3
4
5
#include <stdio.h>
int main() {
    printf("this had better work\
");
}

并且file test

1
test: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31, BuildID[sha1]=0xf2e49db65394b77c77ee5b65b83c0cc9220cbfc0, not stripped


您可以通过使用-L标志提供arm-linux-gnueabi共享库的路径来运行示例。

1
qemu-arm -L /usr/arm-linux-gnueabi/

还请确保未设置LD_LIBRARY_PATH。

1
unset LD_LIBRARY_PATH


1
$ export QEMU_LD_PREFIX=/usr/arm-linux-gnueabi

这对我有用。
基本上与以下内容相同:

1
$ qemu-arm -L /usr/arm-linux-gnueabi/

您可以将其添加到?/ .bashrc文件中,这样就不必在每次打开终端时都键入它。


使用汇编代码运行C程序时,我也遇到了这个问题。我的解决方案是使用例如" -static"选项构建可执行文件

1
arm-linux-gnueabi-gcc -static -g main.c square.s

然后

1
qemu-arm a.out

将不会报告错误消息"找不到/lib/ld-linux.so.3"。

唯一的缺点是可执行文件可能很大。但是,当您只想测试代码时,这很有用。

当然,您可以使用Balau中的方法(请参阅artless noise的答案)。但是,如果您不想在此步骤中被" UART串行端口"之类的东西感到沮丧,而这仅仅是运行一个简单的"测试"功能,请尝试一下我的解决方法。


我通过将以下库复制到/ lib来解决了该问题,但我相信应该有比我发明的这种讨厌的解决方案更好的解决方案!

1
2
3
sudo cp  /usr/arm-linux-gnueabi/lib/ld-linux.so.3 /lib
sudo cp /usr/arm-linux-gnueabi/lib/libgcc_s.so.1 /lib
sudo cp /usr/arm-linux-gnueabi/lib/libc.so.6 /lib

如果我有兴趣知道,请告诉我是否还有其他更好的解决方案。


如果要在没有Linux的情况下运行ARM,则至少需要一个不同的编译器。 arm-linux-gnueabi-gcc是Linux的编译器。编译器和libc紧密链接。您将需要一个带有可移植层的newlib编译器用于qemu.porting newlib

请参阅:Balau和Google newlib + qemu。 newlib端口托管在Github上,看起来与Balau博客相同。

通常,非Linux gcc称为arm-none-eabi-gcc。一些配置脚本可以识别前缀arm-none-eabi-。


对我有用的一个变体是直接传递加载程序库,并使用加载程序参数--library-path指定所需的库路径。例如:

1
2
$ TOOLCHAIN_ROOT=/usr/local/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/arm-linux-gnueabihf
$ qemu-arm $TOOLCHAIN_ROOT/libc/lib/ld-linux-armhf.so.3 --library-path $TOOLCHAIN_ROOT/libc/lib/arm-linux-gnueabihf:/$TOOLCHAIN_ROOT/lib ./my_executable

或者等效地导出LD_LIBRARY_PATH而不是使用--library-path