rs6000-tdep.c:skip_prologue avoid negative left shift
authorJoel Brobecker <brobecker@adacore.com>
Thu, 1 Nov 2018 21:46:05 +0000 (16:46 -0500)
committerJoel Brobecker <brobecker@adacore.com>
Thu, 1 Nov 2018 21:46:58 +0000 (17:46 -0400)
the rs6000-tdep.c::skip_prologue function has the following code:

          unsigned int all_mask = ~((1U << fdata->saved_gpr) - 1);

          /* Not a recognized prologue instruction.
             Handle optimizer code motions into the prologue by continuing
             the search if we have no valid frame yet or if the return
             address is not yet saved in the frame.  Also skip instructions
             if some of the GPRs expected to be saved are not yet saved.  */
          if (fdata->frameless == 0 && fdata->nosavedpc == 0
              && (fdata->gpr_mask & all_mask) == all_mask)
            break;

The problem is that fdata->saved_gpr is initialized to -1, and so,
if no instruction is found in the function's prologue that causes us
to set that field to a non-negative value, the sanitizer crashes
with the following message:

    rs6000-tdep.c:1965:34: runtime error: shift exponent -1 is negative

This patch fixes the issue the by only doing the shift if saved_gpr
is not negative. When saved_gpr is negative, we actually don't need
the shift.

gdb/ChangeLog:

        * rs6000-tdep.c (skip_prologue): Fix potential negative left
        shifting.

Tested on ppc-linux native.
Also tested on ppc-elf (baremetal) using AdaCore's testsuite.

gdb/ChangeLog
gdb/rs6000-tdep.c

index 075dd3ddb36cad798484fa2dd878133195b3dada..9f220d99bb98a758b00a0db3dfa7e8f79513c94c 100644 (file)
@@ -1,3 +1,8 @@
+2018-11-01  Joel Brobecker  <brobecker@adacore.com>
+
+       * rs6000-tdep.c (skip_prologue): Fix potential negative left
+       shifting.
+
 2018-11-01  Jerome Guitton  <guitton@adacore.com>
            Joel Brobecker  <brobecker@adacore.com>
 
index 504de3657e6463fd29600db72112ac21bbeddc2a..67c7a36125996aa396b5e71da0de2827bd271654 100644 (file)
@@ -1975,16 +1975,19 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc,
 
       else
        {
-         unsigned int all_mask = ~((1U << fdata->saved_gpr) - 1);
-
          /* Not a recognized prologue instruction.
             Handle optimizer code motions into the prologue by continuing
             the search if we have no valid frame yet or if the return
             address is not yet saved in the frame.  Also skip instructions
             if some of the GPRs expected to be saved are not yet saved.  */
          if (fdata->frameless == 0 && fdata->nosavedpc == 0
-             && (fdata->gpr_mask & all_mask) == all_mask)
-           break;
+             && fdata->saved_gpr != -1)
+           {
+             unsigned int all_mask = ~((1U << fdata->saved_gpr) - 1);
+
+             if ((fdata->gpr_mask & all_mask) == all_mask)
+               break;
+           }
 
          if (op == 0x4e800020          /* blr */
              || op == 0x4e800420)      /* bctr */