Improvements to REL & map support

- Fix symbols.txt align attribute
- Fully support nested RARC files & transparent Yaz0 decompression
- Guess symbol visibility for maps without link map
- Add module name config
- Add manual force_active config
- Quiet option for shasum
- `symbols_known` and `fill_gaps` config
- Allow disabling .comment generation per-unit (`comment:0`)
- Various minor fixes
- Add `rarc` and `yaz0` commands
This commit is contained in:
2023-09-05 17:22:22 -04:00
parent f9f7fb2e1e
commit e3857d3212
32 changed files with 975 additions and 366 deletions

View File

@@ -14,7 +14,7 @@ pub fn detect_objects(obj: &mut ObjInfo) -> Result<()> {
let mut replace_symbols = vec![];
for (idx, symbol) in obj.symbols.for_section(section_index) {
let mut symbol = symbol.clone();
if is_linker_generated_label(&symbol.name) {
if is_linker_generated_label(&symbol.name) || symbol.name.starts_with("..") {
continue;
}
let expected_size = match symbol.data_kind {
@@ -124,6 +124,11 @@ pub fn detect_strings(obj: &mut ObjInfo) -> Result<()> {
.for_section(section_index)
.filter(|(_, sym)| sym.data_kind == ObjDataKind::Unknown)
{
if symbol.name.starts_with("@stringBase") {
symbols_set.push((symbol_idx, ObjDataKind::StringTable, symbol.size as usize));
continue;
}
let data = section.symbol_data(symbol)?;
match is_string(data) {
StringResult::None => {}

View File

@@ -33,7 +33,7 @@ impl AnalysisPass for FindTRKInterruptVectorTable {
if data.starts_with(TRK_TABLE_HEADER.as_bytes())
&& data[TRK_TABLE_HEADER.as_bytes().len()] == 0
{
log::info!("Found gTRKInterruptVectorTable @ {:#010X}", start);
log::debug!("Found gTRKInterruptVectorTable @ {:#010X}", start);
state.known_symbols.insert(start, ObjSymbol {
name: "gTRKInterruptVectorTable".to_string(),
demangled_name: None,

View File

@@ -1,4 +1,4 @@
use anyhow::{anyhow, bail, Result};
use anyhow::{anyhow, Result};
use crate::{
analysis::{
@@ -272,21 +272,21 @@ fn apply_ctors_signatures(obj: &mut ObjInfo) -> Result<()> {
}
fn apply_dtors_signatures(obj: &mut ObjInfo) -> Result<()> {
let Some((_, symbol)) = obj.symbols.by_name("_dtors")? else {
for symbol in obj.symbols.iter() {
println!("{:?} {:#010X} {}", symbol.section, symbol.address, symbol.name);
}
bail!("Missing _dtors symbol");
// return Ok(());
};
let dtors_section_index =
symbol.section.ok_or_else(|| anyhow!("Missing _dtors symbol section"))?;
let dtors_section = &obj.sections[dtors_section_index];
let (dtors_section_index, dtors_section) =
if let Some((_, symbol)) = obj.symbols.by_name("_dtors")? {
let section_index =
symbol.section.ok_or_else(|| anyhow!("Missing _dtors symbol section"))?;
(section_index, &obj.sections[section_index])
} else if let Some((section_index, section)) = obj.sections.by_name(".dtors")? {
(section_index, section)
} else {
return Ok(());
};
// __destroy_global_chain_reference + null pointer
if dtors_section.size < 8 {
return Ok(());
}
let address = symbol.address;
let address = dtors_section.address;
let dgc_target = read_address(obj, dtors_section, address as u32).ok();
let fce_target = read_address(obj, dtors_section, address as u32 + 4).ok();
let mut found_dgc = false;
@@ -319,7 +319,7 @@ fn apply_dtors_signatures(obj: &mut ObjInfo) -> Result<()> {
)?;
found_dgc = true;
} else {
log::warn!("Failed to match __destroy_global_chain signature ({:#010X})", dgc_target);
log::debug!("Failed to match __destroy_global_chain signature ({:#010X})", dgc_target);
}
}
@@ -445,3 +445,40 @@ pub fn apply_signatures_post(obj: &mut ObjInfo) -> Result<()> {
}
Ok(())
}
/// Create _ctors and _dtors symbols if missing
pub fn update_ctors_dtors(obj: &mut ObjInfo) -> Result<()> {
if obj.symbols.by_name("_ctors")?.is_none() {
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(),
})?;
}
}
if obj.symbols.by_name("_dtors")?.is_none() {
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(),
})?;
}
}
Ok(())
}

View File

@@ -433,7 +433,9 @@ impl Tracker {
|| self.sda2_base == Some(addr)
|| self.sda_base == Some(addr)
{
return Some(SectionAddress::new(usize::MAX, addr));
let section_index =
obj.sections.at_address(addr).ok().map(|(idx, _)| idx).unwrap_or(usize::MAX);
return Some(SectionAddress::new(section_index, addr));
}
// if addr > 0x80000000 && addr < 0x80003100 {
// return true;