Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 8663bbe

Browse files
committed
refactor extern-fn-reachable to make sure symbols are exported
1 parent 158f1ea commit 8663bbe

File tree

2 files changed

+29
-15
lines changed

2 files changed

+29
-15
lines changed

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

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::path::Path;
22

3-
use object::{self, Object, ObjectSymbol, SymbolIterator};
3+
use object::{self, Object, Symbol, ObjectSymbol, SymbolIterator};
44

55
/// Iterate through the symbols in an object file.
66
///
@@ -43,28 +43,38 @@ pub fn any_symbol_contains(path: impl AsRef<Path>, substrings: &[&str]) -> bool
4343
})
4444
}
4545

46-
/// Check if an object file contains *all* of the given symbols.
46+
/// Get a list of symbols that are in `symbol_names` but not the final binary.
47+
///
48+
/// The symbols must also match `pred`.
4749
///
4850
/// The symbol names must match exactly.
4951
///
5052
/// Panics if `path` is not a valid object file readable by the current user.
51-
pub fn contains_exact_symbols(path: impl AsRef<Path>, symbol_names: &[&str]) -> bool {
53+
pub fn missing_exact_symbols<'a>(path: impl AsRef<Path>, symbol_names: &[&'a str], pred: impl Fn(&Symbol<'_, '_>) -> bool) -> Vec<&'a str> {
5254
let mut found = vec![false; symbol_names.len()];
5355
with_symbol_iter(path, |syms| {
54-
for sym in syms {
56+
for sym in syms.filter(&pred) {
5557
for (i, symbol_name) in symbol_names.iter().enumerate() {
5658
found[i] |= sym.name_bytes().unwrap() == symbol_name.as_bytes();
5759
}
5860
}
5961
});
60-
let result = found.iter().all(|x| *x);
61-
if !result {
62-
eprintln!("does not contain symbol(s): ");
63-
for i in 0..found.len() {
64-
if !found[i] {
65-
eprintln!("* {}", symbol_names[i]);
66-
}
62+
return found.iter().enumerate()
63+
.filter_map(|(i, found)| if !*found {
64+
Some(symbol_names[i])
65+
} else {
66+
None
67+
}).collect();
68+
}
69+
70+
/// Assert that the symbol file contains all of the listed symbols and they all match the given predicate
71+
pub fn assert_contains_exact_symbols(path: impl AsRef<Path>, symbol_names: &[&str], pred: impl Fn(&Symbol<'_, '_>) -> bool) {
72+
let missing = missing_exact_symbols(path.as_ref(), symbol_names, pred);
73+
if missing.len() > 0 {
74+
eprintln!("{} does not contain symbol(s): ", path.as_ref().display());
75+
for sn in missing {
76+
eprintln!("* {}", sn);
6777
}
78+
panic!("missing symbols");
6879
}
69-
result
7080
}
Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
//@ ignore-cross-compile
22
use run_make_support::rustc;
3-
use run_make_support::symbols::contains_exact_symbols;
4-
3+
use run_make_support::symbols::assert_contains_exact_symbols;
4+
use run_make_support::object::ObjectSymbol;
55
fn main() {
66
rustc().input("dylib.rs").output("dylib.so").prefer_dynamic().run();
7-
assert!(contains_exact_symbols("dylib.so", &["fun1", "fun2", "fun3", "fun4", "fun5"]));
7+
assert_contains_exact_symbols(
8+
"dylib.so",
9+
&["fun1", "fun2", "fun3", "fun4", "fun5"],
10+
|sym| dbg!(dbg!(sym).is_global()) && !dbg!(sym.is_undefined()),
11+
);
812
}

0 commit comments

Comments
 (0)