summaryrefslogtreecommitdiffstats
path: root/disassembler
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-01-26 19:30:23 -0800
committerAndreas Gampe <agampe@google.com>2015-01-27 08:44:15 -0800
commit031b00dc87cca699f02ce4206a9ecd99d59090dd (patch)
tree931769ccc85050469f5e5cb502021d8d35d5ae30 /disassembler
parent94fc0e7be35ab1dd42c6336071ea53dfc565faee (diff)
downloadart-031b00dc87cca699f02ce4206a9ecd99d59090dd.zip
art-031b00dc87cca699f02ce4206a9ecd99d59090dd.tar.gz
art-031b00dc87cca699f02ce4206a9ecd99d59090dd.tar.bz2
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
Diffstat (limited to 'disassembler')
-rw-r--r--disassembler/disassembler_x86.cc26
1 files changed, 16 insertions, 10 deletions
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) {