What compilation flags I need to use to get this `file` output? - c

I want to compile some code to run on an embedded Linux w/ MIPS arch. But I can't get my MIPS cross compiler (mips-linux-gnu-gcc) to compile my hello-world file correctly. I mean, it is compiling without errors. It just doesn't run on my embedded device.
I downloaded a sample executable from the device (which is proved to be running correctly obviously) and running file this is the output I get:
ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked, interpreter /lib/ld-, stripped
But when I compile my code with
mips-linux-gnu-gcc main.c
file's result on my compiled file is:
ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld., for GNU/Linux 3.2.0, BuildID[sha1]=..., not stripped
I've tried adding -mips1 -mfp32 to the compilation command but still the output isn't what I want:
ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, interpreter /lib/ld., for GNU/Linux 3.2.0, BuildID[sha1]=..., not stripped
What flags do I need to use for the compiler to compile my program correctly? Or do I need a completely different compiler?
I suspect it's only flags but I don't know which. I suspect that the problem is that I get MIPS32 instead of MIPS-I.

Related

How can i emulate an x86 32 bits program on an ARM host?

I am running a Kali Linux distribution on an arm cpu (aarch64).
I have successfully install x86_64-linux-gnux32-gcc and x86_64-linux-gnu-gcc.
I have wrote a basic c program:
#include <stdio.h>
void main()
{
printf("Hello world\n");
}
I have compiled 2 versions:
x86_64-linux-gnu-gcc test1.c -o test1_64
x86_64-linux-gnux32-gcc test1.c -o test1_32
The first binary (64 bits) works fine when i run it with this command:
qemu-x86_64-static ./test1_64
But i have an error with the second binary (32 bits):
qemu-x86_64-static ./test1_32
qemu-x86_64-static: ./test1_32: Invalid ELF image for this architecture
I have tried to force a 32 bits cpu with this command:
qemu-x86_64-static -cpu qemu32 ./test1_32
I have also tried to compile the binary with -static option. I got the same result.
How can i run my 32 bits executable ?
Thanks a lot
x86_64-linux-gnux32-gcc is not what you want for building 32-bit programs. This is actually a 64-bit compiler that targets the x32 ABI, a scheme to have 64-bit code that needs only 32 bits for pointers. It never really caught on and is fairly obscure these days, so I'm not surprised that qemu wouldn't support it.
The x86_64 target of gcc supports building 32-bit programs as well, using the -m32 option. So you ought to be able to build your 32-bit Hello World with
x86_64-linux-gnu-gcc test1.c -o test1_32 -m32
(You might have to separately install 32-bit x86 libraries to successfully cross compile.)
Then to run it, use qemu-i386 instead of qemu-x86_64.
file ./test1_32 should show you that you've still made an x86-64 executable, not i386, with a compiler for the x32 ABI as Nate noticed.
Unfortunately the file output says "ELF 32-bit LSB executable, x86-64, version 1 (SYSV), ..." so the 32-bit part could be misleading.
An actual 32-bit build has "ELF 32-bit LSB executable, Intel 80386,".
A single install of GCC/GAS can build for 32 or 64-bit x86, unlike for ARM32 vs. AArch64 where you need different builds of GCC, so I expect that was part of the confusion. GCC treats i386 and x86-64 as flavours of the same architecture, while AArch64 is treated as a totally separate architecture from ARM. (IDK if GCC did that because x86-64 machine code is similar to 32-bit, so the same assembler can pretty easily handle both. But AArch64 uses a totally different machine code format from ARM32, no point in trying to share code in the assembler between the two architectures.)
So you were probably expecting to need a GCC with 32 in its name to make 32-bit x86 executables. That is not the case.

linux - gbdk returns a fatal error whenever I try to use it

Gbdk works fine on windows but it doesn't work if I try it on linux:
When I run
/usr/lib/gbdk/bin/lcc -Wa-1 -Wl-m -Wl-j -DUSE_SFR_FOR_REG -c main.c -o main.o
it returns this error:
/usr/lib/gbdk/bin/lcc: fatal error in /usr/lib/gbdk/bin/sdcc
That's it. Can anyone please help?
Running cat /etc/os-release returns:
NAME="Linux Mint"
VERSION="19.3 (Tricia)"
ID=linuxmint
ID_LIKE=ubuntu
PRETTY_NAME="Linux Mint 19.3"
VERSION_ID="19.3"
HOME_URL="https://www.linuxmint.com/"
SUPPORT_URL="https://forums.ubuntu.com/"
BUG_REPORT_URL="http://linuxmint-troubleshooting-guide.readthedocs.io/en/latest/"
PRIVACY_POLICY_URL="https://www.linuxmint.com/"
VERSION_CODENAME=tricia
UBUNTU_CODENAME=bionic
Running uname -r returns
5.3.0-46-generic
Running file /usr/lib/gbdk/bin/sdcc returns
/usr/lib/gbdk/bin/sdcc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.0.0, stripped
Running file /usr/lib/gbdk/bin/lcc returns
/usr/lib/gbdk/bin/lcc: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.0.0, stripped
Please use https://github.com/gbdk-2020/gbdk-2020 if you were using 20 years old GBDK.
To see the actual error message run sdcc manually, you can feed lcc -v to see which programs it calls with which arguments.
Last time I've seen something like /usr/lib/gbdk/bin/lcc: fatal error in /usr/lib/gbdk/bin/sdcc, it was a segmentation fault. lcc sadly catches errors and replaces them with an unhelpful error message.

Execution file cannot execute after cross-compiling on a X86 computer (Ubuntu 16.04) and move to arm board (odroid, Ubuntu Mate 18.04)

I am new in ARM architecture.
I want to compile a simple c code (hello world) and move the output executor onto odroid xu4. (Ubuntu mate 18.04)
But when I move it to odroid. I got this:
bash: ./hello: No such file or directory
I download a toolchain gcc-arm-8.3-2019.03-x86_64-arm-eabi.tar.xz from (https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads) and install on my x86_64 computer(Ubuntu 16.04).
here is my hello_world.c
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
I compile with this cmd:
$ arm-linux-gnueabi-gcc hello_world.c -o hello
Here is the result of file hello
hello: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 3.2.0, BuildID[sha1]=f80d3d5cecbb2d688b978a6c889613f158dda657, not stripped
here is the normal executor build on odroid-xu4 by its native compiler
hello: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib, for GNU/Linux 3.2.0, BuildID[sha1]=697300990ba7610219175192f540cdd7411caa84, not stripped
Thank you!

How to create a binary executable for 32 bit gcc machine from my 64 bit gcc machine? [duplicate]

This question already has answers here:
How to compile a 32-bit binary on a 64-bit linux machine with gcc/cmake
(6 answers)
Closed 6 years ago.
I want to create binary executable of my source code to run on 32 bit gcc machine. But I have 64 bit gcc installed. Is there any way to create a binary executable for 32 bit gcc machines from my 64 bit gcc??
My machine is ELF 64-bit LSB by default if u compile it will produce you 64 bit executable.
gcc hello.c -o hello
use file to check it
hello: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=9f8fa8ac13fc03672306da1d5d4ee6671114eb11, not stripped
Use flag -m32 then you forcing your compiler for 32 bit
gcc -m32 hello.c -o hello
file hello
hello : ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=c72216023939b2832467c624850f164d1857e645, not stripped
If you looking for cross-compiling This might help u How to determine host value for configure when using cross compiler
You need to make GCC use the -m32 flag.
You could try writing a simple shell script to your $PATH and call it gcc (make sure you don't overwrite the original gcc, and make sure the new script comes earlier in $PATH, and that it uses the full path to GCC.
compile your binary like -:
/bin/gcc -m32 "source file"

why is binary compiled with gcc not stripped by default

When I compile my program gcc -o myprog myprog.c, the produced binary is not stripped:
myprog: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
linked (uses shared libs), for GNU/Linux 2.6.26,
BuildID[sha1]=0x2697ed96b65e8a11239af0a44abc7896954b6e20, not stripped
I am wondering why gcc produces non-stripped binaries by default, when I did not provide any debuging parameter.
Should all binaries be stripped after being compiled, i.e. using strip myprog? Or is there an advantage of having a binary non-stripped?
AFAICS, most binaries in /bin/, /usr/bin/ are stripped.
AFAIK Once the binary is stripped you wont be able to get the stripped information back until or unless you regenerate the binary. stripping is useful when you have memory constraints to look after. This might be the reason strip is not enabled by default in GCC.

Resources