summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2011-02-23 03:31:28 +0000
committerSean Callanan <scallanan@apple.com>2011-02-23 03:31:28 +0000
commit8fbc00b5bab870d3c756d40add9b0eb27827fb97 (patch)
tree9700c9e5222aa5e8b125aacda4ae83833e39dcdf
parent3894a795e6283b4b62ccf7b20d69eebd49e8532f (diff)
downloadllvm-8fbc00b5bab870d3c756d40add9b0eb27827fb97.tar.gz
llvm-8fbc00b5bab870d3c756d40add9b0eb27827fb97.tar.bz2
llvm-8fbc00b5bab870d3c756d40add9b0eb27827fb97.tar.xz
Fixed a bug in the enhanced disassembler that caused
it to ignore valid uses of FS and GS as additional base registers in address computations. Added a test case for this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@126302 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/MC/MCDisassembler/EDOperand.cpp20
-rw-r--r--test/MC/Disassembler/X86/enhanced.txt2
2 files changed, 19 insertions, 3 deletions
diff --git a/lib/MC/MCDisassembler/EDOperand.cpp b/lib/MC/MCDisassembler/EDOperand.cpp
index cfeb56fa3d..2b0c73e805 100644
--- a/lib/MC/MCDisassembler/EDOperand.cpp
+++ b/lib/MC/MCDisassembler/EDOperand.cpp
@@ -152,10 +152,23 @@ int EDOperand::evaluate(uint64_t &result,
uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
- //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
-
+
uint64_t addr = 0;
+ unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
+
+ if (segmentReg != 0 && Disassembler.Key.Arch == Triple::x86_64) {
+ unsigned fsID = Disassembler.registerIDWithName("FS");
+ unsigned gsID = Disassembler.registerIDWithName("GS");
+
+ if (segmentReg == fsID ||
+ segmentReg == gsID) {
+ uint64_t segmentBase;
+ if (!callback(&segmentBase, segmentReg, arg))
+ addr += segmentBase;
+ }
+ }
+
if (baseReg) {
uint64_t baseVal;
if (callback(&baseVal, baseReg, arg))
@@ -175,7 +188,7 @@ int EDOperand::evaluate(uint64_t &result,
result = addr;
return 0;
}
- }
+ } // switch (operandType)
break;
case Triple::arm:
case Triple::thumb:
@@ -203,6 +216,7 @@ int EDOperand::evaluate(uint64_t &result,
return 0;
}
}
+ break;
}
return -1;
diff --git a/test/MC/Disassembler/X86/enhanced.txt b/test/MC/Disassembler/X86/enhanced.txt
index 691f87651c..fc6949901b 100644
--- a/test/MC/Disassembler/X86/enhanced.txt
+++ b/test/MC/Disassembler/X86/enhanced.txt
@@ -2,3 +2,5 @@
# CHECK: [o:jne][w: ][0-p:-][0-l:10=10] <br> 0:[RIP/111](pc)=18446744073709551606
0x0f 0x85 0xf6 0xff 0xff 0xff
+# CHECK: [o:movq][w: ][1-r:%gs=r63][1-p::][1-l:8=8][p:,][w: ][0-r:%rcx=r108] <mov> 0:[RCX/108]=0 1:[GS/63]=8
+0x65 0x48 0x8b 0x0c 0x25 0x08 0x00 0x00 0x00