[PATCH] target/i386: fix immediate stack adjustment for RET and RETF

Artemii Mashanov posted 1 patch 1 day, 22 hours ago
target/i386/tcg/emit.c.inc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
[PATCH] target/i386: fix immediate stack adjustment for RET and RETF
Posted by Artemii Mashanov 1 day, 22 hours ago
The imm16 operand of RET and RETF specifies an unsigned 16-bit count
of additional bytes to release from the stack.

Previously, gen_RET() and gen_RETF() stored this operand in an int16_t.
For example, 0xcaf5 was interpreted as -13579 instead of 51957.

Use uint16_t for the adjustment in both functions to preserve the
immediate's unsigned value.

Tested locally with near and far returns in both 32-bit and 64-bit
modes. Each combination covered the form without an immediate and
immediate values 0x0000, 0x0001, 0x7fff, 0x8000, 0xcaf5, and 0xffff.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2599

Signed-off-by: Artemii Mashanov <ralerrdirsardx@gmail.com>
---
 target/i386/tcg/emit.c.inc | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc
index 473f415766..0c35403ebc 100644
--- a/target/i386/tcg/emit.c.inc
+++ b/target/i386/tcg/emit.c.inc
@@ -3598,7 +3598,7 @@ static void gen_RDxxBASE(DisasContext *s, X86DecodedInsn *decode)
 
 static void gen_RET(DisasContext *s, X86DecodedInsn *decode)
 {
-    int16_t adjust = decode->e.op1 == X86_TYPE_I ? decode->immediate : 0;
+    uint16_t adjust = decode->e.op1 == X86_TYPE_I ? decode->immediate : 0;
 
     MemOp ot = gen_pop_T0(s);
     gen_stack_update(s, adjust + (1 << ot));
@@ -3609,7 +3609,7 @@ static void gen_RET(DisasContext *s, X86DecodedInsn *decode)
 
 static void gen_RETF(DisasContext *s, X86DecodedInsn *decode)
 {
-    int16_t adjust = decode->e.op1 == X86_TYPE_I ? decode->immediate : 0;
+    uint16_t adjust = decode->e.op1 == X86_TYPE_I ? decode->immediate : 0;
 
     if (!PE(s) || VM86(s)) {
         gen_lea_ss_ofs(s, s->A0, cpu_regs[R_ESP], 0);
-- 
2.55.0