4

I am trying to cross-compile a binary to use on an old Linux distribution (kernel 2.4.25, i586 architecture).

Steps I took

  • I have downloaded the landley i586 cross-compiler (http://landley.net/aboriginal/downloads/binaries/)
  • I downloaded the net-utils source: https://ftp.gnu.org/gnu/inetutils/ version 1.9.4
  • I included the cross-compiler in my path: export PATH=/root/Documents/cross-compiler-i586/bin/:$PATH
  • I then built the telnet binary as follows: LDFLAGS=”-static" ./configure --host=i586 --build=x86_64 --target=i586 --disable-ifconfig --with-ncurses-include-dir=/root/Documents/tnbuild --disable-hostname --disable-logger --disable-rcp --disable-rexec --disable-rlogin --disable-rsh --disable-tftp --disable-traceroute --disable-inetd --disable-rexecd --disable-syslogd --disable-tftpd
  • This successfully compiled, and checking (after stripping) the binary with the file command gives: telnet: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, stripped

I compared this with a binary which is already on the old Linux system, and the output is exactly the same: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter lib/ld-linux.so.2, for GNU/Linux 2.4.0, stripped

The problem I am facing

The telnet binary that I compiled is not working on the old Linux system. The error that is thrown is simply 'Segmentation Fault'. Googling this error learns that it is likely due to differences in architecture (i586?), but I have no clue anymore how to fix it, as the 'file' command outputs exactly the same for a working binary as well as for the failing binary.

I then stumbled across this topic: GCC Cross compile to a i586 architecture (Vortex86DX) , but as it is not pursued, I am not sure if I should indeed compile all toolchains for i586 and how exactly I would need to do that.

Community
  • 1
  • 1
Michael
  • 363
  • 5
  • 20
  • Put it in GDB. That may give a clue on the location where it failed. May be it fails while loading (any shared libraries?). May be it fails while loading configuration, properties (if there are any). Strace also would give you hints. – blackpen Oct 28 '16 at 21:36
  • @blackpen, thanks, but I forgot to mention that GDB is not installed on the target system. So I cannot see where it fails, unless I am able to install gdb first.. – Michael Oct 28 '16 at 21:38
  • Do you have strace? You may be able to see in which system call it fails. – blackpen Oct 28 '16 at 21:42
  • You could also try **LD_DEBUG=all telnet**. This dumps the debug output from the dynamic linker. You will be able to see possible libraries being loaded from wrong paths. You could also try **ldd telnet** to see the list of shared libraries being used (and their paths) as shown in the [man page](http://man7.org/linux/man-pages/man1/ldd.1.html). – blackpen Oct 28 '16 at 21:49
  • @blackpen: strace is not available; when I try 'LD_DEBUG=all telnet', I just get 'Segmentation fault'. Is it possible that even the ld_debug is failing because its libraries are not fit for the architecture on which I wish to run them? – Michael Oct 28 '16 at 22:13
  • Is **ldd** available? Any output from **ldd telnet**? Give absolute path to telnet if need be. I am also suspecting LD_LIBRARY_PATH (this variable is used by dynamic linker and ldd .. etc). – blackpen Oct 28 '16 at 22:25
  • statically linked and dynamically linked are not the same thing. – Appleman1234 Oct 29 '16 at 03:36
  • @blackpen, no output. I can execute these commands on my non-i586 system, and then ldd just says 'not a dynamic executable'. I assume that's also what Appleman1234 means: my telnet binary is statically linked. This is on purpose, as I would think it increases my chances of being able to run it on the old system.. – Michael Oct 29 '16 at 06:19
  • Even statically linked executables still have some dependencies on some system related shared libraries (for ex., libm.so.0, libc.so.0, ld-uClibc.so.0. Try running **ldd /bin/cat**. You can do the same with **ldd /bin/sh**. It will show you some basic system level shared libraries). If it doesn't show them for the compiled telnet, there is something completely different. I have a feeling that the loader isn't able to run even the first instruction in the binary. We need some ELF analysis tools. I will get back if I find more information. – blackpen Oct 29 '16 at 19:45
  • @blackpen, small update: When I download the telnet rpm from http://rpm.pbone.net/index.php3/stat/4/idpl/2394547/dir/redhat_6.x/com/telnet-0.10-31.i386.rpm.html and I 1) extract the binary, 2) download libncurses.so.4, 3) transfer both files to the target system, then I get an error "symbol herror, version GLIBC_2.0 not defined in file libc.so.6 with link time reference". Not sure if that helps, but it seems to get me one step further (i.e. the error is thrown after I run 'telnet open localhost'. – Michael Oct 30 '16 at 21:03
  • 1
    if redhat/centos you might be able to point to the archive repo in the /etc/yum.repos.d/*repo files. For centos, http://vault.centos.org/2.1/final/i386/CentOS/RPMS/ (but I couldn't find a 2.4 path). – strobelight Nov 01 '16 at 13:51
  • Try objdump or objconv like [here](http://stackoverflow.com/questions/5125896/how-to-disassemble-a-binary-executable-in-linux-to-get-the-assembly-code). I am suggesting this to see if the executable file has any recognizable instructions for your platform. You could compile a helloworld.c on the same machine for comparison. – blackpen Nov 01 '16 at 19:41
  • @strobelight, that actually worked for me! I'm inclined to accept yours as an answer, even though it does not really explain why I cannot build it myself.. – Michael Nov 02 '16 at 18:28
  • @blackpen, I cannot compile on the machine itself. I can only compile on my machine, and then transfer the binary.. – Michael Nov 02 '16 at 18:29
  • Since, the other machine is a good one (where you can play with tools), could you run [`readelf`](https://sourceware.org/binutils/docs/binutils/readelf.html) on these executables there? You could do the same on the binaries pointed out by strobelight. That would give you a comparison of what worked and what didn't. – blackpen Nov 02 '16 at 18:52
  • @blackpen: hard to tell. A lot is different, and my cross-compiled binary does not contain version information it seems. Is there anything in particular I should pay attention to? – Michael Nov 02 '16 at 21:11
  • You could run `readelf -h` and look out for fields: Class, OS/ABI, ABI Version, Type, Machine, Version. Compare them for working/non-working executables. If there is any mismatch of 32 vs 64 bit executables/libraries, Machine architecture, Version, ... I hope that may give us a clue. – blackpen Nov 03 '16 at 00:39

1 Answers1

0

Is there a specific reason you want to cross-compile this rather than just compiling for generic 32-bit i386? You may need to disable some compiler optimizations if they are not supported by the CPU, but you probably don't need to create a staticly-linked binary.

These instructions for compiling 32-bit (-m 32) seem sufficient to create the telnet binary.

They boil down to:

apt-get install gcc-multilib;
./configure CFLAGS='-m32' -disable-ifconfig \
    --with-ncurses-include-dir=/root/Documents/tnbuild  \
    --disable-hostname --disable-logger --disable-rcp \
    --disable-rexec --disable-rlogin --disable-rsh \
    --disable-tftp --disable-traceroute --disable-inetd \
    --disable-rexecd --disable-syslogd --disable-tftpd
make
saarp
  • 1,931
  • 1
  • 15
  • 28