Skip to content

test: port upstream x86 unit tests - #18

Open
KeyCode17 wants to merge 1 commit into
unicorn-engine:mainfrom
KeyCode17:test/x86-unit-tests
Open

KeyCode17 wants to merge 1 commit into
unicorn-engine:mainfrom
KeyCode17:test/x86-unit-tests

Conversation

@KeyCode17

Copy link
Copy Markdown

x86 is the only architecture whose upstream unit-test file has no Rust counterpart, even though it is by far the largest one. Every other arch was ported:

upstream tests/unit/ size Rust module
test_x86.c 71 KB (none)
test_arm64.c 34 KB tests/arm64.rs
test_arm.c 33 KB tests/arm.rs
test_riscv.c 25 KB tests/riscv.rs
test_mem.c 19 KB tests/mem.rs
test_ctl.c 12 KB tests/ctl.rs
test_mips / ppc / m68k / s390x 1–8 KB all present

x86 appears incidentally in ctl.rs and mem.rs, but nothing covers the x86-specific behaviour that test_x86.c exercises: SMC, MMIO, TCG-op hooks, nested emu_start, TB-cache invalidation, x87 fnstenv, fxsave FPIP, bswap/REX prefix handling, unaligned access logging.

What's in it

  • crates/unicorn/src/tests/x86.rs — 50 tests ported from tests/unit/test_x86.c at the current submodule pin (681bd32), following the existing per-arch module conventions (uc_common_setup, state via new_with_data + get_data_mut, assert_eq! over TEST_CHECK).
  • crates/unicorn/src/tests/mod.rs — registers the module behind #[cfg(feature = "arch_x86")], matching the other arch gates.

No library code is touched.

Not ported (6 of 56), and why

These need bindings that don't exist yet. I deliberately left them out rather than adding API in a test PR — happy to follow up with the bindings if you want them.

upstream test missing binding
test_x86_hook_cpuid, test_x86_hook_insn_rdtsc, test_x86_hook_insn_rdtscp an instruction hook whose callback returns a value (uc_cb_insn_cpuid_t). add_insn_sys_hook takes FnMut(..) -> (), so the "skip the instruction" return can't be expressed.
test_x86_mmu, test_x86_read_virtual uc_x86_msr read/write. MSR isn't in value_size_x86, and reg_read only yields u64.
test_x86_segmentation a uc_x86_mmr accessor to write GDTR.

One judgement call worth flagging

test_x86_unaligned_access / test_x86_64_unaligned_access sit behind #if !defined(TARGET_READ_INLINED) && defined(BOOST_LITTLE_ENDIAN) upstream (CMake sets TARGET_READ_INLINED for aarch64 and ppc). I mirrored that guard with a cfg. Both tests actually pass on aarch64 here when I remove the guard — so it can be dropped if you'd rather have the coverage on Apple Silicon / arm64 CI. I kept it to match upstream's stated constraint rather than silently diverging.

Verification

  • cargo test154 passed, 0 failed (106 before, +48 on this aarch64 host; the two guarded tests bring it to +50 on x86_64).
  • cargo fmt --all --check — clean.
  • cargo clippy --workspace --all-targetsno new hits from this file. (There are 3 pre-existing -D warnings errors in crates/unicorn-sys/build.rs under clippy 1.96 — collapsible_if ×2 and unnecessary_debug_formatting. Untouched here; can send a separate PR if you'd like.)
  • Spot-checked that the hook-driven tests aren't passing vacuously: probed that the fnstenv and mem_hooks_pc_guarantee callbacks actually fire, and confirmed a deliberately broken expectation does fail.

Ports tests/unit/test_x86.c from the unicorn submodule (pin 681bd32) to
crates/unicorn/src/tests/x86.rs, following the existing per-arch test
modules. x86 was the only architecture whose upstream test file had no
Rust counterpart, despite being the largest one (71 KB of C).

50 of the 56 upstream tests are ported. The remaining 6 need bindings
that do not exist yet:

  test_x86_hook_cpuid, test_x86_hook_insn_rdtsc, test_x86_hook_insn_rdtscp
    need an instruction hook whose callback returns a value
    (uc_cb_insn_cpuid_t); add_insn_sys_hook takes FnMut(..) -> ().

  test_x86_mmu, test_x86_read_virtual
    need uc_x86_msr read/write; MSR is not covered by value_size_x86 and
    reg_read only returns u64.

  test_x86_segmentation
    needs a uc_x86_mmr accessor to write GDTR.

test_x86_unaligned_access and test_x86_64_unaligned_access are gated on
the same host-arch condition upstream uses (TARGET_READ_INLINED is set
for aarch64 and ppc targets).

Signed-off-by: KeyCode17 <m.daffa.karyudi@gmail.com>
@PhilippTakacs

Copy link
Copy Markdown
Contributor

I don't think there is any benefit in copy the unit test from unicorn. The rust test should test the rust api. If unicorn is working correct is tested by unicorn.

@wtdcode

wtdcode commented Sep 9, 2026

Copy link
Copy Markdown
Member

Same feeling. This does not make too much sense and it will be out of sync easily.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants