Page 1 of 1

issue with using clang for osdev

Posted: Wed Mar 18, 2015 2:03 pm
by beyondsociety
I've just gotten back into osdev and have began cleaning up my old code. I decided I wanted to give Clang and LLVM a try instead of cross-compiling like before. I've ran into a few issues that hopefully someone that's more familiar with using clang for osdev knows about and can help. I have a cross-compiled gcc that works just fine. A lot of info, so bare with me.

In the barebones tutorial, it states:

Code: Select all

i686-elf-gcc -T linker.ld -o myos.bin -ffreestanding -O2 -nostdlib boot.o kernel.o -lgcc

Note: Some tutorials suggest linking with i686-elf-ld rather than the compiler, however this prevents the compiler from performing various tasks during linking. Note: that we are linking against libgcc, which implements various runtime routines that your cross-compiler depends on. Leaving it out will give you problems in the future. If you did not build and install libgcc as part of your cross-compiler, you should go back now and build a cross-compiler with libgcc. The compiler depends on this library and will use it regardless of whether you provide it or not.
Doing some research, I've noticed on other sites like stack overflow, they mention the same thing as the barebones, compared to the traditional way of using GCC to compile and then LD to link the executable. Cause when I try to do that with CLANG, I get unused option warnings for "-lgcc and -T linker.ld" and it doesn't create the executable then. I would think clang being similar and all to GCC, would work just fine but that's not the case. I've played around with different ways to get it to work and the the only way I know is by using the old method of GCC / CLANG compiling and then passing the linker options to LD.

If I also supply the -nostdlib option without -lgcc as Clang / LLVM uses compiler-rt (replacement for libgcc), I don’t get any warnings and can compile the code just fine. If I leave both out, then it cant find any of the libgcc/crt.*/start files which makes sense since were freestanding. If I pass the path of the LIBGCC file to LD it finds LIBGCC just fine as well but seems like a hack as -lgcc should work just fine without it but it doesn’t.

Whats the best way to get this to work, right now i'm using Clang to compile and then using cross-compiled LD to link with no LIBGCC added and it works just fine but feels like a hack. Also, is adding -lgcc (libgcc) necessary when the underlaying libs are there?

Re: issue with using clang for osdev

Posted: Wed Mar 18, 2015 2:31 pm
by Candy
GCC has a hack where if you tell it some linker option, it adds -Wl to it for you. Clang doesn't.

What happens if you prefix those two linker options as "-Wl,-T -Wl,linker.ld" ?

Re: issue with using clang for osdev

Posted: Wed Mar 18, 2015 3:27 pm
by beyondsociety
With clang, I get:

Code: Select all

clang -c src/bga.c -o src/bga.o -m32 -O2 -ffreestanding -std=gnu99 -Wl,-T -Wl,linker.ld -nostdlib -Wall -Wextra -Werror -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wuninitialized -Wstrict-prototypes -Wconversion -I ./include 

clang: error: -Wl,-T: 'linker' input unused
clang: error: -Wl,linker.ld: 'linker' input unused
While if i use i686-elf-gcc, it compiles just fine with those options given

Re: issue with using clang for osdev

Posted: Thu Mar 19, 2015 1:23 am
by Combuster
-c
Compile, but do not link.

What are those linker options doing there in the first place? #-o

Re: issue with using clang for osdev

Posted: Thu Mar 19, 2015 2:04 am
by Roman
Shouldn't you use the -target option with clang? Also read this.

Re: issue with using clang for osdev

Posted: Thu Mar 19, 2015 11:15 am
by beyondsociety
Good catch on the -c option, I think it has to do with me trying to compile and link in one go using gcc and my mis understanding of what's going on. I now realize that I need to split them apart. When I have some free time, I'm going to strip the code to bare minimum and see where the issue lies. Thanks for the help.

Re: issue with using clang for osdev

Posted: Fri Mar 20, 2015 5:21 pm
by beyondsociety
I finally got around to striping my code and testing with clang. I was able to get clang to link with

Code: Select all

-Wl,-T -Wl,linker.ld

The problem now is that when I link with clang, it tries to use /usr/bin/ld to link and throws

Code: Select all

 /usr/bin/ld: i386 architecture of input file `src/boot.o' is incompatible with i386:x86-64 output
/usr/bin/ld: i386 architecture of input file `src/kmain.o' is incompatible with i386:x86-64 output
which is not what I want. Im building on a 64-bit version of ubuntu, Ive added the 32-bit libs to ubuntu, but still throws this error. -m elf-i386 doesnt work for clang or gcc as its a ld option only.

I tried to use --target but didnt help much, would be nice if clang was much better at documentation. Unless someone knows how to pass my cross-compiled ld to clang, I think for now the best bet is to just use clang for compiling and then the cross-compiled binutils to link my executable. Or even better just use my cross-compiled gcc.

If i pass 64 bit options to nasm, gcc, and my linker.script, it then compiles but doesn't find the multiboot_header when I run bochs, the boch log shows mismatched registers. If i compile and link with my cross-compiled gcc, everything works fine in bochs and prints my code to screen, registers are what they should be.

Re: issue with using clang for osdev

Posted: Fri Mar 20, 2015 10:11 pm
by ExeTwezz
beyondsociety wrote:

Code: Select all

 /usr/bin/ld: i386 architecture of input file `src/boot.o' is incompatible with i386:x86-64 output
/usr/bin/ld: i386 architecture of input file `src/kmain.o' is incompatible with i386:x86-64 output
which is not what I want. Im building on a 64-bit version of ubuntu, Ive added the 32-bit libs to ubuntu, but still throws this error.
This error is thrown when the linker wants object files for architecture X, but they are for architecture Y. In your case, you can just add

Code: Select all

OUTPUT_ARCH(i386);
and if you want ELF kernel:

Code: Select all

OUTPUT_FORMAT(elf32-i386);
to your linker.ld.

Re: issue with using clang for osdev (solved)

Posted: Sat Mar 21, 2015 9:36 pm
by beyondsociety
Thanks for the help, I was missing the

Code: Select all

OUTPUT_ARCH(i386)
It now compiles fine with just clang.