Fix shifting of negative value
authorLuis Machado <luis.machado@linaro.org>
Wed, 2 Dec 2020 14:29:30 +0000 (11:29 -0300)
committerLuis Machado <luis.machado@linaro.org>
Fri, 4 Dec 2020 14:17:00 +0000 (11:17 -0300)
When UBSan is enabled, I noticed runtime errors complaining of shifting
of negative numbers.

This patch fixes this by reusing existing macros from the ARM port.

It also removes unused macros from AArch64's port.

gdb/ChangeLog:

2020-12-04  Luis Machado  <luis.machado@linaro.org>

* aarch64-tdep.c (submask, bit, bits): Remove.
* arch/aarch64-insn.c (extract_signed_bitfield): Remove.
(aarch64_decode_adr, aarch64_decode_b aarch64_decode_bcond)
(aarch64_decode_cb, aarch64_decode_tb)
(aarch64_decode_ldr_literal): Use sbits to extract a signed
immediate.
* arch/aarch64-insn.h (submask, bits, bit, sbits): New macros.

gdb/ChangeLog
gdb/aarch64-tdep.c
gdb/arch/aarch64-insn.c
gdb/arch/aarch64-insn.h

index bbd50291bb48bf13e848d2e06313b629a945bcfd..ea51985c99ac83ee4a27a39d2a27163a2d724233 100644 (file)
@@ -1,3 +1,13 @@
+2020-12-04  Luis Machado  <luis.machado@linaro.org>
+
+       * aarch64-tdep.c (submask, bit, bits): Remove.
+       * arch/aarch64-insn.c (extract_signed_bitfield): Remove.
+       (aarch64_decode_adr, aarch64_decode_b aarch64_decode_bcond)
+       (aarch64_decode_cb, aarch64_decode_tb)
+       (aarch64_decode_ldr_literal): Use sbits to extract a signed
+       immediate.
+       * arch/aarch64-insn.h (submask, bits, bit, sbits): New macros.
+
 2020-12-04  Tom de Vries  <tdevries@suse.de>
 
        PR tdep/27007
index 2c1d888904a980c9bdf6ada65be741a385416fdb..680b53ffa6c808cfb619d53f6289fa7833915b93 100644 (file)
 #include "opcode/aarch64.h"
 #include <algorithm>
 
-#define submask(x) ((1L << ((x) + 1)) - 1)
-#define bit(obj,st) (((obj) >> (st)) & 1)
-#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
-
 /* A Homogeneous Floating-Point or Short-Vector Aggregate may have at most
    four members.  */
 #define HA_MAX_NUM_FLDS                4
index 711500aaf4fec2106f7fd99e10685b23cca5eb12..b7c5a601a168bfd8febea2aab1569d0a77751948 100644 (file)
 /* Toggle this file's internal debugging dump.  */
 bool aarch64_debug = false;
 
-/* Extract a signed value from a bit field within an instruction
-   encoding.
-
-   INSN is the instruction opcode.
-
-   WIDTH specifies the width of the bit field to extract (in bits).
-
-   OFFSET specifies the least significant bit of the field where bits
-   are numbered zero counting from least to most significant.  */
-
-static int32_t
-extract_signed_bitfield (uint32_t insn, unsigned width, unsigned offset)
-{
-  unsigned shift_l = sizeof (int32_t) * 8 - (offset + width);
-  unsigned shift_r = sizeof (int32_t) * 8 - width;
-
-  return ((int32_t) insn << shift_l) >> shift_r;
-}
-
 /* Determine if specified bits within an instruction opcode matches a
    specific pattern.
 
@@ -74,7 +55,7 @@ aarch64_decode_adr (CORE_ADDR addr, uint32_t insn, int *is_adrp,
   if (decode_masked_match (insn, 0x1f000000, 0x10000000))
     {
       uint32_t immlo = (insn >> 29) & 0x3;
-      int32_t immhi = extract_signed_bitfield (insn, 19, 5) << 2;
+      int32_t immhi = sbits (insn, 5, 23) * 4;
 
       *is_adrp = (insn >> 31) & 0x1;
       *rd = (insn >> 0) & 0x1f;
@@ -118,7 +99,7 @@ aarch64_decode_b (CORE_ADDR addr, uint32_t insn, int *is_bl,
   if (decode_masked_match (insn, 0x7c000000, 0x14000000))
     {
       *is_bl = (insn >> 31) & 0x1;
-      *offset = extract_signed_bitfield (insn, 26, 0) << 2;
+      *offset = sbits (insn, 0, 25) * 4;
 
       if (aarch64_debug)
        {
@@ -151,7 +132,7 @@ aarch64_decode_bcond (CORE_ADDR addr, uint32_t insn, unsigned *cond,
   if (decode_masked_match (insn, 0xff000010, 0x54000000))
     {
       *cond = (insn >> 0) & 0xf;
-      *offset = extract_signed_bitfield (insn, 19, 5) << 2;
+      *offset = sbits (insn, 5, 23) * 4;
 
       if (aarch64_debug)
        {
@@ -186,7 +167,7 @@ aarch64_decode_cb (CORE_ADDR addr, uint32_t insn, int *is64, int *is_cbnz,
       *rn = (insn >> 0) & 0x1f;
       *is64 = (insn >> 31) & 0x1;
       *is_cbnz = (insn >> 24) & 0x1;
-      *offset = extract_signed_bitfield (insn, 19, 5) << 2;
+      *offset = sbits (insn, 5, 23) * 4;
 
       if (aarch64_debug)
        {
@@ -222,7 +203,7 @@ aarch64_decode_tb (CORE_ADDR addr, uint32_t insn, int *is_tbnz,
       *rt = (insn >> 0) & 0x1f;
       *is_tbnz = (insn >> 24) & 0x1;
       *bit = ((insn >> (31 - 4)) & 0x20) | ((insn >> 19) & 0x1f);
-      *imm = extract_signed_bitfield (insn, 14, 5) << 2;
+      *imm = sbits (insn, 5, 18) * 4;
 
       if (aarch64_debug)
        {
@@ -267,7 +248,7 @@ aarch64_decode_ldr_literal (CORE_ADDR addr, uint32_t insn, int *is_w,
        *is64 = (insn >> 30) & 0x1;
 
       *rt = (insn >> 0) & 0x1f;
-      *offset = extract_signed_bitfield (insn, 19, 5) << 2;
+      *offset = sbits (insn, 5, 23) * 4;
 
       if (aarch64_debug)
        debug_printf ("decode: %s 0x%x %s %s%u, #?\n",
index 6a63ce9c2005acd6fe018a12c640f1be01751d6b..5ce46c1e9da855f95256400c12591d9be37cc13a 100644 (file)
 
 extern bool aarch64_debug;
 
+/* Support routines for instruction parsing.  */
+
+/* Create a mask of X bits.  */
+#define submask(x) ((1L << ((x) + 1)) - 1)
+
+/* Extract the bitfield from OBJ starting at bit ST and ending at bit FN.  */
+#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
+
+/* Extract bit ST from OBJ.  */
+#define bit(obj,st) (((obj) >> (st)) & 1)
+
+/* Extract the signed bitfield from OBJ starting at bit ST and ending at
+   bit FN.  The result is sign-extended.  */
+#define sbits(obj,st,fn) \
+  ((long) (bits(obj,st,fn) | ((long) bit(obj,fn) * ~ submask (fn - st))))
+
 /* List of opcodes that we need for building the jump pad and relocating
    an instruction.  */