instructionAPI: use uintmax_t when formatting addresses
[dyninst.git] / instructionAPI / src / Operand.C
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
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.
9  * 
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.
15  * 
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.
20  * 
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.
25  * 
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
29  */
30
31 #include "../h/Operand.h"
32 #include "../h/Dereference.h"
33 #include "../h/Register.h"
34 #include "../h/Expression.h"
35 #include <iostream>
36
37 using namespace std;
38
39
40 namespace Dyninst
41 {
42   namespace InstructionAPI
43   {
44     INSTRUCTION_EXPORT void Operand::getReadSet(std::set<RegisterAST::Ptr>& regsRead) const
45     {
46       std::set<InstructionAST::Ptr> useSet;
47       op_value->getUses(useSet);
48       std::set<InstructionAST::Ptr>::const_iterator curUse;
49       for(curUse = useSet.begin(); curUse != useSet.end(); ++curUse)
50       {
51         RegisterAST::Ptr tmp = boost::dynamic_pointer_cast<RegisterAST>(*curUse);
52         if(tmp) 
53         {
54             if(m_isRead || !(*tmp == *op_value))
55                 regsRead.insert(tmp);
56         }
57       }
58     }
59     INSTRUCTION_EXPORT void Operand::getWriteSet(std::set<RegisterAST::Ptr>& regsWritten) const
60     {
61       RegisterAST::Ptr op_as_reg = boost::dynamic_pointer_cast<RegisterAST>(op_value);
62       if(m_isWritten && op_as_reg)
63       {
64         regsWritten.insert(op_as_reg);
65       }
66     }
67
68     INSTRUCTION_EXPORT bool Operand::isRead(Expression::Ptr candidate) const
69     {
70       // The whole expression of a read, any subexpression of a write
71       return op_value->isUsed(candidate) && (m_isRead || !(*candidate == *op_value));
72     }
73     INSTRUCTION_EXPORT bool Operand::isWritten(Expression::Ptr candidate) const
74     {
75       // Whole expression of a write
76       return m_isWritten && (*op_value == *candidate);
77     }    
78     INSTRUCTION_EXPORT bool Operand::readsMemory() const
79     {
80       return (boost::dynamic_pointer_cast<Dereference>(op_value) && m_isRead);
81     }
82     INSTRUCTION_EXPORT bool Operand::writesMemory() const
83     {
84       return (boost::dynamic_pointer_cast<Dereference>(op_value) && m_isWritten);
85     }
86     INSTRUCTION_EXPORT void Operand::addEffectiveReadAddresses(std::set<Expression::Ptr>& memAccessors) const
87     {
88       if(m_isRead && boost::dynamic_pointer_cast<Dereference>(op_value))
89       {
90         std::vector<Expression::Ptr> tmp;
91         op_value->getChildren(tmp);
92         for(std::vector<Expression::Ptr>::const_iterator curKid = tmp.begin();
93             curKid != tmp.end();
94             ++curKid)
95         {
96           memAccessors.insert(*curKid);
97         }
98       }
99     }
100     INSTRUCTION_EXPORT void Operand::addEffectiveWriteAddresses(std::set<Expression::Ptr>& memAccessors) const
101     {
102       if(m_isWritten && boost::dynamic_pointer_cast<Dereference>(op_value))
103       {
104         std::vector<Expression::Ptr> tmp;
105         op_value->getChildren(tmp);
106         for(std::vector<Expression::Ptr>::const_iterator curKid = tmp.begin();
107             curKid != tmp.end();
108             ++curKid)
109         {
110           memAccessors.insert(*curKid);
111         }
112       }
113     }
114     INSTRUCTION_EXPORT std::string Operand::format(Architecture arch, Address addr) const
115     {
116       if(!op_value) return "ERROR: format() called on empty operand!";
117       if (addr) {
118           Expression::Ptr thePC = Expression::Ptr(new RegisterAST(MachRegister::getPC(arch)));
119           op_value->bind(thePC.get(), Result(u32, addr));
120           Result res = op_value->eval();
121           if (res.defined) {
122               stringstream ret;
123               ret << hex << res.convert<uintmax_t>() << dec;
124               return ret.str();
125           }
126       }
127       return op_value->format();
128     }
129     INSTRUCTION_EXPORT Expression::Ptr Operand::getValue() const
130     {
131       return op_value;
132     }
133   };
134 };
135