Add `noexport` attr to symbols.txt
Rename `auto_force_active` to `export_all`. This is a better solution to code_merging, as individual functions can be marked `noexport`.
This commit is contained in:
parent
1614997108
commit
7b7c8ce251
|
@ -295,7 +295,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "decomp-toolkit"
|
name = "decomp-toolkit"
|
||||||
version = "0.7.1"
|
version = "0.7.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"ar",
|
"ar",
|
||||||
|
|
|
@ -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.7.1"
|
version = "0.7.2"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
publish = false
|
publish = false
|
||||||
repository = "https://github.com/encounter/decomp-toolkit"
|
repository = "https://github.com/encounter/decomp-toolkit"
|
||||||
|
|
|
@ -228,9 +228,9 @@ pub struct ProjectConfig {
|
||||||
/// Fills gaps between symbols to avoid linker realignment.
|
/// Fills gaps between symbols to avoid linker realignment.
|
||||||
#[serde(default = "bool_true", skip_serializing_if = "is_true")]
|
#[serde(default = "bool_true", skip_serializing_if = "is_true")]
|
||||||
pub fill_gaps: bool,
|
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")]
|
#[serde(default = "bool_true", skip_serializing_if = "is_true")]
|
||||||
pub auto_force_active: bool,
|
pub export_all: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
|
||||||
|
@ -248,7 +248,7 @@ pub struct ModuleConfig {
|
||||||
pub symbols: Option<PathBuf>,
|
pub symbols: Option<PathBuf>,
|
||||||
#[serde(with = "path_slash_serde_option", default, skip_serializing_if = "is_default")]
|
#[serde(with = "path_slash_serde_option", default, skip_serializing_if = "is_default")]
|
||||||
pub map: Option<PathBuf>,
|
pub map: Option<PathBuf>,
|
||||||
/// 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")]
|
#[serde(default, skip_serializing_if = "is_default")]
|
||||||
pub force_active: Vec<String>,
|
pub force_active: Vec<String>,
|
||||||
#[serde(skip_serializing_if = "is_default")]
|
#[serde(skip_serializing_if = "is_default")]
|
||||||
|
@ -397,7 +397,7 @@ fn apply_selfile(obj: &mut ObjInfo, buf: &[u8]) -> Result<()> {
|
||||||
section,
|
section,
|
||||||
size: existing_symbol.size,
|
size: existing_symbol.size,
|
||||||
size_known: existing_symbol.size_known,
|
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,
|
kind: existing_symbol.kind,
|
||||||
align: existing_symbol.align,
|
align: existing_symbol.align,
|
||||||
data_kind: existing_symbol.data_kind,
|
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(),
|
demangled_name: symbol.demangled_name.clone(),
|
||||||
address: address as u64,
|
address: address as u64,
|
||||||
section,
|
section,
|
||||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global | ObjSymbolFlags::ForceActive),
|
flags: ObjSymbolFlagSet(ObjSymbolFlags::Global | ObjSymbolFlags::Exported),
|
||||||
..*symbol
|
..*symbol
|
||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
|
@ -574,7 +574,7 @@ fn update_symbols(
|
||||||
name,
|
name,
|
||||||
address: rel_reloc.addend as u64,
|
address: rel_reloc.addend as u64,
|
||||||
section: Some(target_section_index),
|
section: Some(target_section_index),
|
||||||
flags: ObjSymbolFlagSet(ObjSymbolFlags::ForceActive.into()),
|
flags: ObjSymbolFlagSet(ObjSymbolFlags::Exported.into()),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
@ -862,7 +862,7 @@ fn split_write_obj(
|
||||||
entry,
|
entry,
|
||||||
};
|
};
|
||||||
for (unit, split_obj) in module.obj.link_order.iter().zip(&split_objs) {
|
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));
|
let out_path = obj_dir.join(obj_path_for_unit(&unit.name));
|
||||||
out_config.units.push(OutputUnit {
|
out_config.units.push(OutputUnit {
|
||||||
object: out_path.clone(),
|
object: out_path.clone(),
|
||||||
|
@ -1766,7 +1766,7 @@ fn config(args: ConfigArgs) -> Result<()> {
|
||||||
common_start: None,
|
common_start: None,
|
||||||
symbols_known: false,
|
symbols_known: false,
|
||||||
fill_gaps: true,
|
fill_gaps: true,
|
||||||
auto_force_active: true,
|
export_all: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut modules = Vec::<(u32, ModuleConfig)>::new();
|
let mut modules = Vec::<(u32, ModuleConfig)>::new();
|
||||||
|
|
|
@ -34,7 +34,8 @@ flags! {
|
||||||
Weak,
|
Weak,
|
||||||
Common,
|
Common,
|
||||||
Hidden,
|
Hidden,
|
||||||
ForceActive,
|
/// Force symbol to be exported (force active)
|
||||||
|
Exported,
|
||||||
/// Symbol isn't referenced by any relocations
|
/// Symbol isn't referenced by any relocations
|
||||||
RelocationIgnore,
|
RelocationIgnore,
|
||||||
/// Symbol won't be written to symbols file
|
/// Symbol won't be written to symbols file
|
||||||
|
@ -42,6 +43,8 @@ flags! {
|
||||||
/// Symbol was stripped from the original object,
|
/// Symbol was stripped from the original object,
|
||||||
/// but is still useful for common BSS matching.
|
/// but is still useful for common BSS matching.
|
||||||
Stripped,
|
Stripped,
|
||||||
|
/// Disable automatic export of symbol
|
||||||
|
NoExport,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +81,7 @@ impl ObjSymbolFlagSet {
|
||||||
pub fn is_hidden(&self) -> bool { self.0.contains(ObjSymbolFlags::Hidden) }
|
pub fn is_hidden(&self) -> bool { self.0.contains(ObjSymbolFlags::Hidden) }
|
||||||
|
|
||||||
#[inline]
|
#[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]
|
#[inline]
|
||||||
pub fn is_relocation_ignore(&self) -> bool { self.0.contains(ObjSymbolFlags::RelocationIgnore) }
|
pub fn is_relocation_ignore(&self) -> bool { self.0.contains(ObjSymbolFlags::RelocationIgnore) }
|
||||||
|
@ -89,6 +92,9 @@ impl ObjSymbolFlagSet {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_stripped(&self) -> bool { self.0.contains(ObjSymbolFlags::Stripped) }
|
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]
|
#[inline]
|
||||||
pub fn set_scope(&mut self, scope: ObjSymbolScope) {
|
pub fn set_scope(&mut self, scope: ObjSymbolScope) {
|
||||||
match scope {
|
match scope {
|
||||||
|
@ -113,9 +119,9 @@ impl ObjSymbolFlagSet {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_force_active(&mut self, value: bool) {
|
pub fn set_force_active(&mut self, value: bool) {
|
||||||
if value {
|
if value {
|
||||||
self.0 |= ObjSymbolFlags::ForceActive;
|
self.0 = (self.0 & !ObjSymbolFlags::NoExport) | ObjSymbolFlags::Exported;
|
||||||
} else {
|
} else {
|
||||||
self.0 &= !ObjSymbolFlags::ForceActive;
|
self.0 &= !ObjSymbolFlags::Exported;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,10 +129,11 @@ impl ObjSymbolFlagSet {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn keep_flags(&self) -> FlagSet<ObjSymbolFlags> {
|
pub fn keep_flags(&self) -> FlagSet<ObjSymbolFlags> {
|
||||||
self.0
|
self.0
|
||||||
& (ObjSymbolFlags::ForceActive
|
& (ObjSymbolFlags::Exported
|
||||||
| ObjSymbolFlags::NoWrite
|
| ObjSymbolFlags::NoWrite
|
||||||
| ObjSymbolFlags::RelocationIgnore
|
| ObjSymbolFlags::RelocationIgnore
|
||||||
| ObjSymbolFlags::Stripped)
|
| ObjSymbolFlags::Stripped
|
||||||
|
| ObjSymbolFlags::NoExport)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ impl ToWriter for CommentSym {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
let align = match symbol.align {
|
||||||
Some(align) => align,
|
Some(align) => align,
|
||||||
None => {
|
None => {
|
||||||
|
@ -277,8 +277,9 @@ impl CommentSym {
|
||||||
}
|
}
|
||||||
let mut active_flags = 0;
|
let mut active_flags = 0;
|
||||||
if !symbol.flags.is_stripped()
|
if !symbol.flags.is_stripped()
|
||||||
&& (symbol.flags.is_force_active()
|
&& (symbol.flags.is_exported()
|
||||||
|| (force_active
|
|| (export_all
|
||||||
|
&& !symbol.flags.is_no_export()
|
||||||
&& matches!(symbol.kind, ObjSymbolKind::Function | ObjSymbolKind::Object)))
|
&& matches!(symbol.kind, ObjSymbolKind::Function | ObjSymbolKind::Object)))
|
||||||
{
|
{
|
||||||
active_flags |= 0x8;
|
active_flags |= 0x8;
|
||||||
|
|
|
@ -85,7 +85,7 @@ pub fn parse_symbol_line(line: &str, obj: &mut ObjInfo) -> Result<Option<ObjSymb
|
||||||
ObjSymbol { name, demangled_name, address: addr as u64, section, ..Default::default() };
|
ObjSymbol { name, demangled_name, address: addr as u64, section, ..Default::default() };
|
||||||
// TODO move somewhere common
|
// TODO move somewhere common
|
||||||
if symbol.name.starts_with("..") {
|
if symbol.name.starts_with("..") {
|
||||||
symbol.flags.0 |= ObjSymbolFlags::ForceActive;
|
symbol.flags.0 |= ObjSymbolFlags::Exported;
|
||||||
}
|
}
|
||||||
let attrs = captures["attrs"].split(' ');
|
let attrs = captures["attrs"].split(' ');
|
||||||
for attr in attrs {
|
for attr in attrs {
|
||||||
|
@ -128,7 +128,7 @@ pub fn parse_symbol_line(line: &str, obj: &mut ObjInfo) -> Result<Option<ObjSymb
|
||||||
symbol.flags.0 |= ObjSymbolFlags::Hidden;
|
symbol.flags.0 |= ObjSymbolFlags::Hidden;
|
||||||
}
|
}
|
||||||
"force_active" => {
|
"force_active" => {
|
||||||
symbol.flags.0 |= ObjSymbolFlags::ForceActive;
|
symbol.flags.0 |= ObjSymbolFlags::Exported;
|
||||||
}
|
}
|
||||||
"stripped" => {
|
"stripped" => {
|
||||||
symbol.flags.0 |= ObjSymbolFlags::Stripped;
|
symbol.flags.0 |= ObjSymbolFlags::Stripped;
|
||||||
|
@ -147,6 +147,9 @@ pub fn parse_symbol_line(line: &str, obj: &mut ObjInfo) -> Result<Option<ObjSymb
|
||||||
let addr = SectionAddress::new(section.unwrap(), symbol.address as u32);
|
let addr = SectionAddress::new(section.unwrap(), symbol.address as u32);
|
||||||
obj.blocked_ranges.insert(addr, addr.address + symbol.size as u32);
|
obj.blocked_ranges.insert(addr, addr.address + symbol.size as u32);
|
||||||
}
|
}
|
||||||
|
"noexport" => {
|
||||||
|
symbol.flags.0 |= ObjSymbolFlags::NoExport;
|
||||||
|
}
|
||||||
_ => bail!("Unknown symbol attribute '{attr}'"),
|
_ => bail!("Unknown symbol attribute '{attr}'"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -281,6 +284,9 @@ where W: Write + ?Sized {
|
||||||
write!(w, " noreloc")?;
|
write!(w, " noreloc")?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if symbol.flags.is_no_export() {
|
||||||
|
write!(w, " noexport")?;
|
||||||
|
}
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,7 +346,7 @@ where P: AsRef<Path> {
|
||||||
Ok(obj)
|
Ok(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_elf(obj: &ObjInfo, force_active: bool) -> Result<Vec<u8>> {
|
pub fn write_elf(obj: &ObjInfo, export_all: bool) -> Result<Vec<u8>> {
|
||||||
let mut out_data = Vec::new();
|
let mut out_data = Vec::new();
|
||||||
let mut writer = object::write::elf::Writer::new(Endianness::Big, false, &mut out_data);
|
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<Vec<u8>> {
|
||||||
out_symbols.push(OutSymbol { index, sym });
|
out_symbols.push(OutSymbol { index, sym });
|
||||||
symbol_map[symbol_index] = Some(index.0);
|
symbol_map[symbol_index] = Some(index.0);
|
||||||
if let Some(comment_data) = &mut comment_data {
|
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)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,7 @@ pub fn generate_ldscript(
|
||||||
|
|
||||||
let mut force_active = force_active.to_vec();
|
let mut force_active = force_active.to_vec();
|
||||||
for symbol in obj.symbols.iter() {
|
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());
|
force_active.push(symbol.name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,8 +97,7 @@ pub fn generate_ldscript_partial(
|
||||||
|
|
||||||
let mut force_active = force_active.to_vec();
|
let mut force_active = force_active.to_vec();
|
||||||
for symbol in obj.symbols.iter() {
|
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());
|
force_active.push(symbol.name.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -823,7 +823,7 @@ fn add_symbol(obj: &mut ObjInfo, symbol_entry: &SymbolEntry, section: Option<usi
|
||||||
};
|
};
|
||||||
// TODO move somewhere common
|
// TODO move somewhere common
|
||||||
if symbol_entry.name.starts_with("..") {
|
if symbol_entry.name.starts_with("..") {
|
||||||
flags |= ObjSymbolFlags::ForceActive;
|
flags |= ObjSymbolFlags::Exported;
|
||||||
}
|
}
|
||||||
if symbol_entry.unused {
|
if symbol_entry.unused {
|
||||||
flags |= ObjSymbolFlags::Stripped;
|
flags |= ObjSymbolFlags::Stripped;
|
||||||
|
|
|
@ -563,7 +563,7 @@ fn add_padding_symbols(obj: &mut ObjInfo) -> Result<()> {
|
||||||
size: next_symbol_address - addr as u64,
|
size: next_symbol_address - addr as u64,
|
||||||
size_known: true,
|
size_known: true,
|
||||||
flags: ObjSymbolFlagSet(
|
flags: ObjSymbolFlagSet(
|
||||||
ObjSymbolFlags::Local | ObjSymbolFlags::ForceActive | ObjSymbolFlags::NoWrite,
|
ObjSymbolFlags::Local | ObjSymbolFlags::Exported | ObjSymbolFlags::NoWrite,
|
||||||
),
|
),
|
||||||
kind: match section.kind {
|
kind: match section.kind {
|
||||||
ObjSectionKind::Code => ObjSymbolKind::Function,
|
ObjSectionKind::Code => ObjSymbolKind::Function,
|
||||||
|
@ -616,7 +616,7 @@ fn add_padding_symbols(obj: &mut ObjInfo) -> Result<()> {
|
||||||
flags: ObjSymbolFlagSet(
|
flags: ObjSymbolFlagSet(
|
||||||
ObjSymbolFlags::Global
|
ObjSymbolFlags::Global
|
||||||
| ObjSymbolFlags::Hidden
|
| ObjSymbolFlags::Hidden
|
||||||
| ObjSymbolFlags::ForceActive
|
| ObjSymbolFlags::Exported
|
||||||
| ObjSymbolFlags::NoWrite,
|
| ObjSymbolFlags::NoWrite,
|
||||||
),
|
),
|
||||||
kind: match section.kind {
|
kind: match section.kind {
|
||||||
|
|
Loading…
Reference in New Issue