Calculation of immediate operand in logical immediate instructions was done wrong...
[dyninst.git] / instructionAPI / h / Dereference.h
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 #if !defined(DEREFERENCE_H)
32 #define DEREFERENCE_H
33
34 #include "Expression.h"
35 #include "Register.h"
36 #include <sstream>
37 #include "Visitor.h"
38
39 namespace Dyninst
40 {
41   namespace InstructionAPI
42   {
43     using std::vector;
44
45     /// A %Dereference object is a %Expression that dereferences another %ValueComputation.
46     ///
47     /// A %Dereference contains an %Expression representing an effective address computation.
48     /// Its use set is the same as the use set of the
49     /// %Expression being dereferenced.
50     ///
51     /// It is not possible, given the information in a single instruction, to evaluate
52     /// the result of a dereference.  \c eval may still be called on a %Expression
53     /// that includes dereferences, but the expected use case is as follows:
54     ///   - Determine the address being used in a dereference via the \c eval mechanism
55     ///   - Perform analysis to determine the contents of that address
56     ///   - If necessary, fill in the %Dereference node with the contents of that addresss, using \c setValue
57     ///
58     /// The type associated with a %Dereference node will be the type of the value \em read \em from \em memory,
59     /// not the type used for the address computation.  Two %Dereferences that access the same address but interpret
60     /// the contents of that memory as different types will produce different values.  The children of a %Dereference at
61     /// a given address are identical, regardless of the type of dereference being performed at that address.
62     /// For example, the %Expression shown in Figure 6 could have its root %Dereference, which interprets the memory being dereferenced
63     /// as a unsigned 16-bit integer, replaced with a %Dereference that
64     /// interprets the memory being dereferenced as any other type.  The remainder of the %Expression tree would, however, remain unchanged.
65     class INSTRUCTION_EXPORT Dereference : public Expression
66     {
67
68     public:
69       /// A %Dereference is constructed from a %Expression pointer (raw or shared) representing the address
70       /// to be dereferenced and a type
71       /// indicating how the memory at the address in question is to be interpreted.
72       Dereference(Expression::Ptr addr, Result_Type result_type) : Expression(result_type), addressToDereference(addr)
73       {
74       }
75       virtual ~Dereference() 
76       {
77       }
78       /// A %Dereference has one child, which represents the address being dereferenced.
79       /// \param children Appends the child of this %Dereference to \c children.
80       virtual void getChildren(vector<InstructionAST::Ptr>& children) const
81       {
82         children.push_back(addressToDereference);
83         return;
84       }
85       virtual void getChildren(vector<Expression::Ptr>& children) const
86       {
87           children.push_back(addressToDereference);
88           return;
89       }
90       /// The use set of a %Dereference is the same as the use set of its children.
91       /// \param uses The use set of this %Dereference is inserted into \c uses.
92       virtual void getUses(set<InstructionAST::Ptr>& uses)
93       {
94         addressToDereference->getUses(uses);
95         return;
96       }
97       /// An %InstructionAST is used by a %Dereference if it is equivalent to the 
98       /// %Dereference or it is used by the lone child of the %Dereference
99       virtual bool isUsed(InstructionAST::Ptr findMe) const
100       {
101         return addressToDereference->isUsed(findMe) || *findMe == *this;
102       }
103       virtual std::string format(formatStyle) const
104       {
105         std::stringstream retVal;
106 #if defined(DEBUG_MEMORY_ACCESS_WIDTH)
107         switch(Expression::userSetValue.type)
108         {
109             case u8:
110                 retVal << "u8 @ ";
111                 break;
112             case s8:
113                 retVal << "s8 @ ";
114                 break;
115             case u16:
116                 retVal << "u16 @ ";
117                 break;
118             case s16:
119                 retVal << "s16 @ ";
120                 break;
121             case u32:
122                 retVal << "u32 @ ";
123                 break;
124             case s32:
125                 retVal << "s32 @ ";
126                 break;
127             case u64:
128                 retVal << "u64 @ ";
129                 break;
130             case s64:
131                 retVal << "s64 @ ";
132                 break;
133             case sp_float:
134                 retVal << "float @ ";
135                 break;
136             case dp_float:
137                 retVal << "double @ ";
138                 break;
139             case dbl128:
140                 retVal << "packed double @ ";
141                 break;
142             default:
143                 retVal << "UNKNOWN SIZE @ ";
144                 break;
145         }
146 #endif
147         retVal << "[" << addressToDereference->format() << "]";
148 //        retVal << addressToDereference->format(memoryAccessStyle);
149         return retVal.str();
150       }
151
152       virtual bool bind(Expression* expr, const Result& value)
153       {
154           if(Expression::bind(expr, value))
155           {
156               return true;
157           }
158           return addressToDereference->bind(expr, value);
159       }
160       virtual void apply(Visitor* v)
161       {
162           addressToDereference->apply(v);
163           v->visit(this);
164       }
165     
166
167     protected:
168       virtual bool isSameType(const InstructionAST& rhs) const
169       {
170         return dynamic_cast<const Dereference*>(&rhs) != NULL;
171       }
172       virtual bool isStrictEqual(const InstructionAST& rhs) const
173       {
174         const Dereference& other(dynamic_cast<const Dereference&>(rhs));
175         return *(other.addressToDereference) == *addressToDereference;
176       }
177   
178   
179     private:
180       Expression::Ptr addressToDereference;
181   
182     };
183   };
184 };
185
186
187
188 #endif // !defined(DEREFERENCE_H)