2 * See the dyninst/COPYRIGHT file for copyright information.
4 * We provide the Paradyn Tools (below described as "Paradyn")
5 * on an AS IS basis, and do not warrant its validity or performance.
6 * We reserve the right to update, modify, or discontinue this
7 * software at any time. We shall have no obligation to supply such
8 * updates or modifications or any other form of support to you.
10 * By your use of Paradyn, you understand and agree that we (or any
11 * other person or entity with proprietary rights in Paradyn) are
12 * under no obligation to provide either maintenance services,
13 * update services, notices of latent defects, or correction of
14 * defects for Paradyn.
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "ExpressionConversionVisitor.h"
33 #include "Immediate.h"
34 #include "BinaryFunction.h"
35 #include "Dereference.h"
39 #include "../rose/SgAsmExpression.h"
41 using namespace Dyninst;
42 using namespace Dyninst::InstructionAPI;
44 //#include "../rose/x86InstructionSemantics.h"
45 //#include "../rose/powerpcInstructionSemantics.h"
47 using namespace Dyninst;
48 using namespace DataflowAPI;
50 void ExpressionConversionVisitor::visit(InstructionAPI::Immediate* immed) {
53 const Result &value = immed->eval();
55 // TODO rose doesn't distinguish signed/unsigned within the value itself,
56 // only at operations?
58 // TODO rose doesn't handle large values (XMM?)
60 // build different kind of rose value object based on type
64 roseExpression = new SgAsmByteValueExpression(value.val.u8val);
68 roseExpression = new SgAsmWordValueExpression(value.val.u16val);
72 roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
76 // This only happens with far calls. ROSE appears to be set up to
77 // expect a 32-bit absolute destination (or doesn't handle far call at
78 // all), so give it what it wants.
79 roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
83 roseExpression = new SgAsmQuadWordValueExpression(value.val.u64val);
86 roseExpression = new SgAsmSingleFloatValueExpression(value.val.floatval);
89 roseExpression = new SgAsmDoubleFloatValueExpression(value.val.dblval);
92 roseExpression = NULL;
96 m_stack.push_front(roseExpression);
100 void ExpressionConversionVisitor::visit(RegisterAST* regast) {
103 m_stack.push_front(archSpecificRegisterProc(regast, addr));
104 roseExpression = m_stack.front();
108 void ExpressionConversionVisitor::visit(Dereference* deref) {
110 assert(m_stack.size());
111 SgAsmExpression *toderef = m_stack.front();
113 if(toderef == NULL) {
114 roseExpression = NULL;
119 // TODO fix some mismatched types?
121 switch (deref->eval().type)
125 type = new SgAsmTypeByte();
129 type = new SgAsmTypeWord();
133 type = new SgAsmTypeDoubleWord();
137 type = new SgAsmTypeQuadWord();
140 type = new SgAsmTypeSingleFloat();
143 type = new SgAsmTypeDoubleFloat();
151 SgAsmExpression *segReg = makeSegRegExpr();
152 SgAsmMemoryReferenceExpression* result = new SgAsmMemoryReferenceExpression(toderef, segReg);
153 result->set_type(type);
154 roseExpression = result;
157 SgAsmExpression* ExpressionConversionVisitor::archSpecificRegisterProc(InstructionAPI::RegisterAST* regast, uint64_t addr)
159 MachRegister machReg = regast->getID();
160 if(machReg.isPC()) return NULL;
168 MachRegister machReg = regast->getID();
170 // ideally this would be symbolic
171 SgAsmExpression *constAddrExpr = new SgAsmDoubleWordValueExpression(addr);
172 return constAddrExpr;
174 machReg.getROSERegister(regClass, regNum, regPos);
176 return new SgAsmx86RegisterReferenceExpression((X86RegisterClass) regClass,
178 (X86PositionInRegister) regPos);
184 int regGran = powerpc_condreggranularity_whole;
186 machReg.getROSERegister(regClass, regNum, regGran);
188 return new SgAsmPowerpcRegisterReferenceExpression((PowerpcRegisterClass) regClass,
190 (PowerpcConditionRegisterAccessGranularity) regGran);
199 SgAsmExpression* ExpressionConversionVisitor::makeSegRegExpr()
201 if (arch == Arch_x86) {
202 return new SgAsmx86RegisterReferenceExpression(x86_regclass_segment,
203 x86_segreg_none, x86_regpos_all);
210 /////////////// Visitor class /////////////////
212 void ExpressionConversionVisitor::visit(BinaryFunction* binfunc) {
213 assert(m_stack.size() >= 2);
214 SgAsmExpression *rhs = m_stack.front();
216 SgAsmExpression *lhs = m_stack.front();
218 // If the RHS didn't convert, that means it should disappear
219 // And we are just left with the LHS
221 roseExpression = NULL;
224 roseExpression = lhs;
227 roseExpression = rhs;
230 // now build either add or multiply
231 if (binfunc->isAdd())
232 roseExpression = new SgAsmBinaryAdd(lhs, rhs);
233 else if (binfunc->isMultiply())
234 roseExpression = new SgAsmBinaryMultiply(lhs, rhs);
235 else roseExpression = NULL; // error
237 m_stack.push_front(roseExpression);