Page 1 of 1

Multilib libgcc for x86 and x86_64

Posted: Wed Jan 24, 2024 12:18 pm
by codeExplorer
Hi everyone! I've been trying to convert my OS to x86_64, and have run into a problem with libgcc. As I'm using GRUB to boot a multiboot kernel (booting a small 32-bit init that sets up 64-bit mode, and loading the actual kernel as a module), I need to be able to compile 32-bit code, ideally using the same compiler for simplicity. However, the compiler built following https://wiki.osdev.org/GCC_Cross-Compiler has only support for one architecture. GCC does have multilib support, and I thought about using that. However, since it's a 64-bit OS, I also followed https://wiki.osdev.org/Libgcc_without_red_zone, which, as far as I understand it, "hijacks" the multilib support to provide a libgcc without red zone. My question would then be if it's still possible to somehow build a normal 32-bit libgcc with which to link the 32-bit parts of my OS, still using the 64-bit gcc?

Re: Multilib libgcc for x86 and x86_64

Posted: Wed Jan 24, 2024 9:15 pm
by Octocontrabass
It should be possible, but I've never tried it. (Actually, it might already be there - doesn't x86-64 multilib include 32-bit by default?)

Re: Multilib libgcc for x86 and x86_64

Posted: Wed Jan 24, 2024 10:03 pm
by nullplan
codeExplorer wrote: need to be able to compile 32-bit code, ideally using the same compiler for simplicity.
Is it not simpler to have a separate compiler for 32-bit code? That's what I'm doing, and it works well. I have one i686-elf-gcc and one x86_64-elf-gcc, compiled from the same source.

As for libgcc, I just don't link it in. So far I have not had linker failures. If I do get them, I will research the function in question and add an implementation for it to the kernel.

Re: Multilib libgcc for x86 and x86_64

Posted: Thu Jan 25, 2024 7:06 am
by codeExplorer
Octocontrabass wrote:It should be possible, but I've never tried it. (Actually, it might already be there - doesn't x86-64 multilib include 32-bit by default?)
As far as I'm aware, not really, when I try to do it, the linking with gcc fails. It tries to use the 64-bit version, deems it invalid, and can't find anything else (and as for the installed files, there's no 32-bit version)
nullplan wrote:Is it not simpler to have a separate compiler for 32-bit code? That's what I'm doing, and it works well. I have one i686-elf-gcc and one x86_64-elf-gcc, compiled from the same source.
As for libgcc, I just don't link it in. So far I have not had linker failures. If I do get them, I will research the function in question and add an implementation for it to the kernel.
Well, I was trying to avoid it, since I'm using CMake as a build system, and there's no "proper" way to define a different compiler for parts of your project (there is a hack using ExternalProject, but that is just not ideal)

I can also link it without libgcc, and just fix the code whenever it complains (for example, not really using operations between int64_t types in the loader), but that also just doesn't seem ideal.

I guess the best solution is to indeed have two different compilers, and just use one or the other depending on what you're compiling. Though, for that, I think I'd better go back to good old Make, which I was trying to avoid. Oh well

Re: Multilib libgcc for x86 and x86_64

Posted: Thu Jan 25, 2024 8:30 am
by nullplan
codeExplorer wrote:since I'm using CMake as a build system,
Well there's your problem. A tool that does not allow you to do what needs to be done is not a tool worth using. Even just POSIX make has no issue with this task whatsoever, so don't hobble yourself with this crutch.

FYI: I just use a shell script to generate a build.ninja file for ninja-build. Another tool that has no issue with using multiple compilers.
codeExplorer wrote:I can also link it without libgcc, and just fix the code whenever it complains (for example, not really using operations between int64_t types in the loader), but that also just doesn't seem ideal.
I am not using libgcc for the simple reason that I am compiling kernel code, and libgcc might not know that. For instance, there are versions of libgcc using vector registers for integer operations. But a kernel cannot do that (using SSE in kernel, when you're building a higher-half kernel, would mean saving FPU on every kernel entry, not just on every context switch). So I write the code in assembler in a way that works for the kernel.

Mind you, my 32-bit code stub works with 64-bit values to set up paging, and I have not yet had to implement any libgcc function.
codeExplorer wrote:I guess the best solution is to indeed have two different compilers, and just use one or the other depending on what you're compiling. Though, for that, I think I'd better go back to good old Make, which I was trying to avoid. Oh well
Expand your horizon, young Padawan. There are more options than make and cmake out there. ninja-build I already mentioned, and the shell script works shockingly well. Also a good way to generate POSIX make files, if that were requested. Or, on the subject of shell scripts, you could just use a build script and always rebuild everything. When you compare the added build time with the removed headaches from dependency tracking, it seems very alluring. I once created such a build script at my day job, just as experiment, and the 500,000 lines of code were compiled in 1 minute. And that was just because of Cygwin. Imagine how fast it would have been on Linux! Don't discount the simple options!