ELF file exists in /usr/bin but turns out "-ash: file: not found"

coder picture coder · Jul 13, 2015 · Viewed 8k times · Source

i'm trying to install some new software package under openwrt using opkg,and the installation has been successful,and we can see the binary file really exists in the /usr/bin,and i have trird the lld check but turns out the same . as below:

root@OpenWrt /usr/bin [#]# opkg files cfdisk
Package cfdisk (2.25.2-4) is installed on root and has the following files:
/usr/sbin/cfdisk
root@OpenWrt /usr/bin [#]# ls /usr/sbin/
adjtimex                arping                  ethtool                 iptables-save           mkfs.ext3               pppd                    telnetd
airbase-ng              besside-ng              fdisk                   iw                      mkfs.ext4               rate.awk                uhttpd
aireplay-ng             brctl                   hostapd                 iwconfig                modinfo                 rmmod                   wpa_supplicant
airmon-ng               cfdisk                  insmod                  iwlist                  modprobe                samba_multicall         wpad
airmon-zc               chroot                  ip6tables               iwpriv                  nmbd                    smbd                    xtables-multi
airodump-ng             crond                   ip6tables-restore       lsmod                   ntpclient               smbpasswd
airodump-ng-oui-update  dnsmasq                 ip6tables-save          miniupnpd               ntpd                    swapoff
airserv-ng              dropbear                iptables                mke2fs                  odhcp6c                 swapon
airtun-ng               e2fsck                  iptables-restore        mkfs.ext2               pdnsd                   tc
root@OpenWrt /usr/bin [#]# cfdisk
-ash: cfdisk: not found
root@OpenWrt /usr/bin [#]# ./cfdisk
-ash: ./cfdisk: not found
root@OpenWrt /usr/bin [#]# ldd cfdisk
-ash: cfdisk: not found
root@OpenWrt /usr/bin [#]# ldd id
        libcrypt.so.0 => /lib/libcrypt.so.0 (0x77898000)
        libm.so.0 => /lib/libm.so.0 (0x77872000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x7784e000)
        libc.so.0 => /lib/libc.so.0 (0x777e2000)
        ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x778bc000)
root@OpenWrt /usr/bin [#]# export
export HOME='/root'
export LOGNAME='root'
export OLDPWD='/usr'
export PATH='/usr/bin:/usr/sbin:/bin:/sbin'
export PS1='\[\033[35;1m\]\u\[\033[0m\]@\[\033[31;1m\]\h \[\033[32;1m\]$PWD\[\033[0m\] [\[\033[35m\]\#\[\033[0m\]]\[\033[31m\]\$\[\033[0m\] '
export PWD='/usr/bin'
export SHELL='/bin/ash'
export SHLVL='1'
export SSH_CONNECTION='192.168.1.152 29105 192.168.1.1 22'
export SSH_TTY='/dev/pts/0'
export TERM='xterm'
export USER='root'
root@OpenWrt /usr/bin [#]# 

thanks.

Answer

Dave picture Dave · Feb 28, 2016

As mentioned by @nos in the comments on the question this can happen if binary is linked with a libc that doesn't exist on your device.

e.g. This is the output I get when I try to run a binary that's been built with the wrong libc (note that I specify the full path /usr/bin/ldd because without that for some reason I was getting the same "not found" error you note in your question).

root@OpenWrt:~# /usr/bin/ldd badbin 
ldd: can't open cache '/etc/ld.so.cache'
checking sub-depends for '/usr/lib/libusb-1.0.so.0'
checking sub-depends for '/lib/libgcc_s.so.1'
checking sub-depends for 'not found'
    libusb-1.0.so.0 => /usr/lib/libusb-1.0.so.0 (0x00000000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00000000)
    libc.so => not found (0x00000000)
    not a dynamic executable

For me the issue was that I was building my package using the wrong toolchain. I'd assumed that the git://git.openwrt.org/openwrt.git repo was for Chaos Calmer (the current release at time of writing). But of course that repo is the development branch (svn trunk). I needed to use git://git.openwrt.org/15.05/openwrt.git instead.

You can confirm which libc you're building with by checking the name of the toolchain directory staging_dir. The libc version is the last component of the name (e.g. toolchain-mips_34kc+dsp_gcc-4.8-linaro_uClibc-0.9.33.2 is using uClibc-0.9.33.2).

Compare this version to the version of libc that's present on your router by checking what /lib/libc.so* links to on your router (run ls -l /lib/libc.so*). If you need to change the libc version used by your toolchain then do make menuconfig in the OpenWRT buildroot and set the libc version in Advanced configuration options (for developers) -> Toolchain Options -> C Library implementation. You probably shouldn't need to change this setting though -- make sure you're building from the correct source repo for the version installed on your router.