/rust/registry/src/index.crates.io-6f17d22bba15001f/dynasmrt-1.2.3/src/x86.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Runtime support for the x86 architecture assembling target. |
2 | | //! |
3 | | //! The x86 instruction set features variable-length instructions and |
4 | | //! relative relocations up to 16 bits in size, or absolute relocations of 32 bits in size. |
5 | | //! |
6 | | //! The core relocation behaviour for this architecture is provided by the [`X86Relocation`] type. |
7 | | //! |
8 | | //! Next to that, this module contains the following: |
9 | | //! |
10 | | //! ## Type aliases |
11 | | //! |
12 | | //! Several specialized type aliases of the generic [`Assembler`] are provided as these are by far the most common usecase. |
13 | | //! |
14 | | //! ## Enums |
15 | | //! |
16 | | //! There are enumerator of every logically distinct register family usable in x86. |
17 | | //! These enums implement the [`Register`] trait and their discriminant values match their numeric encoding in dynamic register literals. |
18 | | //! |
19 | | //! *Note: The presence of some registers listed here is purely what is encodable. Check the relevant architecture documentation to find what is architecturally valid.* |
20 | | |
21 | | |
22 | | use crate::Register; |
23 | | use crate::relocations::{Relocation, RelocationSize, RelocationKind, ImpossibleRelocation}; |
24 | | |
25 | | |
26 | | /// Relocation implementation for the x86 architecture. |
27 | | #[derive(Debug, Clone)] |
28 | | pub struct X86Relocation { |
29 | | size: RelocationSize, |
30 | | kind: RelocationKind, |
31 | | } |
32 | | |
33 | | impl Relocation for X86Relocation { |
34 | | type Encoding = (u8, u8); |
35 | 0 | fn from_encoding(encoding: Self::Encoding) -> Self { |
36 | 0 | Self { |
37 | 0 | size: RelocationSize::from_encoding(encoding.0), |
38 | 0 | kind: RelocationKind::from_encoding(encoding.1), |
39 | 0 | } |
40 | 0 | } Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::from_encoding Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::from_encoding |
41 | 0 | fn from_size(size: RelocationSize) -> Self { |
42 | 0 | Self { |
43 | 0 | size, |
44 | 0 | kind: RelocationKind::Relative, |
45 | 0 | } |
46 | 0 | } Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::from_size Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::from_size |
47 | 0 | fn size(&self) -> usize { |
48 | 0 | self.size.size() |
49 | 0 | } Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::size Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::size |
50 | 0 | fn write_value(&self, buf: &mut [u8], value: isize) -> Result<(), ImpossibleRelocation> { |
51 | 0 | self.size.write_value(buf, value) |
52 | 0 | } Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::write_value Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::write_value |
53 | 0 | fn read_value(&self, buf: &[u8]) -> isize { |
54 | 0 | self.size.read_value(buf) |
55 | 0 | } Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::read_value Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::read_value |
56 | 0 | fn kind(&self) -> RelocationKind { |
57 | 0 | self.kind |
58 | 0 | } Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::kind Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::kind |
59 | 0 | fn page_size() -> usize { |
60 | 0 | 4096 |
61 | 0 | } Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::page_size Unexecuted instantiation: <dynasmrt::x86::X86Relocation as dynasmrt::relocations::Relocation>::page_size |
62 | | } |
63 | | |
64 | | |
65 | | /// An x86 Assembler. This is aliased here for backwards compatability. |
66 | | pub type Assembler = crate::Assembler<X86Relocation>; |
67 | | /// An x86 AssemblyModifier. This is aliased here for backwards compatability. |
68 | | pub type AssemblyModifier<'a> = crate::Modifier<'a, X86Relocation>; |
69 | | /// An x86 UncommittedModifier. This is aliased here for backwards compatability. |
70 | | pub type UncommittedModifier<'a> = crate::UncommittedModifier<'a>; |
71 | | |
72 | | |
73 | | /// 1, 2 or 4-byte general purpose "double-word" registers. |
74 | | /// |
75 | | /// EIP does not appear here as it cannot be addressed dynamically. |
76 | | #[allow(missing_docs)] |
77 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
78 | | pub enum Rd { |
79 | | EAX = 0x00, ECX = 0x01, EDX = 0x02, EBX = 0x03, |
80 | | ESP = 0x04, EBP = 0x05, ESI = 0x06, EDI = 0x07, |
81 | | } |
82 | | reg_impls!(Rd); |
83 | | |
84 | | /// High-byte general purpose registers. |
85 | | #[allow(missing_docs)] |
86 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
87 | | pub enum Rh { |
88 | | AH = 0x4, CH = 0x5, DH = 0x6, BH = 0x7, |
89 | | } |
90 | | reg_impls!(Rh); |
91 | | |
92 | | /// 10-byte floating point registers. |
93 | | #[allow(missing_docs)] |
94 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
95 | | pub enum Rf { |
96 | | ST0 = 0x0, ST1 = 0x1, ST2 = 0x2, ST3 = 0x3, |
97 | | ST4 = 0x4, ST5 = 0x5, ST6 = 0x6, ST7 = 0x7, |
98 | | } |
99 | | reg_impls!(Rf); |
100 | | |
101 | | /// 8-byte MMX registers. |
102 | | #[allow(missing_docs)] |
103 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
104 | | pub enum Rm { |
105 | | MMX0 = 0x0, MMX1 = 0x1, MMX2 = 0x2, MMX3 = 0x3, |
106 | | MMX4 = 0x4, MMX5 = 0x5, MMX6 = 0x6, MMX7 = 0x7, |
107 | | } |
108 | | reg_impls!(Rm); |
109 | | |
110 | | /// 16 or 32-byte SSE registers. |
111 | | #[allow(missing_docs)] |
112 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
113 | | pub enum Rx { |
114 | | XMM0 = 0x0, XMM1 = 0x1, XMM2 = 0x2, XMM3 = 0x3, |
115 | | XMM4 = 0x4, XMM5 = 0x5, XMM6 = 0x6, XMM7 = 0x7, |
116 | | } |
117 | | reg_impls!(Rx); |
118 | | |
119 | | /// 2-byte segment registers. |
120 | | #[allow(missing_docs)] |
121 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
122 | | pub enum Rs { |
123 | | ES = 0x0, CS = 0x1, SS = 0x2, DS = 0x3, |
124 | | FS = 0x4, GS = 0x5, |
125 | | } |
126 | | reg_impls!(Rs); |
127 | | |
128 | | /// 4-byte control registers. |
129 | | #[allow(missing_docs)] |
130 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
131 | | pub enum RC { |
132 | | CR0 = 0x0, CR1 = 0x1, CR2 = 0x2, CR3 = 0x3, |
133 | | CR4 = 0x4, CR5 = 0x5, CR6 = 0x6, CR7 = 0x7, |
134 | | } |
135 | | reg_impls!(RC); |
136 | | |
137 | | /// 4-byte debug registers. |
138 | | #[allow(missing_docs)] |
139 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
140 | | pub enum RD { |
141 | | DR0 = 0x0, DR1 = 0x1, DR2 = 0x2, DR3 = 0x3, |
142 | | DR4 = 0x4, DR5 = 0x5, DR6 = 0x6, DR7 = 0x7, |
143 | | DR8 = 0x8, DR9 = 0x9, DR10 = 0xA, DR11 = 0xB, |
144 | | DR12 = 0xC, DR13 = 0xD, DR14 = 0xE, DR15 = 0xF, |
145 | | } |
146 | | reg_impls!(RD); |
147 | | |
148 | | /// 16-byte bound registers. |
149 | | #[allow(missing_docs)] |
150 | | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
151 | | pub enum RB { |
152 | | BND0 = 0x0, BND1 = 0x1, BND2 = 0x2, BND3 = 0x3 |
153 | | } |
154 | | reg_impls!(RB); |
155 | | |
156 | | #[cfg(test)] |
157 | | mod tests { |
158 | | use super::Rd::*; |
159 | | use crate::Register; |
160 | | |
161 | | #[test] |
162 | | fn reg_code() { |
163 | | assert_eq!(EAX.code(), 0); |
164 | | } |
165 | | |
166 | | #[test] |
167 | | fn reg_code_from() { |
168 | | assert_eq!(u8::from(ECX), 1); |
169 | | } |
170 | | } |