Branch: refs/heads/master
Home: https://github.com/dyninst/dyninst
Commit: f5fd6ba666cf807c386ef5c67c859cf83d47221c
https://github.com/dyninst/dyninst/commit/f5fd6ba666cf807c386ef5c67c859cf83d47221c
Author: bbiiggppiigg <bbiiggppiigg@xxxxxxxxx>
Date: 2026-06-02 (Tue, 02 Jun 2026)
Changed paths:
M dataflowAPI/rose/x86_64InstructionSemantics.h
M parseAPI/src/BoundFactData.C
Log Message:
-----------
Fix 64-bit shift count masking in ROSE x86-64 semantics (#2269)
x86 masks shift/rotate counts modulo the operand size: mod 32 for
8/16/32-bit operands, but mod 64 for 64-bit operands. The ROSE
semantics extracted the count as Word(5) (extract<0,5>, i.e. mod 32)
for all sizes, so a 64-bit shift like `shrq $0x28` (count 40) was
truncated to 40 & 0x1f = 8.
In jump-table index analysis this produced a bogus bound: an index
computed as `(imm >> 40)` was evaluated as `imm >> 8`, scaling the
StridedInterval by 2^32 and yielding strides/ranges like
2^32[0,10*2^32]. Combined with the 32-bit loop counter in
ReadTable that became an infinite loop.
Fix the 64-bit (case 8) branches of shl/shr/sar/ror to mask the count
mod 64 using Word(6)/extract<0,6>. The <=32-bit branches keep their
correct mod-32 masking.
Also harden StridedInterval::ShiftLeft/ShiftRight: `1 << rhs.low` used
a 32-bit int literal, which is undefined for counts >= 31. Use
(int64_t)1 << rhs.low and bail to top for counts >= 64. Without this,
the now-correct large shift counts would overflow.
Co-authored-by: Claude Opus 4.8 <noreply@xxxxxxxxxxxxx>
To unsubscribe from these emails, change your notification settings at https://github.com/dyninst/dyninst/settings/notifications
|