I have installed Debian on qemu 64-bit ARM (followed this tutorial)
uname -a
Linux test 4.9.0-7-arm64 #1 SMP Debian 4.9.110-1 (2018-07-05) aarch64 GNU/Linux
and I am trying to run 32 bit elf files on it, but some work some don't:
bash: ./file_2: cannot execute binary file: Exec format error
running file command on the file that runs, I get:
file_1: ELF 32-bit LSB executable, ARM, EABI4 version 1 (SYSV), statically linked, not stripped
and the one that does not run:
file_2: ELF 32-bit LSB executable, ARM, version 1 (ARM), statically
linked, stripped
and both work on 32bit system(armv7l)
the only difference is that SYSV/ARM version.
is there any work around without recompiling the kernel?(read this post)
As the linked post suggests, this requires CONFIG_COMPAT to be enabled in the kernel. On the other hand I would be surprised if your kernel didn't have it -- the Debian 4.9.0-4 kernel I have from doing that tutorial does set CONFIG_COMPAT. You can check whether your kernel has it enabled by looking at the config file for it which will be in /boot/ in the guest. If it's missing then you need a new kernel, and nothing else will help.
However in your case you do have CONFIG_COMPAT, and some executables work. The difference between the ones that work and the ones that don't is that the working ones are EABI, and the non-working ones are OABI. OABI is an old and obsolete ABI for 32-bit Arm Linux binaries (the "O" stands for "old", and it's been a bad choice for a decade or so...) and it is not supported by the 64-bit kernel's CONFIG_COMPAT. You'll need to rebuild those binaries from source as EABI binaries if you want to run them under a 64-bit kernel.
Related
I am working on a armv7-a and try to use ltrace installed via buildroot.
# ltrace /usr/bin/ssh-keygen -t ecdsa -b 256
"/usr/bin/ssh-keygen" is not an ELF file
# file /usr/bin/ssh-keygen
/usr/bin/ssh-keygen: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, stripped
Upstream supports armv7, but says:
The following targets are currently (at least somewhat) supported.
Some of them may be more or less broken in reality
Has one made it work please?
I cross compiled a program on Ubuntu 12.04 running on x86 using gcc-arm-linux-gnueabi and binutils-arm-linux-gnueabi and compiling with arm-linux-gnueabi-gcc instead of gcc with my target architecture being ARM. It compiles fine with no errors or warnings.
When I try to run it on the ARM machine (Pandaboard - also running Ubuntu 12.04) I get:
bash: ./sttyl: No such file or directory
I know the file is there and it has the proper permissions:
-rwxrwxr-x 1 haziz haziz 8.5K Feb 10 10:34 sttyl
The output of file sttyl is
sttyl: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31,BuildID[sha1]=0x6d504f7d84b93603122223a89e2b5960c840309f, not stripped
When I compile it natively on the Pandaboard it compiles and runs fine. This is the output of file sttyl on the natively compiled copy:
sttyl: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.31,BuildID[sha1]=0x9897c785266c5b7cdf580e08091aba239db84ecf, not stripped
What am I doing wrong? Moreover if I had made a mistake in the cross compilation I would have expected the shell/kernel to tell me effectively that the executable is for the wrong architecture not that it does not exist!
It isn't telling you that ./sttyl doesn't exist.
It's telling you that it spawned a new process, which exited with error No such file or directory. No information is provided about which file or directory was missing.
For example, a shell script starting with #!/bin/specialsh could generate that error if the interpreter /bin/specialsh was missing, even though the script existed and was executable.
Try using strace to find out what call (and path) caused the error.
I want to automate expect for passwd but I don't have permission to install.
But if I could copy and paste the expect source code and execute the .c files usingcc/gcc
and generate the executable expect.
or
Can I copy the expect executable from linux and just use it anywhere else like on solaris, aix etc?
This is the expect in /usr/bin/expect in my linux box:
[root#test]# file /usr/bin/expect
/usr/bin/expect: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped
The prebuilt executables for Solaris and Linux at kbskit include Expect (along with lots of other Tcl extensions) in the *bi "Batteries Included" versions. Each is just one big file, no unpacking or installing is needed, apart from eg. chmod a+x SunOS_kbsvq8.5-bi to make the file executable. You use this executable to run your script, and at the start of the script you need to add package require Expect to set up the Expect commands.
If you have a C compiler, you can build expect (but you have to build Tcl first).
The executable from Linux can't be used almost anywhere else (on solaris, aix, etc.); there is a chance for it to work on FreeBSD.
If you are on Solaris 11 then installing expect is as easy as:
pkg install //solaris/shell/expect
The package will come from the official Oracle Solaris repository so nothing to worry about. There's no need to get sources, build, etc.
I understand that you may not have permission to do this but since this comes from official source (Oracle) I'm pretty sure your sysadmin will do it in a sec.
I have applications which successfully compile with the -m32 switch (in DMD and/or GCC) to produce:
appname: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked
(uses shared libs), for GNU/Linux 2.6.15, not stripped
The source packages I have created work fine, on both 32 bit and 64 bit Ubuntu to build the appropriate binary .debs.
I would like to produce the i386 .deb on the same 64 bit machine i use to produce the 64 bit .deb.
Is this possible, and where should I look for instructions?
The answer depends on the complexity of your build. When the normal 64 bit userland tools suffice for a build, simply specify the architecture via -a
debuild -ai386
However, there are often cases where this doesn't work, and in these cases you'll need pbuilder. pbuilder builds a clean Debian/Ubuntu system in a chroot-ed environment. man pbuilder is a good introduction. To get started, you'll need:
sudo pbuilder --create --architecture i386
sudo pbuilder --build mypackage.dsc
It starts with calling debuild with the -ai386 option, which will
change the architecture that the package is built for.
Of course you have to ensure that the package contains the i386 build of the application.
You don't do anything thing different from building a 64bit .deb. Except that you include a 32bit build of your application.
The control file specifies the architecture, so be sure you select the correct one.
I'm trying to use GDB to debug (to find an annoying segfault). When I run:
gdb ./filename
from the command line, I get the following error:
This GDB was configured as "i686-pc-linux-
gnu"..."/path/exec": not in executable
format: File format not recognized
When I execute:
file /path/executable/
I get the following info:
ELF 64-bit LSB executable, AMD x86-64,
version 1 (SYSV), for GNU/Linux 2.4.0,
dynamically linked (uses shared libs), not stripped
I am using GDB 6.1, and the executable is compiled with gcc version 3.4.6.
I'm a little out of my water in terms of using gdb, but as far as I can tell it should be working in this instance. Any ideas what's going wrong?
The executable is 64-bit (x86-64) and the debugger is a 32 bit (i686-pc-linux) build. You may need to install a 64-bit (x86-64) version of the debugger.
I'm not sure if this is your problem, but I faced this situation very often. The executable in the build tree, build by make/automake is not a binary, but a script, so you cannot use gdb with it. Try to install the application and change the directory, because else gdb tries to debug the script.
The question refers to "./filename" and to "/path/executable". Are these the same file?
If you are doing a post-mortem analysis, you would run:
gdb executable-file core-file
If you are going to ignore the core file, you would run:
gdb executable-file
In both cases, 'executable-file' means a pathname to the binary you want to debug. Most usually, that is actually a simple filename in the current directory, since you have the source code from your debug build there.
On Solaris, a 64-bit build of GDB is supposed to be able to debug both 32-bit and 64-bit executables (though I've had some issues with recent versions of GDB). I'm not sure of the converse - that a 32-bit GDB can necessarily debug 64-bit executables.
What you need to be checking, is really the bfd library. The binary file descriptor library is what binutils / gdb uses to actually parse and handle binaries (ELF/a.out etc..).
You can see the current supported platforms via objdump;
# objdump -H
objdump: supported targets: elf32-powerpc aixcoff-rs6000 elf32-powerpcle ppcboot elf64-powerpc elf64-powerpcle elf64-little elf64-big elf32-little elf32-big srec symbolsrec tekhex binary ihex
objdump: supported architectures: rs6000:6000 rs6000:rs1 rs6000:rsc rs6000:rs2 powerpc:common powerpc:common64 powerpc:603 powerpc:EC603e powerpc:604 powerpc:403 powerpc:601 powerpc:620 powerpc:630 powerpc:a35 powerpc:rs64ii powerpc:rs64iii powerpc:7400 powerpc:e500 powerpc:MPC8XX powerpc:750
The following PPC specific disassembler options are supported for use with
the -M switch:
booke|booke32|booke64 Disassemble the BookE instructions
e300 Disassemble the e300 instructions
e500|e500x2 Disassemble the e500 instructions
efs Disassemble the EFS instructions
power4 Disassemble the Power4 instructions
power5 Disassemble the Power5 instructions
power6 Disassemble the Power6 instructions
32 Do not disassemble 64-bit instructions
64 Allow disassembly of 64-bit instructions
It seems your GNU Debugger (gdb) doesn't support x86_64 architecture.
So try LLDB Debugger (lldb) which aims to replace it. It supports i386, x86-64 and ARM instruction sets.
It's available by default on BSD/OS X, on Linux install via: sudo apt-get install lldb (or use yum).
See: gdb to lldb command map page for more info.