2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "mips")]
|
2022-09-11 13:52:55 -04:00
|
|
|
pub mod mips;
|
2024-02-26 18:43:26 -07:00
|
|
|
#[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;
|
2024-02-28 21:44:53 -07:00
|
|
|
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
|
|
|
|
2024-02-26 18:43:26 -07: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};
|
2024-02-28 21:44:53 -07:00
|
|
|
use split_meta::SplitMeta;
|
2022-09-08 17:19:20 -04:00
|
|
|
|
2024-02-26 18:43:26 -07: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,
|
2023-10-07 13:27:12 -04:00
|
|
|
Hidden,
|
2022-09-08 17:19:20 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#[derive(Debug, Copy, Clone, Default)]
|
2024-02-26 18:43:26 -07:00
|
|
|
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>,
|
2024-02-28 21:44:53 -07:00
|
|
|
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
|
|
|
|
2024-02-26 18:43:26 -07:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq)]
|
|
|
|
|
pub enum ObjInsArgValue {
|
2024-03-16 23:30:27 -06:00
|
|
|
Signed(i64),
|
|
|
|
|
Unsigned(u64),
|
2024-02-26 18:43:26 -07:00
|
|
|
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,
|
2024-02-26 18:43:26 -07:00
|
|
|
(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),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-06 01:22:07 -04:00
|
|
|
#[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),
|
2024-02-26 18:43:26 -07:00
|
|
|
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
|
|
|
|
2023-11-22 00:07:21 -05:00
|
|
|
impl ObjInsArg {
|
|
|
|
|
pub fn loose_eq(&self, other: &ObjInsArg) -> bool {
|
|
|
|
|
match (self, other) {
|
2024-02-26 18:43:26 -07:00
|
|
|
(ObjInsArg::Arg(a), ObjInsArg::Arg(b)) => a.loose_eq(b),
|
2023-11-22 00:07:21 -05:00
|
|
|
(ObjInsArg::Reloc, ObjInsArg::Reloc) => true,
|
2024-03-16 23:30:27 -06:00
|
|
|
(ObjInsArg::BranchDest(a), ObjInsArg::BranchDest(b)) => a == b,
|
2023-11-22 00:07:21 -05:00
|
|
|
_ => false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-08 17:19:20 -04:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
|
pub struct ObjInsArgDiff {
|
|
|
|
|
/// Incrementing index for coloring
|
|
|
|
|
pub idx: usize,
|
|
|
|
|
}
|
2024-02-26 18:43:26 -07:00
|
|
|
|
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,
|
|
|
|
|
}
|
2024-02-26 18:43:26 -07:00
|
|
|
|
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,
|
|
|
|
|
}
|
2024-02-26 18:43:26 -07:00
|
|
|
|
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,
|
|
|
|
|
}
|
2024-02-26 18:43:26 -07:00
|
|
|
|
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>,
|
2024-02-28 21:44:53 -07:00
|
|
|
/// 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
|
|
|
}
|
2024-02-26 18:43:26 -07: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>>,
|
|
|
|
|
}
|
2024-02-26 18:43:26 -07:00
|
|
|
|
2022-11-06 00:49:46 -04:00
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
|
|
|
|
|
pub enum ObjDataDiffKind {
|
|
|
|
|
#[default]
|
|
|
|
|
None,
|
|
|
|
|
Replace,
|
|
|
|
|
Delete,
|
|
|
|
|
Insert,
|
|
|
|
|
}
|
2024-02-26 18:43:26 -07:00
|
|
|
|
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
|
|
|
}
|
2024-02-26 18:43:26 -07: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,
|
2022-09-20 18:19:44 -04:00
|
|
|
pub addend: i64,
|
2024-03-04 18:06:21 -07:00
|
|
|
/// Original virtual address (from .note.split section)
|
2024-02-28 21:44:53 -07:00
|
|
|
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
|
|
|
}
|
2024-02-26 18:43:26 -07:00
|
|
|
|
2022-09-11 13:52:55 -04:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
|
|
|
pub enum ObjArchitecture {
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "ppc")]
|
2022-09-11 13:52:55 -04:00
|
|
|
PowerPc,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[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
|
|
|
}
|
2024-02-26 18:43:26 -07: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>,
|
2024-02-28 21:44:53 -07:00
|
|
|
/// Common BSS symbols
|
2022-09-08 17:19:20 -04:00
|
|
|
pub common: Vec<ObjSymbol>,
|
2024-02-28 21:44:53 -07:00
|
|
|
/// 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)
|
2024-02-28 21:44:53 -07:00
|
|
|
pub split_meta: Option<SplitMeta>,
|
2022-09-08 17:19:20 -04:00
|
|
|
}
|
2024-02-26 18:43:26 -07:00
|
|
|
|
2022-09-08 17:19:20 -04:00
|
|
|
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
|
|
|
|
pub enum ObjRelocKind {
|
|
|
|
|
Absolute,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
PpcAddr16Hi,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
PpcAddr16Ha,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
PpcAddr16Lo,
|
2024-02-26 18:43:26 -07:00
|
|
|
// #[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
// PpcAddr32,
|
2024-02-26 18:43:26 -07:00
|
|
|
// #[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
// PpcRel32,
|
2024-02-26 18:43:26 -07:00
|
|
|
// #[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
// PpcAddr24,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
PpcRel24,
|
2024-02-26 18:43:26 -07:00
|
|
|
// #[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
// PpcAddr14,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
PpcRel14,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "ppc")]
|
2022-09-08 17:19:20 -04:00
|
|
|
PpcEmbSda21,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "mips")]
|
2022-09-11 13:52:55 -04:00
|
|
|
Mips26,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "mips")]
|
2022-09-11 13:52:55 -04:00
|
|
|
MipsHi16,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "mips")]
|
2022-09-11 13:52:55 -04:00
|
|
|
MipsLo16,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "mips")]
|
2023-01-21 12:41:41 -05:00
|
|
|
MipsGot16,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "mips")]
|
2023-01-21 12:41:41 -05:00
|
|
|
MipsCall16,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[cfg(feature = "mips")]
|
2023-01-21 12:41:41 -05:00
|
|
|
MipsGpRel16,
|
2024-02-26 18:43:26 -07:00
|
|
|
#[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
|
|
|
}
|
2024-02-26 18:43:26 -07: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>,
|
|
|
|
|
}
|