Calculation of immediate operand in logical immediate instructions was done wrong...
[dyninst.git] / instructionAPI / h / Result.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(RESULT_H)
32 #define RESULT_H
33
34 #include <sstream>
35 #include <string.h> // memcmp
36 #if !defined(_MSC_VER)
37 #include <inttypes.h>
38 #else
39    typedef __int64 int64_t;
40    typedef __int32 int32_t;
41    typedef __int16 int16_t;
42    typedef unsigned __int64 uint64_t;
43    typedef unsigned __int32 uint32_t;
44    typedef unsigned __int16 uint16_t;
45 #endif
46 #include <assert.h>
47
48
49
50 namespace Dyninst
51 {
52   namespace InstructionAPI
53   {
54     union Result_Value
55     {
56       unsigned char bitval : 1;
57       unsigned char u8val;
58       char s8val;
59       uint16_t u16val;
60       int16_t s16val;
61       uint32_t u24val:24;
62       uint32_t u32val;
63       int32_t s32val;
64       uint64_t u64val;
65       int64_t s64val;
66       float floatval;
67       double dblval;
68       uint64_t u48val : 48;
69       int64_t s48val : 48;
70       void * m14val;
71       void * m96val;
72       void * dbl128val;
73       void * m192val;
74       void * m256val;
75       void * m384val;
76       void * m512val;
77     };
78     enum Result_Type
79     {
80       bit_flag = 0,
81       s8,
82       u8,
83       s16,
84       u16,
85       u24,
86       s32,
87       u32,
88       s48,
89       u48,
90       s64,
91       u64,
92       sp_float,
93       dp_float,
94       // 48-bit pointers...yay Intel
95       m14,
96       m96,
97       dbl128,
98       m192,
99       m256,
100       m384,
101       m512
102     };
103
104     template < Result_Type t > struct Result_type2type
105     {
106       typedef void* type;
107     };
108     template < > struct Result_type2type<s8>
109     {
110       typedef char type;
111     };
112     template < > struct Result_type2type<u8>
113     {
114       typedef unsigned char type;
115     };
116     template < > struct Result_type2type <s16>
117     {
118       typedef int16_t type;
119     };
120     template < > struct Result_type2type <u16>
121     {
122       typedef uint16_t type;
123     };
124     template < > struct Result_type2type <u24>
125     {
126       typedef uint32_t type;
127     };
128     template <  > struct Result_type2type <s32>
129     {
130       typedef int32_t type;
131     };
132     template < > struct Result_type2type <u32>
133     {
134       typedef uint32_t type;
135     };
136     template <  > struct Result_type2type <s48>
137     {
138       typedef int64_t type;
139     };
140     template < > struct Result_type2type <u48>
141     {
142       typedef uint64_t type;
143     };
144     template <  > struct Result_type2type <s64>
145     {
146       typedef int64_t type;
147     };
148     template < > struct Result_type2type <u64>
149     {
150       typedef uint64_t type;
151     };
152     template < > struct Result_type2type <sp_float>
153     {
154       typedef float type;
155     };
156     template < > struct Result_type2type <dp_float>
157     {
158       typedef double type;
159     };
160    template < > struct Result_type2type <bit_flag>
161     {
162       typedef unsigned char type;
163     };
164     /// A %Result object represents a value computed by a %Expression AST.
165     ///
166     /// The %Result class is a tagged-union representation of the results that
167     /// %Expressions can produce.  It includes 8, 16, 32, 48, and 64 bit integers
168     /// (signed and unsigned), bit values, and single and double precision floating point values.
169     /// For each of these types, the value of a %Result may be undefined, or it may be a value within
170     /// the range of the type.
171     ///
172     /// The \c type field is an enum that may contain any of the following values:
173     /// - \c u8: an unsigned 8-bit integer
174     /// - \c s8: a signed 8-bit integer
175     /// - \c u16: an unsigned 16-bit integer
176     /// - \c s16: a signed 16-bit integer
177     /// - \c u32: an unsigned 32-bit integer
178     /// - \c s32: a signed 32-bit integer
179     /// - \c u48: an unsigned 48-bit integer (IA32 pointers)
180     /// - \c s48: a signed 48-bit integer (IA32 pointers)
181     /// - \c u64: an unsigned 64-bit integer
182     /// - \c s64: a signed 64-bit integer
183     /// - \c sp_float: a single-precision float
184     /// - \c dp_float: a double-precision float
185     /// - \c bit_flag: a single bit (individual flags)
186     /// - \c m512: a 512-bit memory value
187     /// - \c dbl128: a 128-bit integer, which often contains packed floating point values
188    /// - \c m14: a 14 byte memory value
189     ///
190     // The %Instruction API's model of %Results is a simple one, and may seem overly aggressive about
191     // making an %Expression's %Result undefined.  It follows the same basic rule as the rest of the API:
192     // a decoded %Instruction object represents only the information that may be obtained from the machine
193     // instruction that was decoded.  As discussed in the Expression section, the \c setValue
194     // and \c eval interface allows you to determine the possible %Results of an %Expression when evaluated over various
195     // machine states.  From this, you may construct abstractions to represent the set of possible results.
196     // Alternately, you may use instrumentation to determine the exact machine state at the time an
197     // instruction executes, which will allow you to evaluate the %Result of an %Expression in its actual context.
198     class INSTRUCTION_EXPORT Result
199     {
200     public:
201       Result_Value val;
202       Result_Type type;
203       bool defined;
204
205       Result() :
206               type(u32), defined(false)
207       {
208           val.u32val = 0;
209       }
210       Result(const Result& o) :
211               val(o.val), type(o.type), defined(o.defined)
212       {
213       }
214
215       const Result& operator=(const Result& rhs)
216       {
217           val = rhs.val;
218           type = rhs.type;
219           defined = rhs.defined;
220           return *this;
221       }
222
223       /// A %Result may be constructed from a type without providing a value.
224       /// This constructor creates a %Result of type \c t with undefined contents.
225       Result(Result_Type t) :
226               type(t), defined(false)
227       {
228           val.u32val = 0;
229       }
230
231       /// A %Result may be constructed from a type and any value convertible to the type that the
232       /// tag represents.
233       /// This constructor creates a %Result of type \c t and contents \c v for any \c v that is implicitly
234       /// convertible to type \c t.  Attempting to construct a %Result with a value that is incompatible with
235       /// its type will result in a compile-time error.
236       template<typename T>
237       Result(Result_Type t, T v) :
238       type(t), defined(true)
239       {
240         switch(type)
241         {
242         case u8:
243           val.u8val = (unsigned char)(v);
244           break;
245         case s8:
246           val.s8val = (char)(v);
247           break;
248         case u16:
249           val.u16val = (uint16_t)(v);
250           break;
251         case s16:
252           val.s16val = (int16_t)(v);
253           break;
254         case u24:
255           val.u24val = (uint32_t)(v & 0xFFFFFF);
256           break;
257         case u32:
258           val.u32val = (uint32_t)(v );
259           break;
260         case s32:
261           val.s32val = (int32_t)(v);
262           break;
263         case u64:
264           val.u64val = (uint64_t)(v);
265           break;
266         case s64:
267           val.s64val = (int64_t)(v);
268           break;
269         case bit_flag:
270           val.bitval = (v != 0) ? 1 : 0;
271           break;
272         case u48:
273           val.u48val = (uint64_t)(v & 0x0000FFFFFFFFFFFFLL);
274           break;
275         case s48:
276           val.s48val = (int64_t)(v & 0x0000FFFFFFFFFFFFLL);
277           break;
278         case m512:
279           val.m512val = (void *)(intptr_t) v;
280           break;
281     case dbl128:
282           val.dbl128val = (void*)(intptr_t) v;
283           break;
284         case m14:
285           val.m14val = (void*)(intptr_t) v;
286           break;
287         case m96:
288           val.m96val = (void *)(intptr_t) v;
289           break;
290         case m192:
291           val.m192val = (void *)(intptr_t) v;
292           break;
293         case m256:
294           val.m256val = (void *)(intptr_t) v;
295           break;
296         case m384:
297           val.m384val = (void *)(intptr_t) v;
298           break;
299           // Floats should be constructed with float types
300         default:
301         case sp_float:
302         case dp_float:
303           assert(!"Invalid type!");
304           break;
305         }
306       }
307       Result(Result_Type t, float v) :
308       type(t), defined(true)
309       {
310         assert(t == sp_float || t == dp_float);
311         val.dblval = v;
312       }
313       Result(Result_Type t, double v) :
314       type(t), defined(true)
315       {
316         assert(t == sp_float || t == dp_float);
317         val.dblval = v;
318       }
319       ~Result()
320       {
321       }
322
323       bool operator<(const Result& o) const
324       {
325         if(type < o.type) return true;
326         if(!defined) return false;
327         if(!o.defined) return true;
328
329
330         switch(type)
331         {
332         case u8:
333           return val.u8val < o.val.u8val;
334           break;
335         case s8:
336           return val.s8val < o.val.s8val;
337           break;
338         case u16:
339           return val.u16val < o.val.u16val;
340           break;
341         case s16:
342           return val.s16val < o.val.s16val;
343           break;
344         case u24:
345           return val.u24val < o.val.u24val;
346           break;
347         case u32:
348           return val.u32val < o.val.u32val;
349           break;
350         case s32:
351           return val.s32val < o.val.s32val;
352           break;
353         case u64:
354           return val.u64val < o.val.u64val;
355           break;
356         case s64:
357           return val.s64val < o.val.s64val;
358           break;
359         case sp_float:
360           return val.floatval < o.val.floatval;
361           break;
362         case dp_float:
363           return val.dblval < o.val.dblval;
364           break;
365         case bit_flag:
366           return val.bitval < o.val.bitval;
367           break;
368         case u48:
369           return val.u48val < o.val.u48val;
370           break;
371         case s48:
372           return val.s48val < o.val.s48val;
373           break;
374         case m512:
375           return memcmp(val.m512val, o.val.m512val, 512) < 0;
376           break;
377         case dbl128:
378           return memcmp(val.dbl128val, o.val.dbl128val, 128 / 8) < 0;
379           break;
380         case m14:
381           return memcmp(val.m14val, o.val.m14val, 14) < 0;
382           break;
383         case m96:
384           return memcmp(val.m96val, o.val.m96val, 96) < 0;
385           break;
386         case m192:
387           return memcmp(val.m192val, o.val.m192val, 192) < 0;
388           break;
389         case m256:
390           return memcmp(val.m256val, o.val.m256val, 256) < 0;
391           break;
392         case m384:
393           return memcmp(val.m384val, o.val.m384val, 384) < 0;
394           break;
395         default:
396           assert(!"Invalid type!");
397           break;
398         }
399         return false;
400       }
401
402       /// Two %Results are equal if any of the following hold:
403       /// - Both %Results are of the same type and undefined
404       /// - Both %Results are of the same type, defined, and have the same value
405       ///
406       /// Otherwise, they are unequal (due to having different types, an undefined %Result compared to a defined %Result,
407       /// or different values).
408
409
410       bool operator==(const Result& o) const
411       {
412         return !((*this < o) || (o < *this));
413
414
415       }
416       /// %Results are formatted as strings containing their contents, represented as hexadecimal.
417       /// The type of the %Result is not included in the output.
418       std::string format() const
419       {
420         if(!defined)
421         {
422           return "[empty]";
423         }
424         else
425         {
426           std::stringstream ret;
427 //        ret << std::hex << "0x";
428           ret << std::hex;
429           switch(type)
430           {
431           case u8:
432             // Type promote the characters so that they're treated as integral, not as strings
433             ret << (unsigned long)(val.u8val);
434             break;
435           case s8:
436             ret << (long)(val.s8val);
437             break;
438           case u16:
439             ret << val.u16val;
440             break;
441           case s16:
442             ret << val.s16val;
443             break;
444           case u24:
445             ret << val.u24val;
446             break;
447           case u32:
448             ret << val.u32val;
449             break;
450           case s32:
451             ret << val.s32val;
452             break;
453           case u64:
454             ret << val.u64val;
455             break;
456           case s64:
457             ret << val.s64val;
458             break;
459           case sp_float:
460             ret << val.floatval;
461             break;
462           case dp_float:
463             ret << val.dblval;
464             break;
465           case bit_flag:
466             ret << val.bitval;
467             break;
468           case u48:
469             ret << val.u48val;
470             break;
471           case s48:
472             ret << val.s48val;
473             break;
474      case m512:
475         ret << val.m512val;
476         break;
477      case m14:
478         ret << val.m14val;
479         break;
480      case m96:
481         ret << val.m96val;
482         break;
483      case dbl128:
484        ret << val.dbl128val;
485          break;
486      case m192:
487         ret << val.m192val;
488         break;
489      case m256:
490         ret << val.m256val;
491         break;
492      case m384:
493         ret << val.m384val;
494         break;
495           default:
496             ret << "[ERROR: invalid type value!]";
497             break;
498           };
499       ret << std::dec;
500           return ret.str();
501         }
502       }
503
504
505
506       template< typename to_type >
507       to_type convert() const
508       {
509         switch(type)
510         {
511         case s8:
512           return to_type(val.s8val);
513         case u8:
514           return to_type(val.u8val);
515         case s16:
516           return to_type(val.s16val);
517         case u16:
518           return to_type(val.u16val);
519         case u24:
520           return to_type(val.u24val);
521         case s32:
522           return to_type(val.s32val);
523         case u32:
524           return to_type(val.u32val);
525         case s48:
526           return to_type(val.s48val);
527         case u48:
528           return to_type(val.u48val);
529         case s64:
530           return to_type(val.s64val);
531         case u64:
532           return to_type(val.u64val);
533         case sp_float:
534           return to_type(val.floatval);
535         case dp_float:
536           return to_type(val.dblval);
537         case bit_flag:
538           return to_type(val.bitval);
539         case m512:
540         case dbl128:
541     case m192:
542     case m256:
543     case m384:
544     case m96:
545           assert(!"M512 and DBL128 types cannot be converted yet");
546           return to_type(0);
547         default:
548           assert(!"Invalid type in result!");
549           return to_type(0);
550         }
551       }
552
553
554     /// Returns the size of the contained type, in bytes
555       int size() const
556       {
557         switch(type)
558         {
559         case u8:
560         case s8:
561           return 1;
562         case u16:
563         case s16:
564           return 2;
565     case u24:
566       return 3;
567         case u32:
568         case s32:
569           return 4;
570         case u64:
571         case s64:
572           return 8;
573         case u48:
574         case s48:
575           return 6;
576         case sp_float:
577           return sizeof(float);
578         case dp_float:
579              return sizeof(double);
580         case bit_flag:
581           return 1;
582    case m512:
583       return 512;
584    case dbl128:
585       return 16;
586    case m192:
587       return 192;
588    case m256:
589       return 256;
590         default:
591           // In probabilistic gap parsing,
592           // we could start to decode at any byte and reach here.
593           // It is a sign for junk bytes
594           return 0;
595         };
596       }
597     };
598
599     INSTRUCTION_EXPORT Result operator+(const Result& arg1, const Result& arg2);
600     INSTRUCTION_EXPORT Result operator*(const Result& arg1, const Result& arg2);
601     INSTRUCTION_EXPORT Result operator<<(const Result& arg1, const Result& arg2);
602     INSTRUCTION_EXPORT Result operator>>(const Result& arg1, const Result& arg2);
603     INSTRUCTION_EXPORT Result operator&(const Result& arg1, const Result& arg2);
604     INSTRUCTION_EXPORT Result operator|(const Result& arg1, const Result& arg2);
605
606   };
607 };
608
609
610 #endif // !defined(RESULT_H)
611