Search code examples
c++armcross-compilinglibrariesdd-wrt

Valid ARM executable doesn't find libraries


I cross-compiled a small Hello World program for an ARM embedded device (an Asus RT-AC68U router running DD-WRT):

# arm-linux-gnueabi-g++ hello.cpp -mcpu=cortex-a9 -s -o hello

The file seems fine:

# file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV),
dynamically linked (uses shared libs), for GNU/Linux 2.6.32, 
BuildID[sha1]=5099693c31154cdd7f04c16ced5b80b1e35e625b, stripped

It depends on a few libraries:

# readelf -d hello

Dynamic section at offset 0xf08 contains 26 entries:
Tag        Type                         Name/Value
0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
0x00000001 (NEEDED)                     Shared library: [libc.so.6]
(...)

When I try to execute the file on the target system, I get the following:

# ./hello
-sh: ./hello: not found

If I launch execution from ld-linux.so.3 without any other parameters, everything works:

# /opt/lib/ld-linux.so.3 ./hello
Hello, world.

When listing the libraries, the file seems to be searching for libraries in the /lib folder (they are not there, they are in /opt/lib):

# /opt/lib/ld-linux.so.3 --list ./hello
    libstdc++.so.6 => /lib/libstdc++.so.6 (0x76dfb000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x76de0000)
    libc.so.6 => /opt/lib/libc.so.6 (0x76cb2000)
    libc.so => /lib/libc.so (0x76c35000)
    /lib/ld-linux.so.3 => /opt/lib/ld-linux.so.3 (0x76f20000)

I'm guessing the error is due to the fact that the executable when launched on its own is not finding the required shared libraries. All the required libraries are present in the /opt/lib folder and this folder is included in LD_LIBRARY_PATH environment variable:

# echo $LD_LIBRARY_PATH
/lib:/usr/lib:/jffs/lib:/jffs/usr/lib:/jffs/usr/local/lib
:/mmc/lib:/mmc/usr/lib:/opt/lib:/opt/usr/lib

How do I get the executable to find the libraries in the right place?

Edit: I tried linking the libraries statically in the executable and the program runs fine on the target platform. However that is not a workable solution for what I want to do.


Solution

  • Your ld-linux.so.3 appears to be in a nonstandard location (/opt/lib), and it's possible that your gcc is specifying a different program interpreter. You can use readelf -l <program> to check what program interpreter your binary is expecting (under PT_INTERP, "Requesting program interpreter").

    If the binary's program interpreter is wrong for your platform, you can specify it manually by passing -Wl,--dynamic-linker=/opt/lib/ld-linux.so.3 to gcc.