|
10 | 10 |
|
11 | 11 | use std::collections::HashSet;
|
12 | 12 | use std::env;
|
| 13 | +use std::ffi::OsStr; |
13 | 14 | use std::fs;
|
14 | 15 | use std::path::{Path, PathBuf};
|
15 | 16 | use std::process::Command;
|
16 | 17 |
|
| 18 | +use object::read::archive::ArchiveFile; |
| 19 | +use object::BinaryFormat; |
| 20 | + |
17 | 21 | use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
|
18 | 22 | use crate::cache::{Interned, INTERNER};
|
19 | 23 | use crate::channel;
|
@@ -555,6 +559,39 @@ fn skip_host_target_lib(builder: &Builder<'_>, compiler: Compiler) -> bool {
|
555 | 559 | }
|
556 | 560 | }
|
557 | 561 |
|
| 562 | +/// Check that all objects in rlibs for UEFI targets are COFF. This |
| 563 | +/// ensures that the C compiler isn't producing ELF objects, which would |
| 564 | +/// not link correctly with the COFF objects. |
| 565 | +fn verify_uefi_rlib_format(builder: &Builder<'_>, target: TargetSelection, stamp: &Path) { |
| 566 | + if !target.ends_with("-uefi") { |
| 567 | + return; |
| 568 | + } |
| 569 | + |
| 570 | + for (path, _) in builder.read_stamp_file(stamp) { |
| 571 | + if path.extension() != Some(OsStr::new("rlib")) { |
| 572 | + continue; |
| 573 | + } |
| 574 | + |
| 575 | + let data = t!(fs::read(&path)); |
| 576 | + let data = data.as_slice(); |
| 577 | + let archive = t!(ArchiveFile::parse(data)); |
| 578 | + for member in archive.members() { |
| 579 | + let member = t!(member); |
| 580 | + let member_data = t!(member.data(data)); |
| 581 | + |
| 582 | + let is_coff = match object::File::parse(member_data) { |
| 583 | + Ok(member_file) => member_file.format() == BinaryFormat::Coff, |
| 584 | + Err(_) => false, |
| 585 | + }; |
| 586 | + |
| 587 | + if !is_coff { |
| 588 | + let member_name = String::from_utf8_lossy(member.name()); |
| 589 | + panic!("member {} in {} is not COFF", member_name, path.display()); |
| 590 | + } |
| 591 | + } |
| 592 | + } |
| 593 | +} |
| 594 | + |
558 | 595 | /// Copy stamped files into an image's `target/lib` directory.
|
559 | 596 | fn copy_target_libs(builder: &Builder<'_>, target: TargetSelection, image: &Path, stamp: &Path) {
|
560 | 597 | let dst = image.join("lib/rustlib").join(target.triple).join("lib");
|
@@ -610,6 +647,7 @@ impl Step for Std {
|
610 | 647 |
|
611 | 648 | let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
|
612 | 649 | let stamp = compile::libstd_stamp(builder, compiler_to_use, target);
|
| 650 | + verify_uefi_rlib_format(builder, target, &stamp); |
613 | 651 | copy_target_libs(builder, target, &tarball.image_dir(), &stamp);
|
614 | 652 |
|
615 | 653 | Some(tarball.generate())
|
|
0 commit comments