diff options
author | Luis Machado <luis.machado@linaro.org> | 2020-12-02 11:29:30 -0300 |
---|---|---|
committer | Luis Machado <luis.machado@linaro.org> | 2020-12-04 11:17:00 -0300 |
commit | 5382f97180f5be551868449e411a4daaebf232fb (patch) | |
tree | 8cc4c6f8a8d23877ce212441c8946122c829c630 | |
parent | 67748e0f666f0645d7f182e1365f4d9859e55f1d (diff) | |
download | gdb-5382f97180f5be551868449e411a4daaebf232fb.zip gdb-5382f97180f5be551868449e411a4daaebf232fb.tar.gz gdb-5382f97180f5be551868449e411a4daaebf232fb.tar.bz2 |
Fix shifting of negative value
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.
-rw-r--r-- | gdb/ChangeLog | 10 | ||||
-rw-r--r-- | gdb/aarch64-tdep.c | 4 | ||||
-rw-r--r-- | gdb/arch/aarch64-insn.c | 31 | ||||
-rw-r--r-- | gdb/arch/aarch64-insn.h | 16 |
4 files changed, 32 insertions, 29 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index bbd5029..ea51985 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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 diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 2c1d888..680b53f 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -53,10 +53,6 @@ #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 diff --git a/gdb/arch/aarch64-insn.c b/gdb/arch/aarch64-insn.c index 711500a..b7c5a60 100644 --- a/gdb/arch/aarch64-insn.c +++ b/gdb/arch/aarch64-insn.c @@ -22,25 +22,6 @@ /* 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", diff --git a/gdb/arch/aarch64-insn.h b/gdb/arch/aarch64-insn.h index 6a63ce9..5ce46c1 100644 --- a/gdb/arch/aarch64-insn.h +++ b/gdb/arch/aarch64-insn.h @@ -21,6 +21,22 @@ 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. */ |