use core::fmt;
use core::ops::{Deref, DerefMut};
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Architecture {
Unknown,
Aarch64,
#[allow(non_camel_case_types)]
Aarch64_Ilp32,
Alpha,
Arm,
Avr,
Bpf,
Csky,
E2K32,
E2K64,
I386,
X86_64,
#[allow(non_camel_case_types)]
X86_64_X32,
Hexagon,
Hppa,
Ia64,
LoongArch32,
LoongArch64,
M68k,
Mips,
Mips64,
#[allow(non_camel_case_types)]
Mips64_N32,
Msp430,
PowerPc,
PowerPc64,
Riscv32,
Riscv64,
S390x,
Sbf,
Sharc,
Sparc,
Sparc32Plus,
Sparc64,
SuperH,
Wasm32,
Wasm64,
Xtensa,
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SubArchitecture {
Arm64E,
Arm64EC,
}
impl Architecture {
pub fn address_size(self) -> Option<AddressSize> {
match self {
Architecture::Unknown => None,
Architecture::Aarch64 => Some(AddressSize::U64),
Architecture::Aarch64_Ilp32 => Some(AddressSize::U32),
Architecture::Alpha => Some(AddressSize::U64),
Architecture::Arm => Some(AddressSize::U32),
Architecture::Avr => Some(AddressSize::U8),
Architecture::Bpf => Some(AddressSize::U64),
Architecture::Csky => Some(AddressSize::U32),
Architecture::E2K32 => Some(AddressSize::U32),
Architecture::E2K64 => Some(AddressSize::U64),
Architecture::I386 => Some(AddressSize::U32),
Architecture::X86_64 => Some(AddressSize::U64),
Architecture::X86_64_X32 => Some(AddressSize::U32),
Architecture::Hexagon => Some(AddressSize::U32),
Architecture::Hppa => Some(AddressSize::U32),
Architecture::Ia64 => Some(AddressSize::U64),
Architecture::LoongArch32 => Some(AddressSize::U32),
Architecture::LoongArch64 => Some(AddressSize::U64),
Architecture::M68k => Some(AddressSize::U32),
Architecture::Mips => Some(AddressSize::U32),
Architecture::Mips64 => Some(AddressSize::U64),
Architecture::Mips64_N32 => Some(AddressSize::U32),
Architecture::Msp430 => Some(AddressSize::U16),
Architecture::PowerPc => Some(AddressSize::U32),
Architecture::PowerPc64 => Some(AddressSize::U64),
Architecture::Riscv32 => Some(AddressSize::U32),
Architecture::Riscv64 => Some(AddressSize::U64),
Architecture::S390x => Some(AddressSize::U64),
Architecture::Sbf => Some(AddressSize::U64),
Architecture::Sharc => Some(AddressSize::U32),
Architecture::Sparc => Some(AddressSize::U32),
Architecture::Sparc32Plus => Some(AddressSize::U32),
Architecture::Sparc64 => Some(AddressSize::U64),
Architecture::Wasm32 => Some(AddressSize::U32),
Architecture::Wasm64 => Some(AddressSize::U64),
Architecture::Xtensa => Some(AddressSize::U32),
Architecture::SuperH => Some(AddressSize::U32),
}
}
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
#[repr(u8)]
pub enum AddressSize {
U8 = 1,
U16 = 2,
U32 = 4,
U64 = 8,
}
impl AddressSize {
#[inline]
pub fn bytes(self) -> u8 {
self as u8
}
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum BinaryFormat {
Coff,
Elf,
MachO,
Pe,
Wasm,
Xcoff,
}
impl BinaryFormat {
pub fn native_object() -> BinaryFormat {
if cfg!(target_os = "windows") {
BinaryFormat::Coff
} else if cfg!(target_os = "macos") {
BinaryFormat::MachO
} else {
BinaryFormat::Elf
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SectionKind {
Unknown,
Text,
Data,
ReadOnlyData,
ReadOnlyDataWithRel,
ReadOnlyString,
UninitializedData,
Tls,
UninitializedTls,
TlsVariables,
OtherString,
Other,
Debug,
DebugString,
Linker,
Note,
Metadata,
}
impl SectionKind {
pub fn is_bss(self) -> bool {
self == SectionKind::UninitializedData || self == SectionKind::UninitializedTls
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum ComdatKind {
Unknown,
Any,
NoDuplicates,
SameSize,
ExactMatch,
Largest,
Newest,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SymbolKind {
Unknown,
Text,
Data,
Section,
File,
Label,
Tls,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SymbolScope {
Unknown,
Compilation,
Linkage,
Dynamic,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum RelocationKind {
Unknown,
None,
Absolute,
Relative,
Got,
GotRelative,
GotBaseRelative,
GotBaseOffset,
PltRelative,
ImageOffset,
SectionOffset,
SectionIndex,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum RelocationEncoding {
Unknown,
Generic,
X86Signed,
X86RipRelative,
X86RipRelativeMovq,
X86Branch,
S390xDbl,
AArch64Call,
LoongArchBranch,
SharcTypeA,
SharcTypeB,
E2KLit,
E2KDisp,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum FileFlags {
None,
#[cfg(feature = "elf")]
Elf {
os_abi: crate::elf::OsAbi,
abi_version: u8,
e_flags: crate::elf::FileFlags,
},
#[cfg(feature = "macho")]
MachO {
flags: crate::macho::FileFlags,
},
#[cfg(feature = "coff")]
Coff {
characteristics: crate::pe::FileFlags,
},
#[cfg(feature = "xcoff")]
Xcoff {
f_flags: crate::xcoff::FileFlags,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SegmentFlags {
None,
#[cfg(feature = "elf")]
Elf {
p_type: crate::elf::ProgramType,
p_flags: crate::elf::ProgramFlags,
},
#[cfg(feature = "macho")]
MachO {
flags: crate::macho::SegmentFlags,
maxprot: crate::macho::VmProt,
initprot: crate::macho::VmProt,
},
#[cfg(feature = "coff")]
Coff {
characteristics: crate::pe::SectionFlags,
},
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Permissions {
bits: u8,
}
impl core::fmt::Debug for Permissions {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"{}{}{}",
if self.readable() { 'R' } else { '-' },
if self.writable() { 'W' } else { '-' },
if self.executable() { 'X' } else { '-' },
)
}
}
impl Permissions {
const R: u8 = 1 << 0;
const W: u8 = 1 << 1;
const X: u8 = 1 << 2;
pub fn new(readable: bool, writable: bool, executable: bool) -> Self {
let mut bits = 0;
if readable {
bits |= Self::R;
}
if writable {
bits |= Self::W;
}
if executable {
bits |= Self::X;
}
Permissions { bits }
}
#[inline]
pub fn readable(&self) -> bool {
self.bits & Self::R != 0
}
#[inline]
pub fn writable(&self) -> bool {
self.bits & Self::W != 0
}
#[inline]
pub fn executable(&self) -> bool {
self.bits & Self::X != 0
}
#[inline]
pub fn readonly(&self) -> bool {
self.readable() && !self.writable()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SectionFlags {
None,
#[cfg(feature = "elf")]
Elf {
sh_type: crate::elf::SectionType,
sh_flags: crate::elf::SectionFlags,
},
#[cfg(feature = "macho")]
MachO {
flags: crate::macho::SectionFlags,
reserved2: u32,
},
#[cfg(feature = "coff")]
Coff {
characteristics: crate::pe::SectionFlags,
},
#[cfg(feature = "xcoff")]
Xcoff {
s_flags: crate::xcoff::SectionFlags,
},
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum SymbolFlags<Section, Symbol> {
None,
#[cfg(feature = "elf")]
Elf {
st_info: crate::elf::SymbolInfo,
st_other: crate::elf::SymbolOther,
},
#[cfg(feature = "macho")]
MachO {
n_type: crate::macho::SymbolFlags,
n_desc: crate::macho::SymbolDesc,
},
#[cfg(feature = "coff")]
Coff {
typ: crate::pe::SymbolType,
storage_class: crate::pe::SymbolClass,
},
#[cfg(feature = "coff")]
CoffSection {
typ: crate::pe::SymbolType,
storage_class: crate::pe::SymbolClass,
selection: crate::pe::ComdatSelection,
associative_section: Option<Section>,
},
#[cfg(feature = "xcoff")]
Xcoff {
n_type: crate::xcoff::SymbolType,
n_sclass: crate::xcoff::SymbolClass,
x_smtyp: crate::xcoff::CsectAuxSmtyp,
x_smclas: crate::xcoff::CsectAuxClass,
containing_csect: Option<Symbol>,
},
#[doc(hidden)]
#[cfg(not(all(feature = "coff", feature = "xcoff")))]
_Phantom(core::marker::PhantomData<(Section, Symbol)>),
}
impl<Section, Symbol> SymbolFlags<Section, Symbol> {
#[cfg(feature = "elf")]
pub fn elf_visibility(&self) -> Option<crate::elf::SymbolVisibility> {
match self {
SymbolFlags::Elf { st_other, .. } => Some(st_other.visibility()),
_ => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum RelocationFlags {
Generic {
kind: RelocationKind,
encoding: RelocationEncoding,
size: u8,
},
#[cfg(feature = "elf")]
Elf {
r_type: crate::elf::RelocationType,
},
#[cfg(feature = "macho")]
MachO {
r_type: crate::macho::RelocationType,
r_pcrel: bool,
r_length: u8,
},
#[cfg(feature = "coff")]
Coff {
typ: crate::pe::RelocationType,
},
#[cfg(feature = "xcoff")]
Xcoff {
r_rtype: crate::xcoff::RelocationType,
r_rsize: u8,
},
#[cfg(feature = "wasm")]
Wasm {
r_type: u8,
},
}
#[allow(unused)]
#[derive(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) struct SkipDebugList<T>(pub T);
impl<T> fmt::Debug for SkipDebugList<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "[..]")
}
}
impl<T> Deref for SkipDebugList<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> DerefMut for SkipDebugList<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}