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>
99 lines
2.9 KiB
Rust
99 lines
2.9 KiB
Rust
use crate::MemoryError;
|
|
|
|
/// Reserve a contiguous virtual address region without committing physical pages.
|
|
#[cfg(unix)]
|
|
pub fn reserve_address_space(size: usize) -> Result<*mut u8, MemoryError> {
|
|
unsafe {
|
|
let ptr = libc::mmap(
|
|
std::ptr::null_mut(),
|
|
size,
|
|
libc::PROT_NONE,
|
|
libc::MAP_PRIVATE | libc::MAP_ANONYMOUS | libc::MAP_NORESERVE,
|
|
-1,
|
|
0,
|
|
);
|
|
if ptr == libc::MAP_FAILED {
|
|
Err(MemoryError::AllocationFailed(format!(
|
|
"mmap failed for {} bytes: {}",
|
|
size,
|
|
std::io::Error::last_os_error()
|
|
)))
|
|
} else {
|
|
Ok(ptr as *mut u8)
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Commit (make accessible) a region within a previously reserved address space.
|
|
#[cfg(unix)]
|
|
pub fn commit_memory(ptr: *mut u8, size: usize) -> Result<(), MemoryError> {
|
|
unsafe {
|
|
let result = libc::mprotect(ptr as *mut libc::c_void, size, libc::PROT_READ | libc::PROT_WRITE);
|
|
if result != 0 {
|
|
Err(MemoryError::AllocationFailed(format!(
|
|
"mprotect failed for {} bytes: {}",
|
|
size,
|
|
std::io::Error::last_os_error()
|
|
)))
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Release a previously reserved address space.
|
|
#[cfg(unix)]
|
|
pub unsafe fn release_address_space(ptr: *mut u8, size: usize) {
|
|
unsafe { libc::munmap(ptr as *mut libc::c_void, size); }
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
pub fn reserve_address_space(size: usize) -> Result<*mut u8, MemoryError> {
|
|
unsafe {
|
|
let ptr = windows_sys::Win32::System::Memory::VirtualAlloc(
|
|
std::ptr::null_mut(),
|
|
size,
|
|
windows_sys::Win32::System::Memory::MEM_RESERVE,
|
|
windows_sys::Win32::System::Memory::PAGE_NOACCESS,
|
|
);
|
|
if ptr.is_null() {
|
|
Err(MemoryError::AllocationFailed(format!(
|
|
"VirtualAlloc reserve failed for {} bytes",
|
|
size,
|
|
)))
|
|
} else {
|
|
Ok(ptr as *mut u8)
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
pub fn commit_memory(ptr: *mut u8, size: usize) -> Result<(), MemoryError> {
|
|
unsafe {
|
|
let result = windows_sys::Win32::System::Memory::VirtualAlloc(
|
|
ptr as *mut _,
|
|
size,
|
|
windows_sys::Win32::System::Memory::MEM_COMMIT,
|
|
windows_sys::Win32::System::Memory::PAGE_READWRITE,
|
|
);
|
|
if result.is_null() {
|
|
Err(MemoryError::AllocationFailed(format!(
|
|
"VirtualAlloc commit failed for {} bytes",
|
|
size,
|
|
)))
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
pub unsafe fn release_address_space(ptr: *mut u8, size: usize) {
|
|
let _ = size;
|
|
windows_sys::Win32::System::Memory::VirtualFree(
|
|
ptr as *mut _,
|
|
0,
|
|
windows_sys::Win32::System::Memory::MEM_RELEASE,
|
|
);
|
|
}
|