Skip to content

Commit e3857d3

Browse files
committed
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
1 parent f9f7fb2 commit e3857d3

32 files changed

+975
-366
lines changed

assets/ldscript.lcf

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@ SECTIONS
1919
__ArenaHi = $ARENAHI;
2020
}
2121

22-
FORCEFILES
23-
{
24-
$FORCEFILES
25-
}
26-
2722
FORCEACTIVE
2823
{
2924
$FORCEACTIVE

assets/ldscript_partial.lcf

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,3 @@ FORCEACTIVE
1919
_epilog
2020
$FORCEACTIVE
2121
}
22-
23-
FORCEFILES
24-
{
25-
$FORCEFILES
26-
}

src/analysis/objects.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub fn detect_objects(obj: &mut ObjInfo) -> Result<()> {
1414
let mut replace_symbols = vec![];
1515
for (idx, symbol) in obj.symbols.for_section(section_index) {
1616
let mut symbol = symbol.clone();
17-
if is_linker_generated_label(&symbol.name) {
17+
if is_linker_generated_label(&symbol.name) || symbol.name.starts_with("..") {
1818
continue;
1919
}
2020
let expected_size = match symbol.data_kind {
@@ -124,6 +124,11 @@ pub fn detect_strings(obj: &mut ObjInfo) -> Result<()> {
124124
.for_section(section_index)
125125
.filter(|(_, sym)| sym.data_kind == ObjDataKind::Unknown)
126126
{
127+
if symbol.name.starts_with("@stringBase") {
128+
symbols_set.push((symbol_idx, ObjDataKind::StringTable, symbol.size as usize));
129+
continue;
130+
}
131+
127132
let data = section.symbol_data(symbol)?;
128133
match is_string(data) {
129134
StringResult::None => {}

src/analysis/pass.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ impl AnalysisPass for FindTRKInterruptVectorTable {
3333
if data.starts_with(TRK_TABLE_HEADER.as_bytes())
3434
&& data[TRK_TABLE_HEADER.as_bytes().len()] == 0
3535
{
36-
log::info!("Found gTRKInterruptVectorTable @ {:#010X}", start);
36+
log::debug!("Found gTRKInterruptVectorTable @ {:#010X}", start);
3737
state.known_symbols.insert(start, ObjSymbol {
3838
name: "gTRKInterruptVectorTable".to_string(),
3939
demangled_name: None,

src/analysis/signatures.rs

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use anyhow::{anyhow, bail, Result};
1+
use anyhow::{anyhow, Result};
22

33
use crate::{
44
analysis::{
@@ -272,21 +272,21 @@ fn apply_ctors_signatures(obj: &mut ObjInfo) -> Result<()> {
272272
}
273273

274274
fn apply_dtors_signatures(obj: &mut ObjInfo) -> Result<()> {
275-
let Some((_, symbol)) = obj.symbols.by_name("_dtors")? else {
276-
for symbol in obj.symbols.iter() {
277-
println!("{:?} {:#010X} {}", symbol.section, symbol.address, symbol.name);
278-
}
279-
bail!("Missing _dtors symbol");
280-
// return Ok(());
281-
};
282-
let dtors_section_index =
283-
symbol.section.ok_or_else(|| anyhow!("Missing _dtors symbol section"))?;
284-
let dtors_section = &obj.sections[dtors_section_index];
275+
let (dtors_section_index, dtors_section) =
276+
if let Some((_, symbol)) = obj.symbols.by_name("_dtors")? {
277+
let section_index =
278+
symbol.section.ok_or_else(|| anyhow!("Missing _dtors symbol section"))?;
279+
(section_index, &obj.sections[section_index])
280+
} else if let Some((section_index, section)) = obj.sections.by_name(".dtors")? {
281+
(section_index, section)
282+
} else {
283+
return Ok(());
284+
};
285285
// __destroy_global_chain_reference + null pointer
286286
if dtors_section.size < 8 {
287287
return Ok(());
288288
}
289-
let address = symbol.address;
289+
let address = dtors_section.address;
290290
let dgc_target = read_address(obj, dtors_section, address as u32).ok();
291291
let fce_target = read_address(obj, dtors_section, address as u32 + 4).ok();
292292
let mut found_dgc = false;
@@ -319,7 +319,7 @@ fn apply_dtors_signatures(obj: &mut ObjInfo) -> Result<()> {
319319
)?;
320320
found_dgc = true;
321321
} else {
322-
log::warn!("Failed to match __destroy_global_chain signature ({:#010X})", dgc_target);
322+
log::debug!("Failed to match __destroy_global_chain signature ({:#010X})", dgc_target);
323323
}
324324
}
325325

@@ -445,3 +445,40 @@ pub fn apply_signatures_post(obj: &mut ObjInfo) -> Result<()> {
445445
}
446446
Ok(())
447447
}
448+
449+
/// Create _ctors and _dtors symbols if missing
450+
pub fn update_ctors_dtors(obj: &mut ObjInfo) -> Result<()> {
451+
if obj.symbols.by_name("_ctors")?.is_none() {
452+
if let Some((section_index, section)) = obj.sections.by_name(".ctors")? {
453+
obj.symbols.add_direct(ObjSymbol {
454+
name: "_ctors".to_string(),
455+
demangled_name: None,
456+
address: section.address,
457+
section: Some(section_index),
458+
size: 0,
459+
size_known: true,
460+
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
461+
kind: ObjSymbolKind::Unknown,
462+
align: None,
463+
data_kind: Default::default(),
464+
})?;
465+
}
466+
}
467+
if obj.symbols.by_name("_dtors")?.is_none() {
468+
if let Some((section_index, section)) = obj.sections.by_name(".dtors")? {
469+
obj.symbols.add_direct(ObjSymbol {
470+
name: "_dtors".to_string(),
471+
demangled_name: None,
472+
address: section.address,
473+
section: Some(section_index),
474+
size: 0,
475+
size_known: true,
476+
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global.into()),
477+
kind: ObjSymbolKind::Unknown,
478+
align: None,
479+
data_kind: Default::default(),
480+
})?;
481+
}
482+
}
483+
Ok(())
484+
}

src/analysis/tracker.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,9 @@ impl Tracker {
433433
|| self.sda2_base == Some(addr)
434434
|| self.sda_base == Some(addr)
435435
{
436-
return Some(SectionAddress::new(usize::MAX, addr));
436+
let section_index =
437+
obj.sections.at_address(addr).ok().map(|(idx, _)| idx).unwrap_or(usize::MAX);
438+
return Some(SectionAddress::new(section_index, addr));
437439
}
438440
// if addr > 0x80000000 && addr < 0x80003100 {
439441
// return true;

src/cmd/ar.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ fn create(args: CreateArgs) -> Result<()> {
6060
Entry::Vacant(e) => e.insert(Vec::new()),
6161
Entry::Occupied(_) => bail!("Duplicate file name '{path_str}'"),
6262
};
63-
let mmap = map_file(path)?;
64-
let obj = object::File::parse(&*mmap)?;
63+
let file = map_file(path)?;
64+
let obj = object::File::parse(file.as_slice())?;
6565
for symbol in obj.symbols() {
6666
if symbol.scope() == SymbolScope::Dynamic {
6767
entries.push(symbol.name_bytes()?.to_vec());

0 commit comments

Comments
 (0)