2 * Copyright (c) 1996-2007 Barton P. Miller
4 * We provide the Paradyn Parallel Performance Tools (below
5 * described as "Paradyn") on an AS IS basis, and do not warrant its
6 * validity or performance. We reserve the right to update, modify,
7 * or discontinue this software at any time. We shall have no
8 * obligation to supply such updates or modifications or any other
9 * form of support to you.
11 * By your use of Paradyn, you understand and agree that we (or any
12 * other person or entity with proprietary rights in Paradyn) are
13 * under no obligation to provide either maintenance services,
14 * update services, notices of latent defects, or correction of
15 * defects for Paradyn.
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License as published by the Free Software Foundation; either
20 * version 2.1 of the License, or (at your option) any later version.
22 * This library is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
27 * You should have received a copy of the GNU Lesser General Public
28 * License along with this library; if not, write to the Free Software
29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
35 #include "SymEvalPolicy.h"
39 #include "../rose/x86InstructionSemantics.h"
41 using namespace Dyninst;
42 using namespace Dyninst::InstructionAPI;
43 using namespace Dyninst::SymbolicEvaluation;
45 AST::Ptr SymEval::expand(const Assignment::Ptr &assignment) {
46 // This is a shortcut version for when we only want a
50 // Fill it in to mark it as existing
51 res[assignment] = AST::Ptr();
53 return res[assignment];
56 void SymEval::expand(Result &res) {
57 // Symbolic evaluation works off an Instruction
58 // so we have something to hand to ROSE.
59 // Let's assume (and, in fact, assert) that
60 // all of the Assignments we've been handed are for
61 // the same instruction.
63 Result::iterator i = res.begin();
64 if (i == res.end()) return;
66 Assignment::Ptr ptr = i->first;
67 expandInsn(ptr->insn(),
73 void SymEval::expandInsn(const InstructionAPI::Instruction::Ptr insn,
76 SgAsmx86Instruction roseInsn = convert(insn, addr);
77 SymEvalPolicy policy(res, insn->getArch());
78 X86InstructionSemantics<SymEvalPolicy, Handle> t(policy);
79 t.processInstruction(&roseInsn);
83 SgAsmx86Instruction SymEval::convert(const InstructionAPI::Instruction::Ptr &insn, uint64_t addr) {
84 SgAsmx86Instruction rinsn;
86 rinsn.set_address(addr);
87 rinsn.set_mnemonic(insn->format());
88 rinsn.set_kind(convert(insn->getOperation().getID()));
89 // semantics don't support 64-bit code
90 rinsn.set_operandSize(x86_insnsize_32);
91 rinsn.set_addressSize(x86_insnsize_32);
93 std::vector<unsigned char> rawBytes;
94 for (unsigned i = 0; i < insn->size(); ++i) rawBytes.push_back(insn->rawByte(i));
95 rinsn.set_raw_bytes(rawBytes);
98 SgAsmOperandList *roperands = new SgAsmOperandList;
99 std::vector<InstructionAPI::Operand> operands;
100 insn->getOperands(operands);
102 // Override for LEA conversion
103 if (rinsn.get_kind() == x86_lea) {
104 assert(operands.size() == 2);
105 roperands->append_operand(convert(operands[0]));
107 SgAsmExpression *o1 = convert(operands[1]);
108 // We need to wrap o1 in a memory dereference...
109 SgAsmMemoryReferenceExpression *expr = new SgAsmMemoryReferenceExpression(o1);
110 roperands->append_operand(expr);
113 else if (rinsn.get_kind() == x86_push) {
114 assert(operands.size() == 2);
115 roperands->append_operand(convert(operands[0]));
117 else if (rinsn.get_kind() == x86_pop) {
118 assert(operands.size() == 2);
119 roperands->append_operand(convert(operands[0]));
122 for (std::vector<InstructionAPI::Operand>::iterator opi = operands.begin(),
123 ope = operands.end();
126 InstructionAPI::Operand &currOperand = *opi;
127 roperands->append_operand(convert(currOperand));
130 rinsn.set_operandList(roperands);
135 SgAsmExpression *SymEval::convert(const InstructionAPI::Operand &operand) {
136 return convert(operand.getValue());
139 SgAsmExpression *SymEval::convert(const Expression::Ptr expression) {
140 ExpressionConversionVisitor visitor;
141 expression->apply(&visitor);
142 return visitor.getRoseExpression();
145 void ExpressionConversionVisitor::visit(BinaryFunction* binfunc) {
147 vector<InstructionAST::Ptr> children;
148 binfunc->getChildren(children);
149 // convert each InstAST::Ptr to SgAsmExpression*
150 // these casts will not fail
151 SgAsmExpression *lhs =
152 SymEval::convert(dyn_detail::boost::dynamic_pointer_cast<Expression>(children[0]));
153 SgAsmExpression *rhs =
154 SymEval::convert(dyn_detail::boost::dynamic_pointer_cast<Expression>(children[1]));
156 // now build either add or multiply
157 if (binfunc->isAdd())
158 roseExpression = new SgAsmBinaryAdd(lhs, rhs);
159 else if (binfunc->isMultiply())
160 roseExpression = new SgAsmBinaryMultiply(lhs, rhs);
161 else roseExpression = NULL; // error
164 void ExpressionConversionVisitor::visit(Immediate* immed) {
167 const Result &value = immed->eval();
169 // TODO rose doesn't distinguish signed/unsigned within the value itself,
170 // only at operations?
172 // TODO rose doesn't handle large values (XMM?)
174 // build different kind of rose value object based on type
175 switch (value.type) {
178 roseExpression = new SgAsmByteValueExpression(value.val.u8val);
182 roseExpression = new SgAsmWordValueExpression(value.val.u16val);
186 roseExpression = new SgAsmDoubleWordValueExpression(value.val.u32val);
190 roseExpression = new SgAsmQuadWordValueExpression(value.val.u64val);
193 roseExpression = new SgAsmSingleFloatValueExpression(value.val.floatval);
196 roseExpression = new SgAsmDoubleFloatValueExpression(value.val.dblval);
199 roseExpression = NULL;
204 void ExpressionConversionVisitor::visit(RegisterAST* regast) {
211 unsigned int machRegID = regast->getID();
212 MachRegister machReg(machRegID);
213 machReg.getROSERegister(rreg_class, rreg_num, rreg_pos);
215 roseExpression = new SgAsmx86RegisterReferenceExpression((X86RegisterClass)rreg_class,
217 (X86PositionInRegister)rreg_pos);
220 void ExpressionConversionVisitor::visit(Dereference* deref) {
222 vector<InstructionAST::Ptr> children;
223 deref->getChildren(children);
224 SgAsmExpression *toderef =
225 SymEval::convert(dyn_detail::boost::dynamic_pointer_cast<Expression>(children[0]));
229 // TODO fix some mismatched types?
231 switch (deref->eval().type)
235 type = new SgAsmTypeByte();
239 type = new SgAsmTypeWord();
243 type = new SgAsmTypeDoubleWord();
247 type = new SgAsmTypeQuadWord();
250 type = new SgAsmTypeSingleFloat();
253 type = new SgAsmTypeDoubleFloat();
260 SgAsmx86RegisterReferenceExpression *segReg = new SgAsmx86RegisterReferenceExpression(x86_regclass_segment, x86_segreg_none, x86_regpos_all);
262 SgAsmMemoryReferenceExpression *result = new SgAsmMemoryReferenceExpression(toderef, segReg);
263 result->set_type(type);
264 roseExpression = result;