mirror of
https://github.com/encounter/decomp-toolkit.git
synced 2025-12-12 22:56:28 +00:00
Add alf support (NVIDIA Shield TV binaries)
- Supports .alf files in all places .dol files are accepted. - Adds `hash` and `dhash` to symbols config.
This commit is contained in:
92
src/cmd/alf.rs
Normal file
92
src/cmd/alf.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use std::{
|
||||
io::{stdout, Write},
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use argp::FromArgs;
|
||||
|
||||
use crate::{
|
||||
cmd,
|
||||
util::{
|
||||
alf::AlfFile,
|
||||
file::{buf_writer, map_file},
|
||||
reader::{Endian, FromReader},
|
||||
},
|
||||
};
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
/// Commands for processing NVIDIA Shield TV alf files.
|
||||
#[argp(subcommand, name = "alf")]
|
||||
pub struct Args {
|
||||
#[argp(subcommand)]
|
||||
command: SubCommand,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argp(subcommand)]
|
||||
enum SubCommand {
|
||||
Info(InfoArgs),
|
||||
Hashes(HashesArgs),
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
/// Prints information about an alf file. (Same as `dol info`)
|
||||
#[argp(subcommand, name = "info")]
|
||||
pub struct InfoArgs {
|
||||
#[argp(positional)]
|
||||
/// alf file
|
||||
file: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
/// Extracts symbol hashes from an alf file.
|
||||
#[argp(subcommand, name = "hashes")]
|
||||
pub struct HashesArgs {
|
||||
#[argp(positional)]
|
||||
/// alf file
|
||||
alf_file: PathBuf,
|
||||
#[argp(positional)]
|
||||
/// output file
|
||||
output: Option<PathBuf>,
|
||||
}
|
||||
|
||||
pub fn run(args: Args) -> Result<()> {
|
||||
match args.command {
|
||||
SubCommand::Info(c_args) => info(c_args),
|
||||
SubCommand::Hashes(c_args) => hashes(c_args),
|
||||
}
|
||||
}
|
||||
|
||||
fn hashes(args: HashesArgs) -> Result<()> {
|
||||
let alf_file = {
|
||||
let file = map_file(&args.alf_file)?;
|
||||
let mut reader = file.as_reader();
|
||||
AlfFile::from_reader(&mut reader, Endian::Little)?
|
||||
};
|
||||
let mut w: Box<dyn Write> = if let Some(output) = args.output {
|
||||
Box::new(buf_writer(output)?)
|
||||
} else {
|
||||
Box::new(stdout())
|
||||
};
|
||||
let mut symbols = alf_file.symbols.clone();
|
||||
symbols.sort_by_key(|s| s.address);
|
||||
for symbol in symbols {
|
||||
writeln!(
|
||||
w,
|
||||
"{:#010X} | {} | {:?} | {} | {} | {:#X}",
|
||||
symbol.address,
|
||||
symbol.section,
|
||||
symbol.kind,
|
||||
symbol.name,
|
||||
symbol.demangled_name,
|
||||
symbol.size
|
||||
)?;
|
||||
}
|
||||
w.flush()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn info(args: InfoArgs) -> Result<()> {
|
||||
cmd::dol::info(cmd::dol::InfoArgs { dol_file: args.file, selfile: None })
|
||||
}
|
||||
@@ -31,9 +31,8 @@ use crate::{
|
||||
},
|
||||
cmd::shasum::file_sha1_string,
|
||||
obj::{
|
||||
best_match_for_reloc, ObjDataKind, ObjInfo, ObjKind, ObjReloc, ObjRelocKind,
|
||||
ObjSectionKind, ObjSymbol, ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope,
|
||||
SymbolIndex,
|
||||
best_match_for_reloc, ObjInfo, ObjKind, ObjReloc, ObjRelocKind, ObjSectionKind, ObjSymbol,
|
||||
ObjSymbolFlagSet, ObjSymbolFlags, ObjSymbolKind, ObjSymbolScope, SymbolIndex,
|
||||
},
|
||||
util::{
|
||||
asm::write_asm,
|
||||
@@ -79,10 +78,10 @@ enum SubCommand {
|
||||
pub struct InfoArgs {
|
||||
#[argp(positional)]
|
||||
/// DOL file
|
||||
dol_file: PathBuf,
|
||||
pub dol_file: PathBuf,
|
||||
#[argp(option, short = 's')]
|
||||
/// optional path to selfile.sel
|
||||
selfile: Option<PathBuf>,
|
||||
pub selfile: Option<PathBuf>,
|
||||
}
|
||||
|
||||
#[derive(FromArgs, PartialEq, Eq, Debug)]
|
||||
@@ -366,6 +365,8 @@ fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> {
|
||||
kind: existing_symbol.kind,
|
||||
align: existing_symbol.align,
|
||||
data_kind: existing_symbol.data_kind,
|
||||
name_hash: existing_symbol.name_hash,
|
||||
demangled_name_hash: existing_symbol.demangled_name_hash,
|
||||
})?;
|
||||
} else {
|
||||
log::debug!("Creating symbol {} at {:#010X}", symbol.name, address);
|
||||
@@ -385,7 +386,7 @@ fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn info(args: InfoArgs) -> Result<()> {
|
||||
pub fn info(args: InfoArgs) -> Result<()> {
|
||||
let mut obj = {
|
||||
let file = map_file(&args.dol_file)?;
|
||||
process_dol(file.as_slice(), "")?
|
||||
@@ -523,15 +524,10 @@ fn update_symbols(obj: &mut ObjInfo, modules: &ModuleMap<'_>, create_symbols: bo
|
||||
};
|
||||
obj.symbols.add_direct(ObjSymbol {
|
||||
name,
|
||||
demangled_name: None,
|
||||
address: rel_reloc.addend as u64,
|
||||
section: Some(target_section_index),
|
||||
size: 0,
|
||||
size_known: false,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::ForceActive.into()),
|
||||
kind: Default::default(),
|
||||
align: None,
|
||||
data_kind: ObjDataKind::Unknown,
|
||||
..Default::default()
|
||||
})?;
|
||||
}
|
||||
}
|
||||
@@ -654,14 +650,7 @@ fn resolve_external_relocations(
|
||||
let symbol_idx = obj.symbols.add_direct(ObjSymbol {
|
||||
name: target_symbol.name.clone(),
|
||||
demangled_name: target_symbol.demangled_name.clone(),
|
||||
address: 0,
|
||||
section: None,
|
||||
size: 0,
|
||||
size_known: false,
|
||||
flags: Default::default(),
|
||||
kind: Default::default(),
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
})?;
|
||||
|
||||
e.insert(symbol_idx);
|
||||
@@ -1542,6 +1531,8 @@ fn apply(args: ApplyArgs) -> Result<()> {
|
||||
kind: linked_sym.kind,
|
||||
align: linked_sym.align,
|
||||
data_kind: linked_sym.data_kind,
|
||||
name_hash: linked_sym.name_hash,
|
||||
demangled_name_hash: linked_sym.demangled_name_hash,
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod alf;
|
||||
pub mod ar;
|
||||
pub mod demangle;
|
||||
pub mod dol;
|
||||
|
||||
@@ -471,8 +471,10 @@ fn merge(args: MergeArgs) -> Result<()> {
|
||||
size_known: mod_symbol.size_known,
|
||||
flags: mod_symbol.flags,
|
||||
kind: mod_symbol.kind,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
align: mod_symbol.align,
|
||||
data_kind: mod_symbol.data_kind,
|
||||
name_hash: mod_symbol.name_hash,
|
||||
demangled_name_hash: mod_symbol.demangled_name_hash,
|
||||
})?;
|
||||
}
|
||||
offset += align32(mod_section.size as u32);
|
||||
@@ -506,15 +508,9 @@ fn merge(args: MergeArgs) -> Result<()> {
|
||||
// Create a new label
|
||||
let symbol_idx = obj.symbols.add_direct(ObjSymbol {
|
||||
name: String::new(),
|
||||
demangled_name: None,
|
||||
address: target_addr as u64,
|
||||
section: Some(target_section_index),
|
||||
size: 0,
|
||||
size_known: false,
|
||||
flags: Default::default(),
|
||||
kind: Default::default(),
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
})?;
|
||||
(symbol_idx, 0)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user