Coverage Report

Created: 2024-10-16 07:58

/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
}