Page 1 of 1

I686 cross compiler builds 64 bit elf. Hilarity ensues

Posted: Wed Nov 18, 2020 6:22 pm
by MeitWouldSeem
Hello everyone. I've built a cross compiler as per the instructions on the wiki GCC Cross-Compiler. I'm trying to use it to build a tiny test kernel in C. Its able to build the kernel just fine but when it gets to the linking phase it says:

Code: Select all

kernel.o: file not recognized: file format not recognized
Which is strange because it just built kernel.o a moment ago.

If I do "readelf -h kernel.o" I get

Code: Select all

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          432 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         9
  Section header string table index: 8
Its in a 64 bit elf format despite the fact that the compiler is targeting i686. I can only guess that this is the reason that the linker dosen't know what to do with it but then I still have no idea why it built a 64 bit elf in the first place. I tried to persuade it to build a 32 bit elf with "-m32" but this flag didn't make a difference. Is it possible that I built the compiler wrong? I'm using WSL if that makes a difference.

Here is my full makefile. I am well aware that it's not a shining example of best practice and I don't intend for it to look like this forever.

Code: Select all

export PATH:=$(HOME)/opt/cross/bin/:$(PATH)

ASM=nasm
CC=i686-elf-gcc
LD=i686-elf-ld
CFLAGS=-std=gnu99 -ffreestanding -O2 -Wall -Wextra
LINKFLAGS=-ffreestanding -O2 -nostdlib -lgcc
ASMFLAGS=-f bin

.PHONY: all clean

all: bootloader.flp

bootloader.flp: bootsec.bin stageone.bin
	cat bootsec.bin stageone.bin > bootloader.flp

bootsec.bin:
	$(ASM) bootsec.asm $(ASMFLAGS) -o bootsec.bin

stageone.bin: stageone.o kernel.o
	$(CC) -T linker.ld -o stageone.bin $(LINKFLAGS) stageone.o kernel.o

stageone.o:
	$(ASM) stageone.asm -f elf -o stageone.o

kernel.o:
	$(CC) -c kernel.c -o kernel.o $(CFLAGS)

clean:
	rm -f bootloader.flp bootsec.bin stageone.bin stageone.o kernel.o

Re: I686 cross compiler builds 64 bit elf. Hilarity ensues

Posted: Fri Nov 20, 2020 1:35 am
by Ryanel
I believe it's a bug in your Makefile, and that CC is not actually getting overwritten. I would test this with echo $CC in one of the rules. To ensure that your compiler is not the issue, you can always just run the commands manually.

Make has different ways of assigning things. Look here for more detail: https://www.gnu.org/software/make/manua ... tting.html

I would recommend either switching to := assignment or ?= assignment for the variables. ?= can be overwritten on the command line, which is nice.

Hope this helps,
Ryanel

Re: I686 cross compiler builds 64 bit elf. Hilarity ensues

Posted: Fri Nov 20, 2020 1:55 am
by Solar
Also, check if your i686-elf-gcc executable actually is an i686-elf-gcc (i686-elf-gcc -v | grep Target)...

Sidenote: The variables used in implicit rules for assembly are $(AS) / $(ASFLAGS), not $(ASM) / $(ASMFLAGS).

Re: I686 cross compiler builds 64 bit elf. Hilarity ensues

Posted: Fri Nov 20, 2020 3:19 am
by iansjack
Have you tried running make with the -n flag to show you what commands are being executed?

And are you sure that kernel.o actually was built and didn't already exist?