1 //===-EDOperand.cpp - LLVM Enhanced Disassembler --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the Enhanced Disassembly library's operand class. The
11 // operand is responsible for allowing evaluation given a particular register
14 //===----------------------------------------------------------------------===//
16 #include "EDDisassembler.h"
18 #include "EDOperand.h"
20 #include "llvm/MC/MCInst.h"
24 EDOperand::EDOperand(const EDDisassembler &disassembler,
27 unsigned int &mcOpIndex) :
28 Disassembler(disassembler),
31 MCOpIndex(mcOpIndex) {
32 unsigned int numMCOperands = 0;
34 if(Disassembler.Key.Arch == Triple::x86 ||
35 Disassembler.Key.Arch == Triple::x86_64) {
36 uint8_t operandFlags = inst.ThisInstInfo->operandFlags[opIndex];
38 if (operandFlags & kOperandFlagImmediate) {
41 else if (operandFlags & kOperandFlagRegister) {
44 else if (operandFlags & kOperandFlagMemory) {
45 if (operandFlags & kOperandFlagPCRelative) {
52 else if (operandFlags & kOperandFlagEffectiveAddress) {
57 mcOpIndex += numMCOperands;
60 EDOperand::~EDOperand() {
63 int EDOperand::evaluate(uint64_t &result,
64 EDRegisterReaderCallback callback,
66 if (Disassembler.Key.Arch == Triple::x86 ||
67 Disassembler.Key.Arch == Triple::x86_64) {
68 uint8_t operandFlags = Inst.ThisInstInfo->operandFlags[OpIndex];
70 if (operandFlags & kOperandFlagImmediate) {
71 result = Inst.Inst->getOperand(MCOpIndex).getImm();
74 if (operandFlags & kOperandFlagRegister) {
75 unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
76 return callback(&result, reg, arg);
78 if (operandFlags & kOperandFlagMemory ||
79 operandFlags & kOperandFlagEffectiveAddress){
80 if(operandFlags & kOperandFlagPCRelative) {
81 int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
85 // TODO fix how we do this
87 if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
90 result = ripVal + displacement;
94 unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
95 uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
96 unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
97 int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
98 //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
104 if (callback(&baseVal, baseReg, arg))
111 if (callback(&indexVal, indexReg, arg))
113 addr += (scaleAmount * indexVal);
116 addr += displacement;
129 struct RegisterReaderWrapper {
130 EDRegisterBlock_t regBlock;
133 int readerWrapperCallback(uint64_t *value,
136 struct RegisterReaderWrapper *wrapper = (struct RegisterReaderWrapper *)arg;
137 return wrapper->regBlock(value, regID);
140 int EDOperand::evaluate(uint64_t &result,
141 EDRegisterBlock_t regBlock) {
142 struct RegisterReaderWrapper wrapper;
143 wrapper.regBlock = regBlock;
144 return evaluate(result,
145 readerWrapperCallback,