aboutsummaryrefslogtreecommitdiff
path: root/test/protected_mode
diff options
context:
space:
mode:
authoriximeow <me@iximeow.net>2023-12-15 17:26:59 -0800
committeriximeow <me@iximeow.net>2023-12-15 17:26:59 -0800
commit003183a4ce31cfb718f4e4083d32c845352c2321 (patch)
treee6931eb0d6baa7eaa99a2386e8d13a6037fd421f /test/protected_mode
parent792eb993a87fab799b3a6659c7750f2221608cbf (diff)
more RegSpec constructor validation, fix bug in x86_64 1b reg specs
* the first four 1-byte registers, `al`, `cl`, `dl`, `bl`, can be constructed in two ways that produce "identical" `RegSpec` that are.. not. e.g. `RegSpec::al() != Regspec::rb(0)` even though `RegSpec::al().name() == RegSpec::rb(0).name()`. this corrects the `rb` constructor at least, but instructions like `4830c0` and `30c0` still produce incompatible versions of `al`. * also fix register numbering used explicit qword-sized RegSpec constructors, r12 and r13 used to produce r8 and r9
Diffstat (limited to 'test/protected_mode')
-rw-r--r--test/protected_mode/mod.rs89
1 files changed, 88 insertions, 1 deletions
diff --git a/test/protected_mode/mod.rs b/test/protected_mode/mod.rs
index 85d92ce..8b5571d 100644
--- a/test/protected_mode/mod.rs
+++ b/test/protected_mode/mod.rs
@@ -3132,10 +3132,97 @@ fn from_reports() {
test_display(&[0xf3, 0x0f, 0x1e, 0x0f], "nop dword [edi], ecx");
}
-mod reg_masks {
+mod reg_specs {
use yaxpeax_x86::protected_mode::RegSpec;
#[test]
+ fn reg_specs_are_correct() {
+ #[cfg(feature = "fmt")]
+ {
+ let cases: Vec<(RegSpec, &'static str)> = vec![
+ (RegSpec::d(0), "eax"), (RegSpec::eax(), "eax"),
+ (RegSpec::d(1), "ecx"), (RegSpec::ecx(), "ecx"),
+ (RegSpec::d(2), "edx"), (RegSpec::edx(), "edx"),
+ (RegSpec::d(3), "ebx"), (RegSpec::ebx(), "ebx"),
+ (RegSpec::d(4), "esp"), (RegSpec::esp(), "esp"),
+ (RegSpec::d(5), "ebp"), (RegSpec::ebp(), "ebp"),
+ (RegSpec::d(6), "esi"), (RegSpec::esi(), "esi"),
+ (RegSpec::d(7), "edi"), (RegSpec::edi(), "edi"),
+
+ (RegSpec::w(0), "ax"), (RegSpec::ax(), "ax"),
+ (RegSpec::w(1), "cx"), (RegSpec::cx(), "cx"),
+ (RegSpec::w(2), "dx"), (RegSpec::dx(), "dx"),
+ (RegSpec::w(3), "bx"), (RegSpec::bx(), "bx"),
+ (RegSpec::w(4), "sp"), (RegSpec::sp(), "sp"),
+ (RegSpec::w(5), "bp"), (RegSpec::bp(), "bp"),
+ (RegSpec::w(6), "si"), (RegSpec::si(), "si"),
+ (RegSpec::w(7), "di"), (RegSpec::di(), "di"),
+
+ (RegSpec::b(0), "al"), (RegSpec::al(), "al"),
+ (RegSpec::b(1), "cl"), (RegSpec::cl(), "cl"),
+ (RegSpec::b(2), "dl"), (RegSpec::dl(), "dl"),
+ (RegSpec::b(3), "bl"), (RegSpec::bl(), "bl"),
+ (RegSpec::b(4), "ah"), (RegSpec::ah(), "ah"),
+ (RegSpec::b(5), "ch"), (RegSpec::ch(), "ch"),
+ (RegSpec::b(6), "dh"), (RegSpec::dh(), "dh"),
+ (RegSpec::b(7), "bh"), (RegSpec::bh(), "bh"),
+
+ (RegSpec::eip(), "eip"),
+ (RegSpec::eflags(), "eflags"),
+ (RegSpec::es(), "es"), (RegSpec::cs(), "cs"),
+ (RegSpec::ss(), "ss"), (RegSpec::ds(), "ds"),
+ (RegSpec::fs(), "fs"), (RegSpec::gs(), "gs"),
+
+ (RegSpec::mask(0), "k0"),
+ (RegSpec::mask(1), "k1"),
+ (RegSpec::mask(2), "k2"),
+ (RegSpec::mask(3), "k3"),
+ (RegSpec::mask(4), "k4"),
+ (RegSpec::mask(5), "k5"),
+ (RegSpec::mask(6), "k6"),
+ (RegSpec::mask(7), "k7"),
+ ];
+
+ for (reg, name) in cases.iter() {
+ assert_eq!(reg.name(), *name);
+ }
+ }
+
+ let cases: Vec<(RegSpec, RegSpec)> = vec![
+ (RegSpec::d(0), RegSpec::eax()),
+ (RegSpec::d(1), RegSpec::ecx()),
+ (RegSpec::d(2), RegSpec::edx()),
+ (RegSpec::d(3), RegSpec::ebx()),
+ (RegSpec::d(4), RegSpec::esp()),
+ (RegSpec::d(5), RegSpec::ebp()),
+ (RegSpec::d(6), RegSpec::esi()),
+ (RegSpec::d(7), RegSpec::edi()),
+
+ (RegSpec::w(0), RegSpec::ax()),
+ (RegSpec::w(1), RegSpec::cx()),
+ (RegSpec::w(2), RegSpec::dx()),
+ (RegSpec::w(3), RegSpec::bx()),
+ (RegSpec::w(4), RegSpec::sp()),
+ (RegSpec::w(5), RegSpec::bp()),
+ (RegSpec::w(6), RegSpec::si()),
+ (RegSpec::w(7), RegSpec::di()),
+
+ (RegSpec::b(0), RegSpec::al()),
+ (RegSpec::b(1), RegSpec::cl()),
+ (RegSpec::b(2), RegSpec::dl()),
+ (RegSpec::b(3), RegSpec::bl()),
+ (RegSpec::b(4), RegSpec::ah()),
+ (RegSpec::b(5), RegSpec::ch()),
+ (RegSpec::b(6), RegSpec::dh()),
+ (RegSpec::b(7), RegSpec::bh()),
+ ];
+
+ for (reg1, reg2) in cases.iter() {
+ assert_eq!(reg1, reg2);
+ }
+ }
+
+ #[test]
#[should_panic]
fn invalid_mask_reg_panics() {
RegSpec::mask(8);