1 #include "ExpressionConversionVisitor.h"
5 #include "BinaryFunction.h"
6 #include "Dereference.h"
10 #include "../rose/SgAsmExpression.h"
12 using namespace Dyninst;
13 using namespace Dyninst::InstructionAPI;
15 //#include "../rose/x86InstructionSemantics.h"
16 //#include "../rose/powerpcInstructionSemantics.h"
18 using namespace Dyninst;
19 using namespace DataflowAPI;
21 void ExpressionConversionVisitor::visit(InstructionAPI::Immediate* immed) {
24 const Result &value = immed->eval();
26 // TODO rose doesn't distinguish signed/unsigned within the value itself,
27 // only at operations?
29 // TODO rose doesn't handle large values (XMM?)
31 // build different kind of rose value object based on type
35 roseExpression = new SgAsmByteValueExpression(value.val.u8val);
39 roseExpression = new SgAsmWordValueExpression(value.val.u16val);
43 roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
47 roseExpression = new SgAsmQuadWordValueExpression(value.val.u64val);
50 roseExpression = new SgAsmSingleFloatValueExpression(value.val.floatval);
53 roseExpression = new SgAsmDoubleFloatValueExpression(value.val.dblval);
56 roseExpression = NULL;
59 m_stack.push_front(roseExpression);
63 void ExpressionConversionVisitor::visit(RegisterAST* regast) {
66 m_stack.push_front(archSpecificRegisterProc(regast, addr));
67 roseExpression = m_stack.front();
71 void ExpressionConversionVisitor::visit(Dereference* deref) {
73 assert(m_stack.size());
74 SgAsmExpression *toderef = m_stack.front();
77 roseExpression = NULL;
82 // TODO fix some mismatched types?
84 switch (deref->eval().type)
88 type = new SgAsmTypeByte();
92 type = new SgAsmTypeWord();
96 type = new SgAsmTypeDoubleWord();
100 type = new SgAsmTypeQuadWord();
103 type = new SgAsmTypeSingleFloat();
106 type = new SgAsmTypeDoubleFloat();
114 SgAsmExpression *segReg = makeSegRegExpr();
115 SgAsmMemoryReferenceExpression* result = new SgAsmMemoryReferenceExpression(toderef, segReg);
116 result->set_type(type);
117 roseExpression = result;
120 SgAsmExpression* ExpressionConversionVisitor::archSpecificRegisterProc(InstructionAPI::RegisterAST* regast, uint64_t addr)
122 MachRegister machReg = regast->getID();
123 if(machReg.isPC()) return NULL;
131 MachRegister machReg = regast->getID();
133 // ideally this would be symbolic
134 SgAsmExpression *constAddrExpr = new SgAsmDoubleWordValueExpression(addr);
135 return constAddrExpr;
137 machReg.getROSERegister(regClass, regNum, regPos);
139 return new SgAsmx86RegisterReferenceExpression((X86RegisterClass) regClass,
141 (X86PositionInRegister) regPos);
147 int regGran = powerpc_condreggranularity_whole;
149 machReg.getROSERegister(regClass, regNum, regGran);
151 return new SgAsmPowerpcRegisterReferenceExpression((PowerpcRegisterClass) regClass,
153 (PowerpcConditionRegisterAccessGranularity) regGran);
162 SgAsmExpression* ExpressionConversionVisitor::makeSegRegExpr()
164 if (arch == Arch_x86) {
165 return new SgAsmx86RegisterReferenceExpression(x86_regclass_segment,
166 x86_segreg_none, x86_regpos_all);
173 /////////////// Visitor class /////////////////
175 void ExpressionConversionVisitor::visit(BinaryFunction* binfunc) {
176 assert(m_stack.size() >= 2);
177 SgAsmExpression *rhs = m_stack.front();
179 SgAsmExpression *lhs = m_stack.front();
181 // If the RHS didn't convert, that means it should disappear
182 // And we are just left with the LHS
184 roseExpression = NULL;
187 roseExpression = lhs;
190 roseExpression = rhs;
193 // now build either add or multiply
194 if (binfunc->isAdd())
195 roseExpression = new SgAsmBinaryAdd(lhs, rhs);
196 else if (binfunc->isMultiply())
197 roseExpression = new SgAsmBinaryMultiply(lhs, rhs);
198 else roseExpression = NULL; // error
200 m_stack.push_front(roseExpression);