Friday, January 3, 2014

Heimdall

Heimdall is the open source tool for flashing Samsung phones. Unfortunately, it failed to run and produced a perplexing error message on my Xubuntu 13.10 laptop.

$ ./heimdall
bash: ./heimdall: No such file or directory


But the file is present and executable.

$ ls -al heimdall
-rwxr-xr-x 1 user user 2361659 Dec 31 2012 heimdall


The file is 64bit as is our installation, so it isn't a mismatch between the two.

$ file heimdall heimdall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=0xe3d400859c94ab4be1c7d4279f18143aafeec089, not stripped
$ uname -a
Linux shine 3.11.0-14-generic #21-Ubuntu SMP Tue Nov 12 17:04:55 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux


All the shared libraries are found as well:

$ ldd ./heimdall
    linux-vdso.so.1 =>  (0x00007fff693fe000)
    libusb-1.0.so.0 => /lib/x86_64-linux-gnu/libusb-1.0.so.0 (0x00007ff62d2c4000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff62cfc0000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff62ccbb000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff62caa5000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff62c6dd000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff62c4bf000)
    libudev.so.1 => /lib/x86_64-linux-gnu/libudev.so.1 (0x00007ff62c2ae000)
    /lib/ld-linux-x86-64.so.2 => /lib64/ld-linux-x86-64.so.2 (0x00007ff62d4fe000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007ff62c0a6000)


It's a real head scratcher, but the reason can be found.

$ readelf -p .interp ./heimdall

String dump of section '.interp':
  [     0]  /lib/ld-linux-x86-64.so.2


$ ls -l /lib/ld-linux-x86-64.so.2
ls: cannot access /lib/ld-linux-x86-64.so.2: No such file or directory

The dynamic linker specified in the executable is incorrect for the Xubuntu (Ubuntu) system. The correct file is:

$ ls -l /lib64/ld-linux-x86-64.so.2
lrwxrwxrwx 1 root root 32 Oct 12 00:52 /lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.17.so


This dynamic linker can be invoked explicitly to execute the file.

$ /lib64/ld-linux-x86-64.so.2 ./heimdall version
v1.4 RC1


An interesting side effect of directly launching the dynamic linker is the file does not need to be executable.

$ chmod -x heimdall
$ ls -l heimdall
-rw-r--r-- 1 user user 2361659 Dec 31  2012 heimdall
$ /lib64/ld-linux-x86-64.so.2 ./heimdall version
v1.4 RC1
$ ls -l heimdall
-rw-r--r-- 1 user user 2361659 Dec 31  2012 heimdall