mirror of https://github.com/encounter/objdiff.git
objdiff-core API adjustments
- Allows using process_code without constructing an ObjInfo - Allows creating an arch without having to provide an object Used in decomp-toolkit
This commit is contained in:
parent
0ea6242669
commit
3f82c1a50f
|
@ -1,4 +1,4 @@
|
||||||
use std::{borrow::Cow, sync::Mutex};
|
use std::{borrow::Cow, collections::BTreeMap, sync::Mutex};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
use object::{elf, Endian, Endianness, File, FileFlags, Object, Relocation, RelocationFlags};
|
use object::{elf, Endian, Endianness, File, FileFlags, Object, Relocation, RelocationFlags};
|
||||||
|
@ -7,7 +7,7 @@ use rabbitizer::{config, Abi, InstrCategory, Instruction, OperandType};
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{ObjArch, ProcessCodeResult},
|
arch::{ObjArch, ProcessCodeResult},
|
||||||
diff::{DiffObjConfig, MipsAbi, MipsInstrCategory},
|
diff::{DiffObjConfig, MipsAbi, MipsInstrCategory},
|
||||||
obj::{ObjInfo, ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection, SymbolRef},
|
obj::{ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection},
|
||||||
};
|
};
|
||||||
|
|
||||||
static RABBITIZER_MUTEX: Mutex<()> = Mutex::new(());
|
static RABBITIZER_MUTEX: Mutex<()> = Mutex::new(());
|
||||||
|
@ -57,15 +57,12 @@ impl ObjArchMips {
|
||||||
impl ObjArch for ObjArchMips {
|
impl ObjArch for ObjArchMips {
|
||||||
fn process_code(
|
fn process_code(
|
||||||
&self,
|
&self,
|
||||||
obj: &ObjInfo,
|
address: u64,
|
||||||
symbol_ref: SymbolRef,
|
code: &[u8],
|
||||||
|
relocations: &[ObjReloc],
|
||||||
|
line_info: &BTreeMap<u64, u64>,
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ProcessCodeResult> {
|
) -> Result<ProcessCodeResult> {
|
||||||
let (section, symbol) = obj.section_symbol(symbol_ref);
|
|
||||||
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
|
|
||||||
let code = §ion.data
|
|
||||||
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
|
|
||||||
|
|
||||||
let _guard = RABBITIZER_MUTEX.lock().map_err(|e| anyhow!("Failed to lock mutex: {e}"))?;
|
let _guard = RABBITIZER_MUTEX.lock().map_err(|e| anyhow!("Failed to lock mutex: {e}"))?;
|
||||||
configure_rabbitizer(match config.mips_abi {
|
configure_rabbitizer(match config.mips_abi {
|
||||||
MipsAbi::Auto => self.abi,
|
MipsAbi::Auto => self.abi,
|
||||||
|
@ -82,14 +79,14 @@ impl ObjArch for ObjArchMips {
|
||||||
MipsInstrCategory::R5900 => InstrCategory::R5900,
|
MipsInstrCategory::R5900 => InstrCategory::R5900,
|
||||||
};
|
};
|
||||||
|
|
||||||
let start_address = symbol.address;
|
let start_address = address;
|
||||||
let end_address = symbol.address + symbol.size;
|
let end_address = address + code.len() as u64;
|
||||||
let ins_count = code.len() / 4;
|
let ins_count = code.len() / 4;
|
||||||
let mut ops = Vec::<u16>::with_capacity(ins_count);
|
let mut ops = Vec::<u16>::with_capacity(ins_count);
|
||||||
let mut insts = Vec::<ObjIns>::with_capacity(ins_count);
|
let mut insts = Vec::<ObjIns>::with_capacity(ins_count);
|
||||||
let mut cur_addr = start_address as u32;
|
let mut cur_addr = start_address as u32;
|
||||||
for chunk in code.chunks_exact(4) {
|
for chunk in code.chunks_exact(4) {
|
||||||
let reloc = section.relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
|
let reloc = relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
|
||||||
let code = self.endianness.read_u32_bytes(chunk.try_into()?);
|
let code = self.endianness.read_u32_bytes(chunk.try_into()?);
|
||||||
let instruction = Instruction::new(code, cur_addr, instr_category);
|
let instruction = Instruction::new(code, cur_addr, instr_category);
|
||||||
|
|
||||||
|
@ -155,7 +152,7 @@ impl ObjArch for ObjArchMips {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let line = section.line_info.range(..=cur_addr as u64).last().map(|(_, &b)| b);
|
let line = line_info.range(..=cur_addr as u64).last().map(|(_, &b)| b);
|
||||||
insts.push(ObjIns {
|
insts.push(ObjIns {
|
||||||
address: cur_addr as u64,
|
address: cur_addr as u64,
|
||||||
size: 4,
|
size: 4,
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
use std::borrow::Cow;
|
use std::{borrow::Cow, collections::BTreeMap};
|
||||||
|
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use object::{Architecture, Object, Relocation, RelocationFlags};
|
use object::{Architecture, Object, Relocation, RelocationFlags};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
diff::DiffObjConfig,
|
diff::DiffObjConfig,
|
||||||
obj::{ObjInfo, ObjIns, ObjSection, SymbolRef},
|
obj::{ObjIns, ObjReloc, ObjSection},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "mips")]
|
#[cfg(feature = "mips")]
|
||||||
mod mips;
|
pub mod mips;
|
||||||
#[cfg(feature = "ppc")]
|
#[cfg(feature = "ppc")]
|
||||||
mod ppc;
|
pub mod ppc;
|
||||||
#[cfg(feature = "x86")]
|
#[cfg(feature = "x86")]
|
||||||
mod x86;
|
pub mod x86;
|
||||||
|
|
||||||
pub trait ObjArch: Send + Sync {
|
pub trait ObjArch: Send + Sync {
|
||||||
fn process_code(
|
fn process_code(
|
||||||
&self,
|
&self,
|
||||||
obj: &ObjInfo,
|
address: u64,
|
||||||
symbol_ref: SymbolRef,
|
code: &[u8],
|
||||||
|
relocations: &[ObjReloc],
|
||||||
|
line_info: &BTreeMap<u64, u64>,
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ProcessCodeResult>;
|
) -> Result<ProcessCodeResult>;
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use std::borrow::Cow;
|
use std::{borrow::Cow, collections::BTreeMap};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use object::{elf, File, Relocation, RelocationFlags};
|
use object::{elf, File, Relocation, RelocationFlags};
|
||||||
use ppc750cl::{Argument, InsIter, GPR};
|
use ppc750cl::{Argument, InsIter, GPR};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{ObjArch, ProcessCodeResult},
|
arch::{ObjArch, ProcessCodeResult},
|
||||||
diff::DiffObjConfig,
|
diff::DiffObjConfig,
|
||||||
obj::{ObjInfo, ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection, SymbolRef},
|
obj::{ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Relative relocation, can be Simm, Offset or BranchDest
|
// Relative relocation, can be Simm, Offset or BranchDest
|
||||||
|
@ -31,20 +31,17 @@ impl ObjArchPpc {
|
||||||
impl ObjArch for ObjArchPpc {
|
impl ObjArch for ObjArchPpc {
|
||||||
fn process_code(
|
fn process_code(
|
||||||
&self,
|
&self,
|
||||||
obj: &ObjInfo,
|
address: u64,
|
||||||
symbol_ref: SymbolRef,
|
code: &[u8],
|
||||||
|
relocations: &[ObjReloc],
|
||||||
|
line_info: &BTreeMap<u64, u64>,
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ProcessCodeResult> {
|
) -> Result<ProcessCodeResult> {
|
||||||
let (section, symbol) = obj.section_symbol(symbol_ref);
|
|
||||||
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
|
|
||||||
let code = §ion.data
|
|
||||||
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
|
|
||||||
|
|
||||||
let ins_count = code.len() / 4;
|
let ins_count = code.len() / 4;
|
||||||
let mut ops = Vec::<u16>::with_capacity(ins_count);
|
let mut ops = Vec::<u16>::with_capacity(ins_count);
|
||||||
let mut insts = Vec::<ObjIns>::with_capacity(ins_count);
|
let mut insts = Vec::<ObjIns>::with_capacity(ins_count);
|
||||||
for (cur_addr, mut ins) in InsIter::new(code, symbol.address as u32) {
|
for (cur_addr, mut ins) in InsIter::new(code, address as u32) {
|
||||||
let reloc = section.relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
|
let reloc = relocations.iter().find(|r| (r.address as u32 & !3) == cur_addr);
|
||||||
if let Some(reloc) = reloc {
|
if let Some(reloc) = reloc {
|
||||||
// Zero out relocations
|
// Zero out relocations
|
||||||
ins.code = match reloc.flags {
|
ins.code = match reloc.flags {
|
||||||
|
@ -133,7 +130,7 @@ impl ObjArch for ObjArchPpc {
|
||||||
}
|
}
|
||||||
|
|
||||||
ops.push(ins.op as u16);
|
ops.push(ins.op as u16);
|
||||||
let line = section.line_info.range(..=cur_addr as u64).last().map(|(_, &b)| b);
|
let line = line_info.range(..=cur_addr as u64).last().map(|(_, &b)| b);
|
||||||
insts.push(ObjIns {
|
insts.push(ObjIns {
|
||||||
address: cur_addr as u64,
|
address: cur_addr as u64,
|
||||||
size: 4,
|
size: 4,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::borrow::Cow;
|
use std::{borrow::Cow, collections::BTreeMap};
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, ensure, Result};
|
use anyhow::{anyhow, bail, ensure, Result};
|
||||||
use iced_x86::{
|
use iced_x86::{
|
||||||
|
@ -11,7 +11,7 @@ use object::{pe, Endian, Endianness, File, Object, Relocation, RelocationFlags};
|
||||||
use crate::{
|
use crate::{
|
||||||
arch::{ObjArch, ProcessCodeResult},
|
arch::{ObjArch, ProcessCodeResult},
|
||||||
diff::{DiffObjConfig, X86Formatter},
|
diff::{DiffObjConfig, X86Formatter},
|
||||||
obj::{ObjInfo, ObjIns, ObjInsArg, ObjInsArgValue, ObjSection, SymbolRef},
|
obj::{ObjIns, ObjInsArg, ObjInsArgValue, ObjReloc, ObjSection},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct ObjArchX86 {
|
pub struct ObjArchX86 {
|
||||||
|
@ -28,17 +28,14 @@ impl ObjArchX86 {
|
||||||
impl ObjArch for ObjArchX86 {
|
impl ObjArch for ObjArchX86 {
|
||||||
fn process_code(
|
fn process_code(
|
||||||
&self,
|
&self,
|
||||||
obj: &ObjInfo,
|
address: u64,
|
||||||
symbol_ref: SymbolRef,
|
code: &[u8],
|
||||||
|
relocations: &[ObjReloc],
|
||||||
|
line_info: &BTreeMap<u64, u64>,
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ProcessCodeResult> {
|
) -> Result<ProcessCodeResult> {
|
||||||
let (section, symbol) = obj.section_symbol(symbol_ref);
|
|
||||||
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
|
|
||||||
let code = §ion.data
|
|
||||||
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
|
|
||||||
|
|
||||||
let mut result = ProcessCodeResult { ops: Vec::new(), insts: Vec::new() };
|
let mut result = ProcessCodeResult { ops: Vec::new(), insts: Vec::new() };
|
||||||
let mut decoder = Decoder::with_ip(self.bits, code, symbol.address, DecoderOptions::NONE);
|
let mut decoder = Decoder::with_ip(self.bits, code, address, DecoderOptions::NONE);
|
||||||
let mut formatter: Box<dyn Formatter> = match config.x86_formatter {
|
let mut formatter: Box<dyn Formatter> = match config.x86_formatter {
|
||||||
X86Formatter::Intel => Box::new(IntelFormatter::new()),
|
X86Formatter::Intel => Box::new(IntelFormatter::new()),
|
||||||
X86Formatter::Gas => Box::new(GasFormatter::new()),
|
X86Formatter::Gas => Box::new(GasFormatter::new()),
|
||||||
|
@ -70,11 +67,10 @@ impl ObjArch for ObjArchX86 {
|
||||||
|
|
||||||
let address = instruction.ip();
|
let address = instruction.ip();
|
||||||
let op = instruction.mnemonic() as u16;
|
let op = instruction.mnemonic() as u16;
|
||||||
let reloc = section
|
let reloc = relocations
|
||||||
.relocations
|
|
||||||
.iter()
|
.iter()
|
||||||
.find(|r| r.address >= address && r.address < address + instruction.len() as u64);
|
.find(|r| r.address >= address && r.address < address + instruction.len() as u64);
|
||||||
let line = section.line_info.range(..=address).last().map(|(_, &b)| b);
|
let line = line_info.range(..=address).last().map(|(_, &b)| b);
|
||||||
output.ins = ObjIns {
|
output.ins = ObjIns {
|
||||||
address,
|
address,
|
||||||
size: instruction.len() as u8,
|
size: instruction.len() as u8,
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::{
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{anyhow, Result};
|
||||||
use similar::{capture_diff_slices_deadline, Algorithm};
|
use similar::{capture_diff_slices_deadline, Algorithm};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -16,34 +16,41 @@ use crate::{
|
||||||
obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSymbol, ObjSymbolFlags, SymbolRef},
|
obj::{ObjInfo, ObjInsArg, ObjReloc, ObjSymbol, ObjSymbolFlags, SymbolRef},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn no_diff_code(
|
pub fn process_code_symbol(
|
||||||
obj: &ObjInfo,
|
obj: &ObjInfo,
|
||||||
symbol_ref: SymbolRef,
|
symbol_ref: SymbolRef,
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<ObjSymbolDiff> {
|
) -> Result<ProcessCodeResult> {
|
||||||
let out = obj.arch.process_code(obj, symbol_ref, config)?;
|
let (section, symbol) = obj.section_symbol(symbol_ref);
|
||||||
|
let section = section.ok_or_else(|| anyhow!("Code symbol section not found"))?;
|
||||||
|
let code = §ion.data
|
||||||
|
[symbol.section_address as usize..(symbol.section_address + symbol.size) as usize];
|
||||||
|
obj.arch.process_code(symbol.address, code, §ion.relocations, §ion.line_info, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn no_diff_code(out: &ProcessCodeResult, symbol_ref: SymbolRef) -> Result<ObjSymbolDiff> {
|
||||||
let mut diff = Vec::<ObjInsDiff>::new();
|
let mut diff = Vec::<ObjInsDiff>::new();
|
||||||
for i in out.insts {
|
for i in &out.insts {
|
||||||
diff.push(ObjInsDiff { ins: Some(i), kind: ObjInsDiffKind::None, ..Default::default() });
|
diff.push(ObjInsDiff {
|
||||||
|
ins: Some(i.clone()),
|
||||||
|
kind: ObjInsDiffKind::None,
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
resolve_branches(&mut diff);
|
resolve_branches(&mut diff);
|
||||||
Ok(ObjSymbolDiff { symbol_ref, diff_symbol: None, instructions: diff, match_percent: None })
|
Ok(ObjSymbolDiff { symbol_ref, diff_symbol: None, instructions: diff, match_percent: None })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn diff_code(
|
pub fn diff_code(
|
||||||
left_obj: &ObjInfo,
|
left_out: &ProcessCodeResult,
|
||||||
right_obj: &ObjInfo,
|
right_out: &ProcessCodeResult,
|
||||||
left_symbol_ref: SymbolRef,
|
left_symbol_ref: SymbolRef,
|
||||||
right_symbol_ref: SymbolRef,
|
right_symbol_ref: SymbolRef,
|
||||||
config: &DiffObjConfig,
|
config: &DiffObjConfig,
|
||||||
) -> Result<(ObjSymbolDiff, ObjSymbolDiff)> {
|
) -> Result<(ObjSymbolDiff, ObjSymbolDiff)> {
|
||||||
let left_out = left_obj.arch.process_code(left_obj, left_symbol_ref, config)?;
|
|
||||||
let right_out = right_obj.arch.process_code(right_obj, right_symbol_ref, config)?;
|
|
||||||
|
|
||||||
let mut left_diff = Vec::<ObjInsDiff>::new();
|
let mut left_diff = Vec::<ObjInsDiff>::new();
|
||||||
let mut right_diff = Vec::<ObjInsDiff>::new();
|
let mut right_diff = Vec::<ObjInsDiff>::new();
|
||||||
diff_instructions(&mut left_diff, &mut right_diff, &left_out, &right_out)?;
|
diff_instructions(&mut left_diff, &mut right_diff, left_out, right_out)?;
|
||||||
|
|
||||||
resolve_branches(&mut left_diff);
|
resolve_branches(&mut left_diff);
|
||||||
resolve_branches(&mut right_diff);
|
resolve_branches(&mut right_diff);
|
||||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
diff::{
|
diff::{
|
||||||
code::{diff_code, no_diff_code},
|
code::{diff_code, no_diff_code, process_code_symbol},
|
||||||
data::{
|
data::{
|
||||||
diff_bss_section, diff_bss_symbol, diff_data_section, diff_data_symbol,
|
diff_bss_section, diff_bss_symbol, diff_data_section, diff_data_symbol,
|
||||||
diff_text_section, no_diff_symbol,
|
diff_text_section, no_diff_symbol,
|
||||||
|
@ -13,8 +13,8 @@ use crate::{
|
||||||
obj::{ObjInfo, ObjIns, ObjSection, ObjSectionKind, ObjSymbol, SymbolRef},
|
obj::{ObjInfo, ObjIns, ObjSection, ObjSectionKind, ObjSymbol, SymbolRef},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod code;
|
pub mod code;
|
||||||
mod data;
|
pub mod data;
|
||||||
pub mod display;
|
pub mod display;
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
@ -321,9 +321,11 @@ pub fn diff_objs(
|
||||||
let (right_obj, right_out) = right.as_mut().unwrap();
|
let (right_obj, right_out) = right.as_mut().unwrap();
|
||||||
match section_kind {
|
match section_kind {
|
||||||
ObjSectionKind::Code => {
|
ObjSectionKind::Code => {
|
||||||
|
let left_code = process_code_symbol(left_obj, left_symbol_ref, config)?;
|
||||||
|
let right_code = process_code_symbol(right_obj, right_symbol_ref, config)?;
|
||||||
let (left_diff, right_diff) = diff_code(
|
let (left_diff, right_diff) = diff_code(
|
||||||
left_obj,
|
&left_code,
|
||||||
right_obj,
|
&right_code,
|
||||||
left_symbol_ref,
|
left_symbol_ref,
|
||||||
right_symbol_ref,
|
right_symbol_ref,
|
||||||
config,
|
config,
|
||||||
|
@ -333,9 +335,10 @@ pub fn diff_objs(
|
||||||
|
|
||||||
if let Some(prev_symbol_ref) = prev_symbol_ref {
|
if let Some(prev_symbol_ref) = prev_symbol_ref {
|
||||||
let (prev_obj, prev_out) = prev.as_mut().unwrap();
|
let (prev_obj, prev_out) = prev.as_mut().unwrap();
|
||||||
|
let prev_code = process_code_symbol(prev_obj, prev_symbol_ref, config)?;
|
||||||
let (_, prev_diff) = diff_code(
|
let (_, prev_diff) = diff_code(
|
||||||
right_obj,
|
&right_code,
|
||||||
prev_obj,
|
&prev_code,
|
||||||
right_symbol_ref,
|
right_symbol_ref,
|
||||||
prev_symbol_ref,
|
prev_symbol_ref,
|
||||||
config,
|
config,
|
||||||
|
@ -369,8 +372,9 @@ pub fn diff_objs(
|
||||||
let (left_obj, left_out) = left.as_mut().unwrap();
|
let (left_obj, left_out) = left.as_mut().unwrap();
|
||||||
match section_kind {
|
match section_kind {
|
||||||
ObjSectionKind::Code => {
|
ObjSectionKind::Code => {
|
||||||
|
let code = process_code_symbol(left_obj, left_symbol_ref, config)?;
|
||||||
*left_out.symbol_diff_mut(left_symbol_ref) =
|
*left_out.symbol_diff_mut(left_symbol_ref) =
|
||||||
no_diff_code(left_obj, left_symbol_ref, config)?;
|
no_diff_code(&code, left_symbol_ref)?;
|
||||||
}
|
}
|
||||||
ObjSectionKind::Data | ObjSectionKind::Bss => {
|
ObjSectionKind::Data | ObjSectionKind::Bss => {
|
||||||
*left_out.symbol_diff_mut(left_symbol_ref) =
|
*left_out.symbol_diff_mut(left_symbol_ref) =
|
||||||
|
@ -382,8 +386,9 @@ pub fn diff_objs(
|
||||||
let (right_obj, right_out) = right.as_mut().unwrap();
|
let (right_obj, right_out) = right.as_mut().unwrap();
|
||||||
match section_kind {
|
match section_kind {
|
||||||
ObjSectionKind::Code => {
|
ObjSectionKind::Code => {
|
||||||
|
let code = process_code_symbol(right_obj, right_symbol_ref, config)?;
|
||||||
*right_out.symbol_diff_mut(right_symbol_ref) =
|
*right_out.symbol_diff_mut(right_symbol_ref) =
|
||||||
no_diff_code(right_obj, right_symbol_ref, config)?;
|
no_diff_code(&code, right_symbol_ref)?;
|
||||||
}
|
}
|
||||||
ObjSectionKind::Data | ObjSectionKind::Bss => {
|
ObjSectionKind::Data | ObjSectionKind::Bss => {
|
||||||
*right_out.symbol_diff_mut(right_symbol_ref) =
|
*right_out.symbol_diff_mut(right_symbol_ref) =
|
||||||
|
|
Loading…
Reference in New Issue