Skip to content

AArch64: fix LDR literal detail operand truncation#2984

Draft
amaanmujawar wants to merge 3 commits into
capstone-engine:nextfrom
amaanmujawar:fix-2878-aarch64-ldr-literal
Draft

AArch64: fix LDR literal detail operand truncation#2984
amaanmujawar wants to merge 3 commits into
capstone-engine:nextfrom
amaanmujawar:fix-2878-aarch64-ldr-literal

Conversation

@amaanmujawar

Copy link
Copy Markdown

Your checklist for this pull request

  • I've documented or updated the documentation of every API function and struct this PR changes.
  • I've added tests that prove my fix is effective or that my feature works (if possible)

Detailed description

This PR fixes an AArch64 detail operand issue for LDR literal instructions.

For this instruction:

./build/cstool -d aarch64 a8792958 0x100c894d4

Capstone prints the correct resolved target address:

ldr x8, 0x100cdc408

Before this change, the detail operand was emitted as a memory operand with a truncated displacement:

operands[1].type: MEM
operands[1].mem.disp: 0xcdc408

The label operand is mapped as CS_OP_IMM | CS_OP_MEM. Previously, AArch64_set_detail_op_imm() redirected any operand carrying CS_OP_MEM into the memory-operand path. For an LDR literal target, this stored the resolved address in aarch64_op_mem.disp, which is int32_t, so target addresses above 32 bits were truncated.

This change only routes an immediate into the memory-displacement path when the previous detail operand is an in-progress memory operand with a base register. Standalone literal-load target addresses remain immediate operands and preserve the full resolved address.

Normal base+displacement memory operands are still emitted as AARCH64_OP_MEM.

No public API function or struct is changed.

Test plan

Added a regression test in tests/issues/issues.yaml for issue 2878.

Ran locally:

./build/cstool -d aarch64 a8792958 0x100c894d4
./build/cstool -d aarch64 200440f9 0x1000
./build/cstool -d aarch64 00000034 0x1000
./build/cstool -d aarch64 000000b4 0x1000
git diff --check

The issue case now reports the full address as an immediate operand:

operands[1].type: IMM = 0x100cdc408

A normal base+displacement load still reports a memory operand:

operands[1].type: MEM
operands[1].mem.base: REG = x1
operands[1].mem.disp: 0x8

I could not run cstest locally on macOS because my local build attempts to link cstest as a universal x86_64/arm64 binary while its dependencies are arm64-only. I did not include any build-system changes in this PR.

Closing issues

Closes #2878

@github-actions github-actions Bot added the AArch64 Arch label Jul 2, 2026

@Rot127 Rot127 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That it is a memory operand is intended.
Because the instruction loads at that memory address.
So in the Capstone model it is not an immediate operand but a memory operand.

Please change the disp type to an int64 instead, update the v6 guide (docs/cs_v6_release_guide.mde) and add a test please.

@amaanmujawar

Copy link
Copy Markdown
Author

Done, thanks. I kept it as AARCH64_OP_MEM, changed cs_aarch64_op.mem.disp to int64_t, updated the v6 release guide, and added a regression test.

@Rot127

Rot127 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Please check the tests. Changing the API means you also need to change the test code.

@amaanmujawar amaanmujawar marked this pull request as draft July 3, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AArch64 memory load immediate disponent truncated

2 participants