bzt wrote:
It took me quite a while to figure out all the necessary CLang and lld switches. The most problematic part is, UEFI has renamed all the standard C functions
It's not C library functions. like at all, bzt.
bzt wrote:
like there's no memset, memcmp, memcpy etc. you have ZeroMem, CompareMem, CopyMem etc.
exactly, there is no memset, memcmp, memcpy etc. there is no standard C library in the UEFI environment.
bzt wrote:
but mem* still might be inserted into the binary by any C compiler even if the source doesn't reference them directly (depending on the code and optimization level of course). When such a builtin gets inlined, then no probs, you won't even notice. But under some circumstances sometimes only a libc call is emitted (even in the freestanding mode), and bam, you have a big problem, lots of linking errors.
and how this is a problem of UEFI or a proof, that it has been made with only MSVC in mind? if your compiler is so dumb, that still makes references to a library, it was explicitly commanded to not to, then this means your compiler is dumb and it failed to be "freestanding" even after being asked to be. there is no any "libc" in UEFI.
bzt wrote:
Yes, once you've figured out all the necessary switches, it's easy, but all problems seem easy once you know the solution... Maybe there's a switch in CLang that simply tells it to always use UEFI equivalents of these builtins, but I couldn't find this switch, that's for sure.
there should not be any "builtins" in this case, how is it that hard to get? you just call CopyMem() Boot Service as any other Boot Service, why on earth one would start to talk nonsense about gcc builtins?!! All the sane compiler should do here is just emit an indirect call to this function,
PROVIDED by UEFI.
anyway, this statement of this user:
bzt wrote:
Correction: UEFI was written with purely MSVC in mind, not C in general
is one of those cases, where there is a need to put a huge @$$ font banner in red, suggested by the very same user, ironically, as a follow up to the statement, to not confuse newcomers, like this:
EXTREME_BULLSH1T!!!
I understand, that staring at CamelCased function names of UEFI, a MS crony Intel decorated UEFI in, causes bzt to feel non-stoppable overheat at his bottom parts, YET this is not an excuse to emit such WRONG and CONFUSING statements.
And of course, writing UEFI in assembly isn't any harder, than for BIOS. you just need to read carefully about calling conventions used and follow that. the why question is another one. but it's about personal preferences. it's doable, do it, if you want. there might be a few of tutorials, but again, remember, there is not much specific about that programming compared to the BIOS case or even assembly programming in the OS environment. read the UEFI spec and if you know the assembly in question, you are ready to go.
PS. personally, just for the sake of completeness, I compiled my UEFI OS Loader with clang too. For ARM32 and ARM64[1]. And it worked. heck, I even compiled the code for RISCV64! Just need to finish my ELF->PE conversion utility to try it out! yep, clang can't make PE targets for RISCV.
1 - There was one problem with 32 bit ARM, because clang linkers do not set proper MachineType for UEFI targets (which is 1C2), despite generate proper code - UEFI allows OSL to be compiled in Thumb code, but expects it to be "interworking" aware, that is, be aware, that UEFI services itself may be in ARM code. given, all the calls to UEFI go through the function pointer tables, the problem resolves itself, - 32 bit ARM's indirect call (through register) always takes care about changing the CPU mode - blx <reg> (branch, link and exchange (the mode)). but the linker in clang doesn't care about UEFI and supports only what's needed for Windows and because the latter is Thumb only, it sets the MachineType in 1C4 (Thumb only). Whereas it should be 1C2 (ARM or Thumb). MSVC's linker recognizes EFI_* subsystems and sets the subsystem properly, clang doesn't. irony, eh? seems, they at clang neglected UEFI completely. isn't it weird? like it's what nobody until now ever tried to use clang for UEFI OSL for 32 bit ARM? hardly so, so what's the reason of such a weird thing? well, the answer is probably that, all those who used clang for UEFI did it targetting ELF and then making manually ELF to PE conversion, with edk incl! either through some scripts or ugly trickery with headers. and noone even thought, wait the minute, why can't we try the already available PE targetting? ... anyway, a little patch for clang's linker is needed. or hexediting the resulting image. what I did.
and it ran.