You've already forked decomp-toolkit
mirror of
https://github.com/encounter/decomp-toolkit.git
synced 2026-03-30 11:06:18 -07: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:
+2
-7
@@ -144,15 +144,12 @@ impl AnalyzerState {
|
||||
obj.add_symbol(
|
||||
ObjSymbol {
|
||||
name,
|
||||
demangled_name: None,
|
||||
address: start.address as u64,
|
||||
section: Some(start.section),
|
||||
size: (end.address - start.address) as u64,
|
||||
size_known: true,
|
||||
flags: Default::default(),
|
||||
kind: ObjSymbolKind::Function,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
},
|
||||
false,
|
||||
)?;
|
||||
@@ -188,15 +185,13 @@ impl AnalyzerState {
|
||||
obj.add_symbol(
|
||||
ObjSymbol {
|
||||
name: format!("jumptable_{}", address_str),
|
||||
demangled_name: None,
|
||||
address: addr.address as u64,
|
||||
section: Some(addr.section),
|
||||
size: size as u64,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Local.into()),
|
||||
kind: ObjSymbolKind::Object,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
},
|
||||
false,
|
||||
)?;
|
||||
|
||||
+6
-30
@@ -37,28 +37,20 @@ impl AnalysisPass for FindTRKInterruptVectorTable {
|
||||
log::debug!("Found gTRKInterruptVectorTable @ {:#010X}", start);
|
||||
state.known_symbols.insert(start, ObjSymbol {
|
||||
name: "gTRKInterruptVectorTable".to_string(),
|
||||
demangled_name: None,
|
||||
address: start.address as u64,
|
||||
section: Some(start.section),
|
||||
size: 0,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(FlagSet::from(ObjSymbolFlags::Global)),
|
||||
kind: ObjSymbolKind::Unknown,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
let end = start + TRK_TABLE_SIZE;
|
||||
state.known_symbols.insert(end, ObjSymbol {
|
||||
name: "gTRKInterruptVectorTableEnd".to_string(),
|
||||
demangled_name: None,
|
||||
address: end.address as u64,
|
||||
section: Some(start.section),
|
||||
size: 0,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(FlagSet::from(ObjSymbolFlags::Global)),
|
||||
kind: ObjSymbolKind::Unknown,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
return Ok(());
|
||||
@@ -96,29 +88,23 @@ impl AnalysisPass for FindSaveRestSleds {
|
||||
});
|
||||
state.known_symbols.insert(start, ObjSymbol {
|
||||
name: func.to_string(),
|
||||
demangled_name: None,
|
||||
address: start.address as u64,
|
||||
section: Some(start.section),
|
||||
size: SLED_SIZE as u64,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
|
||||
kind: ObjSymbolKind::Function,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
for i in 14..=31 {
|
||||
let addr = start + (i - 14) * 4;
|
||||
state.known_symbols.insert(addr, ObjSymbol {
|
||||
name: format!("{}{}", label, i),
|
||||
demangled_name: None,
|
||||
address: addr.address as u64,
|
||||
section: Some(start.section),
|
||||
size: 0,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
|
||||
kind: ObjSymbolKind::Unknown,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -202,30 +188,20 @@ impl AnalysisPass for FindRelCtorsDtors {
|
||||
state.known_sections.insert(ctors_section_index, ".ctors".to_string());
|
||||
state.known_symbols.insert(SectionAddress::new(ctors_section_index, 0), ObjSymbol {
|
||||
name: "_ctors".to_string(),
|
||||
demangled_name: None,
|
||||
address: 0,
|
||||
section: Some(ctors_section_index),
|
||||
size: 0,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
|
||||
kind: Default::default(),
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
let dtors_section_index = possible_sections[1].0;
|
||||
state.known_sections.insert(dtors_section_index, ".dtors".to_string());
|
||||
state.known_symbols.insert(SectionAddress::new(dtors_section_index, 0), ObjSymbol {
|
||||
name: "_dtors".to_string(),
|
||||
demangled_name: None,
|
||||
address: 0,
|
||||
section: Some(dtors_section_index),
|
||||
size: 0,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
|
||||
kind: Default::default(),
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
// Check for duplicate entries in .dtors, indicating __destroy_global_chain_reference
|
||||
|
||||
@@ -245,15 +245,13 @@ fn apply_ctors_signatures(obj: &mut ObjInfo) -> Result<()> {
|
||||
obj.symbols.add(
|
||||
ObjSymbol {
|
||||
name: "__init_cpp_exceptions_reference".to_string(),
|
||||
demangled_name: None,
|
||||
address,
|
||||
section: Some(ctors_section_index),
|
||||
size: 4,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global | ObjSymbolFlags::RelocationIgnore),
|
||||
kind: ObjSymbolKind::Object,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
},
|
||||
true,
|
||||
)?;
|
||||
@@ -303,7 +301,6 @@ fn apply_dtors_signatures(obj: &mut ObjInfo) -> Result<()> {
|
||||
obj.add_symbol(
|
||||
ObjSymbol {
|
||||
name: "__destroy_global_chain_reference".to_string(),
|
||||
demangled_name: None,
|
||||
address,
|
||||
section: Some(dtors_section_index),
|
||||
size: 4,
|
||||
@@ -312,8 +309,7 @@ fn apply_dtors_signatures(obj: &mut ObjInfo) -> Result<()> {
|
||||
ObjSymbolFlags::Global | ObjSymbolFlags::RelocationIgnore,
|
||||
),
|
||||
kind: ObjSymbolKind::Object,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
},
|
||||
true,
|
||||
)?;
|
||||
@@ -334,7 +330,6 @@ fn apply_dtors_signatures(obj: &mut ObjInfo) -> Result<()> {
|
||||
obj.add_symbol(
|
||||
ObjSymbol {
|
||||
name: "__fini_cpp_exceptions_reference".to_string(),
|
||||
demangled_name: None,
|
||||
address: address + 4,
|
||||
section: Some(dtors_section_index),
|
||||
size: 4,
|
||||
@@ -343,8 +338,7 @@ fn apply_dtors_signatures(obj: &mut ObjInfo) -> Result<()> {
|
||||
ObjSymbolFlags::Global | ObjSymbolFlags::RelocationIgnore,
|
||||
),
|
||||
kind: ObjSymbolKind::Object,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
},
|
||||
true,
|
||||
)?;
|
||||
@@ -452,15 +446,11 @@ pub fn update_ctors_dtors(obj: &mut ObjInfo) -> Result<()> {
|
||||
if let Some((section_index, section)) = obj.sections.by_name(".ctors")? {
|
||||
obj.symbols.add_direct(ObjSymbol {
|
||||
name: "_ctors".to_string(),
|
||||
demangled_name: None,
|
||||
address: section.address,
|
||||
section: Some(section_index),
|
||||
size: 0,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
|
||||
kind: ObjSymbolKind::Unknown,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
})?;
|
||||
}
|
||||
}
|
||||
@@ -468,15 +458,11 @@ pub fn update_ctors_dtors(obj: &mut ObjInfo) -> Result<()> {
|
||||
if let Some((section_index, section)) = obj.sections.by_name(".dtors")? {
|
||||
obj.symbols.add_direct(ObjSymbol {
|
||||
name: "_dtors".to_string(),
|
||||
demangled_name: None,
|
||||
address: section.address,
|
||||
section: Some(section_index),
|
||||
size: 0,
|
||||
size_known: true,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
|
||||
kind: ObjSymbolKind::Unknown,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,15 +710,10 @@ impl Tracker {
|
||||
};
|
||||
let symbol_idx = obj.symbols.add_direct(ObjSymbol {
|
||||
name,
|
||||
demangled_name: None,
|
||||
address: target.address as u64,
|
||||
section: Some(target.section),
|
||||
size: 0,
|
||||
size_known: false,
|
||||
flags: Default::default(),
|
||||
kind: Default::default(),
|
||||
align: None,
|
||||
data_kind,
|
||||
..Default::default()
|
||||
})?;
|
||||
(symbol_idx, 0)
|
||||
};
|
||||
|
||||
@@ -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 })
|
||||
}
|
||||
+11
-20
@@ -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;
|
||||
|
||||
+5
-9
@@ -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)
|
||||
};
|
||||
|
||||
@@ -74,6 +74,7 @@ struct TopLevel {
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
#[argp(subcommand)]
|
||||
enum SubCommand {
|
||||
Alf(cmd::alf::Args),
|
||||
Ar(cmd::ar::Args),
|
||||
Demangle(cmd::demangle::Args),
|
||||
Dol(cmd::dol::Args),
|
||||
@@ -122,6 +123,7 @@ fn main() {
|
||||
});
|
||||
}
|
||||
result = result.and_then(|_| match args.command {
|
||||
SubCommand::Alf(c_args) => cmd::alf::run(c_args),
|
||||
SubCommand::Ar(c_args) => cmd::ar::run(c_args),
|
||||
SubCommand::Demangle(c_args) => cmd::demangle::run(c_args),
|
||||
SubCommand::Dol(c_args) => cmd::dol::run(c_args),
|
||||
|
||||
@@ -165,6 +165,9 @@ pub struct ObjSymbol {
|
||||
pub kind: ObjSymbolKind,
|
||||
pub align: Option<u32>,
|
||||
pub data_kind: ObjDataKind,
|
||||
/// ALF hashes
|
||||
pub name_hash: Option<u32>,
|
||||
pub demangled_name_hash: Option<u32>,
|
||||
}
|
||||
|
||||
pub type SymbolIndex = usize;
|
||||
@@ -263,6 +266,8 @@ impl ObjSymbols {
|
||||
ObjDataKind::Unknown => existing.data_kind,
|
||||
kind => kind,
|
||||
},
|
||||
name_hash: in_symbol.name_hash.or(existing.name_hash),
|
||||
demangled_name_hash: in_symbol.demangled_name_hash.or(existing.demangled_name_hash),
|
||||
};
|
||||
if existing != &new_symbol {
|
||||
log::debug!("Replacing {:?} with {:?}", existing, new_symbol);
|
||||
@@ -282,6 +287,8 @@ impl ObjSymbols {
|
||||
kind: in_symbol.kind,
|
||||
align: in_symbol.align,
|
||||
data_kind: in_symbol.data_kind,
|
||||
name_hash: in_symbol.name_hash,
|
||||
demangled_name_hash: in_symbol.demangled_name_hash,
|
||||
})?;
|
||||
target_symbol_idx
|
||||
};
|
||||
|
||||
+274
@@ -0,0 +1,274 @@
|
||||
use std::{
|
||||
io,
|
||||
io::{Read, Seek, SeekFrom},
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use io::{Error, ErrorKind};
|
||||
|
||||
use crate::{
|
||||
obj::{ObjSymbol, ObjSymbolKind},
|
||||
util::{
|
||||
dol::{DolLike, DolSection, DolSectionKind},
|
||||
reader::{
|
||||
read_string, read_vec, read_vec_args, struct_size, Endian, FromReader, DYNAMIC_SIZE,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
pub const ALF_MAGIC: [u8; 4] = *b"RBOF";
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AlfFile {
|
||||
pub header: AlfHeader,
|
||||
pub sections: Vec<DolSection>,
|
||||
pub symbols: Vec<AlfSymbol>,
|
||||
}
|
||||
|
||||
impl FromReader for AlfFile {
|
||||
type Args = ();
|
||||
|
||||
const STATIC_SIZE: usize = DYNAMIC_SIZE;
|
||||
|
||||
#[inline]
|
||||
fn from_reader_args<R>(reader: &mut R, e: Endian, _args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized {
|
||||
let header = AlfHeader::from_reader(reader, e)?;
|
||||
if !matches!(header.version, 104 | 105) {
|
||||
return Err(Error::new(
|
||||
ErrorKind::InvalidData,
|
||||
format!("unsupported ALF version: {}", header.version),
|
||||
));
|
||||
}
|
||||
let alf_sections: Vec<AlfSection> = read_vec(reader, header.section_count as usize, e)?;
|
||||
let symtab =
|
||||
AlfSymTab::from_reader_args(reader, e, AlfVersionArgs { version: header.version })?;
|
||||
|
||||
// Infer section types from data size and symbol typeFs
|
||||
let mut sections = Vec::with_capacity(alf_sections.len());
|
||||
for section in &alf_sections {
|
||||
let kind =
|
||||
if section.data_size == 0 { DolSectionKind::Bss } else { DolSectionKind::Data };
|
||||
sections.push(DolSection {
|
||||
address: section.address,
|
||||
file_offset: section.file_offset,
|
||||
data_size: section.data_size,
|
||||
size: section.size,
|
||||
kind,
|
||||
index: sections.len(),
|
||||
});
|
||||
}
|
||||
for sym in &symtab.symbols {
|
||||
// Section IDs are 1-based
|
||||
if sym.section == 0 {
|
||||
return Err(Error::new(ErrorKind::InvalidData, "invalid ALF symbol section"));
|
||||
}
|
||||
if sym.kind == AlfSymbolKind::Function {
|
||||
sections[sym.section as usize - 1].kind = DolSectionKind::Text;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self { header, sections, symbols: symtab.symbols })
|
||||
}
|
||||
}
|
||||
|
||||
impl DolLike for AlfFile {
|
||||
fn sections(&self) -> &[DolSection] { &self.sections }
|
||||
|
||||
fn symbols(&self) -> &[AlfSymbol] { &self.symbols }
|
||||
|
||||
fn entry_point(&self) -> u32 { self.header.entry }
|
||||
|
||||
fn has_unified_bss(&self) -> bool { false }
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AlfHeader {
|
||||
pub version: u32,
|
||||
pub entry: u32,
|
||||
pub section_count: u32,
|
||||
}
|
||||
|
||||
impl FromReader for AlfHeader {
|
||||
type Args = ();
|
||||
|
||||
const STATIC_SIZE: usize = struct_size([
|
||||
4, // magic
|
||||
u32::STATIC_SIZE, // version
|
||||
u32::STATIC_SIZE, // entry
|
||||
u32::STATIC_SIZE, // section_count
|
||||
]);
|
||||
|
||||
#[inline]
|
||||
fn from_reader_args<R>(reader: &mut R, e: Endian, _args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized {
|
||||
if <[u8; 4]>::from_reader(reader, e)? != ALF_MAGIC {
|
||||
return Err(Error::new(ErrorKind::InvalidData, "invalid ALF magic"));
|
||||
}
|
||||
Ok(Self {
|
||||
version: <_>::from_reader(reader, e)?,
|
||||
entry: <_>::from_reader(reader, e)?,
|
||||
section_count: <_>::from_reader(reader, e)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AlfSection {
|
||||
pub address: u32,
|
||||
pub data_size: u32,
|
||||
pub size: u32,
|
||||
pub file_offset: u32,
|
||||
}
|
||||
|
||||
impl FromReader for AlfSection {
|
||||
type Args = ();
|
||||
|
||||
const STATIC_SIZE: usize = struct_size([
|
||||
u32::STATIC_SIZE, // address
|
||||
u32::STATIC_SIZE, // data_size
|
||||
u32::STATIC_SIZE, // size
|
||||
]);
|
||||
|
||||
#[inline]
|
||||
fn from_reader_args<R>(reader: &mut R, e: Endian, _args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized {
|
||||
let result = Self {
|
||||
address: <_>::from_reader(reader, e)?,
|
||||
data_size: <_>::from_reader(reader, e)?,
|
||||
size: <_>::from_reader(reader, e)?,
|
||||
file_offset: reader.stream_position()? as u32,
|
||||
};
|
||||
reader.seek(SeekFrom::Current(result.data_size as i64))?;
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum AlfSymbolKind {
|
||||
Function,
|
||||
Object,
|
||||
}
|
||||
|
||||
impl FromReader for AlfSymbolKind {
|
||||
type Args = ();
|
||||
|
||||
const STATIC_SIZE: usize = u32::STATIC_SIZE;
|
||||
|
||||
#[inline]
|
||||
fn from_reader_args<R>(reader: &mut R, e: Endian, _args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized {
|
||||
match u32::from_reader(reader, e)? {
|
||||
0 => Ok(Self::Function),
|
||||
1 => Ok(Self::Object),
|
||||
v => Err(Error::new(ErrorKind::InvalidData, format!("invalid ALF symbol kind: {}", v))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AlfSymbol {
|
||||
pub name: String,
|
||||
pub demangled_name: String,
|
||||
pub address: u32,
|
||||
pub size: u32,
|
||||
pub kind: AlfSymbolKind,
|
||||
pub section: u32,
|
||||
pub unk: u32,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct AlfVersionArgs {
|
||||
pub version: u32,
|
||||
}
|
||||
|
||||
impl FromReader for AlfSymbol {
|
||||
type Args = AlfVersionArgs;
|
||||
|
||||
const STATIC_SIZE: usize = DYNAMIC_SIZE;
|
||||
|
||||
#[inline]
|
||||
fn from_reader_args<R>(reader: &mut R, e: Endian, args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized {
|
||||
Ok(Self {
|
||||
name: read_string::<u32, _>(reader, e)?,
|
||||
demangled_name: read_string::<u32, _>(reader, e)?,
|
||||
address: <_>::from_reader(reader, e)?,
|
||||
size: <_>::from_reader(reader, e)?,
|
||||
kind: <_>::from_reader(reader, e)?,
|
||||
section: <_>::from_reader(reader, e)?,
|
||||
unk: if args.version >= 105 { <_>::from_reader(reader, e)? } else { 0 },
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl AlfSymbol {
|
||||
pub fn to_obj_symbol(&self) -> Result<ObjSymbol> {
|
||||
let kind = match self.kind {
|
||||
AlfSymbolKind::Function => ObjSymbolKind::Function,
|
||||
AlfSymbolKind::Object => ObjSymbolKind::Object,
|
||||
};
|
||||
let (name, name_hash) = if self.name.starts_with('#') {
|
||||
let hash_str = self.name.trim_start_matches('#');
|
||||
let hash = u32::from_str_radix(hash_str, 16)?;
|
||||
let name = match self.kind {
|
||||
AlfSymbolKind::Function => format!("fn_{:08X}", self.address),
|
||||
AlfSymbolKind::Object => format!("lbl_{:08X}", self.address),
|
||||
};
|
||||
(name, Some(hash))
|
||||
} else {
|
||||
(self.name.clone(), None)
|
||||
};
|
||||
let (demangled_name, demangled_name_hash) = if self.demangled_name.starts_with('#') {
|
||||
let hash_str = self.demangled_name.trim_start_matches('#');
|
||||
let hash = u32::from_str_radix(hash_str, 16)?;
|
||||
(None, Some(hash))
|
||||
} else {
|
||||
(Some(self.demangled_name.clone()), None)
|
||||
};
|
||||
Ok(ObjSymbol {
|
||||
name,
|
||||
demangled_name,
|
||||
address: self.address as u64,
|
||||
section: Some(self.section as usize - 1),
|
||||
size: self.size as u64,
|
||||
size_known: true,
|
||||
flags: Default::default(),
|
||||
kind,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
name_hash,
|
||||
demangled_name_hash,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AlfSymTab {
|
||||
pub symbols: Vec<AlfSymbol>,
|
||||
}
|
||||
|
||||
impl FromReader for AlfSymTab {
|
||||
type Args = AlfVersionArgs;
|
||||
|
||||
const STATIC_SIZE: usize = DYNAMIC_SIZE;
|
||||
|
||||
#[inline]
|
||||
fn from_reader_args<R>(reader: &mut R, e: Endian, args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized {
|
||||
let _size = u32::from_reader(reader, e)?;
|
||||
let count = u32::from_reader(reader, e)? as usize;
|
||||
let symbols = read_vec_args(reader, count, e, args)?;
|
||||
Ok(Self { symbols })
|
||||
}
|
||||
}
|
||||
|
||||
pub const ALF_HASH_SEED: u32 = 0x1505;
|
||||
|
||||
pub fn alf_hash(mut h: u32, s: &str) -> u32 {
|
||||
for c in s.bytes() {
|
||||
h *= 33;
|
||||
h ^= c as u32;
|
||||
}
|
||||
h
|
||||
}
|
||||
+23
-13
@@ -75,18 +75,8 @@ pub fn parse_symbol_line(line: &str, obj: &mut ObjInfo) -> Result<Option<ObjSymb
|
||||
bail!("Section {} not found", section_name)
|
||||
};
|
||||
let demangled_name = demangle(&name, &DemangleOptions::default());
|
||||
let mut symbol = ObjSymbol {
|
||||
name,
|
||||
demangled_name,
|
||||
address: addr as u64,
|
||||
section,
|
||||
size: 0,
|
||||
size_known: false,
|
||||
flags: Default::default(),
|
||||
kind: ObjSymbolKind::Unknown,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
};
|
||||
let mut symbol =
|
||||
ObjSymbol { name, demangled_name, address: addr as u64, section, ..Default::default() };
|
||||
// TODO move somewhere common
|
||||
if symbol.name.starts_with("..") {
|
||||
symbol.flags.0 |= ObjSymbolFlags::ForceActive;
|
||||
@@ -114,6 +104,16 @@ pub fn parse_symbol_line(line: &str, obj: &mut ObjInfo) -> Result<Option<ObjSymb
|
||||
symbol.data_kind = symbol_data_kind_from_str(value)
|
||||
.ok_or_else(|| anyhow!("Unknown symbol data type '{}'", value))?;
|
||||
}
|
||||
"hash" => {
|
||||
let hash = parse_hex(value)?;
|
||||
symbol.name_hash = Some(hash);
|
||||
if symbol.demangled_name_hash.is_none() {
|
||||
symbol.demangled_name_hash = Some(hash);
|
||||
}
|
||||
}
|
||||
"dhash" => {
|
||||
symbol.demangled_name_hash = Some(parse_hex(value)?);
|
||||
}
|
||||
_ => bail!("Unknown symbol attribute '{name}'"),
|
||||
}
|
||||
} else {
|
||||
@@ -163,7 +163,9 @@ pub fn is_skip_symbol(symbol: &ObjSymbol) -> bool {
|
||||
}
|
||||
|
||||
pub fn is_auto_symbol(symbol: &ObjSymbol) -> bool {
|
||||
symbol.name.starts_with("lbl_") || symbol.name.starts_with("fn_")
|
||||
symbol.name.starts_with("lbl_")
|
||||
|| symbol.name.starts_with("fn_")
|
||||
|| symbol.name.starts_with("jumptable_")
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -204,6 +206,14 @@ fn write_symbol<W: Write>(w: &mut W, obj: &ObjInfo, symbol: &ObjSymbol) -> Resul
|
||||
if let Some(kind) = symbol_data_kind_to_str(symbol.data_kind) {
|
||||
write!(w, " data:{kind}")?;
|
||||
}
|
||||
if let Some(hash) = symbol.name_hash {
|
||||
write!(w, " hash:{:#010X}", hash)?;
|
||||
}
|
||||
if let Some(hash) = symbol.demangled_name_hash {
|
||||
if symbol.name_hash != symbol.demangled_name_hash {
|
||||
write!(w, " dhash:{:#010X}", hash)?;
|
||||
}
|
||||
}
|
||||
if symbol.flags.is_hidden() {
|
||||
write!(w, " hidden")?;
|
||||
}
|
||||
|
||||
+286
-138
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -816,7 +816,7 @@ fn to_obj_symbol(
|
||||
_ => bail!("Unsupported symbol kind: {:?}", symbol),
|
||||
},
|
||||
align,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -688,7 +688,7 @@ fn add_symbol(obj: &mut ObjInfo, symbol_entry: &SymbolEntry, section: Option<usi
|
||||
SymbolKind::NoType => ObjSymbolKind::Unknown,
|
||||
},
|
||||
align: symbol_entry.align,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
},
|
||||
true,
|
||||
)?;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::{borrow::Cow, ops::Deref};
|
||||
|
||||
pub mod alf;
|
||||
pub mod asm;
|
||||
pub mod comment;
|
||||
pub mod config;
|
||||
@@ -12,6 +13,7 @@ pub mod lcf;
|
||||
pub mod map;
|
||||
pub mod nested;
|
||||
pub mod rarc;
|
||||
pub mod reader;
|
||||
pub mod rel;
|
||||
pub mod rso;
|
||||
pub mod signatures;
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
use std::{
|
||||
io,
|
||||
io::{Error, ErrorKind, Read, Seek, SeekFrom},
|
||||
};
|
||||
|
||||
use io::Write;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum Endian {
|
||||
Big,
|
||||
Little,
|
||||
}
|
||||
|
||||
pub const DYNAMIC_SIZE: usize = 0;
|
||||
|
||||
pub const fn struct_size<const N: usize>(fields: [usize; N]) -> usize {
|
||||
let mut result = 0;
|
||||
let mut i = 0;
|
||||
while i < N {
|
||||
let size = fields[i];
|
||||
if size == DYNAMIC_SIZE {
|
||||
// Dynamically sized
|
||||
return DYNAMIC_SIZE;
|
||||
}
|
||||
result += size;
|
||||
i += 1;
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn skip_bytes<const N: usize, R>(reader: &mut R) -> io::Result<()>
|
||||
where R: Read + Seek + ?Sized {
|
||||
reader.seek(SeekFrom::Current(N as i64))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub trait FromReader: Sized {
|
||||
type Args;
|
||||
|
||||
const STATIC_SIZE: usize;
|
||||
|
||||
fn from_reader_args<R>(reader: &mut R, e: Endian, args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized;
|
||||
|
||||
fn from_reader<R>(reader: &mut R, e: Endian) -> io::Result<Self>
|
||||
where
|
||||
R: Read + Seek + ?Sized,
|
||||
Self::Args: Default,
|
||||
{
|
||||
Self::from_reader_args(reader, e, Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_from_reader {
|
||||
($($t:ty),*) => {
|
||||
$(
|
||||
impl FromReader for $t {
|
||||
const STATIC_SIZE: usize = std::mem::size_of::<Self>();
|
||||
|
||||
type Args = ();
|
||||
|
||||
#[inline]
|
||||
fn from_reader_args<R>(reader: &mut R, e: Endian, _args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized {
|
||||
let mut buf = [0u8; Self::STATIC_SIZE];
|
||||
reader.read_exact(&mut buf)?;
|
||||
Ok(match e {
|
||||
Endian::Big => Self::from_be_bytes(buf),
|
||||
Endian::Little => Self::from_le_bytes(buf),
|
||||
})
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl_from_reader!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
|
||||
|
||||
impl<const N: usize> FromReader for [u8; N] {
|
||||
type Args = ();
|
||||
|
||||
const STATIC_SIZE: usize = N;
|
||||
|
||||
#[inline]
|
||||
fn from_reader_args<R>(reader: &mut R, _e: Endian, _args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized {
|
||||
let mut buf = [0u8; N];
|
||||
reader.read_exact(&mut buf)?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const N: usize> FromReader for [u32; N] {
|
||||
type Args = ();
|
||||
|
||||
const STATIC_SIZE: usize = N * u32::STATIC_SIZE;
|
||||
|
||||
#[inline]
|
||||
fn from_reader_args<R>(reader: &mut R, e: Endian, _args: Self::Args) -> io::Result<Self>
|
||||
where R: Read + Seek + ?Sized {
|
||||
let mut buf = [0u32; N];
|
||||
reader.read_exact(unsafe {
|
||||
std::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut u8, Self::STATIC_SIZE)
|
||||
})?;
|
||||
if e == Endian::Big {
|
||||
for x in buf.iter_mut() {
|
||||
*x = u32::from_be(*x);
|
||||
}
|
||||
}
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_bytes<R>(reader: &mut R, count: usize) -> io::Result<Vec<u8>>
|
||||
where R: Read + Seek + ?Sized {
|
||||
let mut buf = vec![0u8; count];
|
||||
reader.read_exact(&mut buf)?;
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_vec<T, R>(reader: &mut R, count: usize, e: Endian) -> io::Result<Vec<T>>
|
||||
where
|
||||
T: FromReader,
|
||||
T::Args: Default,
|
||||
R: Read + Seek + ?Sized,
|
||||
{
|
||||
let mut vec = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
vec.push(T::from_reader(reader, e)?);
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_vec_args<T, R>(
|
||||
reader: &mut R,
|
||||
count: usize,
|
||||
e: Endian,
|
||||
args: T::Args,
|
||||
) -> io::Result<Vec<T>>
|
||||
where
|
||||
T: FromReader,
|
||||
T::Args: Clone,
|
||||
R: Read + Seek + ?Sized,
|
||||
{
|
||||
let mut vec = Vec::with_capacity(count);
|
||||
for _ in 0..count {
|
||||
vec.push(T::from_reader_args(reader, e, args.clone())?);
|
||||
}
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_string<T, R>(reader: &mut R, e: Endian) -> io::Result<String>
|
||||
where
|
||||
T: FromReader + TryInto<usize>,
|
||||
T::Args: Default,
|
||||
R: Read + Seek + ?Sized,
|
||||
{
|
||||
let len = <T>::from_reader(reader, e)?
|
||||
.try_into()
|
||||
.map_err(|_| Error::new(ErrorKind::InvalidData, "invalid string length"))?;
|
||||
let mut buf = vec![0u8; len];
|
||||
reader.read_exact(&mut buf)?;
|
||||
String::from_utf8(buf).map_err(|e| Error::new(ErrorKind::InvalidData, e))
|
||||
}
|
||||
|
||||
pub trait ToWriter: Sized {
|
||||
fn to_writer<W>(&self, writer: &mut W, e: Endian) -> io::Result<()>
|
||||
where W: Write + ?Sized;
|
||||
|
||||
fn to_bytes(&self, e: Endian) -> io::Result<Vec<u8>> {
|
||||
let mut buf = vec![0u8; self.write_size()];
|
||||
self.to_writer(&mut buf.as_mut_slice(), e)?;
|
||||
Ok(buf)
|
||||
}
|
||||
|
||||
fn write_size(&self) -> usize;
|
||||
}
|
||||
|
||||
macro_rules! impl_to_writer {
|
||||
($($t:ty),*) => {
|
||||
$(
|
||||
impl ToWriter for $t {
|
||||
fn to_writer<W>(&self, writer: &mut W, e: Endian) -> io::Result<()>
|
||||
where W: Write + ?Sized {
|
||||
writer.write_all(&match e {
|
||||
Endian::Big => self.to_be_bytes(),
|
||||
Endian::Little => self.to_le_bytes(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_bytes(&self, e: Endian) -> io::Result<Vec<u8>> {
|
||||
Ok(match e {
|
||||
Endian::Big => self.to_be_bytes(),
|
||||
Endian::Little => self.to_le_bytes(),
|
||||
}.to_vec())
|
||||
}
|
||||
|
||||
fn write_size(&self) -> usize {
|
||||
std::mem::size_of::<Self>()
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl_to_writer!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
|
||||
|
||||
impl<const N: usize> ToWriter for [u8; N] {
|
||||
fn to_writer<W>(&self, writer: &mut W, _e: Endian) -> io::Result<()>
|
||||
where W: Write + ?Sized {
|
||||
writer.write_all(self)
|
||||
}
|
||||
|
||||
fn write_size(&self) -> usize { N }
|
||||
}
|
||||
|
||||
impl ToWriter for &[u8] {
|
||||
fn to_writer<W>(&self, writer: &mut W, _e: Endian) -> io::Result<()>
|
||||
where W: Write + ?Sized {
|
||||
writer.write_all(self)
|
||||
}
|
||||
|
||||
fn write_size(&self) -> usize { self.len() }
|
||||
}
|
||||
|
||||
impl ToWriter for Vec<u8> {
|
||||
fn to_writer<W>(&self, writer: &mut W, _e: Endian) -> io::Result<()>
|
||||
where W: Write + ?Sized {
|
||||
writer.write_all(self)
|
||||
}
|
||||
|
||||
fn write_size(&self) -> usize { self.len() }
|
||||
}
|
||||
|
||||
pub fn write_vec<T, W>(writer: &mut W, vec: &[T], e: Endian) -> io::Result<()>
|
||||
where
|
||||
T: ToWriter,
|
||||
W: Write + ?Sized,
|
||||
{
|
||||
for item in vec {
|
||||
item.to_writer(writer, e)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
+1
-5
@@ -232,15 +232,11 @@ pub fn process_rel<R: Read + Seek>(reader: &mut R, name: &str) -> Result<(RelHea
|
||||
}
|
||||
symbols.push(ObjSymbol {
|
||||
name: name.to_string(),
|
||||
demangled_name: None,
|
||||
address: offset as u64,
|
||||
section: Some(section_index),
|
||||
size: 0,
|
||||
size_known: false,
|
||||
flags,
|
||||
kind: ObjSymbolKind::Function,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
|
||||
+2
-11
@@ -128,15 +128,11 @@ pub fn process_rso<R: Read + Seek>(reader: &mut R) -> Result<ObjInfo> {
|
||||
log::debug!("Adding {name} section {rel_section_idx} offset {offset:#X}");
|
||||
symbols.push(ObjSymbol {
|
||||
name: name.to_string(),
|
||||
demangled_name: None,
|
||||
address: offset as u64,
|
||||
section: Some(section_index),
|
||||
size: 0,
|
||||
size_known: false,
|
||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
|
||||
kind: ObjSymbolKind::Function,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
@@ -196,12 +192,7 @@ pub fn process_rso<R: Read + Seek>(reader: &mut R) -> Result<ObjInfo> {
|
||||
demangled_name,
|
||||
address: sym_off as u64,
|
||||
section: Some(section),
|
||||
size: 0,
|
||||
size_known: false,
|
||||
flags: Default::default(),
|
||||
kind: Default::default(),
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
});
|
||||
}
|
||||
reader.seek(SeekFrom::Start(import_table_offset as u64))?;
|
||||
|
||||
@@ -142,8 +142,7 @@ pub fn apply_symbol(
|
||||
size_known: sig_symbol.size > 0 || sig_symbol.kind == ObjSymbolKind::Unknown,
|
||||
flags: sig_symbol.flags,
|
||||
kind: sig_symbol.kind,
|
||||
align: None,
|
||||
data_kind: Default::default(),
|
||||
..Default::default()
|
||||
},
|
||||
false,
|
||||
)?;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user