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;
43 using namespace DataflowAPI;
45 void ExpressionConversionVisitor::visit(InstructionAPI::Immediate *immed) {
48 const Result &value = immed->eval();
50 // TODO rose doesn't distinguish signed/unsigned within the value itself,
51 // only at operations?
53 // TODO rose doesn't handle large values (XMM?)
55 // build different kind of rose value object based on type
56 if(arch == Arch_aarch64 || arch == Arch_ppc32 || arch == Arch_ppc64) {
57 bool isSigned = false;
62 roseExpression = new SgAsmIntegerValueExpression(value.val.u8val,
63 new SgAsmIntegerType(ByteOrder::ORDER_UNSPECIFIED, 8,
69 roseExpression = new SgAsmIntegerValueExpression(value.val.u16val,
70 new SgAsmIntegerType(ByteOrder::ORDER_LSB, 16,
76 roseExpression = new SgAsmIntegerValueExpression(value.val.u32val,
77 new SgAsmIntegerType(ByteOrder::ORDER_LSB, 32,
83 roseExpression = new SgAsmIntegerValueExpression(value.val.u32val,
84 new SgAsmIntegerType(ByteOrder::ORDER_LSB, 32,
90 roseExpression = new SgAsmIntegerValueExpression(value.val.u64val,
91 new SgAsmIntegerType(ByteOrder::ORDER_LSB, 64,
95 roseExpression = new SgAsmSingleFloatValueExpression(value.val.floatval);
98 roseExpression = new SgAsmDoubleFloatValueExpression(value.val.dblval);
101 roseExpression = NULL;
105 switch (value.type) {
108 roseExpression = new SgAsmByteValueExpression(value.val.u8val);
112 roseExpression = new SgAsmWordValueExpression(value.val.u16val);
116 roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
120 // This only happens with far calls. ROSE appears to be set up to
121 // expect a 32-bit absolute destination (or doesn't handle far call at
122 // all), so give it what it wants.
123 roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
127 roseExpression = new SgAsmQuadWordValueExpression(value.val.u64val);
130 roseExpression = new SgAsmSingleFloatValueExpression(value.val.floatval);
133 roseExpression = new SgAsmDoubleFloatValueExpression(value.val.dblval);
136 roseExpression = NULL;
141 m_stack.push_front(roseExpression);
145 void ExpressionConversionVisitor::visit(RegisterAST *regast) {
148 m_stack.push_front(archSpecificRegisterProc(regast, addr, size));
149 roseExpression = m_stack.front();
153 void ExpressionConversionVisitor::visit(Dereference *deref) {
155 assert(m_stack.size());
156 SgAsmExpression *toderef = m_stack.front();
158 if (toderef == NULL) {
159 roseExpression = NULL;
164 // TODO fix some mismatched types?
166 if(arch == Arch_aarch64 || arch == Arch_ppc32 || arch == Arch_ppc64) {
167 bool isSigned = false;
168 switch (deref->eval().type) {
172 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 8, isSigned);
177 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 16, isSigned);
182 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 32, isSigned);
187 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 64, isSigned);
190 type = new SgAsmFloatType(ByteOrder::ORDER_LSB, 64,
191 SgAsmFloatType::BitRange::baseSize(0, 52), // significand
192 SgAsmFloatType::BitRange::baseSize(52, 11), // exponent
194 1023, // exponent bias
195 SgAsmFloatType::NORMALIZED_SIGNIFICAND | SgAsmFloatType::GRADUAL_UNDERFLOW);
198 type = new SgAsmFloatType(ByteOrder::ORDER_LSB, 80,
199 SgAsmFloatType::BitRange::baseSize(0, 64), // significand
200 SgAsmFloatType::BitRange::baseSize(64, 15), // exponent
202 16383, // exponent bias
203 SgAsmFloatType::NORMALIZED_SIGNIFICAND | SgAsmFloatType::GRADUAL_UNDERFLOW);
209 switch (deref->eval().type) {
212 type = new SgAsmTypeByte();
216 type = new SgAsmTypeWord();
220 type = new SgAsmTypeDoubleWord();
224 type = new SgAsmTypeQuadWord();
227 type = new SgAsmTypeSingleFloat();
230 type = new SgAsmTypeDoubleFloat();
238 SgAsmExpression *segReg = makeSegRegExpr();
239 SgAsmMemoryReferenceExpression *result = new SgAsmMemoryReferenceExpression(toderef, segReg);
240 result->set_type(type);
241 roseExpression = result;
244 SgAsmExpression *ExpressionConversionVisitor::archSpecificRegisterProc(InstructionAPI::RegisterAST *regast,
245 uint64_t addr, uint64_t size) {
247 MachRegister machReg = regast->getID();
256 MachRegister machReg = regast->getID();
257 if (machReg.isPC()) {
258 // ideally this would be symbolic
259 // When ip is read, the value read is not the address of the current instruction,
260 // but the address of the next instruction.
261 SgAsmExpression *constAddrExpr;
262 if (arch == Arch_x86)
263 constAddrExpr = new SgAsmDoubleWordValueExpression(addr + size);
265 constAddrExpr = new SgAsmQuadWordValueExpression(addr + size);
267 return constAddrExpr;
269 machReg.getROSERegister(regClass, regNum, regPos);
271 return new SgAsmx86RegisterReferenceExpression((X86RegisterClass) regClass,
273 (X86PositionInRegister) regPos);
280 SgAsmDirectRegisterExpression *dre;
281 machReg.getROSERegister(regClass, regNum, regPos);
282 if (regClass == powerpc_regclass_cr) {
283 dre = new SgAsmDirectRegisterExpression(RegisterDescriptor(regClass, regNum, regPos, 4));
285 dre = new SgAsmDirectRegisterExpression(RegisterDescriptor(regClass, regNum, regPos, machReg.size() * 8));
287 dre->set_type(new SgAsmIntegerType(ByteOrder::ORDER_LSB, machReg.size() * 8, false));
295 if((machReg & 0xFF) == (aarch64::pstate & 0xFF) && (machReg & 0xFF0000) == (aarch64::SPR))
298 machReg.getROSERegister(regClass, regNum, regPos);
300 SgAsmDirectRegisterExpression *dre = new SgAsmDirectRegisterExpression(RegisterDescriptor(regClass, regNum, regPos, machReg.size() * 8));
301 dre->set_type(new SgAsmIntegerType(ByteOrder::ORDER_LSB, machReg.size() * 8, false));
309 SgAsmExpression *ExpressionConversionVisitor::makeSegRegExpr() {
310 if (arch == Arch_x86 || arch == Arch_x86_64) {
311 return new SgAsmx86RegisterReferenceExpression(x86_regclass_segment,
312 x86_segreg_none, x86_regpos_all);
319 /////////////// Visitor class /////////////////
321 void ExpressionConversionVisitor::visit(BinaryFunction *binfunc) {
322 assert(m_stack.size() >= 2);
323 SgAsmExpression *rhs = m_stack.front();
325 SgAsmExpression *lhs = m_stack.front();
327 // If the RHS didn't convert, that means it should disappear
328 // And we are just left with the LHS
330 roseExpression = NULL;
333 roseExpression = lhs;
336 roseExpression = rhs;
339 // now build either add or multiply
340 if (binfunc->isAdd())
341 roseExpression = new SgAsmBinaryAdd(lhs, rhs);
342 else if (binfunc->isMultiply())
343 roseExpression = new SgAsmBinaryMultiply(lhs, rhs);
344 else if (binfunc->isLeftShift())
345 roseExpression = new SgAsmBinaryLsl(lhs, rhs);
346 else if (binfunc->isRightArithmeticShift())
347 roseExpression = new SgAsmBinaryAsr(lhs, rhs);
348 else if (binfunc->isRightLogicalShift())
349 roseExpression = new SgAsmBinaryLsr(lhs, rhs);
350 else if (binfunc->isRightRotate())
351 roseExpression = new SgAsmBinaryRor(lhs, rhs);
352 else roseExpression = NULL; // error
354 m_stack.push_front(roseExpression);