Emit FORCEACTIVE in LCF & various fixes

This commit is contained in:
Luke Street 2023-08-09 01:24:23 -04:00
parent d9e1ae2777
commit 457ee10a42
9 changed files with 49 additions and 21 deletions

2
Cargo.lock generated
View File

@ -214,7 +214,7 @@ dependencies = [
[[package]] [[package]]
name = "decomp-toolkit" name = "decomp-toolkit"
version = "0.3.3" version = "0.3.4"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"ar", "ar",

View File

@ -3,7 +3,7 @@ name = "decomp-toolkit"
description = "Yet another GameCube/Wii decompilation toolkit." description = "Yet another GameCube/Wii decompilation toolkit."
authors = ["Luke Street <luke@street.dev>"] authors = ["Luke Street <luke@street.dev>"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
version = "0.3.3" version = "0.3.4"
edition = "2021" edition = "2021"
publish = false publish = false
build = "build.rs" build = "build.rs"

View File

@ -26,4 +26,5 @@ FORCEFILES
FORCEACTIVE FORCEACTIVE
{ {
$FORCEACTIVE
} }

View File

@ -119,6 +119,7 @@ pub struct ProjectConfig {
/// Version of the MW `.comment` section format. /// Version of the MW `.comment` section format.
/// If not present, no `.comment` sections will be written. /// If not present, no `.comment` sections will be written.
pub mw_comment_version: Option<u8>, pub mw_comment_version: Option<u8>,
#[serde(default)]
pub modules: Vec<ModuleConfig>, pub modules: Vec<ModuleConfig>,
// Analysis options // Analysis options
#[serde(default = "bool_true")] #[serde(default = "bool_true")]
@ -258,6 +259,14 @@ fn split(args: SplitArgs) -> Result<()> {
if let Some((symbol_index, symbol)) = if let Some((symbol_index, symbol)) =
obj.symbols.for_relocation(target, rel_reloc.kind)? obj.symbols.for_relocation(target, rel_reloc.kind)?
{ {
if symbol.flags.is_local() {
bail!(
"Module {} relocation to {:#010X} found local symbol {}",
module_id,
symbol.address,
symbol.name
);
}
let addend = target as i64 - symbol.address as i64; let addend = target as i64 - symbol.address as i64;
if addend != 0 { if addend != 0 {
bail!( bail!(
@ -268,7 +277,7 @@ fn split(args: SplitArgs) -> Result<()> {
addend addend
); );
} }
obj.symbols.set_externally_referenced(symbol_index, true); obj.symbols.flags(symbol_index).set_force_active(true);
} else { } else {
// Add label // Add label
let target_section = obj.section_at(target)?; let target_section = obj.section_at(target)?;
@ -577,6 +586,10 @@ fn diff(args: DiffArgs) -> Result<()> {
apply_map_file(&args.map_file, &mut linked_obj)?; apply_map_file(&args.map_file, &mut linked_obj)?;
for orig_sym in obj.symbols.iter() { for orig_sym in obj.symbols.iter() {
if orig_sym.kind == ObjSymbolKind::Section || orig_sym.section.is_none() {
continue;
}
let linked_sym = linked_obj let linked_sym = linked_obj
.symbols .symbols
.at_address(orig_sym.address as u32) .at_address(orig_sym.address as u32)

View File

@ -34,8 +34,6 @@ flags! {
Common, Common,
Hidden, Hidden,
ForceActive, ForceActive,
// Same as ForceActive, but used internally
ExternallyReferenced,
} }
} }
@ -74,11 +72,6 @@ impl ObjSymbolFlagSet {
#[inline] #[inline]
pub fn is_force_active(&self) -> bool { self.0.contains(ObjSymbolFlags::ForceActive) } pub fn is_force_active(&self) -> bool { self.0.contains(ObjSymbolFlags::ForceActive) }
#[inline]
pub fn is_externally_referenced(&self) -> bool {
self.0.contains(ObjSymbolFlags::ExternallyReferenced)
}
#[inline] #[inline]
pub fn set_scope(&mut self, scope: ObjSymbolScope) { pub fn set_scope(&mut self, scope: ObjSymbolScope) {
match scope { match scope {
@ -101,11 +94,11 @@ impl ObjSymbolFlagSet {
} }
#[inline] #[inline]
pub fn set_externally_referenced(&mut self, value: bool) { pub fn set_force_active(&mut self, value: bool) {
if value { if value {
self.0 |= ObjSymbolFlags::ExternallyReferenced; self.0 |= ObjSymbolFlags::ForceActive;
} else { } else {
self.0 &= !ObjSymbolFlags::ExternallyReferenced; self.0 &= !ObjSymbolFlags::ForceActive;
} }
} }
} }
@ -562,8 +555,9 @@ impl ObjSymbols {
Ok(result) Ok(result)
} }
pub fn set_externally_referenced(&mut self, idx: SymbolIndex, value: bool) { #[inline]
self.symbols[idx].flags.set_externally_referenced(value); pub fn flags(&mut self, idx: SymbolIndex) -> &mut ObjSymbolFlagSet {
&mut self.symbols[idx].flags
} }
} }
@ -629,6 +623,18 @@ impl ObjInfo {
pub fn section_data(&self, start: u32, end: u32) -> Result<(&ObjSection, &[u8])> { pub fn section_data(&self, start: u32, end: u32) -> Result<(&ObjSection, &[u8])> {
let section = self.section_at(start)?; let section = self.section_at(start)?;
ensure!(
section.contains_range(start..end),
"Range {:#010X}-{:#010X} outside of section {}: {:#010X}-{:#010X}",
start,
end,
section.name,
section.address,
section.address + section.size
);
if section.kind == ObjSectionKind::Bss {
return Ok((section, &[]));
}
let data = if end == 0 { let data = if end == 0 {
&section.data[(start as u64 - section.address) as usize..] &section.data[(start as u64 - section.address) as usize..]
} else { } else {

View File

@ -97,7 +97,7 @@ fn split_ctors_dtors(obj: &mut ObjInfo, section_start: u32, section_end: u32) ->
// Hack to avoid deadstripping // Hack to avoid deadstripping
for symbol_idx in referenced_symbols { for symbol_idx in referenced_symbols {
obj.symbols.set_externally_referenced(symbol_idx, true); obj.symbols.flags(symbol_idx).set_force_active(true);
} }
Ok(()) Ok(())

View File

@ -196,7 +196,7 @@ impl CommentSym {
vis_flags |= 0xD; vis_flags |= 0xD;
} }
let mut active_flags = 0; let mut active_flags = 0;
if symbol.flags.is_force_active() || symbol.flags.is_externally_referenced() { if symbol.flags.is_force_active() {
active_flags |= 0x8; // TODO what is 0x10? active_flags |= 0x8; // TODO what is 0x10?
} }
Self { align, vis_flags, active_flags } Self { align, vis_flags, active_flags }

View File

@ -200,9 +200,9 @@ fn write_symbol<W: Write>(w: &mut W, obj: &ObjInfo, symbol: &ObjSymbol) -> Resul
if symbol.flags.is_hidden() { if symbol.flags.is_hidden() {
write!(w, " hidden")?; write!(w, " hidden")?;
} }
if symbol.flags.is_force_active() { // if symbol.flags.is_force_active() {
write!(w, " force_active")?; // write!(w, " force_active")?;
} // }
if obj.blocked_ranges.contains_key(&(symbol.address as u32)) { if obj.blocked_ranges.contains_key(&(symbol.address as u32)) {
write!(w, " noreloc")?; write!(w, " noreloc")?;
} }

View File

@ -23,6 +23,13 @@ pub fn generate_ldscript(obj: &ObjInfo, auto_force_files: bool) -> Result<String
force_files.push(obj_path.file_name().unwrap().to_str().unwrap().to_string()); force_files.push(obj_path.file_name().unwrap().to_str().unwrap().to_string());
} }
let mut force_active = vec![];
for symbol in obj.symbols.iter() {
if symbol.flags.is_force_active() && symbol.flags.is_global() {
force_active.push(symbol.name.clone());
}
}
// Hack to handle missing .sbss2 section... what's the proper way? // Hack to handle missing .sbss2 section... what's the proper way?
let last_section_name = obj.sections.last().unwrap().name.clone(); let last_section_name = obj.sections.last().unwrap().name.clone();
let last_section_symbol = format!("_f_{}", last_section_name.trim_start_matches('.')); let last_section_symbol = format!("_f_{}", last_section_name.trim_start_matches('.'));
@ -31,7 +38,8 @@ pub fn generate_ldscript(obj: &ObjInfo, auto_force_files: bool) -> Result<String
.replacen("$SECTIONS", &section_defs, 1) .replacen("$SECTIONS", &section_defs, 1)
.replace("$LAST_SECTION_SYMBOL", &last_section_symbol) .replace("$LAST_SECTION_SYMBOL", &last_section_symbol)
.replace("$LAST_SECTION_NAME", &last_section_name) .replace("$LAST_SECTION_NAME", &last_section_name)
.replacen("$STACKSIZE", &format!("{:#X}", stack_size), 1); .replacen("$STACKSIZE", &format!("{:#X}", stack_size), 1)
.replacen("$FORCEACTIVE", &force_active.join("\n "), 1);
out = if auto_force_files { out = if auto_force_files {
out.replacen("$FORCEFILES", &force_files.join("\n "), 1) out.replacen("$FORCEFILES", &force_files.join("\n "), 1)
} else { } else {