diff options
| author | iximeow <me@iximeow.net> | 2025-10-19 20:50:09 +0000 | 
|---|---|---|
| committer | iximeow <me@iximeow.net> | 2025-10-19 23:29:05 +0000 | 
| commit | 153b5b3383d016a8a1440b2b932815efed25f847 (patch) | |
| tree | dd861216ad571e479b74a8bb48cab0c35c091592 /differential-tests/tests | |
| parent | d1fefcc4461363b30f69b3cab386254c77de08e0 (diff) | |
tag instruction decode fixes, differential test precision
Diffstat (limited to 'differential-tests/tests')
| -rw-r--r-- | differential-tests/tests/capstone-differential.rs | 73 | 
1 files changed, 59 insertions, 14 deletions
| diff --git a/differential-tests/tests/capstone-differential.rs b/differential-tests/tests/capstone-differential.rs index 3602ac5..9f85e83 100644 --- a/differential-tests/tests/capstone-differential.rs +++ b/differential-tests/tests/capstone-differential.rs @@ -523,16 +523,6 @@ fn capstone_differential() {                          panic!("text: {}, bytes: {:?}", yax_text, bytes);                      } -                    if cs_text.contains("stz2g ") || cs_text.contains("stzg ") || cs_text.contains("st2g ") || cs_text.contains("stg ") || cs_text.contains("irg ") || cs_text.contains("ssbb") { -                        // TODO yax might not scale the offset right? -                        continue; -                    } - -                    if cs_text.contains("ldg ") { -                        // TODO: yax says ldm, cs says ldg -                        continue; -                    } -                      if cs_text.contains("dfb ") {                          // TODO: yax and cs disagree?                          continue; @@ -683,9 +673,9 @@ fn capstone_differential() {                          if cs_text.starts_with("sev ") {                              return true;                          } -//                        if yax_text.starts_with("hint ") { -//                            return true; -//                        } +                        if yax_text.starts_with("hint ") { +                            return true; +                        }                          // fmlal v0.2s, v0.4h, v0.h[0] != fmlal v0.2s, v0.2h, v0.h[0]. bytes: [0,                          // 0, 80, f] @@ -694,13 +684,68 @@ fn capstone_differential() {                              return true;                          } +                        if cs_text.starts_with("irg") && yax_text.starts_with(cs_text) && yax_text.ends_with(", xzr") { +                            // a trailing xzr is implicit in irg if omitted in the instruction +                            // text. yax includes xzr in this case, capstone does not. +                            return true; +                        } + +                        const TAG_INSTRUCTIONS: [&'static str; 8] = [ +                            "stzgm", "stg", "ldg", "stzg", +                            "stgm", "st2g", "ldgm", "stz2g" +                        ]; + +                        for mnemonic in TAG_INSTRUCTIONS { +                            if parsed_yax.opcode != mnemonic || parsed_cs.opcode != mnemonic { +                                continue; +                            } + +                            for (yax_op, cs_op) in parsed_yax.operands.iter().zip(parsed_cs.operands.iter()) { +                                if yax_op == cs_op { +                                    continue; +                                } +                                match (yax_op, cs_op) { +                                    ( +                                        Some(ParsedOperand::MemoryWithOffset { +                                            base: cs_base, offset: Some(cs_offset), writeback: cs_writeback +                                        }), +                                        Some(ParsedOperand::MemoryWithOffset { +                                            base: yax_base, offset: Some(yax_offset), writeback: yax_writeback +                                        }) +                                    ) => { +                                        if cs_base != yax_base || cs_writeback != yax_writeback { +                                            // a pretty fundamental decode mismatch.. +                                            return false; +                                        } + +                                        if *cs_offset != *yax_offset && *yax_offset < 0 { +                                            // capstone decodes offsets as an unsigned integer, not +                                            // clamping to the signed range -4096 to 4080. yaxpeax +                                            // decodes the operand into this range. +                                            if (!*yax_offset + 1) & 0x1fff != *cs_offset { +                                                return false; +                                            } +                                        } +                                    } +                                    _ => { +                                        // some operands differ +                                        return false; +                                    } +                                } +                            } + +                            // operand matching above looks OK, opcodes are the same, we're good +                            // here. +                            return true; +                        } +                          return false;                      }  //                    eprintln!("{}", yax_text);                      if !acceptable_match(&yax_text, &cs_text) {                          eprintln!("disassembly mismatch: {} != {}. bytes: {:x?}", yax_text, cs_text, bytes); -//                        std::process::abort(); +                        std::process::abort();                      } else {                          stats.good.fetch_add(1, Ordering::Relaxed);                      } | 
