mirror of
https://github.com/encounter/objdiff.git
synced 2025-10-05 09:29:51 +00:00
[MIPS] Fix symbols being filtered out from target side of diff if target object contains .NON_MATCHING
markers (#250)
* Fix filtering out symbols from the target side that have a symbol with the same name and a `.NON_MATCHING` suffix. - Target side: Show all the symbols except the `.NON_MATCHING` ones. - Base side: Ignore all the `.NON_MATCHING` symbols and also ignore the ones with the same name without the suffix * fmt * comment * tests * fmt tests * maybe this could fix wasm? * Fix wasm? * fmt * Move `DiffSide` to `diff` mod * Update the stuff the advisories CI told me to
This commit is contained in:
parent
a138dfa907
commit
6fb4bb8855
@ -8,8 +8,8 @@ use objdiff_core::{
|
|||||||
Report, ReportCategory, ReportItem, ReportItemMetadata, ReportUnit, ReportUnitMetadata,
|
Report, ReportCategory, ReportItem, ReportItemMetadata, ReportUnit, ReportUnitMetadata,
|
||||||
},
|
},
|
||||||
config::path::platform_path,
|
config::path::platform_path,
|
||||||
diff, obj,
|
diff,
|
||||||
obj::{SectionKind, SymbolFlag},
|
obj::{self, SectionKind, SymbolFlag},
|
||||||
};
|
};
|
||||||
use prost::Message;
|
use prost::Message;
|
||||||
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
@ -177,14 +177,16 @@ fn report_object(
|
|||||||
.target_path
|
.target_path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
obj::read::read(p.as_ref(), diff_config).with_context(|| format!("Failed to open {p}"))
|
obj::read::read(p.as_ref(), diff_config, diff::DiffSide::Target)
|
||||||
|
.with_context(|| format!("Failed to open {p}"))
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
let base = object
|
let base = object
|
||||||
.base_path
|
.base_path
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
obj::read::read(p.as_ref(), diff_config).with_context(|| format!("Failed to open {p}"))
|
obj::read::read(p.as_ref(), diff_config, diff::DiffSide::Base)
|
||||||
|
.with_context(|| format!("Failed to open {p}"))
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
let result =
|
let result =
|
||||||
|
@ -12,7 +12,7 @@ use rabbitizer::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{Arch, RelocationOverride, RelocationOverrideTarget},
|
arch::{Arch, RelocationOverride, RelocationOverrideTarget},
|
||||||
diff::{DiffObjConfig, MipsAbi, MipsInstrCategory, display::InstructionPart},
|
diff::{DiffObjConfig, DiffSide, MipsAbi, MipsInstrCategory, display::InstructionPart},
|
||||||
obj::{
|
obj::{
|
||||||
InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags,
|
InstructionArg, InstructionArgValue, InstructionRef, Relocation, RelocationFlags,
|
||||||
ResolvedInstructionRef, ResolvedRelocation, Section, Symbol, SymbolFlag, SymbolFlagSet,
|
ResolvedInstructionRef, ResolvedRelocation, Section, Symbol, SymbolFlag, SymbolFlagSet,
|
||||||
@ -27,6 +27,7 @@ pub struct ArchMips {
|
|||||||
pub ri_gp_value: i32,
|
pub ri_gp_value: i32,
|
||||||
pub paired_relocations: Vec<BTreeMap<u64, i64>>,
|
pub paired_relocations: Vec<BTreeMap<u64, i64>>,
|
||||||
pub ignored_symbols: BTreeSet<usize>,
|
pub ignored_symbols: BTreeSet<usize>,
|
||||||
|
pub diff_side: DiffSide,
|
||||||
}
|
}
|
||||||
|
|
||||||
const EF_MIPS_ABI: u32 = 0x0000F000;
|
const EF_MIPS_ABI: u32 = 0x0000F000;
|
||||||
@ -38,7 +39,7 @@ const EF_MIPS_MACH_5900: u32 = 0x00920000;
|
|||||||
const R_MIPS15_S3: u32 = 119;
|
const R_MIPS15_S3: u32 = 119;
|
||||||
|
|
||||||
impl ArchMips {
|
impl ArchMips {
|
||||||
pub fn new(object: &object::File) -> Result<Self> {
|
pub fn new(object: &object::File, diff_side: DiffSide) -> Result<Self> {
|
||||||
let mut abi = Abi::O32;
|
let mut abi = Abi::O32;
|
||||||
let mut isa_extension = None;
|
let mut isa_extension = None;
|
||||||
match object.flags() {
|
match object.flags() {
|
||||||
@ -124,7 +125,11 @@ impl ArchMips {
|
|||||||
let Ok(name) = obj_symbol.name() else { continue };
|
let Ok(name) = obj_symbol.name() else { continue };
|
||||||
if let Some(prefix) = name.strip_suffix(".NON_MATCHING") {
|
if let Some(prefix) = name.strip_suffix(".NON_MATCHING") {
|
||||||
ignored_symbols.insert(obj_symbol.index().0);
|
ignored_symbols.insert(obj_symbol.index().0);
|
||||||
if let Some(target_symbol) = object.symbol_by_name(prefix) {
|
// Only remove the prefixless symbols if we are on the Base side of the diff,
|
||||||
|
// to allow diffing against target objects that contain `.NON_MATCHING` markers.
|
||||||
|
if diff_side == DiffSide::Base
|
||||||
|
&& let Some(target_symbol) = object.symbol_by_name(prefix)
|
||||||
|
{
|
||||||
ignored_symbols.insert(target_symbol.index().0);
|
ignored_symbols.insert(target_symbol.index().0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,6 +142,7 @@ impl ArchMips {
|
|||||||
ri_gp_value,
|
ri_gp_value,
|
||||||
paired_relocations,
|
paired_relocations,
|
||||||
ignored_symbols,
|
ignored_symbols,
|
||||||
|
diff_side,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ use object::Endian as _;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
diff::{
|
diff::{
|
||||||
DiffObjConfig,
|
DiffObjConfig, DiffSide,
|
||||||
display::{ContextItem, HoverItem, InstructionPart},
|
display::{ContextItem, HoverItem, InstructionPart},
|
||||||
},
|
},
|
||||||
obj::{
|
obj::{
|
||||||
@ -418,15 +418,18 @@ pub trait Arch: Any + Debug + Send + Sync {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_arch(object: &object::File) -> Result<Box<dyn Arch>> {
|
pub fn new_arch(object: &object::File, diff_side: DiffSide) -> Result<Box<dyn Arch>> {
|
||||||
use object::Object as _;
|
use object::Object as _;
|
||||||
|
// Avoid unused warnings on non-mips builds
|
||||||
|
let _ = diff_side;
|
||||||
|
|
||||||
Ok(match object.architecture() {
|
Ok(match object.architecture() {
|
||||||
#[cfg(feature = "ppc")]
|
#[cfg(feature = "ppc")]
|
||||||
object::Architecture::PowerPc | object::Architecture::PowerPc64 => {
|
object::Architecture::PowerPc | object::Architecture::PowerPc64 => {
|
||||||
Box::new(ppc::ArchPpc::new(object)?)
|
Box::new(ppc::ArchPpc::new(object)?)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "mips")]
|
#[cfg(feature = "mips")]
|
||||||
object::Architecture::Mips => Box::new(mips::ArchMips::new(object)?),
|
object::Architecture::Mips => Box::new(mips::ArchMips::new(object, diff_side)?),
|
||||||
#[cfg(feature = "x86")]
|
#[cfg(feature = "x86")]
|
||||||
object::Architecture::I386 | object::Architecture::X86_64 => {
|
object::Architecture::I386 | object::Architecture::X86_64 => {
|
||||||
Box::new(x86::ArchX86::new(object)?)
|
Box::new(x86::ArchX86::new(object)?)
|
||||||
|
@ -807,3 +807,11 @@ fn find_section(
|
|||||||
s.kind == section_kind && s.name == name && !matches.iter().any(|m| m.right == Some(i))
|
s.kind == section_kind && s.name == name && !matches.iter().any(|m| m.right == Some(i))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub enum DiffSide {
|
||||||
|
/// The target/expected side of the diff.
|
||||||
|
Target,
|
||||||
|
/// The base side of the diff.
|
||||||
|
Base,
|
||||||
|
}
|
||||||
|
@ -6,7 +6,7 @@ use typed_path::Utf8PlatformPathBuf;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
build::{BuildConfig, BuildStatus, run_make},
|
build::{BuildConfig, BuildStatus, run_make},
|
||||||
diff::{DiffObjConfig, MappingConfig, ObjectDiff, diff_objs},
|
diff::{DiffObjConfig, DiffSide, MappingConfig, ObjectDiff, diff_objs},
|
||||||
jobs::{Job, JobContext, JobResult, JobState, start_job, update_status},
|
jobs::{Job, JobContext, JobResult, JobState, start_job, update_status},
|
||||||
obj::{Object, read},
|
obj::{Object, read},
|
||||||
};
|
};
|
||||||
@ -117,7 +117,7 @@ fn run_build(
|
|||||||
&cancel,
|
&cancel,
|
||||||
)?;
|
)?;
|
||||||
step_idx += 1;
|
step_idx += 1;
|
||||||
match read::read(target_path.as_ref(), &config.diff_obj_config) {
|
match read::read(target_path.as_ref(), &config.diff_obj_config, DiffSide::Target) {
|
||||||
Ok(obj) => Some(obj),
|
Ok(obj) => Some(obj),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
first_status = BuildStatus {
|
first_status = BuildStatus {
|
||||||
@ -141,7 +141,7 @@ fn run_build(
|
|||||||
Some(base_path) if second_status.success => {
|
Some(base_path) if second_status.success => {
|
||||||
update_status(context, format!("Loading base {base_path}"), step_idx, total, &cancel)?;
|
update_status(context, format!("Loading base {base_path}"), step_idx, total, &cancel)?;
|
||||||
step_idx += 1;
|
step_idx += 1;
|
||||||
match read::read(base_path.as_ref(), &config.diff_obj_config) {
|
match read::read(base_path.as_ref(), &config.diff_obj_config, DiffSide::Base) {
|
||||||
Ok(obj) => Some(obj),
|
Ok(obj) => Some(obj),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
second_status = BuildStatus {
|
second_status = BuildStatus {
|
||||||
|
@ -12,7 +12,7 @@ use object::{Object as _, ObjectSection as _, ObjectSymbol as _};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{Arch, RelocationOverride, RelocationOverrideTarget, new_arch},
|
arch::{Arch, RelocationOverride, RelocationOverrideTarget, new_arch},
|
||||||
diff::DiffObjConfig,
|
diff::{DiffObjConfig, DiffSide},
|
||||||
obj::{
|
obj::{
|
||||||
FlowAnalysisResult, Object, Relocation, RelocationFlags, Section, SectionData, SectionFlag,
|
FlowAnalysisResult, Object, Relocation, RelocationFlags, Section, SectionData, SectionFlag,
|
||||||
SectionKind, Symbol, SymbolFlag, SymbolKind,
|
SectionKind, Symbol, SymbolFlag, SymbolKind,
|
||||||
@ -925,21 +925,25 @@ fn do_combine_sections(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
pub fn read(obj_path: &std::path::Path, config: &DiffObjConfig) -> Result<Object> {
|
pub fn read(
|
||||||
|
obj_path: &std::path::Path,
|
||||||
|
config: &DiffObjConfig,
|
||||||
|
diff_side: DiffSide,
|
||||||
|
) -> Result<Object> {
|
||||||
let (data, timestamp) = {
|
let (data, timestamp) = {
|
||||||
let file = std::fs::File::open(obj_path)?;
|
let file = std::fs::File::open(obj_path)?;
|
||||||
let timestamp = filetime::FileTime::from_last_modification_time(&file.metadata()?);
|
let timestamp = filetime::FileTime::from_last_modification_time(&file.metadata()?);
|
||||||
(unsafe { memmap2::Mmap::map(&file) }?, timestamp)
|
(unsafe { memmap2::Mmap::map(&file) }?, timestamp)
|
||||||
};
|
};
|
||||||
let mut obj = parse(&data, config)?;
|
let mut obj = parse(&data, config, diff_side)?;
|
||||||
obj.path = Some(obj_path.to_path_buf());
|
obj.path = Some(obj_path.to_path_buf());
|
||||||
obj.timestamp = Some(timestamp);
|
obj.timestamp = Some(timestamp);
|
||||||
Ok(obj)
|
Ok(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse(data: &[u8], config: &DiffObjConfig) -> Result<Object> {
|
pub fn parse(data: &[u8], config: &DiffObjConfig, diff_side: DiffSide) -> Result<Object> {
|
||||||
let obj_file = object::File::parse(data)?;
|
let obj_file = object::File::parse(data)?;
|
||||||
let mut arch = new_arch(&obj_file)?;
|
let mut arch = new_arch(&obj_file, diff_side)?;
|
||||||
let split_meta = parse_split_meta(&obj_file)?;
|
let split_meta = parse_split_meta(&obj_file)?;
|
||||||
let (mut sections, section_indices) =
|
let (mut sections, section_indices) =
|
||||||
map_sections(arch.as_ref(), &obj_file, split_meta.as_ref())?;
|
map_sections(arch.as_ref(), &obj_file, split_meta.as_ref())?;
|
||||||
|
@ -6,7 +6,12 @@ mod common;
|
|||||||
#[cfg(feature = "arm")]
|
#[cfg(feature = "arm")]
|
||||||
fn read_arm() {
|
fn read_arm() {
|
||||||
let diff_config = diff::DiffObjConfig { ..Default::default() };
|
let diff_config = diff::DiffObjConfig { ..Default::default() };
|
||||||
let obj = obj::read::parse(include_object!("data/arm/LinkStateItem.o"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/arm/LinkStateItem.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
let symbol_idx =
|
let symbol_idx =
|
||||||
obj.symbols.iter().position(|s| s.name == "_ZN13LinkStateItem12OnStateLeaveEi").unwrap();
|
obj.symbols.iter().position(|s| s.name == "_ZN13LinkStateItem12OnStateLeaveEi").unwrap();
|
||||||
@ -20,7 +25,9 @@ fn read_arm() {
|
|||||||
#[cfg(feature = "arm")]
|
#[cfg(feature = "arm")]
|
||||||
fn read_thumb() {
|
fn read_thumb() {
|
||||||
let diff_config = diff::DiffObjConfig { ..Default::default() };
|
let diff_config = diff::DiffObjConfig { ..Default::default() };
|
||||||
let obj = obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config).unwrap();
|
let obj =
|
||||||
|
obj::read::parse(include_object!("data/arm/thumb.o"), &diff_config, diff::DiffSide::Base)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
let symbol_idx = obj
|
let symbol_idx = obj
|
||||||
.symbols
|
.symbols
|
||||||
@ -37,7 +44,12 @@ fn read_thumb() {
|
|||||||
#[cfg(feature = "arm")]
|
#[cfg(feature = "arm")]
|
||||||
fn combine_text_sections() {
|
fn combine_text_sections() {
|
||||||
let diff_config = diff::DiffObjConfig { combine_text_sections: true, ..Default::default() };
|
let diff_config = diff::DiffObjConfig { combine_text_sections: true, ..Default::default() };
|
||||||
let obj = obj::read::parse(include_object!("data/arm/enemy300.o"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/arm/enemy300.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
let symbol_idx = obj.symbols.iter().position(|s| s.name == "Enemy300Draw").unwrap();
|
let symbol_idx = obj.symbols.iter().position(|s| s.name == "Enemy300Draw").unwrap();
|
||||||
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
|
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
|
||||||
insta::assert_debug_snapshot!(diff.instruction_rows);
|
insta::assert_debug_snapshot!(diff.instruction_rows);
|
||||||
|
@ -6,7 +6,9 @@ mod common;
|
|||||||
#[cfg(feature = "mips")]
|
#[cfg(feature = "mips")]
|
||||||
fn read_mips() {
|
fn read_mips() {
|
||||||
let diff_config = diff::DiffObjConfig { mips_register_prefix: true, ..Default::default() };
|
let diff_config = diff::DiffObjConfig { mips_register_prefix: true, ..Default::default() };
|
||||||
let obj = obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config).unwrap();
|
let obj =
|
||||||
|
obj::read::parse(include_object!("data/mips/main.c.o"), &diff_config, diff::DiffSide::Base)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
let symbol_idx = obj.symbols.iter().position(|s| s.name == "ControlEntry").unwrap();
|
let symbol_idx = obj.symbols.iter().position(|s| s.name == "ControlEntry").unwrap();
|
||||||
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
|
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
|
||||||
@ -19,9 +21,19 @@ fn read_mips() {
|
|||||||
#[cfg(feature = "mips")]
|
#[cfg(feature = "mips")]
|
||||||
fn cross_endian_diff() {
|
fn cross_endian_diff() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj_be = obj::read::parse(include_object!("data/mips/code_be.o"), &diff_config).unwrap();
|
let obj_be = obj::read::parse(
|
||||||
|
include_object!("data/mips/code_be.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
assert_eq!(obj_be.endianness, object::Endianness::Big);
|
assert_eq!(obj_be.endianness, object::Endianness::Big);
|
||||||
let obj_le = obj::read::parse(include_object!("data/mips/code_le.o"), &diff_config).unwrap();
|
let obj_le = obj::read::parse(
|
||||||
|
include_object!("data/mips/code_le.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
assert_eq!(obj_le.endianness, object::Endianness::Little);
|
assert_eq!(obj_le.endianness, object::Endianness::Little);
|
||||||
let left_symbol_idx = obj_be.symbols.iter().position(|s| s.name == "func_00000000").unwrap();
|
let left_symbol_idx = obj_be.symbols.iter().position(|s| s.name == "func_00000000").unwrap();
|
||||||
let right_symbol_idx =
|
let right_symbol_idx =
|
||||||
@ -42,6 +54,11 @@ fn cross_endian_diff() {
|
|||||||
#[cfg(feature = "mips")]
|
#[cfg(feature = "mips")]
|
||||||
fn filter_non_matching() {
|
fn filter_non_matching() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj = obj::read::parse(include_object!("data/mips/vw_main.c.o"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/mips/vw_main.c.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj.symbols);
|
insta::assert_debug_snapshot!(obj.symbols);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,9 @@ mod common;
|
|||||||
#[cfg(feature = "ppc")]
|
#[cfg(feature = "ppc")]
|
||||||
fn read_ppc() {
|
fn read_ppc() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj = obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config).unwrap();
|
let obj =
|
||||||
|
obj::read::parse(include_object!("data/ppc/IObj.o"), &diff_config, diff::DiffSide::Base)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
let symbol_idx =
|
let symbol_idx =
|
||||||
obj.symbols.iter().position(|s| s.name == "Type2Text__10SObjectTagFUi").unwrap();
|
obj.symbols.iter().position(|s| s.name == "Type2Text__10SObjectTagFUi").unwrap();
|
||||||
@ -24,7 +26,12 @@ fn read_ppc() {
|
|||||||
#[cfg(feature = "ppc")]
|
#[cfg(feature = "ppc")]
|
||||||
fn read_dwarf1_line_info() {
|
fn read_dwarf1_line_info() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj = obj::read::parse(include_object!("data/ppc/m_Do_hostIO.o"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/ppc/m_Do_hostIO.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
let line_infos = obj
|
let line_infos = obj
|
||||||
.sections
|
.sections
|
||||||
.iter()
|
.iter()
|
||||||
@ -38,7 +45,12 @@ fn read_dwarf1_line_info() {
|
|||||||
#[cfg(feature = "ppc")]
|
#[cfg(feature = "ppc")]
|
||||||
fn read_extab() {
|
fn read_extab() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj = obj::read::parse(include_object!("data/ppc/NMWException.o"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/ppc/NMWException.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,11 +59,17 @@ fn read_extab() {
|
|||||||
fn diff_ppc() {
|
fn diff_ppc() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let mapping_config = diff::MappingConfig::default();
|
let mapping_config = diff::MappingConfig::default();
|
||||||
let target_obj =
|
let target_obj = obj::read::parse(
|
||||||
obj::read::parse(include_object!("data/ppc/CDamageVulnerability_target.o"), &diff_config)
|
include_object!("data/ppc/CDamageVulnerability_target.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Target,
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let base_obj =
|
let base_obj = obj::read::parse(
|
||||||
obj::read::parse(include_object!("data/ppc/CDamageVulnerability_base.o"), &diff_config)
|
include_object!("data/ppc/CDamageVulnerability_base.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let diff =
|
let diff =
|
||||||
diff::diff_objs(Some(&target_obj), Some(&base_obj), None, &diff_config, &mapping_config)
|
diff::diff_objs(Some(&target_obj), Some(&base_obj), None, &diff_config, &mapping_config)
|
||||||
@ -90,7 +108,12 @@ fn diff_ppc() {
|
|||||||
#[cfg(feature = "ppc")]
|
#[cfg(feature = "ppc")]
|
||||||
fn read_vmx128_coff() {
|
fn read_vmx128_coff() {
|
||||||
let diff_config = diff::DiffObjConfig { combine_data_sections: true, ..Default::default() };
|
let diff_config = diff::DiffObjConfig { combine_data_sections: true, ..Default::default() };
|
||||||
let obj = obj::read::parse(include_object!("data/ppc/vmx128.obj"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/ppc/vmx128.obj"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
let symbol_idx =
|
let symbol_idx =
|
||||||
obj.symbols.iter().position(|s| s.name == "?FloatingPointExample@@YAXXZ").unwrap();
|
obj.symbols.iter().position(|s| s.name == "?FloatingPointExample@@YAXXZ").unwrap();
|
||||||
|
@ -6,7 +6,12 @@ mod common;
|
|||||||
#[cfg(feature = "x86")]
|
#[cfg(feature = "x86")]
|
||||||
fn read_x86() {
|
fn read_x86() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj = obj::read::parse(include_object!("data/x86/staticdebug.obj"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/x86/staticdebug.obj"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
let symbol_idx = obj.symbols.iter().position(|s| s.name == "?PrintThing@@YAXXZ").unwrap();
|
let symbol_idx = obj.symbols.iter().position(|s| s.name == "?PrintThing@@YAXXZ").unwrap();
|
||||||
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
|
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
|
||||||
@ -23,7 +28,9 @@ fn read_x86_combine_sections() {
|
|||||||
combine_text_sections: true,
|
combine_text_sections: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let obj = obj::read::parse(include_object!("data/x86/rtest.obj"), &diff_config).unwrap();
|
let obj =
|
||||||
|
obj::read::parse(include_object!("data/x86/rtest.obj"), &diff_config, diff::DiffSide::Base)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj.sections);
|
insta::assert_debug_snapshot!(obj.sections);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,7 +38,12 @@ fn read_x86_combine_sections() {
|
|||||||
#[cfg(feature = "x86")]
|
#[cfg(feature = "x86")]
|
||||||
fn read_x86_64() {
|
fn read_x86_64() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj = obj::read::parse(include_object!("data/x86_64/vs2022.o"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/x86_64/vs2022.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
let symbol_idx =
|
let symbol_idx =
|
||||||
obj.symbols.iter().position(|s| s.name == "?Dot@Vector@@QEAAMPEAU1@@Z").unwrap();
|
obj.symbols.iter().position(|s| s.name == "?Dot@Vector@@QEAAMPEAU1@@Z").unwrap();
|
||||||
@ -45,7 +57,12 @@ fn read_x86_64() {
|
|||||||
#[cfg(feature = "x86")]
|
#[cfg(feature = "x86")]
|
||||||
fn display_section_ordering() {
|
fn display_section_ordering() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj = obj::read::parse(include_object!("data/x86/basenode.obj"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/x86/basenode.obj"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
let obj_diff =
|
let obj_diff =
|
||||||
diff::diff_objs(Some(&obj), None, None, &diff_config, &diff::MappingConfig::default())
|
diff::diff_objs(Some(&obj), None, None, &diff_config, &diff::MappingConfig::default())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -60,7 +77,12 @@ fn display_section_ordering() {
|
|||||||
#[cfg(feature = "x86")]
|
#[cfg(feature = "x86")]
|
||||||
fn read_x86_jumptable() {
|
fn read_x86_jumptable() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj = obj::read::parse(include_object!("data/x86/jumptable.o"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/x86/jumptable.o"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
let symbol_idx = obj.symbols.iter().position(|s| s.name == "?test@@YAHH@Z").unwrap();
|
let symbol_idx = obj.symbols.iter().position(|s| s.name == "?test@@YAHH@Z").unwrap();
|
||||||
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
|
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
|
||||||
@ -74,6 +96,11 @@ fn read_x86_jumptable() {
|
|||||||
#[cfg(feature = "x86")]
|
#[cfg(feature = "x86")]
|
||||||
fn read_x86_local_labels() {
|
fn read_x86_local_labels() {
|
||||||
let diff_config = diff::DiffObjConfig::default();
|
let diff_config = diff::DiffObjConfig::default();
|
||||||
let obj = obj::read::parse(include_object!("data/x86/local_labels.obj"), &diff_config).unwrap();
|
let obj = obj::read::parse(
|
||||||
|
include_object!("data/x86/local_labels.obj"),
|
||||||
|
&diff_config,
|
||||||
|
diff::DiffSide::Base,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
insta::assert_debug_snapshot!(obj);
|
insta::assert_debug_snapshot!(obj);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
source: objdiff-core/tests/arch_mips.rs
|
source: objdiff-core/tests/arch_mips.rs
|
||||||
|
assertion_line: 10
|
||||||
expression: obj
|
expression: obj
|
||||||
---
|
---
|
||||||
Object {
|
Object {
|
||||||
@ -51,6 +52,7 @@ Object {
|
|||||||
{},
|
{},
|
||||||
],
|
],
|
||||||
ignored_symbols: {},
|
ignored_symbols: {},
|
||||||
|
diff_side: Base,
|
||||||
},
|
},
|
||||||
endianness: Little,
|
endianness: Little,
|
||||||
symbols: [
|
symbols: [
|
||||||
|
@ -24,7 +24,7 @@ wit_bindgen::generate!({
|
|||||||
|
|
||||||
use exports::objdiff::core::{
|
use exports::objdiff::core::{
|
||||||
diff::{
|
diff::{
|
||||||
DiffConfigBorrow, DiffResult, Guest as GuestDiff, GuestDiffConfig, GuestObject,
|
DiffConfigBorrow, DiffResult, DiffSide, Guest as GuestDiff, GuestDiffConfig, GuestObject,
|
||||||
GuestObjectDiff, MappingConfig, Object, ObjectBorrow, ObjectDiff, ObjectDiffBorrow,
|
GuestObjectDiff, MappingConfig, Object, ObjectBorrow, ObjectDiff, ObjectDiffBorrow,
|
||||||
SymbolFlags, SymbolInfo, SymbolKind, SymbolRef,
|
SymbolFlags, SymbolInfo, SymbolKind, SymbolRef,
|
||||||
},
|
},
|
||||||
@ -470,8 +470,21 @@ unsafe impl Sync for ObjectCache {}
|
|||||||
|
|
||||||
static OBJECT_CACHE: ObjectCache = ObjectCache::new();
|
static OBJECT_CACHE: ObjectCache = ObjectCache::new();
|
||||||
|
|
||||||
|
impl From<DiffSide> for objdiff_core::diff::DiffSide {
|
||||||
|
fn from(value: DiffSide) -> Self {
|
||||||
|
match value {
|
||||||
|
DiffSide::Target => Self::Target,
|
||||||
|
DiffSide::Base => Self::Base,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl GuestObject for ResourceObject {
|
impl GuestObject for ResourceObject {
|
||||||
fn parse(data: Vec<u8>, diff_config: DiffConfigBorrow) -> Result<Object, String> {
|
fn parse(
|
||||||
|
data: Vec<u8>,
|
||||||
|
diff_config: DiffConfigBorrow,
|
||||||
|
diff_side: DiffSide,
|
||||||
|
) -> Result<Object, String> {
|
||||||
let hash = xxh3_64(&data);
|
let hash = xxh3_64(&data);
|
||||||
let mut cached = None;
|
let mut cached = None;
|
||||||
OBJECT_CACHE.borrow_mut().retain(|c| {
|
OBJECT_CACHE.borrow_mut().retain(|c| {
|
||||||
@ -487,7 +500,9 @@ impl GuestObject for ResourceObject {
|
|||||||
return Ok(Object::new(ResourceObject(obj, hash)));
|
return Ok(Object::new(ResourceObject(obj, hash)));
|
||||||
}
|
}
|
||||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||||
let obj = Rc::new(obj::read::parse(&data, &diff_config).map_err(|e| e.to_string())?);
|
let obj = Rc::new(
|
||||||
|
obj::read::parse(&data, &diff_config, diff_side.into()).map_err(|e| e.to_string())?,
|
||||||
|
);
|
||||||
OBJECT_CACHE.borrow_mut().push(CachedObject(Rc::downgrade(&obj), hash));
|
OBJECT_CACHE.borrow_mut().push(CachedObject(Rc::downgrade(&obj), hash));
|
||||||
Ok(Object::new(ResourceObject(obj, hash)))
|
Ok(Object::new(ResourceObject(obj, hash)))
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ interface diff {
|
|||||||
parse: static func(
|
parse: static func(
|
||||||
data: list<u8>,
|
data: list<u8>,
|
||||||
config: borrow<diff-config>,
|
config: borrow<diff-config>,
|
||||||
|
side: diff-side,
|
||||||
) -> result<object, string>;
|
) -> result<object, string>;
|
||||||
|
|
||||||
hash: func() -> u64;
|
hash: func() -> u64;
|
||||||
@ -80,6 +81,11 @@ interface diff {
|
|||||||
config: borrow<diff-config>,
|
config: borrow<diff-config>,
|
||||||
mapping: mapping-config,
|
mapping: mapping-config,
|
||||||
) -> result<diff-result, string>;
|
) -> result<diff-result, string>;
|
||||||
|
|
||||||
|
enum diff-side {
|
||||||
|
target,
|
||||||
|
base,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface display {
|
interface display {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user