From fbf85632ab73ff1de14b13deb9c1d94c36982693 Mon Sep 17 00:00:00 2001 From: LagoLunatic Date: Thu, 17 Apr 2025 01:33:55 -0400 Subject: [PATCH] PPC: Detect unpooled string literal references (#188) * Update openssl and tokio for Cargo deny * PPC: Detect unpooled string literal references --- Cargo.lock | 22 +++++++++++----------- objdiff-core/src/arch/mod.rs | 8 +++++++- objdiff-core/src/arch/ppc.rs | 13 +++++++++++-- objdiff-core/src/diff/code.rs | 1 + objdiff-core/src/diff/display.rs | 7 ++++--- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d084c22..4bcd2e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1427,7 +1427,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3458,9 +3458,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.71" +version = "0.10.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" dependencies = [ "bitflags 2.9.0", "cfg-if", @@ -3490,9 +3490,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.106" +version = "0.9.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" dependencies = [ "cc", "libc", @@ -3921,7 +3921,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4353,7 +4353,7 @@ dependencies = [ "errno 0.3.10", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4366,7 +4366,7 @@ dependencies = [ "errno 0.3.10", "libc", "linux-raw-sys 0.9.3", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4973,7 +4973,7 @@ dependencies = [ "getrandom 0.3.2", "once_cell", "rustix 1.0.5", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -5131,9 +5131,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.44.1" +version = "1.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" dependencies = [ "backtrace", "bytes", diff --git a/objdiff-core/src/arch/mod.rs b/objdiff-core/src/arch/mod.rs index f2cfa90..c033ef3 100644 --- a/objdiff-core/src/arch/mod.rs +++ b/objdiff-core/src/arch/mod.rs @@ -247,7 +247,13 @@ pub trait Arch: Send + Sync + Debug { SymbolFlagSet::default() } - fn guess_data_type(&self, _resolved: ResolvedInstructionRef) -> Option { None } + fn guess_data_type( + &self, + _resolved: ResolvedInstructionRef, + _bytes: &[u8], + ) -> Option { + None + } fn symbol_hover(&self, _obj: &Object, _symbol_index: usize) -> Vec { Vec::new() } diff --git a/objdiff-core/src/arch/ppc.rs b/objdiff-core/src/arch/ppc.rs index fed7b01..3e2a3c8 100644 --- a/objdiff-core/src/arch/ppc.rs +++ b/objdiff-core/src/arch/ppc.rs @@ -221,12 +221,21 @@ impl Arch for ArchPpc { } } - fn guess_data_type(&self, resolved: ResolvedInstructionRef) -> Option { + fn guess_data_type(&self, resolved: ResolvedInstructionRef, bytes: &[u8]) -> Option { if resolved.relocation.is_some_and(|r| r.symbol.name.starts_with("@stringBase")) { + // Pooled string. return Some(DataType::String); } let opcode = ppc750cl::Opcode::from(resolved.ins_ref.opcode as u8); - guess_data_type_from_load_store_inst_op(opcode) + if let Some(ty) = guess_data_type_from_load_store_inst_op(opcode) { + // Numeric type. + return Some(ty); + } + if bytes.len() >= 2 && bytes.iter().position(|&c| c == b'\0') == Some(bytes.len() - 1) { + // It may be an unpooled string if the symbol contains exactly one null byte at the end of the symbol. + return Some(DataType::String); + } + None } fn symbol_hover(&self, _obj: &Object, symbol_index: usize) -> Vec { diff --git a/objdiff-core/src/diff/code.rs b/objdiff-core/src/diff/code.rs index a42a329..97a1b13 100644 --- a/objdiff-core/src/diff/code.rs +++ b/objdiff-core/src/diff/code.rs @@ -330,6 +330,7 @@ fn reloc_eq( || address_eq(left_reloc, right_reloc)) && (diff_config.function_reloc_diffs == FunctionRelocDiffs::NameAddress || left_reloc.symbol.kind != SymbolKind::Object + || right_reloc.symbol.size == 0 // Likely a pool symbol like ...data, don't treat this as a diff || display_ins_data_literals(left_obj, left_ins) == display_ins_data_literals(right_obj, right_ins)) } diff --git a/objdiff-core/src/diff/display.rs b/objdiff-core/src/diff/display.rs index 193ae68..790b458 100644 --- a/objdiff-core/src/diff/display.rs +++ b/objdiff-core/src/diff/display.rs @@ -564,7 +564,8 @@ pub fn instruction_hover( if let Some(reloc) = resolved.relocation { out.push(HoverItem::Separator); out.append(&mut relocation_hover(obj, reloc, None)); - if let Some(ty) = obj.arch.guess_data_type(resolved) { + let bytes = obj.symbol_data(reloc.relocation.target_symbol).unwrap_or(&[]); + if let Some(ty) = obj.arch.guess_data_type(resolved, bytes) { let literals = display_ins_data_literals(obj, resolved); if !literals.is_empty() { out.push(HoverItem::Separator); @@ -758,7 +759,7 @@ pub fn display_ins_data_labels(obj: &Object, resolved: ResolvedInstructionRef) - }; let bytes = &data[reloc.relocation.addend as usize..]; obj.arch - .guess_data_type(resolved) + .guess_data_type(resolved, bytes) .map(|ty| ty.display_labels(obj.endianness, bytes)) .unwrap_or_default() } @@ -775,7 +776,7 @@ pub fn display_ins_data_literals(obj: &Object, resolved: ResolvedInstructionRef) }; let bytes = &data[reloc.relocation.addend as usize..]; obj.arch - .guess_data_type(resolved) + .guess_data_type(resolved, bytes) .map(|ty| ty.display_literals(obj.endianness, bytes)) .unwrap_or_default() }