diff --git a/crates/rk/src/sections.rs b/crates/rk/src/sections.rs index b283a24..1daedd3 100644 --- a/crates/rk/src/sections.rs +++ b/crates/rk/src/sections.rs @@ -219,6 +219,11 @@ impl Named { if name.is_empty() || name.starts_with(".L") { continue; } + let name = if symbol.is_local() { + unnumbered(name) + } else { + name + }; by_section.entry(section.0).or_default().push(( symbol.address(), symbol.size(), @@ -240,6 +245,19 @@ impl Named { } } +/// A local name without the number a compiler puts after it to tell apart the function-local +/// statics of one name, `___once_key.35`, which each compiler counts its own way. +fn unnumbered(name: &str) -> &str { + match name.rsplit_once('.') { + Some((stem, n)) + if !stem.is_empty() && !n.is_empty() && n.bytes().all(|b| b.is_ascii_digit()) => + { + stem + } + _ => name, + } +} + /// What a relocation in a table entry points at, written so that it reads the same in both /// builds: a string by its text, data by the symbol it falls in, and anything else by section /// and offset. `None` for code, since where code lands is the compiler's business. @@ -336,6 +354,7 @@ fn distinct( }) .unwrap_or_default(), ".altinstructions" => entry.get(8..12).unwrap_or_default().to_vec(), + "__jump_table" => Vec::new(), _ => entry .iter() .enumerate() @@ -657,6 +676,10 @@ mod tests { Some(".initcall6.init") ); assert_eq!(table_of(".text"), None); + assert_eq!(unnumbered("___once_key.35"), "___once_key"); + assert_eq!(unnumbered("x.constprop.0"), "x.constprop"); + assert_eq!(unnumbered("version.3a"), "version.3a"); + assert_eq!(unnumbered(".7"), ".7"); } fn object(sites: usize, jump: usize, license: &str) -> Vec {