run_make_support/
symbols.rs

1use std::path::Path;
2
3use object::{self, Object, ObjectSymbol, SymbolIterator};
4
5/// Given an [`object::File`], find the exported dynamic symbol names via
6/// [`object::Object::exports`]. This does not distinguish between which section the symbols appear
7/// in.
8#[track_caller]
9pub fn exported_dynamic_symbol_names<'file>(file: &'file object::File<'file>) -> Vec<&'file str> {
10    file.exports()
11        .unwrap()
12        .into_iter()
13        .filter_map(|sym| std::str::from_utf8(sym.name()).ok())
14        .collect()
15}
16
17/// Iterate through the symbols in an object file. See [`object::Object::symbols`].
18///
19/// Panics if `path` is not a valid object file readable by the current user or if `path` cannot be
20/// parsed as a recognized object file.
21#[track_caller]
22pub fn with_symbol_iter<P, F, R>(path: P, func: F) -> R
23where
24    P: AsRef<Path>,
25    F: FnOnce(&mut SymbolIterator<'_, '_>) -> R,
26{
27    let path = path.as_ref();
28    let blob = crate::fs::read(path);
29    let f = object::File::parse(&*blob)
30        .unwrap_or_else(|e| panic!("failed to parse `{}`: {e}", path.display()));
31    let mut iter = f.symbols();
32    func(&mut iter)
33}
34
35/// Check an object file's symbols for substrings.
36///
37/// Returns `true` if any of the symbols found in the object file at `path` contain a substring
38/// listed in `substrings`.
39///
40/// Panics if `path` is not a valid object file readable by the current user or if `path` cannot be
41/// parsed as a recognized object file.
42#[track_caller]
43pub fn any_symbol_contains(path: impl AsRef<Path>, substrings: &[&str]) -> bool {
44    with_symbol_iter(path, |syms| {
45        for sym in syms {
46            for substring in substrings {
47                if sym
48                    .name_bytes()
49                    .unwrap()
50                    .windows(substring.len())
51                    .any(|x| x == substring.as_bytes())
52                {
53                    eprintln!("{:?} contains {}", sym, substring);
54                    return true;
55                }
56            }
57        }
58        false
59    })
60}