diff --git a/Cargo.lock b/Cargo.lock index 1a32b3e..6ed26d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -295,7 +295,7 @@ dependencies = [ [[package]] name = "decomp-toolkit" -version = "0.7.1" +version = "0.7.2" dependencies = [ "anyhow", "ar", diff --git a/Cargo.toml b/Cargo.toml index 1b9f30c..e30f23c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ name = "decomp-toolkit" description = "Yet another GameCube/Wii decompilation toolkit." authors = ["Luke Street "] license = "MIT OR Apache-2.0" -version = "0.7.1" +version = "0.7.2" edition = "2021" publish = false repository = "https://github.com/encounter/decomp-toolkit" diff --git a/src/cmd/dol.rs b/src/cmd/dol.rs index d381fc4..d6c7c19 100644 --- a/src/cmd/dol.rs +++ b/src/cmd/dol.rs @@ -228,9 +228,9 @@ pub struct ProjectConfig { /// Fills gaps between symbols to avoid linker realignment. #[serde(default = "bool_true", skip_serializing_if = "is_true")] pub fill_gaps: bool, - /// Marks all emitted symbols as "force active" to prevent the linker from removing them. + /// Marks all emitted symbols as "exported" to prevent the linker from removing them. #[serde(default = "bool_true", skip_serializing_if = "is_true")] - pub auto_force_active: bool, + pub export_all: bool, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] @@ -248,7 +248,7 @@ pub struct ModuleConfig { pub symbols: Option, #[serde(with = "path_slash_serde_option", default, skip_serializing_if = "is_default")] pub map: Option, - /// Forces the given symbols to be active in the linker script. + /// Forces the given symbols to be active (exported) in the linker script. #[serde(default, skip_serializing_if = "is_default")] pub force_active: Vec, #[serde(skip_serializing_if = "is_default")] @@ -397,7 +397,7 @@ fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> { section, size: existing_symbol.size, size_known: existing_symbol.size_known, - flags: ObjSymbolFlagSet(existing_symbol.flags.0 | ObjSymbolFlags::ForceActive), + flags: ObjSymbolFlagSet(existing_symbol.flags.0 | ObjSymbolFlags::Exported), kind: existing_symbol.kind, align: existing_symbol.align, data_kind: existing_symbol.data_kind, @@ -412,7 +412,7 @@ fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> { demangled_name: symbol.demangled_name.clone(), address: address as u64, section, - flags: ObjSymbolFlagSet(ObjSymbolFlags::Global | ObjSymbolFlags::ForceActive), + flags: ObjSymbolFlagSet(ObjSymbolFlags::Global | ObjSymbolFlags::Exported), ..*symbol }, false, @@ -574,7 +574,7 @@ fn update_symbols( name, address: rel_reloc.addend as u64, section: Some(target_section_index), - flags: ObjSymbolFlagSet(ObjSymbolFlags::ForceActive.into()), + flags: ObjSymbolFlagSet(ObjSymbolFlags::Exported.into()), ..Default::default() })?; } @@ -862,7 +862,7 @@ fn split_write_obj( entry, }; for (unit, split_obj) in module.obj.link_order.iter().zip(&split_objs) { - let out_obj = write_elf(split_obj, config.auto_force_active)?; + let out_obj = write_elf(split_obj, config.export_all)?; let out_path = obj_dir.join(obj_path_for_unit(&unit.name)); out_config.units.push(OutputUnit { object: out_path.clone(), @@ -1766,7 +1766,7 @@ fn config(args: ConfigArgs) -> Result<()> { common_start: None, symbols_known: false, fill_gaps: true, - auto_force_active: true, + export_all: true, }; let mut modules = Vec::<(u32, ModuleConfig)>::new(); diff --git a/src/obj/symbols.rs b/src/obj/symbols.rs index 3f68d39..c1040b6 100644 --- a/src/obj/symbols.rs +++ b/src/obj/symbols.rs @@ -34,7 +34,8 @@ flags! { Weak, Common, Hidden, - ForceActive, + /// Force symbol to be exported (force active) + Exported, /// Symbol isn't referenced by any relocations RelocationIgnore, /// Symbol won't be written to symbols file @@ -42,6 +43,8 @@ flags! { /// Symbol was stripped from the original object, /// but is still useful for common BSS matching. Stripped, + /// Disable automatic export of symbol + NoExport, } } @@ -78,7 +81,7 @@ impl ObjSymbolFlagSet { pub fn is_hidden(&self) -> bool { self.0.contains(ObjSymbolFlags::Hidden) } #[inline] - pub fn is_force_active(&self) -> bool { self.0.contains(ObjSymbolFlags::ForceActive) } + pub fn is_exported(&self) -> bool { self.0.contains(ObjSymbolFlags::Exported) } #[inline] pub fn is_relocation_ignore(&self) -> bool { self.0.contains(ObjSymbolFlags::RelocationIgnore) } @@ -89,6 +92,9 @@ impl ObjSymbolFlagSet { #[inline] pub fn is_stripped(&self) -> bool { self.0.contains(ObjSymbolFlags::Stripped) } + #[inline] + pub fn is_no_export(&self) -> bool { self.0.contains(ObjSymbolFlags::NoExport) } + #[inline] pub fn set_scope(&mut self, scope: ObjSymbolScope) { match scope { @@ -113,9 +119,9 @@ impl ObjSymbolFlagSet { #[inline] pub fn set_force_active(&mut self, value: bool) { if value { - self.0 |= ObjSymbolFlags::ForceActive; + self.0 = (self.0 & !ObjSymbolFlags::NoExport) | ObjSymbolFlags::Exported; } else { - self.0 &= !ObjSymbolFlags::ForceActive; + self.0 &= !ObjSymbolFlags::Exported; } } @@ -123,10 +129,11 @@ impl ObjSymbolFlagSet { #[inline] pub fn keep_flags(&self) -> FlagSet { self.0 - & (ObjSymbolFlags::ForceActive + & (ObjSymbolFlags::Exported | ObjSymbolFlags::NoWrite | ObjSymbolFlags::RelocationIgnore - | ObjSymbolFlags::Stripped) + | ObjSymbolFlags::Stripped + | ObjSymbolFlags::NoExport) } } diff --git a/src/util/comment.rs b/src/util/comment.rs index e84e94c..7be6312 100644 --- a/src/util/comment.rs +++ b/src/util/comment.rs @@ -249,7 +249,7 @@ impl ToWriter for CommentSym { } impl CommentSym { - pub fn from(symbol: &ObjSymbol, force_active: bool) -> Self { + pub fn from(symbol: &ObjSymbol, export_all: bool) -> Self { let align = match symbol.align { Some(align) => align, None => { @@ -277,8 +277,9 @@ impl CommentSym { } let mut active_flags = 0; if !symbol.flags.is_stripped() - && (symbol.flags.is_force_active() - || (force_active + && (symbol.flags.is_exported() + || (export_all + && !symbol.flags.is_no_export() && matches!(symbol.kind, ObjSymbolKind::Function | ObjSymbolKind::Object))) { active_flags |= 0x8; diff --git a/src/util/config.rs b/src/util/config.rs index 30d8031..630bb7e 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -85,7 +85,7 @@ pub fn parse_symbol_line(line: &str, obj: &mut ObjInfo) -> Result Result { - symbol.flags.0 |= ObjSymbolFlags::ForceActive; + symbol.flags.0 |= ObjSymbolFlags::Exported; } "stripped" => { symbol.flags.0 |= ObjSymbolFlags::Stripped; @@ -147,6 +147,9 @@ pub fn parse_symbol_line(line: &str, obj: &mut ObjInfo) -> Result { + symbol.flags.0 |= ObjSymbolFlags::NoExport; + } _ => bail!("Unknown symbol attribute '{attr}'"), } } @@ -281,6 +284,9 @@ where W: Write + ?Sized { write!(w, " noreloc")?; } } + if symbol.flags.is_no_export() { + write!(w, " noexport")?; + } writeln!(w)?; Ok(()) } diff --git a/src/util/elf.rs b/src/util/elf.rs index 7fdd7e1..c450e7a 100644 --- a/src/util/elf.rs +++ b/src/util/elf.rs @@ -346,7 +346,7 @@ where P: AsRef { Ok(obj) } -pub fn write_elf(obj: &ObjInfo, force_active: bool) -> Result> { +pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result> { let mut out_data = Vec::new(); let mut writer = object::write::elf::Writer::new(Endianness::Big, false, &mut out_data); @@ -540,7 +540,7 @@ pub fn write_elf(obj: &ObjInfo, force_active: bool) -> Result> { out_symbols.push(OutSymbol { index, sym }); symbol_map[symbol_index] = Some(index.0); if let Some(comment_data) = &mut comment_data { - CommentSym::from(symbol, force_active).to_writer_static(comment_data, Endian::Big)?; + CommentSym::from(symbol, export_all).to_writer_static(comment_data, Endian::Big)?; } } diff --git a/src/util/lcf.rs b/src/util/lcf.rs index 4c31465..9661537 100644 --- a/src/util/lcf.rs +++ b/src/util/lcf.rs @@ -63,8 +63,7 @@ pub fn generate_ldscript( let mut force_active = force_active.to_vec(); for symbol in obj.symbols.iter() { - if symbol.flags.is_force_active() && symbol.flags.is_global() && !symbol.flags.is_no_write() - { + if symbol.flags.is_exported() && symbol.flags.is_global() && !symbol.flags.is_no_write() { force_active.push(symbol.name.clone()); } } @@ -98,8 +97,7 @@ pub fn generate_ldscript_partial( let mut force_active = force_active.to_vec(); for symbol in obj.symbols.iter() { - if symbol.flags.is_force_active() && symbol.flags.is_global() && !symbol.flags.is_no_write() - { + if symbol.flags.is_exported() && symbol.flags.is_global() && !symbol.flags.is_no_write() { force_active.push(symbol.name.clone()); } } diff --git a/src/util/map.rs b/src/util/map.rs index d8a9712..477caf7 100644 --- a/src/util/map.rs +++ b/src/util/map.rs @@ -823,7 +823,7 @@ fn add_symbol(obj: &mut ObjInfo, symbol_entry: &SymbolEntry, section: Option Result<()> { size: next_symbol_address - addr as u64, size_known: true, flags: ObjSymbolFlagSet( - ObjSymbolFlags::Local | ObjSymbolFlags::ForceActive | ObjSymbolFlags::NoWrite, + ObjSymbolFlags::Local | ObjSymbolFlags::Exported | ObjSymbolFlags::NoWrite, ), kind: match section.kind { ObjSectionKind::Code => ObjSymbolKind::Function, @@ -616,7 +616,7 @@ fn add_padding_symbols(obj: &mut ObjInfo) -> Result<()> { flags: ObjSymbolFlagSet( ObjSymbolFlags::Global | ObjSymbolFlags::Hidden - | ObjSymbolFlags::ForceActive + | ObjSymbolFlags::Exported | ObjSymbolFlags::NoWrite, ), kind: match section.kind {