|
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