use std::collections::HashMap; use crate::intermediate_representation::{Jmp, Program, Sub, Term, Tid}; /// Find the extern symbol object for a symbol name and return the symbol tid and name. pub fn find_symbol<'a>(prog: &'a Term<Program>, name: &str) -> Option<(&'a Tid, &'a str)> { let mut symbol: Option<(&'a Tid, &'a str)> = None; prog.term.extern_symbols.iter().for_each(|sym| { if name == sym.name { symbol = Some((&sym.tid, &sym.name)); } }); symbol } /// Match direct calls' target tids in the program's subroutines with /// with the tids of the external symbols given to the function. /// When a match was found, add a triple of (caller name, callsite tid, callee name) /// to a vector. Lastly, return the vector with all callsites of all given external symbols. pub fn get_calls_to_symbols<'a, 'b>( sub: &'a Term<Sub>, symbols: &'b HashMap<&'a Tid, &'a str>, ) -> Vec<(&'a str, &'a Tid, &'a str)> { let mut calls: Vec<(&'a str, &'a Tid, &'a str)> = Vec::new(); for blk in sub.term.blocks.iter() { for jmp in blk.term.jmps.iter() { if let Jmp::Call { target: dst, .. } = &jmp.term { if symbols.contains_key(dst) { calls.push(( sub.term.name.as_str(), &jmp.tid, symbols.get(dst).clone().unwrap(), )); } } } } calls }