Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions objdiff-core/src/arch/ppc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,10 @@ impl Arch for ArchPpc {
bytes: &[u8],
) -> Option<DataType> {
if reloc.is_some_and(|r| {
r.symbol.name.starts_with("@stringBase")
|| r.symbol.name.starts_with("@wstringBase")
r.symbol.name.starts_with("@stringBase") // MWCC
|| r.symbol.name.starts_with("@wstringBase") // MWCC
|| r.symbol.name.starts_with("$SG")
|| r.symbol.demangled_name == Some("`string'".to_string())
|| r.symbol.name.starts_with("??_C") // MSVC
}) {
// Compiler-generated symbol name for a string or a pool of strings.
return Some(DataType::String);
Expand Down
8 changes: 3 additions & 5 deletions objdiff-core/src/diff/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
},
obj::{
InstructionRef, Object, Relocation, ResolvedRelocation, SectionKind, Symbol, SymbolFlag,
SymbolKind,
SymbolKind, read::get_section_base_name,
},
};

Expand Down Expand Up @@ -810,10 +810,8 @@ where

fn symbol_section<'obj>(obj: &'obj Object, symbol: &Symbol) -> Option<(&'obj str, SectionKind)> {
if let Some(section) = symbol.section.and_then(|section_idx| obj.sections.get(section_idx)) {
// Match x86 .rdata$r against .rdata$rs
let section_name =
section.name.split_once('$').map_or(section.name.as_str(), |(prefix, _)| prefix);
Some((section_name, section.kind))
let section_base_name = get_section_base_name(section);
Some((section_base_name, section.kind))
} else if symbol.flags.contains(SymbolFlag::Common) {
Some((".comm", SectionKind::Common))
} else {
Expand Down
30 changes: 19 additions & 11 deletions objdiff-core/src/obj/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,17 @@ fn get_normalized_symbol_name(name: &str) -> Option<String> {
}
}

/// Check if a symbol's name is entirely compiler-generated, such as @1234 or _$E1234.
/// Check if a symbol's name is entirely compiler-generated (e.g. for a literal).
/// This enables pairing these symbols up by their value instead of their name.
fn is_symbol_name_compiler_generated(name: &str) -> bool {
if name.starts_with('@') && name[1..].chars().all(char::is_numeric) {
// Exclude @stringBase0, @GUARD@, etc.
// Match Metrowerks @1234 against @2345
return true;
} else if (name.starts_with("_$E") || name.starts_with("$LC"))
&& name[3..].chars().all(char::is_numeric)
{
} else if name.starts_with("_$E") && name[3..].chars().all(char::is_numeric) {
// Match MSVC _$E1234 against _$E2345
return true;
} else if name.starts_with("$LC") && name[3..].chars().all(char::is_numeric) {
// Match GCC $LC1234 against $LC2345
return true;
}
false
Expand Down Expand Up @@ -926,6 +928,17 @@ fn parse_line_info_coff(
Ok(())
}

pub fn get_section_base_name(section: &Section) -> &str {
// Match MSVC x86 .rdata$r against .rdata$rs
// Match GCC i._ZN14class_00acb578C1Ev against i [combined]
section
.name
.get(1..)
.and_then(|s| s.rfind(['$', '.']))
.and_then(|i| section.name.get(..i + 1))
.unwrap_or(&section.name)
}

fn combine_sections(
sections: &mut [Section],
symbols: &mut [Symbol],
Expand All @@ -934,12 +947,7 @@ fn combine_sections(
let mut data_sections = BTreeMap::<String, Vec<usize>>::new();
let mut text_sections = BTreeMap::<String, Vec<usize>>::new();
for (i, section) in sections.iter().enumerate() {
let base_name = section
.name
.get(1..)
.and_then(|s| s.rfind(['$', '.']))
.and_then(|i| section.name.get(..i + 1))
.unwrap_or(&section.name);
let base_name = get_section_base_name(section);
match section.kind {
SectionKind::Data | SectionKind::Bss => {
data_sections.entry(base_name.to_string()).or_default().push(i);
Expand Down
Loading