From 031b00dc87cca699f02ce4206a9ecd99d59090dd Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Mon, 26 Jan 2015 19:30:23 -0800 Subject: ART: Fix x86 disassembler Index 4 in SIB is valid when given Rex.x, where it denotes r12 and not the invalid rsp. Bug: 19149560 Change-Id: I1a74bcbb1ccf3686e45a3df5d852a86444f9d850 --- disassembler/disassembler_x86.cc | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'disassembler') diff --git a/disassembler/disassembler_x86.cc b/disassembler/disassembler_x86.cc index 1a768c8..203488d 100644 --- a/disassembler/disassembler_x86.cc +++ b/disassembler/disassembler_x86.cc @@ -119,12 +119,6 @@ static void DumpBaseReg(std::ostream& os, uint8_t rex, uint8_t reg) { DumpAddrReg(os, rex, reg_num); } -static void DumpIndexReg(std::ostream& os, uint8_t rex, uint8_t reg) { - bool rex_x = (rex & REX_X) != 0; - uint8_t reg_num = rex_x ? (reg + 8) : reg; - DumpAddrReg(os, rex, reg_num); -} - static void DumpOpcodeReg(std::ostream& os, uint8_t rex, uint8_t reg, bool byte_operand, uint8_t size_override) { bool rex_b = (rex & REX_B) != 0; @@ -184,18 +178,30 @@ std::string DisassemblerX86::DumpAddress(uint8_t mod, uint8_t rm, uint8_t rex64, uint8_t index = (sib >> 3) & 7; uint8_t base = sib & 7; address << "["; + + // REX.x is bit 3 of index. + if ((rex64 & REX_X) != 0) { + index += 8; + } + + // Mod = 0 && base = 5 (ebp): no base (ignores REX.b). + bool has_base = false; if (base != 5 || mod != 0) { + has_base = true; DumpBaseReg(address, rex64, base); - if (index != 4) { - address << " + "; - } } + + // Index = 4 (esp/rsp) is disallowed. if (index != 4) { - DumpIndexReg(address, rex64, index); + if (has_base) { + address << " + "; + } + DumpAddrReg(address, rex64, index); if (scale != 0) { address << StringPrintf(" * %d", 1 << scale); } } + if (mod == 0) { if (base == 5) { if (index != 4) { -- cgit v1.1