|
1 | 1 | use std::path::Path;
|
2 | 2 |
|
3 |
| -use object::{self, Object, ObjectSymbol, SymbolIterator}; |
| 3 | +use object::{self, Object, Symbol, ObjectSymbol, SymbolIterator}; |
4 | 4 |
|
5 | 5 | /// Iterate through the symbols in an object file.
|
6 | 6 | ///
|
@@ -43,28 +43,38 @@ pub fn any_symbol_contains(path: impl AsRef<Path>, substrings: &[&str]) -> bool
|
43 | 43 | })
|
44 | 44 | }
|
45 | 45 |
|
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`. |
47 | 49 | ///
|
48 | 50 | /// The symbol names must match exactly.
|
49 | 51 | ///
|
50 | 52 | /// 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> { |
52 | 54 | let mut found = vec![false; symbol_names.len()];
|
53 | 55 | with_symbol_iter(path, |syms| {
|
54 |
| - for sym in syms { |
| 56 | + for sym in syms.filter(&pred) { |
55 | 57 | for (i, symbol_name) in symbol_names.iter().enumerate() {
|
56 | 58 | found[i] |= sym.name_bytes().unwrap() == symbol_name.as_bytes();
|
57 | 59 | }
|
58 | 60 | }
|
59 | 61 | });
|
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); |
67 | 77 | }
|
| 78 | + panic!("missing symbols"); |
68 | 79 | }
|
69 |
| - result |
70 | 80 | }
|
0 commit comments