ms_codeview/
arch.rs

1//! Architecture-specific definitions
2
3macro_rules! register_set {
4    (
5        $( #[$a:meta] )*
6        $v:vis enum $ty_name:ident;
7        $( $reg_name:ident = $reg_value:expr, )*
8    ) => {
9        $( #[$a] )*
10        #[allow(missing_docs)]
11        #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
12        $v struct $ty_name(pub u16);
13
14        #[allow(missing_docs)]
15        impl $ty_name {
16            $(
17                pub const $reg_name: $ty_name = $ty_name($reg_value);
18            )*
19
20            #[inline(never)]
21            pub fn get_name(self) -> Option<&'static str> {
22                match self {
23                    $(
24                        Self::$reg_name => Some(stringify!($reg_name)),
25                    )*
26                    _ => None,
27                }
28            }
29
30            #[inline(never)]
31            pub fn from_name(name: &str) -> Option<Self> {
32                match name {
33                    $(
34                        stringify!($reg_name) => Some(Self::$reg_name),
35                    )*
36                    _ => None,
37                }
38            }
39        }
40
41        impl core::fmt::Display for $ty_name {
42            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
43                if let Some(s) = self.get_name() {
44                    f.write_str(s)
45                } else {
46                    write!(f, "??(0x{:x})", self.0)
47                }
48            }
49        }
50
51        impl core::fmt::Debug for $ty_name {
52            fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
53                <Self as core::fmt::Display>::fmt(self, f)
54            }
55        }
56    }
57}
58
59/// Identifies COFF CPU architectures.
60#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
61pub enum Arch {
62    /// AMD64
63    AMD64,
64    /// ARM64, including ARM64EC, ARM64X
65    ARM64,
66    /// X86
67    X86,
68}
69
70pub mod amd64;
71pub mod arm64;
72pub mod x86;
73
74/// Identifies a register in a specific architecture
75#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
76pub struct ArchReg {
77    /// Target architecture
78    pub arch: Arch,
79    /// The untyped register index
80    pub reg: u16,
81}
82
83impl ArchReg {
84    /// Ties an arch and a reg
85    pub fn new(arch: Arch, reg: u16) -> Self {
86        Self { arch, reg }
87    }
88}
89
90use core::fmt::{Debug, Display};
91
92impl Debug for ArchReg {
93    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
94        <Self as Display>::fmt(self, f)
95    }
96}
97
98impl Display for ArchReg {
99    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100        match self.arch {
101            Arch::AMD64 => Display::fmt(&amd64::Amd64Reg(self.reg), f),
102            Arch::X86 => Display::fmt(&x86::X86Reg(self.reg), f),
103            Arch::ARM64 => Display::fmt(&arm64::Arm64Reg(self.reg), f),
104        }
105    }
106}