mips: fix left shift of negative value in DecodeMemMMReglistImm4Lsl2#2989
mips: fix left shift of negative value in DecodeMemMMReglistImm4Lsl2#2989Samin061 wants to merge 2 commits into
Conversation
Rot127
left a comment
There was a problem hiding this comment.
If I see this correctly in the ISA, is the offset first shifted then sign extended.
vAddr = zero_extend(offset||02) + GPR[sp]
The ISA defines the offset as zero_extend(offset||0^2), but the non-MMR6 path sign-extended the 4-bit field before the << 2. That both triggered a left-shift-of-negative-value UB (field top bit set) and produced a wrong negative offset. Zero-extend the field to match the ISA and the MMR6 path; the shift is now UB-free. Signed-off-by: bibi samina <sam@bugqore.com>
|
You're right, and good catch. The pseudocode is zero_extend(offset||0^2), so the field is zero-extended, not sign-extended. The old SignExtend32 in the non-MMR6 path was wrong on both counts: it made the offset negative (so 4508 decoded as -0x20 instead of 0x20) and the negative value was what tripped the << 2 UB. Switched that path to zero-extend the field, matching the MMR6 branch and the ISA. Now cstool micromips 4508 prints |
|
If you generate changes with LLMs you have to test them properly and see if they make sense. Feel free to open a PR again if you find time to follow those standards. |
|
Reworked and reopened as #2991. GitHub wouldn't let me reopen this one after the branch was force-pushed. |
Your checklist for this pull request
Detailed description
DecodeMemMMReglistImm4Lsl2decodes the offset of the microMIPSLWM16/SWM16instructions. The ISA defines the address as:so the 4-bit
offsetfield is concatenated with two zero bits and then zero-extended. The MMR6 path already treats it as unsigned (fieldFromInstruction_4), but the non-MMR6 path sign-extended the field (SignExtend32((Insn & 0xf), 4)) before the<< 2. That was wrong in two ways: whenever the field's top bit is set (field >= 8) the value became negative, soOffset << 2is a left shift of a negative value (UB), and the decoded offset came out negative instead of the zero-extended value the ISA requires.ubsanon the unpatched tree:Fix is to zero-extend the field to match both the ISA and the MMR6 path. The shift is then always applied to a non-negative value, so the UB is gone and the offset is correct.
Test plan
Added
test_ub_shift_mips_mm_reglisttotests/integration/test_poc.c, next to the existingtest_ub_shift_sh_dsp_psigned-shift regression. Building with-fsanitize=undefined -fno-sanitize-recover=undefinedand runningtest_pocaborts atMipsDisassembler.c:2432before the change and exits cleanly after.cstool micromips 4508now printslwm16 $s0, $ra, 0x20($sp)(the zero-extended8 << 2 == 0x20).