Skip to content

Commit 4feb949

Browse files
committed
migrate fmt-write-bloat to rmake
1 parent 595316b commit 4feb949

File tree

6 files changed

+86
-26
lines changed

6 files changed

+86
-26
lines changed

src/tools/run-make-support/src/env.rs

+7
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,10 @@ pub fn env_var_os(name: &str) -> OsString {
1717
None => panic!("failed to retrieve environment variable {name:?}"),
1818
}
1919
}
20+
21+
/// Check if `NO_DEBUG_ASSERTIONS` is set (usually this may be set in CI jobs).
22+
#[track_caller]
23+
#[must_use]
24+
pub fn no_debug_assertions() -> bool {
25+
std::env::var_os("NO_DEBUG_ASSERTIONS").is_some()
26+
}

src/tools/run-make-support/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub mod run;
2121
pub mod scoped_run;
2222
pub mod string;
2323
pub mod targets;
24+
pub mod symbols;
2425

2526
// Internally we call our fs-related support module as `fs`, but re-export its content as `rfs`
2627
// to tests to avoid colliding with commonly used `use std::fs;`.
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use object::{self, Object, ObjectSymbol, SymbolIterator};
2+
use std::path::Path;
3+
4+
/// Iterate through the symbols in an object file.
5+
///
6+
/// Uses a callback because `SymbolIterator` does not own its data.
7+
///
8+
/// Panics if `path` is not a valid object file readable by the current user.
9+
pub fn with_symbol_iter<P, F, R>(path: P, func: F) -> R
10+
where
11+
P: AsRef<Path>,
12+
F: FnOnce(&mut SymbolIterator<'_, '_>) -> R,
13+
{
14+
let raw_bytes = crate::fs::read(path);
15+
let f = object::File::parse(raw_bytes.as_slice()).expect("unable to parse file");
16+
let mut iter = f.symbols();
17+
func(&mut iter)
18+
}
19+
20+
/// Check an object file's symbols for substrings.
21+
///
22+
/// Returns `true` if any of the symbols found in the object file at
23+
/// `path` contain a substring listed in `substrings`.
24+
///
25+
/// Panics if `path` is not a valid object file readable by the current user.
26+
pub fn any_symbol_contains(path: impl AsRef<Path>, substrings: &[&str]) -> bool {
27+
with_symbol_iter(path, |syms| {
28+
for sym in syms {
29+
for substring in substrings {
30+
if sym
31+
.name_bytes()
32+
.unwrap()
33+
.windows(substring.len())
34+
.any(|x| x == substring.as_bytes())
35+
{
36+
eprintln!("{:?} contains {}", sym, substring);
37+
return true;
38+
}
39+
}
40+
}
41+
false
42+
})
43+
}

src/tools/tidy/src/allowed_run_make_makefiles.txt

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ run-make/dep-info-spaces/Makefile
1010
run-make/dep-info/Makefile
1111
run-make/emit-to-stdout/Makefile
1212
run-make/extern-fn-reachable/Makefile
13-
run-make/fmt-write-bloat/Makefile
1413
run-make/foreign-double-unwind/Makefile
1514
run-make/foreign-exceptions/Makefile
1615
run-make/incr-add-rust-src-component/Makefile

tests/run-make/fmt-write-bloat/Makefile

-25
This file was deleted.
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//! Before #78122, writing any `fmt::Arguments` would trigger the inclusion of `usize` formatting
2+
//! and padding code in the resulting binary, because indexing used in `fmt::write` would generate
3+
//! code using `panic_bounds_check`, which prints the index and length.
4+
//!
5+
//! These bounds checks are not necessary, as `fmt::Arguments` never contains any out-of-bounds
6+
//! indexes. The test is a `run-make` test, because it needs to check the result after linking. A
7+
//! codegen or assembly test doesn't check the parts that will be pulled in from `core` by the
8+
//! linker.
9+
//!
10+
//! In this test, we try to check that the `usize` formatting and padding code are not present in
11+
//! the final binary by checking that panic symbols such as `panic_bounds_check` are **not**
12+
//! present.
13+
//!
14+
//! Some CI jobs try to run faster by disabling debug assertions (through setting
15+
//! `NO_DEBUG_ASSERTIONS=1`). If debug assertions are disabled, then we can check for the absence of
16+
//! additional `usize` formatting and padding related symbols.
17+
18+
// Reason: This test is `ignore-windows` because the `no_std` test (using `#[link(name = "c")])`
19+
// doesn't link on windows.
20+
//@ ignore-windows
21+
//@ ignore-cross-compile
22+
23+
use run_make_support::{env::no_debug_assertions, rustc, symbols::any_symbol_contains};
24+
25+
fn main() {
26+
rustc().input("main.rs").opt().run();
27+
// panic machinery identifiers, these should not appear in the final binary
28+
let mut panic_syms = vec!["panic_bounds_check", "Debug"];
29+
if no_debug_assertions() {
30+
// if debug assertions are allowed, we need to allow these,
31+
// otherwise, add them to the list of symbols to deny.
32+
panic_syms.extend_from_slice(&["panicking", "panic_fmt", "pad_integral", "Display"]);
33+
}
34+
assert!(!any_symbol_contains("main", &panic_syms));
35+
}

0 commit comments

Comments
 (0)