use rudy_dwarf::{Binary, SymbolName};
use crate::{
database::Db,
index::{self, find_all_by_address},
};
#[salsa::tracked]
pub fn lookup_position(
db: &dyn Db,
binary: Binary,
query: rudy_dwarf::file::SourceLocation,
) -> Option<u64> {
let file = &query.file;
let index = index::debug_index(db, binary);
let symbol_index = index.symbol_index(db);
let source_to_file = index.source_to_file(db);
let mut closest_match: Option<u64> = None;
let mut closest_line = u64::MAX;
for debug_file in source_to_file.get(file)? {
let Some(function_index) = symbol_index.function_index(db, *debug_file) else {
continue;
};
if let Some((addr, distance)) = function_index.location_to_address(db, *debug_file, &query)
{
tracing::debug!("found match {addr:#x} at distance {distance}");
if distance < closest_line {
tracing::debug!(
"found closest match at {addr:#x} for address {addr:#x} in file {debug_file:?}"
);
closest_match = Some(addr);
closest_line = distance;
}
if distance == 0 {
break;
}
}
}
closest_match
}
#[tracing::instrument(skip_all, fields(binary=binary.name(db), address=address))]
#[salsa::tracked]
pub fn lookup_address<'db>(
db: &'db dyn Db,
binary: Binary,
address: u64,
) -> Option<(SymbolName, rudy_dwarf::file::SourceLocation)> {
let mut results = find_all_by_address(db, binary, address);
if results.len() > 1 {
tracing::warn!(
"Multiple results found for address {address:#x} in binary {binary:?}. Returning the first result."
);
}
results.pop()
}