diff options
| author | Karl Mehltretter <kmehltretter@gmail.com> | 2026-08-15 02:41:10 +0100 |
|---|---|---|
| committer | Russell King <rmk+kernel@armlinux.org.uk> | 2026-10-14 17:19:50 +0100 |
| commit | 9f878a6c2207f0c12f34a715a6a05cfc95f47460 (patch) | |
| tree | df66734026abca57827d23f2f22a07916620dff4 /tools/perf/scripts/python/stackcollapse.py | |
| parent | 80dafbcb705cead6d25cb821cf29c47da8860c8c (diff) | |
ARM: 9492/1: alignment: fix LSR #32 and ASR #32 offset decoding
The register-offset form of LDR/STR may apply a shift to Rm. Per
DecodeImmShift() (ARM ARM DDI0406C section A8.4.3, "Pseudocode details
of instruction-specified shifts and rotates"), an imm5 of 0 encodes a
shift of 32 for LSR and ASR; only LSL treats 0 as "no shift", and ROR
with 0 encodes RRX.
do_alignment() special-cases RRX but not LSR or ASR, and IS_SHIFT() does
not filter these encodings out, so the block is entered with
shiftval == 0 and the offset becomes Rm instead of 0 (LSR #32) or the
replicated sign of Rm (ASR #32).
do_alignment_finish_ldst() applies the offset to the base-register
writeback of the post-indexed form, so the emulated access itself uses
the correct faulting address but Rn is left holding the wrong value.
Reproduced on ARM926EJ-S (versatile_defconfig, CONFIG_ALIGNMENT_TRAP=y,
gcc 13.3.0) with a misaligned base and Rm = 0x1000:
ldr r0, [r1], r2, lsr #32 Rn advanced by 0x1000, must be unchanged
ldr r0, [r1], r2, asr #32 Rn advanced by 0x1000, must be unchanged
ldr r0, [r1], r2, asr #32 with Rm negative, Rn must decrease by 1
All three are correct with the patch applied, while a lsr #1 control
case is emulated correctly both before and after.
Assisted-by: Claude:claude-fable-5
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'tools/perf/scripts/python/stackcollapse.py')
0 files changed, 0 insertions, 0 deletions
