Parse ELF exclusively on emulation thread

This commit is contained in:
2025-08-30 13:02:38 -04:00
parent e5abd48337
commit 04c92c1454
9 changed files with 182 additions and 137 deletions
+83
View File
@@ -0,0 +1,83 @@
use std::{path::Path, sync::Arc};
use anyhow::Result;
use fxprof_processed_profile::{LibraryInfo, Symbol, SymbolTable, debugid::DebugId};
use object::{Object, ObjectSymbol};
use wholesym::samply_symbols::{DebugIdExt, demangle_any};
#[derive(Debug)]
pub struct GameInfo {
library_info: LibraryInfo,
}
impl GameInfo {
pub fn new(file_path: &Path, input: &[u8]) -> Result<Self> {
let file = object::File::parse(input)?;
let (name, path) = name_and_path(file_path);
let debug_id = file
.build_id()?
.map(|id| DebugId::from_identifier(id, true))
.unwrap_or_default();
let code_id = file.build_id()?.map(hex::encode);
let mut symbols = vec![];
for sym in file.symbols() {
symbols.push(Symbol {
address: sym.address() as u32,
size: Some(sym.size() as u32),
name: demangle_any(sym.name()?),
});
}
let library_info = LibraryInfo {
name: name.clone(),
debug_name: name,
path: path.clone(),
debug_path: path,
debug_id,
code_id,
arch: None,
symbol_table: Some(Arc::new(SymbolTable::new(symbols))),
};
Ok(Self { library_info })
}
pub fn empty(file_path: &Path) -> Self {
let (name, path) = name_and_path(file_path);
let library_info = LibraryInfo {
name: name.clone(),
debug_name: name,
path: path.clone(),
debug_path: path,
debug_id: DebugId::default(),
code_id: None,
arch: None,
symbol_table: None,
};
Self { library_info }
}
pub fn name(&self) -> &str {
&self.library_info.name
}
pub fn library_info(&self) -> &LibraryInfo {
&self.library_info
}
}
fn name_and_path(file_path: &Path) -> (String, String) {
let normalized = normpath::PathExt::normalize(file_path);
let path = normalized
.as_ref()
.map(|n| n.as_path())
.unwrap_or(file_path);
let name = match path.file_stem() {
Some(s) => s.to_string_lossy().into_owned(),
None => "game".to_string(),
};
let path = path.to_string_lossy().into_owned();
(name, path)
}