This is an automated email from Gerrit.

"Mark O'Donovan <[email protected]>" just uploaded a new patch set to Gerrit, 
which you can find at https://review.openocd.org/c/openocd/+/9502

-- gerrit

commit 53fccd7c02da2c8653167878b518db25c9c5e396
Author: Mark O'Donovan <[email protected]>
Date:   Mon Mar 9 21:24:32 2026 +0000

    target/arm_simulator: fix undefined behaviour
    
    Shifting 32 bit unsigned variables by 32 bits is undefined behaviour
    
    Change-Id: I846619a522c747f9c3b11a814a1864d1d51cfe87
    Signed-off-by: Mark O'Donovan <[email protected]>

diff --git a/src/target/arm_simulator.c b/src/target/arm_simulator.c
index e9f6671166..5ad57c465d 100644
--- a/src/target/arm_simulator.c
+++ b/src/target/arm_simulator.c
@@ -27,25 +27,31 @@ static uint32_t arm_shift(uint8_t shift, uint32_t rm,
        shift_amount &= 0xff;
 
        if (shift == 0x0) {     /* LSL */
-               if ((shift_amount > 0) && (shift_amount <= 32)) {
+               if (shift_amount > 0 && shift_amount < 32) {
                        return_value = rm << shift_amount;
                        *carry = rm >> (32 - shift_amount);
+               } else if (shift_amount == 32) {
+                       return_value = 0x0;
+                       *carry = rm & 0x1;
                } else if (shift_amount > 32) {
                        return_value = 0x0;
                        *carry = 0x0;
                } else /* (shift_amount == 0) */
                        return_value = rm;
        } else if (shift == 0x1) {      /* LSR */
-               if ((shift_amount > 0) && (shift_amount <= 32)) {
+               if (shift_amount > 0 && shift_amount < 32) {
                        return_value = rm >> shift_amount;
                        *carry = (rm >> (shift_amount - 1)) & 1;
+               } else if (shift_amount == 32) {
+                       return_value = 0x0;
+                       *carry = rm & 0x80000000;
                } else if (shift_amount > 32) {
                        return_value = 0x0;
                        *carry = 0x0;
                } else /* (shift_amount == 0) */
                        return_value = rm;
        } else if (shift == 0x2) {      /* ASR */
-               if ((shift_amount > 0) && (shift_amount <= 32)) {
+               if (shift_amount > 0 && shift_amount < 32) {
                        /* C right shifts of unsigned values are guaranteed to
                         * be logical (shift in zeroes); simulate an arithmetic
                         * shift (shift in signed-bit) by adding the sign bit
@@ -54,7 +60,7 @@ static uint32_t arm_shift(uint8_t shift, uint32_t rm,
                        return_value = rm >> shift_amount;
                        if (rm & 0x80000000)
                                return_value |= 0xffffffff << (32 - 
shift_amount);
-               } else if (shift_amount > 32) {
+               } else if (shift_amount >= 32) {
                        if (rm & 0x80000000) {
                                return_value = 0xffffffff;
                                *carry = 0x1;

-- 

Reply via email to