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) {
147 SgAsmExpression* reg = archSpecificRegisterProc(regast, addr, size);
149 roseExpression = NULL;
152 m_stack.push_front(reg);
153 roseExpression = m_stack.front();
157 void ExpressionConversionVisitor::visit(Dereference *deref) {
159 assert(m_stack.size());
160 SgAsmExpression *toderef = m_stack.front();
162 if (toderef == NULL) {
163 roseExpression = NULL;
168 // TODO fix some mismatched types?
170 if(arch == Arch_aarch64 || arch == Arch_ppc32 || arch == Arch_ppc64) {
171 bool isSigned = false;
172 switch (deref->eval().type) {
176 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 8, isSigned);
181 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 16, isSigned);
186 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 32, isSigned);
191 type = new SgAsmIntegerType(ByteOrder::ORDER_LSB, 64, isSigned);
194 type = new SgAsmFloatType(ByteOrder::ORDER_LSB, 64,
195 SgAsmFloatType::BitRange::baseSize(0, 52), // significand
196 SgAsmFloatType::BitRange::baseSize(52, 11), // exponent
198 1023, // exponent bias
199 SgAsmFloatType::NORMALIZED_SIGNIFICAND | SgAsmFloatType::GRADUAL_UNDERFLOW);
202 type = new SgAsmFloatType(ByteOrder::ORDER_LSB, 80,
203 SgAsmFloatType::BitRange::baseSize(0, 64), // significand
204 SgAsmFloatType::BitRange::baseSize(64, 15), // exponent
206 16383, // exponent bias
207 SgAsmFloatType::NORMALIZED_SIGNIFICAND | SgAsmFloatType::GRADUAL_UNDERFLOW);
213 switch (deref->eval().type) {
216 type = new SgAsmTypeByte();
220 type = new SgAsmTypeWord();
224 type = new SgAsmTypeDoubleWord();
228 type = new SgAsmTypeQuadWord();
231 type = new SgAsmTypeSingleFloat();
234 type = new SgAsmTypeDoubleFloat();
242 SgAsmExpression *segReg = makeSegRegExpr();
243 SgAsmMemoryReferenceExpression *result = new SgAsmMemoryReferenceExpression(toderef, segReg);
244 result->set_type(type);
245 roseExpression = result;
248 SgAsmExpression *ExpressionConversionVisitor::archSpecificRegisterProc(InstructionAPI::RegisterAST *regast,
249 uint64_t addr, uint64_t size) {
251 MachRegister machReg = regast->getID();
253 //std::cout << " in " << __func__ << " idx = " << machReg << " arch = " << arch << std::endl;
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);
275 if (regClass < 0) return NULL;
276 return new SgAsmx86RegisterReferenceExpression((X86RegisterClass) regClass,
278 (X86PositionInRegister) regPos);
285 SgAsmDirectRegisterExpression *dre;
286 machReg.getROSERegister(regClass, regNum, regPos);
287 if (regClass < 0) return NULL;
288 if (regClass == powerpc_regclass_cr) {
289 // ROSE treats CR as one register, so regNum is always 0.
290 // CR0 to CR7 are 8 subfields within CR.
291 // CR0 has register offset 0
292 // CR1 has register offset 4
293 dre = new SgAsmDirectRegisterExpression(RegisterDescriptor(regClass, regNum, regPos * 4, 4));
294 dre->set_type(new SgAsmIntegerType(ByteOrder::ORDER_LSB, 4, false));
296 dre = new SgAsmDirectRegisterExpression(RegisterDescriptor(regClass, regNum, regPos, machReg.size() * 8));
297 dre->set_type(new SgAsmIntegerType(ByteOrder::ORDER_LSB, machReg.size() * 8, false));
306 machReg.getROSERegister(regClass, regNum, regPos);
307 if (regClass < 0) return NULL;
308 SgAsmDirectRegisterExpression *dre = new SgAsmDirectRegisterExpression(RegisterDescriptor(regClass, regNum, regPos, machReg.size() * 8));
309 dre->set_type(new SgAsmIntegerType(ByteOrder::ORDER_LSB, machReg.size() * 8, false));
317 SgAsmExpression *ExpressionConversionVisitor::makeSegRegExpr() {
318 if (arch == Arch_x86 || arch == Arch_x86_64) {
319 return new SgAsmx86RegisterReferenceExpression(x86_regclass_segment,
320 x86_segreg_none, x86_regpos_all);
327 /////////////// Visitor class /////////////////
329 void ExpressionConversionVisitor::visit(BinaryFunction *binfunc) {
330 assert(m_stack.size() >= 2);
331 SgAsmExpression *rhs = m_stack.front();
333 SgAsmExpression *lhs = m_stack.front();
335 // If the RHS didn't convert, that means it should disappear
336 // And we are just left with the LHS
338 roseExpression = NULL;
341 roseExpression = lhs;
344 roseExpression = rhs;
347 // now build either add or multiply
348 if (binfunc->isAdd())
349 roseExpression = new SgAsmBinaryAdd(lhs, rhs);
350 else if (binfunc->isMultiply())
351 roseExpression = new SgAsmBinaryMultiply(lhs, rhs);
352 else if (binfunc->isLeftShift())
353 roseExpression = new SgAsmBinaryLsl(lhs, rhs);
354 else if (binfunc->isRightArithmeticShift())
355 roseExpression = new SgAsmBinaryAsr(lhs, rhs);
356 else if (binfunc->isRightLogicalShift())
357 roseExpression = new SgAsmBinaryLsr(lhs, rhs);
358 else if (binfunc->isRightRotate())
359 roseExpression = new SgAsmBinaryRor(lhs, rhs);
360 else roseExpression = NULL; // error
362 m_stack.push_front(roseExpression);