riscvarchive / riscv-qemu

QEMU with RISC-V (RV64G, RV32G) Emulation Support
384 stars 154 forks source link

Failed to load share library from specific library path #151

Closed furuame closed 6 years ago

furuame commented 6 years ago

Hi guys, After I solved the issue: https://github.com/riscv/riscv-gnu-toolchain/issues/347

I try to use qemu-risv32 to execute dynamic linked riscv32 binary as following: qemu-2.12.0/build/bin/qemu-riscv32 -L riscv32-gnu-toolchain/sysroot/lib hello-rsv32

But it still appears that: hello-rsv32: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory

I have checked that the specified directory has libc.so.6. Could any guys give me a hint? Thanks!

jim-wilson commented 6 years ago

Try an absolute pathname for the -L option.

You can set the environment variable LD_DEBUG to help debug dynamic linker issues. This is usually set on the same command line as running the program, e.g. "LD_DEBUG=libs ./a.out". You can use LD_DEBUG=help to see the available choices, but LD_DEBUG=libs is probably what you need. Since you are using qemu to run programs, you probably have to set it right before running qemu, and then ignore the dynamic linker messages for qemu.

furuame commented 6 years ago

Hi @jim-wilson, thanks for your reply.

After I try this command, which takes out the last lib, it works! : qemu-2.12.0/build/bin/qemu-riscv32 -L riscv32-gnu-toolchain/sysroot hello-rsv32

So I think this is the problem of the ELF interpreter? And I also try your solution to observe it: LD_DEBUG=libs qemu-2.12.0/build/bin/qemu-riscv32 -L riscv32-gnu-toolchain/sysroot hello-rsv32

The output, where I skip the dynamic linker messages for qemu, is:

      4428:     initialize program: /home/cwei/Workspace/qemu-2.12.0/build/bin/qemu-riscv32
      4428:
      4428:
      4428:     transferring control: /home/cwei/Workspace/qemu-2.12.0/build/bin/qemu-riscv32
      4428:
      4428:     find library=libc.so.6 [0]; searching
      4428:      search cache=/etc/ld.so.cache
      4428:      search path=/lib/tls:/lib:/usr/lib/tls:/usr/lib                (system search path)
      4428:       trying file=/lib/tls/libc.so.6
      4428:       trying file=/lib/libc.so.6
      4428:
      4428:
      4428:     calling preinit: hello-rsv32
      4428:
      4428:
      4428:     calling init: /lib/libc.so.6
      4428:
      4428:
      4428:     initialize program: hello-rsv32
      4428:
      4428:
      4428:     transferring control: hello-rsv32
      4428:
      4428:
      4428:     calling fini: hello-rsv32 [0]

I get confused again, why the dynamic linker of qemu doesn't find libc.so.6 at the path riscv32-gnu-toolchain/sysroot?

jim-wilson commented 6 years ago

It did find /lib/libc.so.6, otherwise the program would not have worked.

-L sets the sysroot, which means / relative paths on the target are sysroot relative on the host. So the target path /lib/libc.so.6 is riscv32-gnu-toolchain/sysroot/lib/libc.so.6 on the host.

furuame commented 6 years ago

It makes sense! Thanks for your reply.

Last question. When I trace the code, I found that -L help qemu to find the path of ELF interpreter. But -L also helps find the shared library? (I means whether qemu would pass the absolute path to ELF interpreter) Or ELF interpreter would find shared library relative to its path by itself?

furuame commented 6 years ago

Hi, I have traced it that! qemu will intercept the system call, which opens the shared library, and fix the path by the -L argument! @jim-wilson, thanks your hint!

(gdb) bt
#0  0x000055555569606b in path (name=0x7ffff627cd60 "/lib/libc.so.6") at util/path.c:173
#1  0x0000555555618e0f in do_openat (cpu_env=0x555557bbc030, dirfd=-100, pathname=0x7ffff627cd60 "/lib/libc.so.6", flags=524288, mode=0)
    at /home/cwei/Workspace/qemu-2.12.0/linux-user/syscall.c:7713
#2  0x000055555561981c in do_syscall (cpu_env=0x555557bbc030, num=56, arg1=-100, arg2=-8864, arg3=524288, arg4=0, arg5=0, arg6=4259840,
    arg7=0, arg8=0) at /home/cwei/Workspace/qemu-2.12.0/linux-user/syscall.c:7976
#3  0x000055555560677f in cpu_loop (env=0x555557bbc030) at /home/cwei/Workspace/qemu-2.12.0/linux-user/main.c:3601
#4  0x0000555555607f58 in main (argc=4, argv=0x7fffffffe368, envp=0x7fffffffe390) at /home/cwei/Workspace/qemu-2.12.0/linux-user/main.c:5147