1use core::fmt;
11use core::iter::FusedIterator;
12
13use super::error::DecodeError;
14use super::flags::FlagEffects;
15use super::form::{ATTR_D64, ATTR_NOT_R0, Form, ModRmSpec, OpcodeField, OperandKind, Slot};
16use super::inst::{Inst, MAX_OPERANDS, Mnemonic};
17use super::operand::{Cond, Mem, Operand, Scale};
18use super::reg::{Reg, Size};
19use super::table;
20
21#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
36pub struct Decoded {
37 inst: Inst,
38 flags: FlagEffects,
39 form: u16,
40 len: u8,
41}
42
43impl Decoded {
44 #[inline]
55 #[must_use]
56 pub const fn inst(&self) -> Inst {
57 self.inst
58 }
59
60 #[allow(clippy::len_without_is_empty)] #[inline]
72 #[must_use]
73 pub const fn len(&self) -> usize {
74 self.len as usize
75 }
76
77 #[must_use]
88 pub fn form(&self) -> &'static Form {
89 table::form(self.form).unwrap_or(&table::FORMS[0])
92 }
93
94 #[inline]
107 #[must_use]
108 pub const fn flags(&self) -> FlagEffects {
109 self.flags
110 }
111}
112
113pub fn decode(bytes: &[u8]) -> Result<Decoded, DecodeError> {
135 Decoder { bytes, pos: 0 }.run()
136}
137
138struct Decoder<'a> {
140 bytes: &'a [u8],
141 pos: usize,
142}
143
144impl Decoder<'_> {
145 #[inline]
146 fn peek(&self) -> Result<u8, DecodeError> {
147 self.bytes
148 .get(self.pos)
149 .copied()
150 .ok_or(DecodeError::Truncated { at: self.pos })
151 }
152
153 #[inline]
154 fn byte(&mut self) -> Result<u8, DecodeError> {
155 let b = self.peek()?;
156 self.pos += 1;
157 Ok(b)
158 }
159
160 fn int(&mut self, n: usize, signed: bool) -> Result<i64, DecodeError> {
163 let end = self
164 .pos
165 .checked_add(n)
166 .ok_or(DecodeError::Truncated { at: self.pos })?;
167 let Some(field) = self.bytes.get(self.pos..end) else {
168 return Err(DecodeError::Truncated {
169 at: self.bytes.len().max(self.pos),
170 });
171 };
172 let mut raw = [0u8; 8];
173 for (dst, src) in raw.iter_mut().zip(field) {
174 *dst = *src;
175 }
176 self.pos = end;
177 let value = u64::from_le_bytes(raw);
178 let bits = (n * 8) as u32;
179 Ok(if bits >= 64 {
180 value as i64
181 } else if signed {
182 let shift = 64 - bits;
183 ((value << shift) as i64) >> shift
184 } else {
185 value as i64
186 })
187 }
188
189 fn run(mut self) -> Result<Decoded, DecodeError> {
190 let mut p66 = false;
191 loop {
192 let b = self.peek()?;
193 match b {
194 0x66 if p66 => return Err(DecodeError::RepeatedPrefix { at: self.pos }),
195 0x66 => p66 = true,
196 0xF0 | 0xF2 | 0xF3 | 0x2E | 0x36 | 0x3E | 0x26 | 0x64 | 0x65 | 0x67 => {
197 return Err(DecodeError::UnsupportedPrefix {
198 at: self.pos,
199 byte: b,
200 });
201 }
202 _ => break,
203 }
204 self.pos += 1;
205 }
206 let mut rex = Rex::NONE;
207 if self.peek()? & 0xF0 == 0x40 {
208 rex = Rex {
209 bits: self.byte()?,
210 at: self.pos - 1,
211 };
212 if is_prefix(self.peek()?) {
213 return Err(DecodeError::MisplacedRex { at: rex.at });
214 }
215 }
216 let mut map = 0u8;
217 if self.peek()? == 0x0F {
218 map = 1;
219 self.pos += 1;
220 }
221 let opcode_at = self.pos;
222 let opcode = self.byte()?;
223 let candidates = table::by_opcode(map, opcode);
224 if candidates.is_empty() {
225 return Err(DecodeError::UnknownOpcode {
226 at: opcode_at,
227 escaped: map == 1,
228 opcode,
229 });
230 }
231 let mut modrm: Option<ModRm> = None;
232 let mut miss = Miss::Size;
233 for &id in candidates {
234 let Some(form) = table::form(id) else {
235 continue;
236 };
237 if !size_matches(form, p66, rex) || !opreg_allowed(form, opcode, rex) {
238 continue;
239 }
240 if !matches!(form.modrm, ModRmSpec::Absent) && modrm.is_none() {
241 let at = self.pos;
242 let byte = self.byte()?;
243 modrm = Some(ModRm {
244 md: byte >> 6,
245 reg: (byte >> 3) & 7,
246 rm: byte & 7,
247 at,
248 });
249 }
250 match check(form, modrm, rex, &mut self)? {
251 Ok(()) => return self.operands(form, opcode, modrm, rex),
252 Err(m) => miss = miss.closer(m),
253 }
254 }
255 Err(miss.into_error(opcode_at, modrm, rex))
256 }
257
258 fn operands(
260 mut self,
261 form: &Form,
262 opcode: u8,
263 modrm: Option<ModRm>,
264 rex: Rex,
265 ) -> Result<Decoded, DecodeError> {
266 let has_rex = rex.present();
267 let rm_operand = match modrm {
268 Some(m) if m.md == 3 => RmOperand::Reg(rex.b() | m.rm),
269 Some(m) => RmOperand::Mem(self.address(m, rex)?),
270 None => RmOperand::None,
271 };
272 let mut ops = [Operand::Imm(0); MAX_OPERANDS];
273 let mut rel_slot = None;
274 let count = usize::from(form.count).min(MAX_OPERANDS);
275 for i in 0..count {
276 let (Some(&kind), Some(&slot)) = (form.kinds.get(i), form.slots.get(i)) else {
277 continue;
278 };
279 let size = kind_size(kind);
280 let op = match (slot, kind) {
281 (Slot::Implied, OperandKind::Fixed(r)) => Operand::Reg(r),
282 (Slot::Implied, _) => Operand::Imm(1),
283 (Slot::Reg, _) => {
284 let num = rex.r() | modrm.map_or(0, |m| m.reg);
285 Operand::Reg(Reg::decode(size, num, has_rex))
286 }
287 (Slot::Opcode, _) => {
288 Operand::Reg(Reg::decode(size, rex.b() | (opcode & 7), has_rex))
289 }
290 (Slot::Rm, _) => match rm_operand {
291 RmOperand::Reg(num) => Operand::Reg(Reg::decode(size, num, has_rex)),
292 RmOperand::Mem(addr) => Operand::Mem(addr.with_size(size)),
293 RmOperand::None => Operand::Imm(0),
294 },
295 (Slot::Imm, OperandKind::Rel { .. }) => {
296 rel_slot = Some(i);
297 Operand::Rel(self.int(usize::from(form.imm_bytes), true)?)
298 }
299 (Slot::Imm, OperandKind::Imm { signed, .. }) => {
300 Operand::Imm(self.int(usize::from(form.imm_bytes), signed)?)
301 }
302 (Slot::Imm, _) => Operand::Imm(0),
303 };
304 if let Some(o) = ops.get_mut(i) {
305 *o = op;
306 }
307 }
308 let len = self.pos;
309 if let Some(Operand::Rel(r)) = rel_slot.and_then(|i| ops.get_mut(i)) {
311 *r += len as i64;
312 }
313 let cond = Cond::from_code(opcode & 15).unwrap_or(Cond::O);
314 let mnemonic = Mnemonic::from_parts(form.op, cond);
315 let inst = Inst::from_slice(mnemonic, ops.get(..count).unwrap_or(&[]))
316 .unwrap_or(Inst::new(mnemonic, []));
317 let mut flags = form.flags;
318 if form.reads_cond {
319 flags = flags.with_read(cond.reads());
320 }
321 Ok(Decoded {
322 inst,
323 flags,
324 form: form.id,
325 len: len.min(15) as u8,
326 })
327 }
328
329 fn address(&mut self, m: ModRm, rex: Rex) -> Result<Mem, DecodeError> {
332 if m.md == 0 && m.rm == 0b101 {
333 let disp = self.int(4, true)? as i32;
334 return Ok(Mem::rip(Size::Qword, disp));
335 }
336 let (base, index, scale) = if m.rm == 0b100 {
337 let sib = self.byte()?;
338 let index_num = rex.x() | ((sib >> 3) & 7);
339 let index = (index_num != 0b100).then(|| Reg::decode(Size::Qword, index_num, true));
340 let base_low = sib & 7;
341 let base = if base_low == 0b101 && m.md == 0 {
342 None
343 } else {
344 Some(Reg::decode(Size::Qword, rex.b() | base_low, true))
345 };
346 (base, index, Scale::from_bits(sib >> 6))
347 } else {
348 (
349 Some(Reg::decode(Size::Qword, rex.b() | m.rm, true)),
350 None,
351 Scale::X1,
352 )
353 };
354 let disp = match (m.md, base) {
355 (0, None) | (2, _) => self.int(4, true)? as i32,
356 (1, _) => self.int(1, true)? as i32,
357 _ => 0,
358 };
359 Ok(Mem::decoded(Size::Qword, base, index, scale, disp))
360 }
361}
362
363#[derive(Clone, Copy)]
365struct ModRm {
366 md: u8,
367 reg: u8,
368 rm: u8,
369 at: usize,
370}
371
372#[derive(Clone, Copy)]
374struct Rex {
375 bits: u8,
376 at: usize,
377}
378
379impl Rex {
380 const NONE: Rex = Rex {
381 bits: 0,
382 at: usize::MAX,
383 };
384
385 fn present(self) -> bool {
386 self.bits != 0
387 }
388 fn w(self) -> bool {
389 self.bits & 8 != 0
390 }
391 fn r(self) -> u8 {
392 (self.bits & 4) << 1
393 }
394 fn x(self) -> u8 {
395 (self.bits & 2) << 2
396 }
397 fn b(self) -> u8 {
398 (self.bits & 1) << 3
399 }
400}
401
402enum RmOperand {
403 None,
404 Reg(u8),
405 Mem(Mem),
406}
407
408#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
410enum Miss {
411 Size,
412 Extension,
413 Register,
414 Rex,
415}
416
417impl Miss {
418 fn closer(self, other: Miss) -> Miss {
419 self.max(other)
420 }
421
422 fn into_error(self, opcode_at: usize, modrm: Option<ModRm>, rex: Rex) -> DecodeError {
423 match (self, modrm) {
424 (Miss::Extension, Some(m)) => DecodeError::UnknownExtension {
425 at: m.at,
426 ext: m.reg,
427 },
428 (Miss::Register, Some(m)) => DecodeError::RegisterOperand { at: m.at },
429 (Miss::Rex, _) => DecodeError::UnusedRex { at: rex.at },
430 _ => DecodeError::InvalidOperandSize { at: opcode_at },
431 }
432 }
433}
434
435fn is_prefix(b: u8) -> bool {
436 matches!(
437 b,
438 0x66 | 0xF0 | 0xF2 | 0xF3 | 0x2E | 0x36 | 0x3E | 0x26 | 0x64 | 0x65 | 0x67
439 ) || b & 0xF0 == 0x40
440}
441
442fn size_matches(form: &Form, p66: bool, rex: Rex) -> bool {
445 p66 == form.p66 && (rex.w() == form.rex_w || (form.attrs & ATTR_D64 != 0 && !form.rex_w))
446}
447
448fn opreg_allowed(form: &Form, opcode: u8, rex: Rex) -> bool {
450 !(matches!(form.field, OpcodeField::Reg)
451 && form.attrs & ATTR_NOT_R0 != 0
452 && opcode & 7 == 0
453 && rex.b() == 0)
454}
455
456fn check(
460 form: &Form,
461 modrm: Option<ModRm>,
462 rex: Rex,
463 decoder: &mut Decoder<'_>,
464) -> Result<Result<(), Miss>, DecodeError> {
465 let mut uses_r = false;
466 let mut uses_x = false;
467 let mut uses_b = matches!(form.field, OpcodeField::Reg);
468 if let Some(m) = modrm.filter(|_| !matches!(form.modrm, ModRmSpec::Absent)) {
469 if let ModRmSpec::Ext(n) = form.modrm {
470 if m.reg != n {
471 return Ok(Err(Miss::Extension));
472 }
473 } else {
474 uses_r = true;
475 }
476 if m.md == 3 {
477 if form.rm_mem_only {
478 return Ok(Err(Miss::Register));
479 }
480 uses_b = true;
481 } else if m.rm == 0b100 {
482 let sib = decoder.peek()?;
484 uses_x = true;
485 uses_b = !(sib & 7 == 0b101 && m.md == 0);
486 } else {
487 uses_b = !(m.rm == 0b101 && m.md == 0);
488 }
489 }
490 let unused = (rex.bits & 4 != 0 && !uses_r)
491 || (rex.bits & 2 != 0 && !uses_x)
492 || (rex.bits & 1 != 0 && !uses_b);
493 Ok(if unused { Err(Miss::Rex) } else { Ok(()) })
494}
495
496fn kind_size(kind: OperandKind) -> Size {
498 match kind {
499 OperandKind::Reg(s) | OperandKind::RegMem(s) | OperandKind::Mem(s) => s,
500 OperandKind::Fixed(r) => r.size(),
501 OperandKind::One | OperandKind::Imm { .. } | OperandKind::Rel { .. } => Size::Qword,
502 }
503}
504
505#[derive(Clone, Debug)]
521pub struct Instructions<'a> {
522 bytes: &'a [u8],
523 offset: usize,
524 failed: bool,
525}
526
527#[must_use]
540pub fn decode_all(bytes: &[u8]) -> Instructions<'_> {
541 Instructions {
542 bytes,
543 offset: 0,
544 failed: false,
545 }
546}
547
548impl Iterator for Instructions<'_> {
549 type Item = Result<(usize, Decoded), DecodeError>;
550
551 fn next(&mut self) -> Option<Self::Item> {
552 if self.failed {
553 return None;
554 }
555 let rest = self.bytes.get(self.offset..).filter(|r| !r.is_empty())?;
556 match decode(rest) {
557 Ok(d) => {
558 let at = self.offset;
559 self.offset += d.len();
560 Some(Ok((at, d)))
561 }
562 Err(e) => {
563 self.failed = true;
564 Some(Err(rebase(e, self.offset)))
565 }
566 }
567 }
568}
569
570impl FusedIterator for Instructions<'_> {}
571
572fn rebase(e: DecodeError, by: usize) -> DecodeError {
575 match e {
576 DecodeError::Truncated { at } => DecodeError::Truncated { at: at + by },
577 DecodeError::UnsupportedPrefix { at, byte } => {
578 DecodeError::UnsupportedPrefix { at: at + by, byte }
579 }
580 DecodeError::RepeatedPrefix { at } => DecodeError::RepeatedPrefix { at: at + by },
581 DecodeError::MisplacedRex { at } => DecodeError::MisplacedRex { at: at + by },
582 DecodeError::UnknownOpcode {
583 at,
584 escaped,
585 opcode,
586 } => DecodeError::UnknownOpcode {
587 at: at + by,
588 escaped,
589 opcode,
590 },
591 DecodeError::InvalidOperandSize { at } => DecodeError::InvalidOperandSize { at: at + by },
592 DecodeError::UnknownExtension { at, ext } => {
593 DecodeError::UnknownExtension { at: at + by, ext }
594 }
595 DecodeError::RegisterOperand { at } => DecodeError::RegisterOperand { at: at + by },
596 DecodeError::UnusedRex { at } => DecodeError::UnusedRex { at: at + by },
597 }
598}
599
600#[derive(Clone, Copy, Debug)]
622pub struct Disassembly<'a> {
623 bytes: &'a [u8],
624 ip: u64,
625}
626
627#[must_use]
638pub fn disassemble(bytes: &[u8], ip: u64) -> Disassembly<'_> {
639 Disassembly { bytes, ip }
640}
641
642const BYTE_COLUMN: usize = 25;
644
645impl fmt::Display for Disassembly<'_> {
646 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
647 let mut offset = 0usize;
648 while let Some(rest) = self.bytes.get(offset..).filter(|r| !r.is_empty()) {
649 let ip = self.ip.wrapping_add(offset as u64);
650 let (len, decoded) = match decode(rest) {
651 Ok(d) => (d.len(), Some(d)),
652 Err(_) => (1, None),
653 };
654 write!(f, "{ip:016x} ")?;
655 let mut written = 0;
656 for b in rest.iter().take(len) {
657 write!(f, "{b:02x} ")?;
658 written += 3;
659 }
660 for _ in written..BYTE_COLUMN {
661 f.write_str(" ")?;
662 }
663 match decoded {
664 Some(d) => writeln!(f, "{}", d.inst().display_at(ip))?,
665 None => f.write_str("(bad)\n")?,
666 }
667 offset += len;
668 }
669 Ok(())
670 }
671}
672
673#[cfg(test)]
674mod tests {
675 use super::*;
676
677 fn text(bytes: &[u8]) -> alloc::string::String {
678 use alloc::string::ToString;
679 decode(bytes)
680 .map(|d| d.inst().to_string())
681 .unwrap_or_else(|e| e.to_string())
682 }
683
684 #[test]
685 fn test_decode_prefix_errors() {
686 assert_eq!(decode(&[0x66]), Err(DecodeError::Truncated { at: 1 }));
687 assert_eq!(
688 decode(&[0x66, 0x66, 0x01, 0xC0]),
689 Err(DecodeError::RepeatedPrefix { at: 1 })
690 );
691 assert_eq!(
692 decode(&[0x48, 0x66, 0x01, 0xC0]),
693 Err(DecodeError::MisplacedRex { at: 0 })
694 );
695 assert_eq!(
696 decode(&[0x48, 0x41, 0x01, 0xC0]),
697 Err(DecodeError::MisplacedRex { at: 0 })
698 );
699 assert_eq!(
700 decode(&[0x67, 0x8B, 0x00]),
701 Err(DecodeError::UnsupportedPrefix { at: 0, byte: 0x67 })
702 );
703 assert_eq!(decode(&[0x48]), Err(DecodeError::Truncated { at: 1 }));
704 assert_eq!(decode(&[0x0F]), Err(DecodeError::Truncated { at: 1 }));
705 }
706
707 #[test]
708 fn test_decode_form_errors() {
709 assert_eq!(
711 decode(&[0xF7, 0xC8]),
712 Err(DecodeError::UnknownExtension { at: 1, ext: 1 })
713 );
714 assert_eq!(
716 decode(&[0x8D, 0xC0]),
717 Err(DecodeError::RegisterOperand { at: 1 })
718 );
719 assert_eq!(decode(&[0x41, 0xC3]), Err(DecodeError::UnusedRex { at: 0 }));
721 assert_eq!(
723 decode(&[0x42, 0x01, 0xC0]),
724 Err(DecodeError::UnusedRex { at: 0 })
725 );
726 assert_eq!(
728 decode(&[0x66, 0x63, 0xC0]),
729 Err(DecodeError::InvalidOperandSize { at: 1 })
730 );
731 assert_eq!(decode(&[0x8B, 0x04]), Err(DecodeError::Truncated { at: 2 }));
733 assert_eq!(
734 decode(&[0x8B, 0x80, 1, 2]),
735 Err(DecodeError::Truncated { at: 4 })
736 );
737 assert_eq!(decode(&[0x05, 1]), Err(DecodeError::Truncated { at: 2 }));
738 }
739
740 #[test]
741 fn test_decode_nop_and_xchg_share_90() {
742 assert_eq!(text(&[0x90]), "nop");
743 assert_eq!(text(&[0x66, 0x90]), "nop");
744 assert_eq!(text(&[0x48, 0x90]), "nop");
745 assert_eq!(text(&[0x40, 0x90]), "nop");
746 assert_eq!(text(&[0x41, 0x90]), "xchg r8d, eax");
747 assert_eq!(text(&[0x49, 0x90]), "xchg r8, rax");
748 assert_eq!(text(&[0x93]), "xchg ebx, eax");
749 assert_eq!(text(&[0x66, 0x93]), "xchg bx, ax");
750 }
751
752 #[test]
753 fn test_decode_byte_registers_depend_on_rex() {
754 assert_eq!(text(&[0x88, 0xE0]), "mov al, ah");
755 assert_eq!(text(&[0x40, 0x88, 0xE0]), "mov al, spl");
756 assert_eq!(text(&[0x0F, 0xB6, 0xC4]), "movzx eax, ah");
757 assert_eq!(text(&[0x48, 0x0F, 0xB6, 0xC4]), "movzx rax, spl");
758 }
759
760 #[test]
761 fn test_decode_d64_accepts_redundant_rex_w() {
762 assert_eq!(text(&[0x48, 0xFF, 0xE0]), "jmp rax");
763 assert_eq!(text(&[0x48, 0x50]), "push rax");
764 assert_eq!(text(&[0x48, 0xFF, 0x25, 0, 0, 0, 0]), "jmp qword ptr [rip]");
765 assert_eq!(
766 text(&[0x66, 0x50]),
767 "opcode at byte 1 has no form with this operand size"
768 );
769 }
770
771 #[test]
772 fn test_decode_rel_is_from_instruction_start() {
773 assert_eq!(text(&[0xEB, 0xFE]), "jmp $+0x0");
774 assert_eq!(text(&[0xE9, 0, 0, 0, 0]), "jmp $+0x5");
775 assert_eq!(text(&[0x0F, 0x84, 0xFA, 0xFF, 0xFF, 0xFF]), "je $+0x0");
776 }
777
778 #[test]
779 fn test_rebase_shifts_every_variant() {
780 let all = [
781 DecodeError::Truncated { at: 1 },
782 DecodeError::UnsupportedPrefix { at: 1, byte: 0xF0 },
783 DecodeError::RepeatedPrefix { at: 1 },
784 DecodeError::MisplacedRex { at: 1 },
785 DecodeError::UnknownOpcode {
786 at: 1,
787 escaped: false,
788 opcode: 6,
789 },
790 DecodeError::InvalidOperandSize { at: 1 },
791 DecodeError::UnknownExtension { at: 1, ext: 1 },
792 DecodeError::RegisterOperand { at: 1 },
793 DecodeError::UnusedRex { at: 1 },
794 ];
795 for e in all {
796 assert_eq!(rebase(e, 10).at(), 11);
797 }
798 }
799}