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 // This only happens with far calls. ROSE appears to be set up to
48 // expect a 32-bit absolute destination (or doesn't handle far call at
49 // all), so give it what it wants.
50 roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
54 roseExpression = new SgAsmQuadWordValueExpression(value.val.u64val);
57 roseExpression = new SgAsmSingleFloatValueExpression(value.val.floatval);
60 roseExpression = new SgAsmDoubleFloatValueExpression(value.val.dblval);
63 roseExpression = NULL;
67 m_stack.push_front(roseExpression);
71 void ExpressionConversionVisitor::visit(RegisterAST* regast) {
74 m_stack.push_front(archSpecificRegisterProc(regast, addr));
75 roseExpression = m_stack.front();
79 void ExpressionConversionVisitor::visit(Dereference* deref) {
81 assert(m_stack.size());
82 SgAsmExpression *toderef = m_stack.front();
85 roseExpression = NULL;
90 // TODO fix some mismatched types?
92 switch (deref->eval().type)
96 type = new SgAsmTypeByte();
100 type = new SgAsmTypeWord();
104 type = new SgAsmTypeDoubleWord();
108 type = new SgAsmTypeQuadWord();
111 type = new SgAsmTypeSingleFloat();
114 type = new SgAsmTypeDoubleFloat();
122 SgAsmExpression *segReg = makeSegRegExpr();
123 SgAsmMemoryReferenceExpression* result = new SgAsmMemoryReferenceExpression(toderef, segReg);
124 result->set_type(type);
125 roseExpression = result;
128 SgAsmExpression* ExpressionConversionVisitor::archSpecificRegisterProc(InstructionAPI::RegisterAST* regast, uint64_t addr)
130 MachRegister machReg = regast->getID();
131 if(machReg.isPC()) return NULL;
139 MachRegister machReg = regast->getID();
141 // ideally this would be symbolic
142 SgAsmExpression *constAddrExpr = new SgAsmDoubleWordValueExpression(addr);
143 return constAddrExpr;
145 machReg.getROSERegister(regClass, regNum, regPos);
147 return new SgAsmx86RegisterReferenceExpression((X86RegisterClass) regClass,
149 (X86PositionInRegister) regPos);
155 int regGran = powerpc_condreggranularity_whole;
157 machReg.getROSERegister(regClass, regNum, regGran);
159 return new SgAsmPowerpcRegisterReferenceExpression((PowerpcRegisterClass) regClass,
161 (PowerpcConditionRegisterAccessGranularity) regGran);
170 SgAsmExpression* ExpressionConversionVisitor::makeSegRegExpr()
172 if (arch == Arch_x86) {
173 return new SgAsmx86RegisterReferenceExpression(x86_regclass_segment,
174 x86_segreg_none, x86_regpos_all);
181 /////////////// Visitor class /////////////////
183 void ExpressionConversionVisitor::visit(BinaryFunction* binfunc) {
184 assert(m_stack.size() >= 2);
185 SgAsmExpression *rhs = m_stack.front();
187 SgAsmExpression *lhs = m_stack.front();
189 // If the RHS didn't convert, that means it should disappear
190 // And we are just left with the LHS
192 roseExpression = NULL;
195 roseExpression = lhs;
198 roseExpression = rhs;
201 // now build either add or multiply
202 if (binfunc->isAdd())
203 roseExpression = new SgAsmBinaryAdd(lhs, rhs);
204 else if (binfunc->isMultiply())
205 roseExpression = new SgAsmBinaryMultiply(lhs, rhs);
206 else roseExpression = NULL; // error
208 m_stack.push_front(roseExpression);