I used to compile my UEFI bootloader using mingw (as per the current wiki page I suppose). It did work great and I agree with Zaval that it makes things easier.
Unfortunately it was impractical for me to keep using mingw:
1) I needed another compiler (mingw under Linux, MSVC under Windows) just to support UEFI. I much prefer having one toolchain that works for everything.
2) I couldn't figure out how to build mingw to match the latest version of GCC: mingw is out of sync with the latest releases of GCC which I wanted to use. Some C++ constructs would not compiler under mingw.
3) Having ONE compiler for all target is just a net win. Same bugs, same quirks, some behaviour everywhere.
4) One day I will want to have a native compiler toolchain in my OS. This cannot be MSVC. It won't be mingw (out of date compiler). I certainly do not want to have to port multiple compilers to my OS.
5) clang --> I did not investigate this, maybe it's worth looking at.
6) I much prefer dealing with ELF files than PE files. I can use the same tools for everyone and it just works.
IIRC, PE files typically handle being loaded at any address using relocations (just like ELF files do). But the format of these relocations is incompatible between PE and ELF. So the gnu-efi solution is simply to do the ELF relocations at the entry point. This is actually pretty easy to do:
https://github.com/kiznit/rainbow-os/bl ... .S#L40-L46
https://github.com/kiznit/rainbow-os/bl ... pp#L34-L87
Is this hacky? Sure is. Am I entirely happy with this? I am not. Does it work? yes. What's more, it solves all the concerns I had and listed at the top of this post.
Now XenOS's solution seems even better in that he was able to remove any relocation code from inside the bootloader by using Position-Independant Code. So effectively the produced ELF files doesn't need any relocations anymore. This seems less hacky and overall better than what I have right now.
I am not sure why you are being so aggressive about this. I do agree that we could update the wiki to add this new information and not erase the existing one. Ideally the wiki could explain how to use mingw, msvc, gcc or clang to build your UEFI bootloader, perhaps with pros and cons of each method.
For me, using the same toolchain (compiler, linker, tools) for all my binaries for all my target platforms trumps other concerns. MSVC is great but, I can't target ARM and AARCH64 with it. With GCC it's easy to create a cross compiler and target any architecture.
zaval wrote:
guys, are you aware, that all this is not needed for PE/UEFI? shared libraries... why? UEFI loads your OS Loader and performs base relocations ANYWAY. your .so will make a bad service, since base relocated code is faster than PIC. just link you PE image at whatever image base address you want and UEFI will handle it.
1) A PE UEFI executable is relocatable. There is no guarantee that the firmware will load it at the address you specified at link time. This works because PE files have relocations just like ELF files do, they just use a different format.
2) Performance of PIC vs non-PIC code here really doesn't matter. Who cares. It's a bootloader. Here things are I/O bound, CPU usage is a non-issue.