AArch64: Fix truncation of literal load target address (#2878)#2939
AArch64: Fix truncation of literal load target address (#2878)#2939DanielBotnik wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
LLVM doesn't set the loading bit for prefetch instructions. In fact it explicitly sets it to 0.
What is the rational behind that one?
| AArch64_get_detail_op(MI, 0)->type = AARCH64_OP_IMM; | ||
| AArch64_get_detail_op(MI, 0)->imm = Imm; | ||
| AArch64_get_detail_op(MI, 0)->access = map_get_op_access(MI, OpNum); | ||
| AArch64_inc_op_count(MI); |
There was a problem hiding this comment.
There is a helper function for that
|
Also delete the patch file please. I patched it here: capstone-engine/llvm-capstone#92 |
There was a problem hiding this comment.
That instruction wasn't changed here? Why a test?
…ne#2878) Literal load instructions (e.g. `ldr x8, <label>`) map their label operand as IMM|MEM. AArch64_set_detail_op_imm() diverts every operand carrying the MEM flag into AArch64_set_detail_op_mem(), which stores the value into the int32_t memory displacement field. The literal load target is a PC-relative address that can exceed 32 bits, so it was silently truncated (e.g. 0x100cdc408 became 0xcdc408). Only divert an immediate into the memory displacement when a memory operand is actually being assembled, i.e. its base register was set right before (prev_is_mem_base) or the previous operand is a write-back base for a post-indexed offset (prev_is_membase_wb). A standalone immediate that happens to be flagged IMM|MEM - like the literal load target - is now emitted as a full 64 bit immediate, consistent with how adr/adrp report PC-relative targets. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1032df6 to
1d334f7
Compare
|
Thanks for the review! I've addressed all the points: Patch file / prefetch loading bit / "There is a helper function for that" — Agreed. I reverted the The actual truncation bug is in The fix now only diverts an immediate into Validated against the full AArch64 suite ( |
|
Look, I appreciate that you use Capstone in your project and want to fix the bugs. But if you use AI I expect at a bare minimum, that you review the code yourself or let it review by your human if you are a bot. You just changed every single line in the c files in this PR. Although the first attempt was even kinda correct. Feel free to try it another time when you (or your human) has time to review the local changes before asking us to spend time on reviewing it. |
Fixes #2878
Problem
The target address of AArch64 literal load instructions (e.g.
ldr x8, <label>) was truncated to 32 bits:Cause
Literal load instructions map their
$labeloperand asCS_OP_IMM | CS_OP_MEM. TheAlignedLabeloperand group computes the absolute PC-relative target address (MI->address + offset) and passes it toAArch64_set_detail_op_imm(). Because theMEMbit is set, that helper stored the value into the memory displacement fieldmem.disp, which is anint32_t. Target addresses above 32 bits were therefore silently truncated (0x100cdc408→0xcdc408).Fix
Emit the literal load target as a 64-bit immediate, like
adr/adrpdo and as Capstone did prior to 6.x. This restores the correct operand type (IMM) and avoids the truncation:Regular base+offset loads (
ldr x0, [x1, #0x18]) and branch targets are unaffected.Tests
tests/issues/issues.yaml.🤖 Generated with Claude Code