diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2017-03-01 13:39:10 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2017-03-01 13:39:10 -0800 |
commit | 02788e1675f0fba49b97263751e03270a1f332b9 (patch) | |
tree | 95bccd89fb41fc7fd3962bbe1b6d69b7d1777c37 | |
parent | 964d502248e41aba1c208f402ddfb5bb7073b792 (diff) | |
download | nasm-02788e1675f0fba49b97263751e03270a1f332b9.tar.gz |
Revert "asm/assemble.c: change the overflow handling for signed byte immediates"
This reverts commit fbb07d68434c95cbf3638459970457ebf796de36.
This change was quite wrong; it is explicitly there to verify the
validity of the value as a 16/32/64-bit number, not it's
8-bit-worthiness.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r-- | asm/assemble.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/asm/assemble.c b/asm/assemble.c index d45fc329..cd58723b 100644 --- a/asm/assemble.c +++ b/asm/assemble.c @@ -1748,28 +1748,34 @@ static void gencode(struct out_data *data, insn *ins) case4(0274): { - int64_t uv; + uint64_t uv, um; int s; - if (absolute_op(opx)) { - if (ins->rex & REX_W) - s = 64; - else if (ins->prefixes[PPS_OSIZE] == P_O16) - s = 16; - else if (ins->prefixes[PPS_OSIZE] == P_O32) - s = 32; - else - s = bits; + if (ins->rex & REX_W) + s = 64; + else if (ins->prefixes[PPS_OSIZE] == P_O16) + s = 16; + else if (ins->prefixes[PPS_OSIZE] == P_O32) + s = 32; + else + s = bits; - /* - * Forcibly discard bits irrelevant for our needs, to - * prevent bogus warnings. + um = (uint64_t)2 << (s-1); + uv = opx->offset; + + if (uv > 127 && uv < (uint64_t)-128 && + (uv < um-128 || uv > um-1)) { + /* If this wasn't explicitly byte-sized, warn as though we + * had fallen through to the imm16/32/64 case. */ - uv = opx->offset; - uv = (uv << (64-s)) >> (64-s); - opx->offset = uv; + nasm_error(ERR_WARNING | ERR_PASS2 | ERR_WARN_NOV, + "%s value exceeds bounds", + (opx->type & BITS8) ? "signed byte" : + s == 16 ? "word" : + s == 32 ? "dword" : + "signed dword"); } - out_imm(data, opx, 1, OUT_SIGNED); + out_imm(data, opx, 1, OUT_WRAP); /* XXX: OUT_SIGNED? */ break; } |