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
61 if(arch == Arch_aarch64) {
62 bool isSigned = false;
67 roseExpression = new SgAsmIntegerValueExpression(value.val.u8val,
68 new SgAsmIntegerType(ByteOrder::ORDER_UNSPECIFIED, 8,
74 roseExpression = new SgAsmIntegerValueExpression(value.val.u16val,
75 new SgAsmIntegerType(ByteOrder::ORDER_LSB, 16,
81 roseExpression = new SgAsmIntegerValueExpression(value.val.u32val,
82 new SgAsmIntegerType(ByteOrder::ORDER_LSB, 32,
88 roseExpression = new SgAsmIntegerValueExpression(value.val.u32val,
89 new SgAsmIntegerType(ByteOrder::ORDER_LSB, 32,
95 roseExpression = new SgAsmIntegerValueExpression(value.val.u64val,
96 new SgAsmIntegerType(ByteOrder::ORDER_LSB, 64,
100 roseExpression = new SgAsmSingleFloatValueExpression(value.val.floatval);
103 roseExpression = new SgAsmDoubleFloatValueExpression(value.val.dblval);
106 roseExpression = NULL;
110 switch (value.type) {
113 roseExpression = new SgAsmByteValueExpression(value.val.u8val);
117 roseExpression = new SgAsmWordValueExpression(value.val.u16val);
121 roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
125 // This only happens with far calls. ROSE appears to be set up to
126 // expect a 32-bit absolute destination (or doesn't handle far call at
127 // all), so give it what it wants.
128 roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
132 roseExpression = new SgAsmQuadWordValueExpression(value.val.u64val);
135 roseExpression = new SgAsmSingleFloatValueExpression(value.val.floatval);
138 roseExpression = new SgAsmDoubleFloatValueExpression(value.val.dblval);
141 roseExpression = NULL;
146 m_stack.push_front(roseExpression);
150 void ExpressionConversionVisitor::visit(RegisterAST *regast) {
153 m_stack.push_front(archSpecificRegisterProc(regast, addr, size));
154 roseExpression = m_stack.front();
158 void ExpressionConversionVisitor::visit(Dereference *deref) {
160 assert(m_stack.size());
161 SgAsmExpression *toderef = m_stack.front();
163 if (toderef == NULL) {
164 roseExpression = NULL;
169 // TODO fix some mismatched types?
171 if(arch == Arch_aarch64) {
172 bool isSigned = false;
173 switch (deref->eval().type) {
177 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 8, isSigned);
182 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 16, isSigned);
187 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 32, isSigned);
192 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 64, isSigned);
195 type = new SgAsmFloatType(ByteOrder::ORDER_LSB, 64,
196 SgAsmFloatType::BitRange::baseSize(0, 52), // significand
197 SgAsmFloatType::BitRange::baseSize(52, 11), // exponent
199 1023, // exponent bias
200 SgAsmFloatType::NORMALIZED_SIGNIFICAND | SgAsmFloatType::GRADUAL_UNDERFLOW);
203 type = new SgAsmFloatType(ByteOrder::ORDER_LSB, 80,
204 SgAsmFloatType::BitRange::baseSize(0, 64), // significand
205 SgAsmFloatType::BitRange::baseSize(64, 15), // exponent
207 16383, // exponent bias
208 SgAsmFloatType::NORMALIZED_SIGNIFICAND | SgAsmFloatType::GRADUAL_UNDERFLOW);
214 switch (deref->eval().type) {
217 type = new SgAsmTypeByte();
221 type = new SgAsmTypeWord();
225 type = new SgAsmTypeDoubleWord();
229 type = new SgAsmTypeQuadWord();
232 type = new SgAsmTypeSingleFloat();
235 type = new SgAsmTypeDoubleFloat();
243 SgAsmExpression *segReg = makeSegRegExpr();
244 SgAsmMemoryReferenceExpression *result = new SgAsmMemoryReferenceExpression(toderef, segReg);
245 result->set_type(type);
246 roseExpression = result;
249 SgAsmExpression *ExpressionConversionVisitor::archSpecificRegisterProc(InstructionAPI::RegisterAST *regast,
250 uint64_t addr, uint64_t size) {
252 MachRegister machReg = regast->getID();
261 MachRegister machReg = regast->getID();
262 if (machReg.isPC()) {
263 // ideally this would be symbolic
264 // When ip is read, the value read is not the address of the current instruction,
265 // but the address of the next instruction.
266 SgAsmExpression *constAddrExpr;
267 if (arch == Arch_x86)
268 constAddrExpr = new SgAsmDoubleWordValueExpression(addr + size);
270 constAddrExpr = new SgAsmQuadWordValueExpression(addr + size);
272 return constAddrExpr;
274 machReg.getROSERegister(regClass, regNum, regPos);
276 return new SgAsmx86RegisterReferenceExpression((X86RegisterClass) regClass,
278 (X86PositionInRegister) regPos);
283 int regGran = powerpc_condreggranularity_whole;
285 machReg.getROSERegister(regClass, regNum, regGran);
287 return new SgAsmPowerpcRegisterReferenceExpression((PowerpcRegisterClass) regClass,
289 (PowerpcConditionRegisterAccessGranularity) regGran);
296 machReg.getROSERegister(regClass, regNum, regPos);
298 return new SgAsmDirectRegisterExpression(RegisterDescriptor(regClass, regNum, regPos, machReg.size() * 8));
305 SgAsmExpression *ExpressionConversionVisitor::makeSegRegExpr() {
306 if (arch == Arch_x86 || arch == Arch_x86_64) {
307 return new SgAsmx86RegisterReferenceExpression(x86_regclass_segment,
308 x86_segreg_none, x86_regpos_all);
315 /////////////// Visitor class /////////////////
317 void ExpressionConversionVisitor::visit(BinaryFunction *binfunc) {
318 assert(m_stack.size() >= 2);
319 SgAsmExpression *rhs = m_stack.front();
321 SgAsmExpression *lhs = m_stack.front();
323 // If the RHS didn't convert, that means it should disappear
324 // And we are just left with the LHS
326 roseExpression = NULL;
329 roseExpression = lhs;
332 roseExpression = rhs;
335 // now build either add or multiply
336 if (binfunc->isAdd())
337 roseExpression = new SgAsmBinaryAdd(lhs, rhs);
338 else if (binfunc->isMultiply())
339 roseExpression = new SgAsmBinaryMultiply(lhs, rhs);
340 else if (binfunc->isLeftShift())
341 roseExpression = new SgAsmBinaryLsl(lhs, rhs);
342 else if (binfunc->isRightArithmeticShift())
343 roseExpression = new SgAsmBinaryAsr(lhs, rhs);
344 else if (binfunc->isRightLogicalShift())
345 roseExpression = new SgAsmBinaryLsr(lhs, rhs);
346 else if (binfunc->isRightRotate())
347 roseExpression = new SgAsmBinaryRor(lhs, rhs);
348 else roseExpression = NULL; // error
350 m_stack.push_front(roseExpression);