Files
objdiff/objdiff-core/src/obj/mod.rs
T

273 lines
6.3 KiB
Rust
Raw Normal View History

#[cfg(feature = "mips")]
2022-09-11 13:52:55 -04:00
pub mod mips;
#[cfg(feature = "ppc")]
2022-09-11 13:52:55 -04:00
pub mod ppc;
2024-03-16 23:30:27 -06:00
pub mod read;
pub mod split_meta;
2024-03-16 23:30:27 -06:00
#[cfg(feature = "x86")]
pub mod x86;
2022-09-11 13:52:55 -04:00
use std::{collections::BTreeMap, fmt, path::PathBuf};
2022-09-08 17:19:20 -04:00
2023-10-07 14:48:34 -04:00
use filetime::FileTime;
2022-09-08 17:19:20 -04:00
use flagset::{flags, FlagSet};
use split_meta::SplitMeta;
2022-09-08 17:19:20 -04:00
use crate::util::ReallySigned;
2022-09-08 17:19:20 -04:00
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum ObjSectionKind {
Code,
Data,
Bss,
}
flags! {
pub enum ObjSymbolFlags: u8 {
Global,
Local,
Weak,
Common,
Hidden,
2022-09-08 17:19:20 -04:00
}
}
#[derive(Debug, Copy, Clone, Default)]
pub struct ObjSymbolFlagSet(pub FlagSet<ObjSymbolFlags>);
2022-09-08 17:19:20 -04:00
#[derive(Debug, Clone)]
pub struct ObjSection {
pub name: String,
pub kind: ObjSectionKind,
pub address: u64,
pub size: u64,
pub data: Vec<u8>,
pub index: usize,
pub symbols: Vec<ObjSymbol>,
pub relocations: Vec<ObjReloc>,
pub virtual_address: Option<u64>,
2022-11-06 00:49:46 -04:00
// Diff
pub data_diff: Vec<ObjDataDiff>,
pub match_percent: f32,
2022-09-08 17:19:20 -04:00
}
2023-10-05 23:40:45 -04:00
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ObjInsArgValue {
2024-03-16 23:30:27 -06:00
Signed(i64),
Unsigned(u64),
Opaque(String),
}
impl ObjInsArgValue {
pub fn loose_eq(&self, other: &ObjInsArgValue) -> bool {
match (self, other) {
(ObjInsArgValue::Signed(a), ObjInsArgValue::Signed(b)) => a == b,
(ObjInsArgValue::Unsigned(a), ObjInsArgValue::Unsigned(b)) => a == b,
(ObjInsArgValue::Signed(a), ObjInsArgValue::Unsigned(b))
2024-03-16 23:30:27 -06:00
| (ObjInsArgValue::Unsigned(b), ObjInsArgValue::Signed(a)) => *a as u64 == *b,
(ObjInsArgValue::Opaque(a), ObjInsArgValue::Opaque(b)) => a == b,
_ => false,
}
}
}
impl fmt::Display for ObjInsArgValue {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ObjInsArgValue::Signed(v) => write!(f, "{:#x}", ReallySigned(*v)),
ObjInsArgValue::Unsigned(v) => write!(f, "{:#x}", v),
ObjInsArgValue::Opaque(v) => write!(f, "{}", v),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
2022-09-08 17:19:20 -04:00
pub enum ObjInsArg {
2024-03-16 23:30:27 -06:00
PlainText(String),
Arg(ObjInsArgValue),
2022-09-08 17:19:20 -04:00
Reloc,
2024-03-16 23:30:27 -06:00
BranchDest(u64),
2022-09-08 17:19:20 -04:00
}
2023-10-05 23:40:45 -04:00
impl ObjInsArg {
pub fn loose_eq(&self, other: &ObjInsArg) -> bool {
match (self, other) {
(ObjInsArg::Arg(a), ObjInsArg::Arg(b)) => a.loose_eq(b),
(ObjInsArg::Reloc, ObjInsArg::Reloc) => true,
2024-03-16 23:30:27 -06:00
(ObjInsArg::BranchDest(a), ObjInsArg::BranchDest(b)) => a == b,
_ => false,
}
}
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Copy, Clone)]
pub struct ObjInsArgDiff {
/// Incrementing index for coloring
pub idx: usize,
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Clone)]
pub struct ObjInsBranchFrom {
/// Source instruction indices
pub ins_idx: Vec<usize>,
/// Incrementing index for coloring
pub branch_idx: usize,
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Clone)]
pub struct ObjInsBranchTo {
/// Target instruction index
pub ins_idx: usize,
/// Incrementing index for coloring
pub branch_idx: usize,
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub enum ObjInsDiffKind {
#[default]
None,
OpMismatch,
ArgMismatch,
Replace,
Delete,
Insert,
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Clone)]
pub struct ObjIns {
2024-03-16 23:30:27 -06:00
pub address: u64,
pub size: u8,
pub op: u16,
2022-09-08 17:19:20 -04:00
pub mnemonic: String,
pub args: Vec<ObjInsArg>,
pub reloc: Option<ObjReloc>,
2024-03-16 23:30:27 -06:00
pub branch_dest: Option<u64>,
/// Line number
2024-01-21 23:38:52 -07:00
pub line: Option<u64>,
2023-10-05 23:40:45 -04:00
/// Original (unsimplified) instruction
pub orig: Option<String>,
2022-09-08 17:19:20 -04:00
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Clone, Default)]
pub struct ObjInsDiff {
pub ins: Option<ObjIns>,
/// Diff kind
pub kind: ObjInsDiffKind,
/// Branches from instruction
pub branch_from: Option<ObjInsBranchFrom>,
/// Branches to instruction
pub branch_to: Option<ObjInsBranchTo>,
/// Arg diffs
pub arg_diff: Vec<Option<ObjInsArgDiff>>,
}
2022-11-06 00:49:46 -04:00
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
pub enum ObjDataDiffKind {
#[default]
None,
Replace,
Delete,
Insert,
}
2022-11-06 00:49:46 -04:00
#[derive(Debug, Clone, Default)]
pub struct ObjDataDiff {
pub data: Vec<u8>,
pub kind: ObjDataDiffKind,
pub len: usize,
2022-12-06 17:53:32 -05:00
pub symbol: String,
2022-11-06 00:49:46 -04:00
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Clone)]
pub struct ObjSymbol {
pub name: String,
pub demangled_name: Option<String>,
pub address: u64,
2022-09-11 13:52:55 -04:00
pub section_address: u64,
2022-09-08 17:19:20 -04:00
pub size: u64,
pub size_known: bool,
pub flags: ObjSymbolFlagSet,
pub addend: i64,
2024-03-04 18:06:21 -07:00
/// Original virtual address (from .note.split section)
pub virtual_address: Option<u64>,
2022-09-08 17:19:20 -04:00
// Diff
pub diff_symbol: Option<String>,
pub instructions: Vec<ObjInsDiff>,
2022-12-06 17:53:32 -05:00
pub match_percent: Option<f32>,
2022-09-08 17:19:20 -04:00
}
2022-09-11 13:52:55 -04:00
#[derive(Debug, Copy, Clone)]
pub enum ObjArchitecture {
#[cfg(feature = "ppc")]
2022-09-11 13:52:55 -04:00
PowerPc,
#[cfg(feature = "mips")]
2022-09-11 13:52:55 -04:00
Mips,
2024-03-16 23:30:27 -06:00
#[cfg(feature = "x86")]
X86_32,
#[cfg(feature = "x86")]
X86_64,
2022-09-11 13:52:55 -04:00
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Clone)]
pub struct ObjInfo {
2022-09-11 13:52:55 -04:00
pub architecture: ObjArchitecture,
2022-09-08 17:19:20 -04:00
pub path: PathBuf,
2023-10-07 14:48:34 -04:00
pub timestamp: FileTime,
2022-09-08 17:19:20 -04:00
pub sections: Vec<ObjSection>,
/// Common BSS symbols
2022-09-08 17:19:20 -04:00
pub common: Vec<ObjSymbol>,
/// Line number info (.line or .debug_line section)
2024-01-21 23:38:52 -07:00
pub line_info: Option<BTreeMap<u64, u64>>,
2024-03-04 18:06:21 -07:00
/// Split object metadata (.note.split section)
pub split_meta: Option<SplitMeta>,
2022-09-08 17:19:20 -04:00
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum ObjRelocKind {
Absolute,
#[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
PpcAddr16Hi,
#[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
PpcAddr16Ha,
#[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
PpcAddr16Lo,
// #[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
// PpcAddr32,
// #[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
// PpcRel32,
// #[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
// PpcAddr24,
#[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
PpcRel24,
// #[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
// PpcAddr14,
#[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
PpcRel14,
#[cfg(feature = "ppc")]
2022-09-08 17:19:20 -04:00
PpcEmbSda21,
#[cfg(feature = "mips")]
2022-09-11 13:52:55 -04:00
Mips26,
#[cfg(feature = "mips")]
2022-09-11 13:52:55 -04:00
MipsHi16,
#[cfg(feature = "mips")]
2022-09-11 13:52:55 -04:00
MipsLo16,
#[cfg(feature = "mips")]
2023-01-21 12:41:41 -05:00
MipsGot16,
#[cfg(feature = "mips")]
2023-01-21 12:41:41 -05:00
MipsCall16,
#[cfg(feature = "mips")]
2023-01-21 12:41:41 -05:00
MipsGpRel16,
#[cfg(feature = "mips")]
2023-01-21 12:41:41 -05:00
MipsGpRel32,
2024-03-16 23:30:27 -06:00
#[cfg(feature = "x86")]
X86PcRel32,
2022-09-08 17:19:20 -04:00
}
2022-09-08 17:19:20 -04:00
#[derive(Debug, Clone)]
pub struct ObjReloc {
pub kind: ObjRelocKind,
pub address: u64,
pub target: ObjSymbol,
pub target_section: Option<String>,
}