I discovered that the new disted
i686-unknown-uefi target hits linker
errors when you try to use it. Filed an
issue for that and
started looking into it.
There are a few issues that need to be solved. First up, an asm issue:
Asm files aren't getting a special symbol needed by the linker when safe
SEH is enabled. It might be possible to solve that with some extra
compilation flags, except those flags are asm-specific and clang doesn't
like it when you pass the flag to C files. Since compiler_builtins uses
cc::Build object for all files, we can't easily pass
For now I solved this in compiler-builtins by just disabling the asm implementations on UEFI: PR. I also filed an issue in cc-rs suggesting adding a way to set asm-specific flags. That got a quick response indicating that a patch would be welcome. I put together a PR implementing that, which got reviewed and merged in about a half hour, which is a really nice response time :)
The second issue is that the dist script for the UEFI targets is defaulting to gcc for the C files in compiler builtins. That causes us to end up with a compiler-builtins rlib that contains a mix of PE objects (from the Rust code) and ELF objects (from the C code). That doesn't actually cause an error when building compiler-builtins or Rust, which is why we didn't notice it. However, if you try to actually reference one of the symbols in an ELF object you get a linker error.
To solve this we can switch the dist to use clang, but that exposes
another issue: one of the C files in compiler-rt that compiler-builtins
uses tries to include
stdlib.h. That is not really compatible with
-ffreestanding, and can lead to incompatible type
My first attempt to solve this was to just skip including that file (PR), but that was wrong because the file defines functions that are used in other files. Easy to miss because again, you don't find out that it's wrong until you actually call something that (transitively) uses the missing symbol.
Then I realized we could just provide an empty
stdlib.h file since
nothing actually needs to be declared for the C file to compile in our
case. Made a new
PR for that.
The two compiler_builtins PRs were merged and included in the 0.1.84 release.
Next I put up a PR in Rust to update to the new version of compiler_builtins and switch the C compiler for the UEFI targets to clang. I got some feedback requesting some kind of test to ensure that the rlibs all contain just COFF objects, so I spent a little time figuring that out and updated the PR.
That's the status as of Sunday; once the PR is merged the next nightly should contain much more functional UEFI prebuilts.
I also want to enable CI for the aarch64 and i686 UEFI targets. For i686 that might require updating the Dockerfile to a newer version of Ubuntu that has the ovmf-ia32 package. Haven't looked at the aarch64 part yet.
- Released new versions of all the crates.
- Started working on making the uefi-test-runner expect just the special QEMU env. That will help us to make the tests more assertive: PR