Initial commit: xenia-rs workspace for Xbox 360 RE
Rust reimplementation of the xenia Xbox 360 emulator targeting reverse- engineering and preservation, initially scoped to Project Sylpheed. Includes: - XEX2 loader (LZX decompression, AES decryption, PE parsing) - XISO / XGD2 disc image VFS - PPC interpreter with 200+ opcodes and VMX128 decoding - Static analyzer: functions, cross-references, labels, asm + SQLite output - HLE kernel covering the xboxkrnl/xam subset used by Sylpheed init - Debugger with in-memory and SQLite-backed execution tracing - `xenia-rs` CLI with extract/dis/exec commands that produce cumulative, superset SQLite databases and opt-in instruction/import/branch traces Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
87
crates/xenia-analysis/build.rs
Normal file
87
crates/xenia-analysis/build.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
//! Build script: parse xenia's xboxkrnl_table.inc and xam_table.inc to generate
|
||||
//! ordinal->name lookup tables at compile time.
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
fn parse_table(path: &Path) -> Vec<(u32, String, String)> {
|
||||
let content = match fs::read_to_string(path) {
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
eprintln!("cargo:warning=could not read {}: {}", path.display(), e);
|
||||
return Vec::new();
|
||||
}
|
||||
};
|
||||
|
||||
let mut entries = Vec::new();
|
||||
for line in content.lines() {
|
||||
let line = line.trim();
|
||||
// XE_EXPORT(module, 0xNNNNNNNN, Name, kType),
|
||||
if !line.starts_with("XE_EXPORT(") { continue; }
|
||||
let inner = match line.strip_prefix("XE_EXPORT(").and_then(|s| s.strip_suffix("),")) {
|
||||
Some(s) => s,
|
||||
None => continue,
|
||||
};
|
||||
let parts: Vec<&str> = inner.splitn(4, ',').map(|s| s.trim()).collect();
|
||||
if parts.len() < 4 { continue; }
|
||||
let module = parts[0].to_string();
|
||||
let ordinal = match u32::from_str_radix(parts[1].trim_start_matches("0x").trim_start_matches("0X"), 16) {
|
||||
Ok(n) => n,
|
||||
Err(_) => continue,
|
||||
};
|
||||
let name = parts[2].to_string();
|
||||
entries.push((ordinal, name, module));
|
||||
}
|
||||
entries
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let out_dir = env::var("OUT_DIR").unwrap();
|
||||
let dest = Path::new(&out_dir).join("ordinals.rs");
|
||||
let mut f = fs::File::create(&dest).unwrap();
|
||||
|
||||
// Locate xenia tables relative to the workspace root
|
||||
// crates/xenia-analysis/ -> ../../ -> workspace root -> ../xenia-canary/
|
||||
let manifest = env::var("CARGO_MANIFEST_DIR").unwrap();
|
||||
let workspace_root = Path::new(&manifest).parent().unwrap().parent().unwrap();
|
||||
let project_root = workspace_root.parent().unwrap();
|
||||
|
||||
let krnl_path = project_root
|
||||
.join("xenia-canary/src/xenia/kernel/xboxkrnl/xboxkrnl_table.inc");
|
||||
let xam_path = project_root
|
||||
.join("xenia-canary/src/xenia/kernel/xam/xam_table.inc");
|
||||
|
||||
println!("cargo:rerun-if-changed={}", krnl_path.display());
|
||||
println!("cargo:rerun-if-changed={}", xam_path.display());
|
||||
|
||||
let krnl = parse_table(&krnl_path);
|
||||
let xam = parse_table(&xam_path);
|
||||
|
||||
writeln!(f, "/// Auto-generated from xenia's export tables.").unwrap();
|
||||
writeln!(f, "pub fn resolve_ordinal(lib: &str, ordinal: u16) -> Option<&'static str> {{").unwrap();
|
||||
writeln!(f, " match lib {{").unwrap();
|
||||
|
||||
// xboxkrnl.exe
|
||||
writeln!(f, " \"xboxkrnl.exe\" => match ordinal {{").unwrap();
|
||||
for (ord, name, _) in &krnl {
|
||||
writeln!(f, " 0x{ord:04X} => Some(\"{name}\"),").unwrap();
|
||||
}
|
||||
writeln!(f, " _ => None,").unwrap();
|
||||
writeln!(f, " }},").unwrap();
|
||||
|
||||
// xam.xex
|
||||
writeln!(f, " \"xam.xex\" => match ordinal {{").unwrap();
|
||||
for (ord, name, _) in &xam {
|
||||
writeln!(f, " 0x{ord:04X} => Some(\"{name}\"),").unwrap();
|
||||
}
|
||||
writeln!(f, " _ => None,").unwrap();
|
||||
writeln!(f, " }},").unwrap();
|
||||
|
||||
writeln!(f, " _ => None,").unwrap();
|
||||
writeln!(f, " }}").unwrap();
|
||||
writeln!(f, "}}").unwrap();
|
||||
|
||||
eprintln!("ordinals.rs: {} xboxkrnl + {} xam entries", krnl.len(), xam.len());
|
||||
}
|
||||
Reference in New Issue
Block a user