1pub mod ast;
2mod compiler;
3pub mod parser;
4mod debug;
5mod x64data;
6
7use crate::State;
8use crate::arch::{Arch, Error, BasicExprBuilder};
9use crate::common::{Size, Stmt, Jump};
10
11#[cfg(feature = "dynasm_opmap")]
12pub use debug::create_opmap;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum X86Mode {
16 Long,
17 Protected
18}
19
20struct Context<'a> {
21 pub state: &'a mut dyn BasicExprBuilder,
22 pub mode: X86Mode,
23 pub features: x64data::Features
24}
25
26#[derive(Clone, Debug)]
27pub struct Archx64 {
28 features: x64data::Features,
29}
30
31#[derive(Clone, Debug)]
32pub struct Archx86 {
33 features: x64data::Features,
34}
35
36#[derive(Debug)]
37pub struct InstructionX64 {
38 pub inst: ast::Instruction,
39 pub args: Vec<ast::CleanArg>,
40}
41
42#[derive(Debug)]
43pub struct InstructionX86 {
44 pub inst: ast::Instruction,
45 pub args: Vec<ast::CleanArg>,
46}
47
48impl Default for Archx64 {
49 fn default() -> Archx64 {
50 Archx64 { features: x64data::Features::all() }
51 }
52}
53
54impl Default for Archx86 {
55 fn default() -> Archx86 {
56 Archx86 { features: x64data::Features::all() }
57 }
58}
59
60pub trait AssembleX64 {
61 fn compile_instruction(&mut self, arch: &Archx64, _: InstructionX64) -> Result<(), Error>;
64
65 fn build_instruction(&mut self, arch: &Archx64, _: InstructionX64) -> Result<(), Error>
68 where Self: BasicExprBuilder;
69}
70
71pub trait AssembleX86 {
72 fn compile_instruction(&mut self, arch: &Archx86, _: InstructionX86) -> Result<(), Error>;
75
76 fn build_instruction(&mut self, arch: &Archx86, _: InstructionX86) -> Result<(), Error>
79 where Self: BasicExprBuilder;
80}
81
82impl Arch for Archx64 {
83 fn name(&self) -> &str {
84 "x64"
85 }
86
87 fn set_features(&mut self, features: &[String]) {
88 let mut new_features = x64data::Features::empty();
89 for ident in features {
90 new_features |= match x64data::Features::from_str(&ident.to_string()) {
91 Some(feature) => feature,
92 None => {
93 eprintln!("Architecture x64 does not support feature '{}'", ident.to_string());
94 continue;
95 }
96 }
97 }
98 self.features = new_features;
99 }
100
101 fn handle_static_reloc(&self, stmts: &mut Vec<Stmt>, reloc: Jump, size: Size) {
102 let data = [0, size.in_bytes()]; stmts.push(Stmt::zeroed(size));
105 stmts.push(reloc.encode(&data));
106 }
107
108 fn default_align(&self) -> u8 {
109 0x90
110 }
111}
112
113impl AssembleX64 for State<'_> {
114 fn compile_instruction(&mut self, arch: &Archx64, instruction: InstructionX64) -> Result<(), Error> {
115 let InstructionX64 { inst, args } = instruction;
116
117 let ctx = Context {
118 state: self,
119 mode: X86Mode::Long,
120 features: arch.features,
121 };
122
123 compiler::compile_instruction(ctx, inst, args)
124 }
125
126 fn build_instruction(&mut self, _: &Archx64, _: InstructionX64) -> Result<(), Error>
127 where Self: BasicExprBuilder
128 {
129 unreachable!("Statically uncallable, Self is not BasicExprBuilder")
130 }
131}
132
133impl Arch for Archx86 {
134 fn name(&self) -> &str {
135 "x86"
136 }
137
138 fn set_features(&mut self, features: &[String]) {
139 let mut new_features = x64data::Features::empty();
140 for ident in features {
141 new_features |= match x64data::Features::from_str(&ident.to_string()) {
142 Some(feature) => feature,
143 None => {
144 eprintln!("Architecture x86 does not support feature '{}'", ident.to_string());
145 continue;
146 }
147 }
148 }
149 self.features = new_features;
150 }
151
152 fn handle_static_reloc(&self, stmts: &mut Vec<Stmt>, reloc: Jump, size: Size) {
153 let data = [0, size.in_bytes(), 0]; stmts.push(Stmt::zeroed(size));
156 stmts.push(reloc.encode(&data));
157 }
158
159 fn default_align(&self) -> u8 {
160 0x90
161 }
162}
163
164impl AssembleX86 for State<'_> {
165 fn compile_instruction(&mut self, arch: &Archx86, instruction: InstructionX86) -> Result<(), Error> {
166 let InstructionX86 { inst, args } = instruction;
167
168 let ctx = Context {
169 state: self,
170 mode: X86Mode::Protected,
171 features: arch.features,
172 };
173
174 compiler::compile_instruction(ctx, inst, args)
175 }
176
177 fn build_instruction(&mut self, _: &Archx86, _: InstructionX86) -> Result<(), Error>
178 where Self: BasicExprBuilder
179 {
180 unreachable!("Statically uncallable, Self is not BasicExprBuilder")
181 }
182}