use anyhow::Result;
use elf::{ElfBytes, endian::AnyEndian};
use std::fs;
use std::path::Path;
pub(crate) fn get_file_dependencies(path: &Path) -> Result<Vec<String>> {
let file_data = match fs::read(path) {
Ok(data) => data,
Err(_) => return Ok(Vec::new()),
};
let file = match ElfBytes::<AnyEndian>::minimal_parse(&file_data) {
Ok(elf) => elf,
Err(_) => return Ok(Vec::new()),
};
let mut dependencies = Vec::new();
if let Ok(Some(dynamic)) = file.dynamic() {
if let Ok(Some(strtab)) = file.section_header_by_name(".dynstr") {
if let Ok(string_table) = file.section_data(&strtab) {
for entry in dynamic.iter() {
if entry.d_tag == elf::abi::DT_NEEDED {
let offset = entry.d_val() as usize;
if let Some(null_pos) =
string_table.0[offset..].iter().position(|&b| b == 0)
{
if let Ok(lib_name) =
std::str::from_utf8(&string_table.0[offset..offset + null_pos])
{
dependencies.push(lib_name.to_string());
}
}
}
}
}
}
}
Ok(dependencies)
}