You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AsmArm64 package to unit test project.
Currently it's used for test purpose.
It's expected existing arm64 disassembler is replaced to AsmArm64 based implementation. (#3246)
3. Add arm64 disassembler related unit tests.
To ensure existing arm64 disassembler behavior.
Unit test codes are added for major code paths. (It can confirm code coverage results with Analyze Code Coverage on VS)
Note:
Almost of unit tests on .NET Framework are excluded by #if NET directive.
private methods are tested with UnsafeAccessor (It requires .NET 8 or later)
Capstone's native dependencies seems not copied to bin directory when using xUnit v2 (Because it's Library project)
Arm64RegisterValueAccumulator.cs:64 — ExpectingAdd never resets. Unlike ExpectingMovk, this case has no fall-through to LookingForPossibleLdr, so any instruction that isn't the expected ADD
leaves the state machine parked with the stale ADRP value. adrp x0,#0x1000 ; movz x0,#0x100 ; add x0,x0,#0x100 gives HasValue == true, Value == 0x1100 after x0 was clobbered, so a following BR/BLR x0
resolves to a bogus address and the disassembly prints the wrong symbol. The PR's own skipped AdrpThenOther_ThenAdd_ShouldResetValue fails on this today.
Arm64RegisterValueAccumulator.cs:68 — ADD ignores lsl #12. The match checks only Operands[2].Type == Immediate, then does _value | Immediate. adrp x0,#0x1000000 ; add x0,x0,#0xfff, lsl #12
yields page | 0xFFF instead of page + 0xFFF000, with HasValue still true — a silently wrong address rather than a bail-out. At minimum, reject a shifted immediate. (Skipped AdrpThenAdd_WithShiftedImm_ShouldCalculateAddress covers it.)
Arm64RegisterValueAccumulator.cs:41 — MOVZ discards the shift. Same class: _value = details.Operands[1].Immediate drops the lsl amount, so movz x0,#0x1234, lsl #16 seeds 0x1234 instead of 0x12340000.
Arm64RegisterValueAccumulatorTests.Movz.cs:31 — skipped test asserts MOVK semantics.Movz_WithShiftedImmediateValue_ShouldStartNewValue expects 0x3333_2222_1111 from three MOVZs. A real MOVZ
zeroes the rest of the register, so the architectural result is 0x3333_0000_0000. Whoever un-skips this and "fixes" the accumulator to satisfy it will encode a decoding bug.
Tests that can't fail
Arm64DisassemblerTests.TryFollowJumpTrampoline.cs:73 — slot displacement untested. In all four stub tests the getPointer callback returns ExpectedResultAddress for any address, unlike the TryResolvePrecode tests which assert the requested slot. Changing parseBase + (ulong)(long)off0 to parseBase + 4 + (ulong)(long)off0 in the StubPrecode branch leaves the whole suite green. Assert the
address inside getPointer, as TryResolvePrecode_* does.
Arm64DisassemblerTests.TryFollowJumpTrampoline.cs:178 — NonStubHead bails on length, not shape. The test supplies one instruction, so the reader returns 4 bytes and TryReadStubHead bails at read < 12; the stub-shape rejection it names is never reached, and the test passes with all stub matching deleted. Pad to >= 4 non-stub instructions.
Arm64InstructionFormatterTests.cs:19 — padding disabled. The comment says "Use DisassemblyDiagnoserConfig default config value" but FirstOperandCharIndex = 10 is commented out, so the theory runs at
Iced's default of 0 and asserts strings BDN never emits ("b #8" vs. production "b #8" — DisassemblyDiagnoserConfig.cs:86). The shipped column width is only incidentally covered by the one FirstOperandCharIndex = 6 case.
Arm64InstructionFormatterTests.cs:61 — empty symbols map.FormatInstruction_B_WithReferencedAddress passes no symbols, so TryGetValue always misses and the one thing gated on ReferencedAddress
— the Operand.Replace($"#0x{addr:x}", name) substitution — is never run. Add an entry mapping 0x10000 to a name.
Arm64DisassemblerTests.TryGetReferencedAddress.cs:11 — helper skips Init(runtime)._runtime stays null; it works only because no test here feeds an LDR. The first one that does will NRE inside Feed. The sibling helper (Arm64RegisterValueAccumulatorTests.cs:15) does call Init.
Arm64DisassemblerTests.TryGetReferencedAddress.cs:23 — _With_BL builds BR X0. Duplicate of _With_BLR; BL is never covered.
Minor
Arm64Disassembler.cs:145 — constant is ISHLD, not ISH.0xD50339BF has CRm = 0b1001 (DMB ISHLD); DMB ISH is 0xD5033BBF. The new tests construct Arm64BarrierOperationLimitKind.ISHLD,
confirming it. As written a stub prefixed with a plain DMB ISH isn't recognised and precode resolution silently fails — fix the comment/name or widen the match.
ClrMdDisassembler.cs:114 — IClrRuntime switch introduced unchecked downcasts.foreach (ClrModule module in state.Runtime.EnumerateModules()) and the nested foreach (ClrType type in ...) went from
statically-typed iteration to runtime casts, since both interface members are explicit implementations returning IClrModule/IClrType. Nothing breaks against ClrMD 4.0.732401 (the concrete instances
still come back), but FilterAndEnqueue now throws InvalidCastException for any other IClrRuntime — including the MockClrRuntime this PR adds, which makes that path untestable by the harness being
introduced.
Helpers/Arm64TestInstructions.cs:180 — ValidateMultipleOf8 throws "...must be multiple of 4".
It looks like it found some possible bugs in the accumulator (I did not verify myself). Fine if you want to fix them here, or defer for out-of-scope.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains following changes.
1. Cleanup arm64 disassembler related code to preparing to add unit tests
See following PR comment for details.
2. Add AsmArm64 package reference
AsmArm64 package to unit test project.
Currently it's used for test purpose.
It's expected existing arm64 disassembler is replaced to
AsmArm64based implementation. (#3246)3. Add arm64 disassembler related unit tests.
To ensure existing arm64 disassembler behavior.
Unit test codes are added for major code paths. (It can confirm code coverage results with
Analyze Code Coverageon VS)Note:
Almost of unit tests on .NET Framework are excluded by
#if NETdirective.UnsafeAccessor(It requires .NET 8 or later)Libraryproject)