ubsan: aarch64: left shift of negative value
authorAlan Modra <amodra@gmail.com>
Mon, 16 Dec 2019 06:28:30 +0000 (16:58 +1030)
committerAlan Modra <amodra@gmail.com>
Mon, 16 Dec 2019 07:05:13 +0000 (17:35 +1030)
* aarch64-dis.c (sign_extend): Return uint64_t.  Rewrite without
conditional.
(aarch64_ext_imm): Avoid signed overflow.

opcodes/ChangeLog
opcodes/aarch64-dis.c

index d33c7a17d004d280c98e0a04ff79a20383a2dfd6..898a916bbb4ae783dec263dd6fab57bc4270281c 100644 (file)
@@ -1,3 +1,9 @@
+2019-12-16  Alan Modra  <amodra@gmail.com>
+
+       * aarch64-dis.c (sign_extend): Return uint64_t.  Rewrite without
+       conditional.
+       (aarch64_ext_imm): Avoid signed overflow.
+
 2019-12-16  Alan Modra  <amodra@gmail.com>
 
        * microblaze-dis.c (read_insn_microblaze): Avoid signed overflow.
index 8b32097a5fa116d728e7e70b15be11534740c843..abed2d824c5b22075d77a78038dba389844742cc 100644 (file)
@@ -178,18 +178,15 @@ extract_all_fields (const aarch64_operand *self, aarch64_insn code)
 }
 
 /* Sign-extend bit I of VALUE.  */
-static inline int32_t
+static inline uint64_t
 sign_extend (aarch64_insn value, unsigned i)
 {
-  uint32_t ret = value;
+  uint64_t ret, sign;
 
   assert (i < 32);
-  if ((value >> i) & 0x1)
-    {
-      uint32_t val = (uint32_t)(-1) << i;
-      ret = ret | val;
-    }
-  return (int32_t) ret;
+  ret = value;
+  sign = (uint64_t) 1 << i;
+  return ((ret & (sign + sign - 1)) ^ sign) - sign;
 }
 
 /* N.B. the following inline helpfer functions create a dependency on the
@@ -658,7 +655,7 @@ aarch64_ext_imm (const aarch64_operand *self, aarch64_opnd_info *info,
                 const aarch64_inst *inst ATTRIBUTE_UNUSED,
                 aarch64_operand_error *errors ATTRIBUTE_UNUSED)
 {
-  int64_t imm;
+  uint64_t imm;
 
   imm = extract_all_fields (self, code);