Cross compile for ARM environment - arm

I am working on an ARM computer:
Here is /proc/cpuinfo:
processor : 0
model name : ARMv7 Processor rev 0 (v7l)
BogoMIPS : 413.08
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpd32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc09
CPU revision : 0
Hardware : ARM-Versatile Express
Revision : 0000
Serial : 0000000000000000
I have tried to compile this program from an x86 computer:
#include <stdio.h>
int main()
{
printf("Hello world!\n");
return 0;
}
Here is what I've done to compile this program:
arm-linux-gnueabi-gcc -static my_program.c
Here is the error message I get when I try to run it on ARM computer:
Syntax error: word unexpected (expecting ")")
and here is the output of file ./a.out
./a.out: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=0e39c5694c188b0e596666fe6503909394e72f44, not stripped

Related

Why it takes me a long time to compile this simple C code?

Why does it take so long (around 10 ~ 20 sec.) to compile my simple printf code?
#include <stdio.h>
int main (void){
printf("why am i so slow\n");
}
This is the output I got in VSCode terminal:
[Running] cd "c:\Users\Gnij\cs50_classes\" && gcc pset_hello.c -o pset_hello && "c:\Users\Gnij\cs50_classes\"pset_hello
why am I so slow
[Done] exited with code=0 in 19.531 seconds
Windows 11
Processor: Intel(R) Core(TM) i7-9750H CPU # 2.60GHz 2.59 GHz
Compiler: gcc (MinGW.org GCC-6.3.0-1) 6.3.0
I expected this to be done in less than five seconds.
However, when I was executing the .exe file of this program, it ran instantly. Why is this the case?

How do cross-compilie on mips without error?

I want to cross compile for MIPS. I am compiling this simple hello world:
#include <stdio.h>
int main(){
printf("HELLO WORLD\n");
return 0;
}
I compile it's so: mips-gcc e.c -static -o hello .
It is hello: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), statically linked, not stripped
uname -a on MIPS system is:
Linux RT-AC1200 2.6.36 #1 Thu Mar 15 11:18:53 CST 2018 mips GNU/Linux
However, when I'm trying to start hello, I'm getting:
./hello: line 1: syntax error: unexpected "("
I tried to compile with different MIPS cross compilers(including gcc-mips-linux-gnu), however always I get this error. What do I do wrong? How to compile right ?

C code compiles silently with gcc, but raises a "truncated - malformed object" error in objdump

I have the following short and simple C file called composition.c :
long inside (long a1,long a2)
{
return a1+a2-a1*a2;
}
long outside(long b1,long b2,long b3,long b4)
{
long first_half = inside(b2,b3);
long second_half = inside(b1,b4);
return(first_half+second_half);
}
int main(int argc, char** argv)
{
long answer=outside(3,4,5,6);
return 0;
}
In my terminal on my HighSierra MacBook Air, I did gcc -g -O0 composition.c -o composition and objdump -d composition, but the latter produces an error message :
$ objdump -d composition
composition: file format Mach-O 64-bit x86-64
/Library/Developer/CommandLineTools/usr/bin/objdump: 'composition': truncated or malformed object (bad section index: 3 for symbol at index 2)
So I'm asking what's wrong with my C code ?
Update : here are the version details :
$ gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
$ objdump --version
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Optimized build.
Default target: x86_64-apple-darwin17.7.0
Host CPU: broadwell
Registered Targets:
aarch64 - AArch64 (little endian)
aarch64_be - AArch64 (big endian)
arm - ARM
arm64 - ARM64 (little endian)
armeb - ARM (big endian)
thumb - Thumb
thumbeb - Thumb (big endian)
x86 - 32-bit X86: Pentium-Pro and above
x86-64 - 64-bit X86: EM64T and AMD64

Unrecognised emulation mode: elf_i386 on MinGW32

I'm trying to make a kernel, and I cannot link the C output with the assembly. The ld. I'm getting the error:
unrecognized emulation mode: elf_i386
I'm using Windows 10 professional with the MinGW32 and MSYS. The code I am using:
link.ld
/*
* link.ld
*/
OUTPUT_FORMAT(elf32-i386)
ENTRY(start)
SECTIONS
{
. = 0x100000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}
kernel.c
/*
* kernel.c
*/
void kmain(void)
{
const char *str = "my first kernel";
char *vidptr = (char*)0xb8000; //video mem begins here.
unsigned int i = 0;
unsigned int j = 0;
/* this loops clears the screen
* there are 25 lines each of 80 columns; each element takes 2 bytes */
while(j < 80 * 25 * 2) {
/* blank character */
vidptr[j] = ' ';
/* attribute-byte - light grey on black screen */
vidptr[j+1] = 0x07;
j = j + 2;
}
j = 0;
/* this loop writes the string to video memory */
while(str[j] != '\0') {
/* the character's ascii */
vidptr[i] = str[j];
/* attribute-byte: give character black bg and light grey fg */
vidptr[i+1] = 0x07;
++j;
i = i + 2;
}
return;
}
kernel.asm
;;kernel.asm
bits 32 ;nasm directive - 32 bit
section .text
global start
extern kmain ;kmain is defined in the c file
start:
cli ;block interrupts
mov esp, stack_space ;set stack pointer
call kmain
hlt ;halt the CPU
section .bss
resb 8192 ;8KB for stack
stack_space:
To Compile and link I use:
nasm -f elf32 kernel.asm -o kasm.o
gcc -m32 -c kernel.c -o kc.o
ld -m elf_i386 -T link.ld -o kernel kasm.o kc.o
I'm Using:
Gcc 4.8.1
Ld 2.25.1
Nasm 2.11.09rc1
Why am I getting this error, and how can I fix it?
The standard MinGW/32 LD linker doesn't output ELF binaries. Preferably you would be using an i686 cross-compiler, but if you're not you may be able to get away with the tips below.
It appears you are using Arjun's Let's Write a Kernel tutorial. If you are following that tutorial you have missed a step to make kernel.asm compatible with the GRUB boot loader and QEMU's -kernel option. Before we start you should read the rest of the tutorial. The following code adds a Multiboot header to kernel.asm to make it GRUB compatible:
;;kernel.asm
bits 32 ;nasm directive - 32 bit
global entry
extern _kmain ;kmain is defined in the c file
section .text
entry: jmp start
;multiboot spec
align 4
dd 0x1BADB002 ;magic
dd 0x00 ;flags
dd -(0x1BADB002 + 0x00) ;checksum. m+f+c should be zero
start:
cli ;block interrupts
mov esp, stack_space ;set stack pointer
call _kmain
hlt ;halt the CPU
section .bss
resb 8192 ;8KB for stack
stack_space:
Besides adding a header I've also put an entry label in the file and a jmp start to jump over the Multiboot header. I've done this to make it easy to set a breakpoint at 0x100000 in the future if you start debugging.
One other change is that on MinGW, GCC adds an underscore to function names by default. I've changed references to the C function kmain to _kmain. This differs from the Linux convention.
Since the entry point of our code is now entry instead of start I've modified link.ld to be:
/*
* link.ld
*/
OUTPUT_FORMAT(pei-i386)
ENTRY(entry)
SECTIONS
{
. = 0x100000;
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss) }
}
Another important change in the file above is the usage of OUTPUT_FORMAT(pei-i386) . This will output a Portable Executable Image (32-bit) rather than an ELF (which isn't supported).
In order to build the kernel and produce an ELF image from the PEI-I386 we can use these commands:
nasm -f elf32 kernel.asm -o kasm.o
gcc -m32 -c kernel.c -o kc.o -ffreestanding -nostdlib -nostdinc
ld -T link.ld -o kernel kasm.o kc.o -build-id=none
objcopy -O elf32-i386 kernel kernel.elf
The LD command has been modified to not write out the build-id to the executable to avoid the Multiboot header from being shifted outside the first 8k of the executable. The GCC options have been modified to produce freestanding code (without the standard library and includes) using the options -ffreestanding -nostdlib -nostdinc. We use objcopy to convert the PEI-I386 file (kernel) to an ELF32 image called kernel.elf. You will want to be using kernel.elf with GRUB and/or QEMU.

ARM GCC inline assembly

I am trying the following :
int main()
{
unsigned int result = 0;
unsigned int op1 = 10, op2 = 20;
asm volatile ("uadd8 %0, %1, %2" :
"=r" (result) :
"r" (op1), "r" (op2) );
}
I want to compile this for Cortex A9 I am using arm GNU GCC toolchain.
But I keep getting this error:
arm-none-linux-gnueabi-gcc test_2.c
Assembler messages:
Error: selected processor does not support ARM mode `uadd8 r4,r3,r2'
I tried by forcing to thumb mode by adding .code 16 also but no luck .
What is the issue here ?
The reason is that the default ARM architecture in your compiler does not implement that instruction. The uadd8 is supported in Thumb mode for architectures ARMv6T2 and ARMv7 and in ARM mode for ARMv6 and ARMv7. Hence you need to pass the proper -march= option to gcc. For example:
-march=armv6
-march=armv6t2 -mthumb
-march=armv7-a
-march=armv7-a -marm
You can check what is the default (or set by options) architecture for the compilation with:
arm-elf-gcc -E -dM -x c /dev/null | grep ARM_ARCH

Resources