From 4ea6fdc986f40b13c412335bf2e6c8dbeef67833 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 12 Feb 2018 15:03:37 -0500 Subject: [PATCH] target-arm: A64: Avoid left shifting negative integers in disas_pc_rel_addr Shifting a negative integer left is undefined behaviour in C. Avoid it by assembling and shifting the offset fields as unsigned values and then sign extending as the final action. Backports commit 037e1d009e2fcb80784d37f0e12aa999787d46d4 from qemu --- qemu/target-arm/translate-a64.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index d5ff3ad4..66d5eacf 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -2698,11 +2698,12 @@ static void disas_pc_rel_adr(DisasContext *s, uint32_t insn) TCGContext *tcg_ctx = s->uc->tcg_ctx; unsigned int page, rd; uint64_t base; - int64_t offset; + uint64_t offset; page = extract32(insn, 31, 1); /* SignExtend(immhi:immlo) -> offset */ - offset = ((int64_t)sextract32(insn, 5, 19) << 2) | extract32(insn, 29, 2); + offset = sextract64(insn, 5, 19); + offset = offset << 2 | extract32(insn, 29, 2); rd = extract32(insn, 0, 5); base = s->pc - 4;