public inbox for gdb-prs@sourceware.org
help / color / mirror / Atom feed
* [Bug gdb/26835] New: undefined behavior in arm_analyze_prologue: shift exponent 32 is too large for 32-bit type 'unsigned int'
@ 2020-11-03 17:17 simark at simark dot ca
  2020-11-13 17:03 ` [Bug gdb/26835] " cvs-commit at gcc dot gnu.org
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: simark at simark dot ca @ 2020-11-03 17:17 UTC (permalink / raw)
  To: gdb-prs

https://sourceware.org/bugzilla/show_bug.cgi?id=26835

            Bug ID: 26835
           Summary: undefined behavior in arm_analyze_prologue: shift
                    exponent 32 is too large for 32-bit type 'unsigned
                    int'
           Product: gdb
           Version: HEAD
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gdb
          Assignee: unassigned at sourceware dot org
          Reporter: simark at simark dot ca
  Target Milestone: ---

See instructions to reproduce here:

https://sourceware.org/bugzilla/show_bug.cgi?id=26828#c6


I have a patch that fixes it (though it needs to be tested a bit more
thoroughly), but it lacks a test.  Ideally, we should have the equivalent of
aarch64_analyze_prologue_test, but for ARM.  That requires a bit of refactoring
of the classes that abstract memory reading in arm-tdep.c, and I don't have
time for that right now.  So I'm putting the patch here in case somebody wants
to pick it up.


>From 48596638d1998a3abcde5a4b7f5369032f9ea08b Mon Sep 17 00:00:00 2001
From: Simon Marchi <simon.marchi@polymtl.ca>
Date: Tue, 3 Nov 2020 12:13:36 -0500
Subject: [PATCH] gdb/arm: avoid undefined behavior shift when decoding
 immediate value

Change-Id: Ieb1c1799bd66f8c7421384f44f5c2777b578ff8d
---
 gdb/arm-tdep.c | 39 +++++++++++++++++++++++++++------------
 1 file changed, 27 insertions(+), 12 deletions(-)

diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c
index 82e8ec4df49c..ab286eb41a57 100644
--- a/gdb/arm-tdep.c
+++ b/gdb/arm-tdep.c
@@ -1485,6 +1485,25 @@ arm_instruction_restores_sp (unsigned int insn)
   return 0;
 }

+/* Implement immediate value decoding, as described in section A5.2.4
+   (Modified immediate constants in ARM instructions) of the ARM Architecture
+   Reference Manual.  */
+
+static uint32_t
+arm_expand_immediate (uint32_t imm)
+{
+  gdb_assert ((imm & 0xfffff000) == 0);
+
+  uint32_t unrotated_value = imm & 0xff;
+  uint32_t rotate_amount = (imm & 0xf00) >> 7;
+
+  if (rotate_amount == 0)
+    return unrotated_value;
+
+  return ((unrotated_value >> rotate_amount)
+         | (unrotated_value << (32 - rotate_amount)));
+}
+
 /* Analyze an ARM mode prologue starting at PROLOGUE_START and
    continuing no further than PROLOGUE_END.  If CACHE is non-NULL,
    fill it in.  Return the first address not recognized as a prologue
@@ -1535,20 +1554,18 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
       else if ((insn & 0xfff00000) == 0xe2800000       /* add Rd, Rn, #n */
               && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
        {
-         unsigned imm = insn & 0xff;                   /* immediate value */
-         unsigned rot = (insn & 0xf00) >> 7;           /* rotate amount */
+         unsigned imm = insn & 0xfff;                   /* immediate value */
          int rd = bits (insn, 12, 15);
-         imm = (imm >> rot) | (imm << (32 - rot));
+         imm = arm_expand_immediate (imm);
          regs[rd] = pv_add_constant (regs[bits (insn, 16, 19)], imm);
          continue;
        }
       else if ((insn & 0xfff00000) == 0xe2400000       /* sub Rd, Rn, #n */
               && pv_is_register (regs[bits (insn, 16, 19)], ARM_SP_REGNUM))
        {
-         unsigned imm = insn & 0xff;                   /* immediate value */
-         unsigned rot = (insn & 0xf00) >> 7;           /* rotate amount */
+         unsigned imm = insn & 0xfff;                   /* immediate value */
          int rd = bits (insn, 12, 15);
-         imm = (imm >> rot) | (imm << (32 - rot));
+         imm = arm_expand_immediate (imm);
          regs[rd] = pv_add_constant (regs[bits (insn, 16, 19)], -imm);
          continue;
        }
@@ -1604,16 +1621,14 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
        }
       else if ((insn & 0xfffff000) == 0xe24cb000)      /* sub fp, ip #n */
        {
-         unsigned imm = insn & 0xff;                   /* immediate value */
-         unsigned rot = (insn & 0xf00) >> 7;           /* rotate amount */
-         imm = (imm >> rot) | (imm << (32 - rot));
+         unsigned imm = insn & 0xfff;                  /* immediate value */
+         imm = arm_expand_immediate (imm);
          regs[ARM_FP_REGNUM] = pv_add_constant (regs[ARM_IP_REGNUM], -imm);
        }
       else if ((insn & 0xfffff000) == 0xe24dd000)      /* sub sp, sp #n */
        {
-         unsigned imm = insn & 0xff;                   /* immediate value */
-         unsigned rot = (insn & 0xf00) >> 7;           /* rotate amount */
-         imm = (imm >> rot) | (imm << (32 - rot));
+         unsigned imm = insn & 0xfff;                  /* immediate value */
+         imm = arm_expand_immediate (imm);
          regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -imm);
        }
       else if ((insn & 0xffff7fff) == 0xed6d0103       /* stfe f?,
-- 
2.29.1

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2022-10-27 20:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-03 17:17 [Bug gdb/26835] New: undefined behavior in arm_analyze_prologue: shift exponent 32 is too large for 32-bit type 'unsigned int' simark at simark dot ca
2020-11-13 17:03 ` [Bug gdb/26835] " cvs-commit at gcc dot gnu.org
2020-11-13 17:04 ` simark at simark dot ca
2022-10-13 23:05 ` sam at gentoo dot org
2022-10-27 20:29 ` luis.machado at arm dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).