..., at once making it more obvious that even in the negative bit
offset case the resulting bit offset to be used by the inlined
instructions will always be constrained to the operand size of the
original instruction.
Also add a test case which would have failed without the XSA-195 fix.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Release-acked-by: Wei Liu <wei.liu2@citrix.com>
goto fail;
printf("okay\n");
+#ifdef __x86_64__
+ printf("%-40s", "Testing btcq %r8,(%r11)...");
+ instr[0] = 0x4d; instr[1] = 0x0f; instr[2] = 0xbb; instr[3] = 0x03;
+ regs.eflags = 0x200;
+ regs.rip = (unsigned long)&instr[0];
+ regs.r8 = (-1L << 40) + 1;
+ regs.r11 = (unsigned long)(res + (1L << 35));
+ rc = x86_emulate(&ctxt, &emulops);
+ if ( (rc != X86EMUL_OKAY) ||
+ (*res != 0x2233445C) ||
+ (regs.eflags != 0x201) ||
+ (regs.rip != (unsigned long)&instr[4]) )
+ goto fail;
+ printf("okay\n");
+#endif
+
res[0] = 0x12345678;
res[1] = 0x87654321;
else if ( op_bytes == 4 )
src.val = (int32_t)src.val;
if ( (long)src.val < 0 )
- {
- unsigned long byte_offset =
+ ea.mem.off -=
op_bytes + (((-src.val - 1) >> 3) & ~(op_bytes - 1L));
-
- ea.mem.off -= byte_offset;
- src.val = (byte_offset << 3) + src.val;
- }
else
- {
ea.mem.off += (src.val >> 3) & ~(op_bytes - 1L);
- src.val &= (op_bytes << 3) - 1;
- }
+ src.val &= (op_bytes << 3) - 1;
}
/* Becomes a normal DstMem operation from here on. */
d = (d & ~DstMask) | DstMem;