diff options
author | Alan Modra <amodra@gmail.com> | 2019-12-16 16:58:30 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2019-12-16 17:35:13 +1030 |
commit | f81e7e2db6d1aaf47561e54356aee12b585533c2 (patch) | |
tree | 53524a5a7c584b514762e5cd1ca94c40044e2bf2 /opcodes/aarch64-dis.c | |
parent | 488d02fe7729dda5b9414a3942df68e0c316ce53 (diff) | |
download | gdb-f81e7e2db6d1aaf47561e54356aee12b585533c2.zip gdb-f81e7e2db6d1aaf47561e54356aee12b585533c2.tar.gz gdb-f81e7e2db6d1aaf47561e54356aee12b585533c2.tar.bz2 |
ubsan: aarch64: left shift of negative value
* aarch64-dis.c (sign_extend): Return uint64_t. Rewrite without
conditional.
(aarch64_ext_imm): Avoid signed overflow.
Diffstat (limited to 'opcodes/aarch64-dis.c')
-rw-r--r-- | opcodes/aarch64-dis.c | 15 |
1 files changed, 6 insertions, 9 deletions
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index 8b32097..abed2d8 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -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); |