diff --git a/Cargo.lock b/Cargo.lock index 6d823c5b5a596..b90985c039de2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1196,6 +1196,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + [[package]] name = "fallible-iterator" version = "0.3.0" @@ -1478,7 +1484,7 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" dependencies = [ - "fallible-iterator", + "fallible-iterator 0.3.0", "indexmap", "stable_deref_trait", ] @@ -1489,7 +1495,7 @@ version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93563d740bc9ef04104f9ed6f86f1e3275c2cdafb95664e26584b9ca807a8ffe" dependencies = [ - "fallible-iterator", + "fallible-iterator 0.3.0", "indexmap", "stable_deref_trait", ] @@ -2765,6 +2771,17 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +[[package]] +name = "pdb" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82040a392923abe6279c00ab4aff62d5250d1c8555dc780e4b02783a7aa74863" +dependencies = [ + "fallible-iterator 0.2.0", + "scroll", + "uuid", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -3221,6 +3238,7 @@ dependencies = [ "gimli 0.32.0", "libc", "object 0.37.1", + "pdb", "regex", "serde_json", "similar", @@ -4930,6 +4948,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" + [[package]] name = "self_cell" version = "1.2.0" diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index 3226f467ba4f9..d73a27e755fa9 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -13,6 +13,7 @@ gimli = "0.32" build_helper = { path = "../../build_helper" } serde_json = "1.0" libc = "0.2" +pdb = "0.8.0" [lib] crate-type = ["lib", "dylib"] diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 67d8c351a59fb..0574b588c93f2 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -41,6 +41,7 @@ pub use bstr; pub use gimli; pub use libc; pub use object; +pub use pdb; pub use regex; pub use serde_json; pub use similar; diff --git a/tests/run-make/fmt-write-bloat/rmake.rs b/tests/run-make/fmt-write-bloat/rmake.rs index 3348651d501fd..2dbb9a78e426e 100644 --- a/tests/run-make/fmt-write-bloat/rmake.rs +++ b/tests/run-make/fmt-write-bloat/rmake.rs @@ -15,21 +15,89 @@ //! `NO_DEBUG_ASSERTIONS=1`). If debug assertions are disabled, then we can check for the absence of //! additional `usize` formatting and padding related symbols. +// ignore-tidy-linelength + //@ ignore-cross-compile -use run_make_support::artifact_names::bin_name; use run_make_support::env::no_debug_assertions; -use run_make_support::rustc; use run_make_support::symbols::any_symbol_contains; +use run_make_support::{bin_name, is_darwin, is_windows_msvc, pdb, rustc, target}; + +// Not applicable for `extern "C"` symbol decoration handling. +fn sym(sym_name: &str) -> String { + if is_darwin() { + // Symbols are decorated with an underscore prefix on darwin platforms. + format!("_{sym_name}") + } else { + sym_name.to_string() + } +} fn main() { rustc().input("main.rs").opt().run(); // panic machinery identifiers, these should not appear in the final binary - let mut panic_syms = vec!["panic_bounds_check", "Debug"]; + let mut panic_syms = vec![sym("panic_bounds_check"), sym("Debug")]; if no_debug_assertions() { // if debug assertions are allowed, we need to allow these, // otherwise, add them to the list of symbols to deny. - panic_syms.extend_from_slice(&["panicking", "panic_fmt", "pad_integral", "Display"]); + panic_syms.extend_from_slice(&[ + sym("panicking"), + sym("panic_fmt"), + sym("pad_integral"), + sym("Display"), + ]); + } + + if is_windows_msvc() { + use pdb::FallibleIterator; + + let file = std::fs::File::open("main.pdb").expect("failed to open `main.pdb`"); + let mut pdb = pdb::PDB::open(file).expect("failed to parse `main.pdb`"); + + let symbol_table = pdb.global_symbols().expect("failed to parse PDB global symbols"); + let mut symbols = symbol_table.iter(); + + let mut found_symbols = vec![]; + + while let Some(symbol) = symbols.next().expect("failed to parse symbol") { + match symbol.parse() { + Ok(pdb::SymbolData::Public(data)) => { + found_symbols.push(data.name.to_string()); + } + _ => {} + } + } + + // Make sure we at least have the `main` symbol itself, otherwise even no symbols can + // trivially satisfy the "no panic symbol" assertion. + let main_sym = if is_darwin() { + // Symbols are decorated with an underscore prefix on darwin platforms. + "_main" + } else if target().contains("i686") && is_windows_msvc() { + // `extern "C"` i.e. `__cdecl` on `i686` windows-msvc means that the symbol will be + // decorated with an underscore, but not on `x86_64` windows-msvc. + // See . + "_main" + } else { + "main" + }; + + assert!(found_symbols.iter().any(|sym| sym == main_sym), "expected `main` symbol"); + + for found_symbol in found_symbols { + for panic_symbol in &panic_syms { + assert_ne!( + found_symbol, + panic_symbol.as_str(), + "found unexpected panic machinery symbol" + ); + } + } + } else { + let panic_syms = panic_syms.iter().map(String::as_str).collect::>(); + // Make sure we at least have the `main` symbol itself, otherwise even no symbols can + // trivially satisfy the "no panic symbol" assertion. + assert!(any_symbol_contains(bin_name("main"), &["main"])); + assert!(!any_symbol_contains(bin_name("main"), &panic_syms)); } - assert!(!any_symbol_contains(bin_name("main"), &panic_syms)); }