diff --git a/Cargo.lock b/Cargo.lock index acffaaff4d3b3..73256018078d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -792,9 +792,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.82" +version = "0.1.84" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18cd7635fea7bb481ea543b392789844c1ad581299da70184c7175ce3af76603" +checksum = "989b2c1ca6e90ad06fdc69d1d1862fa28d27a977be6d92ae2fa762cf61fe0b10" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index e1a108cea9574..acac9e7a03c60 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -53,6 +53,7 @@ dependencies = [ "hex", "ignore", "libc", + "object", "once_cell", "opener", "pretty_assertions", @@ -400,6 +401,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.12.0" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index f74738437ea3a..4000d6cd477e3 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -42,6 +42,7 @@ getopts = "0.2.19" cc = "1.0.69" libc = "0.2" hex = "0.4" +object = { version = "0.29.0", default-features = false, features = ["archive", "coff", "read_core", "unaligned"] } serde = { version = "1.0.8", features = ["derive"] } serde_json = "1.0.2" sha2 = "0.10" diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index aacd2c7eab981..2fef7f65827dd 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -10,10 +10,14 @@ use std::collections::HashSet; use std::env; +use std::ffi::OsStr; use std::fs; use std::path::{Path, PathBuf}; use std::process::Command; +use object::read::archive::ArchiveFile; +use object::BinaryFormat; + use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::channel; @@ -555,6 +559,39 @@ fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool { } } +/// Check that all objects in rlibs for UEFI targets are COFF. This +/// ensures that the C compiler isn't producing ELF objects, which would +/// not link correctly with the COFF objects. +fn verify_uefi_rlib_format(builder: &Builder<'_>, target: TargetSelection, stamp: &Path) { + if !target.ends_with("-uefi") { + return; + } + + for (path, _) in builder.read_stamp_file(stamp) { + if path.extension() != Some(OsStr::new("rlib")) { + continue; + } + + let data = t!(fs::read(&path)); + let data = data.as_slice(); + let archive = t!(ArchiveFile::parse(data)); + for member in archive.members() { + let member = t!(member); + let member_data = t!(member.data(data)); + + let is_coff = match object::File::parse(member_data) { + Ok(member_file) => member_file.format() == BinaryFormat::Coff, + Err(_) => false, + }; + + if !is_coff { + let member_name = String::from_utf8_lossy(member.name()); + panic!("member {} in {} is not COFF", member_name, path.display()); + } + } + } +} + /// Copy stamped files into an image's `target/lib` directory. fn copy_target_libs(builder: &Builder<'_>, target: TargetSelection, image: &Path, stamp: &Path) { let dst = image.join("lib/rustlib").join(target.triple).join("lib"); @@ -610,6 +647,7 @@ impl Step for Std { let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); let stamp = compile::libstd_stamp(builder, compiler_to_use, target); + verify_uefi_rlib_format(builder, target, &stamp); copy_target_libs(builder, target, &tarball.image_dir(), &stamp); Some(tarball.generate()) diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile index e1adabaac9b56..93ef7dfcbf549 100644 --- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile @@ -61,6 +61,12 @@ ENV \ AR_i686_unknown_freebsd=i686-unknown-freebsd12-ar \ CC_i686_unknown_freebsd=i686-unknown-freebsd12-clang \ CXX_i686_unknown_freebsd=i686-unknown-freebsd12-clang++ \ + CC_aarch64_unknown_uefi=clang-11 \ + CXX_aarch64_unknown_uefi=clang++-11 \ + CC_i686_unknown_uefi=clang-11 \ + CXX_i686_unknown_uefi=clang++-11 \ + CC_x86_64_unknown_uefi=clang-11 \ + CXX_x86_64_unknown_uefi=clang++-11 \ CC=gcc-8 \ CXX=g++-8 diff --git a/src/ci/docker/host-x86_64/test-various/Dockerfile b/src/ci/docker/host-x86_64/test-various/Dockerfile index b0f35bcb9ccf5..0bddffa3436f4 100644 --- a/src/ci/docker/host-x86_64/test-various/Dockerfile +++ b/src/ci/docker/host-x86_64/test-various/Dockerfile @@ -1,6 +1,7 @@ FROM ubuntu:20.04 RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + clang-11 \ g++ \ make \ ninja-build \ @@ -67,7 +68,9 @@ ENV MUSL_TARGETS=x86_64-unknown-linux-musl \ ENV MUSL_SCRIPT python3 /checkout/x.py --stage 2 test --host='' --target $MUSL_TARGETS COPY host-x86_64/test-various/uefi_qemu_test /uefi_qemu_test -ENV UEFI_TARGETS=x86_64-unknown-uefi +ENV UEFI_TARGETS=x86_64-unknown-uefi \ + CC_x86_64_unknown_uefi=clang-11 \ + CXX_x86_64_unknown_uefi=clang++-11 ENV UEFI_SCRIPT python3 /checkout/x.py --stage 2 build --host='' --target $UEFI_TARGETS && \ python3 -u /uefi_qemu_test/run.py