From: Peter Dinda Date: Wed, 2 Mar 2011 21:36:03 +0000 (-0600) Subject: Corrected handling of decode of memory operands that have a X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=784bdb0320899801d2e9a5ee015e146bc31bdfed;p=palacios.git Corrected handling of decode of memory operands that have a displacement. This now correctly handles negative displacements where the displacement width is <64 bits. --- diff --git a/palacios/src/palacios/vmm_xed.c b/palacios/src/palacios/vmm_xed.c index f4408f2..f140d1a 100644 --- a/palacios/src/palacios/vmm_xed.c +++ b/palacios/src/palacios/vmm_xed.c @@ -700,13 +700,15 @@ static int get_memory_operand(struct guest_info * info, xed_decoded_inst_t * xe index = MASK(mem_op.index, mem_op.index_size); scale = mem_op.scale; - // This is a horrendous hack... - // XED really screwed the pooch in calculating the displacement - if (cpu_mode == LONG) { - displacement = mem_op.displacement; - } else { - displacement = MASK(mem_op.displacement, mem_op.displacement_size); - } + // XED returns the displacement as a 2s complement signed number, but it can + // have different sizes, depending on the instruction encoding. + // we put that into a 64 bit unsigned (the unsigned doesn't matter since + // we only ever do 2s complement arithmetic on it. However, this means we + // need to sign-extend what XED provides through 64 bits. + displacement = mem_op.displacement; + displacement <<= 64 - mem_op.displacement_size * 8; + displacement = ((sllong_t)displacement) >> (64 - mem_op.displacement_size * 8); + PrintDebug("Seg=%p, base=%p, index=%p, scale=%p, displacement=%p\n", (void *)seg, (void *)base, (void *)index, (void *)scale, (void *)(addr_t)displacement);