annotate udis86-1.4/libudis86/decode.c @ 1:4a9dcbd9e54f

-files of 0.13 beta -fixes so that it now compiles with the current dmd version
author marton@basel.hu
date Tue, 05 Apr 2011 20:44:01 +0200
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
1 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
2 * decode.c
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
3 *
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
4 * Copyright (c) 2005, 2006, Vivek Mohan <vivek@sig9.com>
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
5 * All rights reserved. See LICENSE
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
6 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
7 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
8
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
9 #include <string.h>
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
10 #include "types.h"
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
11 #include "input.h"
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
12 #include "opcmap.h"
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
13 #include "mnemonics.h"
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
14
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
15 /* The max number of prefixes to an instruction */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
16 #define MAX_PREFIXES 15
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
17
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
18 /* register types */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
19 #define T_NONE 0
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
20 #define T_GPR 1
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
21 #define T_MMX 2
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
22 #define T_CRG 3
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
23 #define T_DBG 4
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
24 #define T_SEG 5
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
25 #define T_XMM 6
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
26
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
27 struct map_entry* ud_me_db();
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
28 struct map_entry* ud_me_invalid();
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
29
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
30 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
31 * resolve_oprsize()- Resolves the size of operand depending on the current
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
32 * disassembly mode, effective operand sizes, etc.
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
33 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
34 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
35 static unsigned int
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
36 resolve_oprsize(register struct ud* u, unsigned int s)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
37 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
38 switch (s) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
39 case SZ_V: return (u->opr_mode);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
40 case SZ_Z: return (u->opr_mode == 16) ? 16 : 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
41 case SZ_P: return (u->opr_mode == 16) ? SZ_WP : SZ_DP;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
42 case SZ_MDQ: return (u->opr_mode == 16) ? 32 : u->opr_mode;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
43 case SZ_RDQ: return (u->dis_mode == 64) ? 64 : 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
44 default: return s;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
45 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
46 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
47
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
48 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
49 * resolve_mnemonic()- Resolves the correct mnemonic that depends on the
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
50 * current effective operand or address mode.
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
51 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
52 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
53 static enum ud_mnemonic_code
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
54 resolve_mnemonic(register struct ud* u)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
55 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
56
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
57 if (u->opr_mode == 32) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
58 switch(u->mnemonic) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
59 case UD_Icbw: return UD_Icwde;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
60 case UD_Icwd: return UD_Icdq;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
61 case UD_Ilodsw: return UD_Ilodsd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
62 case UD_Imovsw: return UD_Imovsd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
63 case UD_Icmpsw: return UD_Icmpsd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
64 case UD_Iinsw: return UD_Iinsd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
65 case UD_Ioutsw: return UD_Ioutsd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
66 case UD_Ipushfw: return UD_Ipushfd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
67 case UD_Ipopfw: return UD_Ipopfd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
68 case UD_Istosw: return UD_Istosd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
69 case UD_Iscasw: return UD_Iscasd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
70 case UD_Iiretw: return UD_Iiretd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
71 case UD_Ipusha: return UD_Ipushad;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
72 case UD_Ipopa: return UD_Ipopad;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
73 default: break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
74 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
75 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
76
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
77 if (u->opr_mode == 64) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
78 switch(u->mnemonic) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
79 case UD_Icbw: return UD_Icdqe;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
80 case UD_Icwd: return UD_Icqo;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
81 case UD_Ilodsw: return UD_Ilodsq;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
82 case UD_Imovsw: return UD_Imovsq;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
83 case UD_Icmpsw: return UD_Icmpsq;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
84 case UD_Iinsw: return UD_Iinsd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
85 case UD_Ioutsw: return UD_Ioutsd;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
86 case UD_Icmpxchg8b: return UD_Icmpxchg16b;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
87 case UD_Istosw: return UD_Istosq;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
88 case UD_Iscasw: return UD_Iscasq;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
89 case UD_Iiretw: return UD_Iiretq;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
90 case UD_Ipushfw: return UD_Ipushfq;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
91 case UD_Ipopfw: return UD_Ipopfq;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
92 default: break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
93 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
94 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
95
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
96 if (u->mnemonic == UD_Iswapgs && u->dis_mode != 64) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
97 u->error = 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
98 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
99
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
100 if (u->adr_mode == 32) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
101 switch(u->mnemonic) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
102 case UD_Ijcxz: return UD_Ijecxz;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
103 default: break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
104 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
105 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
106
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
107 if (u->adr_mode == 64) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
108 switch(u->mnemonic) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
109 case UD_Ijcxz: return UD_Ijrcxz;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
110 default: break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
111 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
112 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
113
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
114 return u->mnemonic;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
115 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
116
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
117
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
118 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
119 * decode_a()- Decodes operands of the type seg:offset
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
120 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
121 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
122 static void
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
123 decode_a(struct ud* u, struct ud_operand *op)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
124 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
125 if (u->opr_mode == 16) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
126 /* seg16:off16 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
127 op->type = UD_OP_PTR;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
128 op->size = 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
129 op->lval.ptr.off = inp_uint16(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
130 op->lval.ptr.seg = inp_uint16(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
131 } else {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
132 /* seg16:off32 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
133 op->type = UD_OP_PTR;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
134 op->size = 48;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
135 op->lval.ptr.off = inp_uint32(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
136 op->lval.ptr.seg = inp_uint16(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
137 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
138 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
139
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
140 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
141 * decode_gpr() - Returns decoded General Purpose Register
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
142 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
143 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
144 static enum ud_type
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
145 decode_gpr(register struct ud* u, unsigned int s, unsigned char rm)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
146 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
147 s = resolve_oprsize(u, s);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
148
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
149 switch (s) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
150 case 64:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
151 return UD_R_RAX + rm;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
152 case SZ_DP:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
153 case 32:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
154 return UD_R_EAX + rm;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
155 case SZ_WP:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
156 case 16:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
157 return UD_R_AX + rm;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
158 case 8:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
159 if (u->dis_mode == 64 && u->pfx_rex) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
160 if (rm >= 4)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
161 return UD_R_SPL + (rm-4);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
162 return UD_R_AL + rm;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
163 } else return UD_R_AL + rm;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
164 default:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
165 return 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
166 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
167 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
168
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
169 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
170 * resolve_gpr64() - 64bit General Purpose Register-Selection.
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
171 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
172 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
173 static enum ud_type
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
174 resolve_gpr64(struct ud* u, enum map_operand_type gpr_op)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
175 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
176 if (gpr_op >= OP_rAXr8 && gpr_op <= OP_rDIr15)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
177 gpr_op = (gpr_op - OP_rAXr8) | (P_REX_B(u->pfx_rex) << 3);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
178 else gpr_op = (gpr_op - OP_rAX);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
179
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
180 if (u->opr_mode == 16)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
181 return gpr_op + UD_R_AX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
182 if (u->dis_mode == 32 ||
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
183 (u->opr_mode == 32 && ! (P_REX_W(u->pfx_rex) || u->default64))) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
184 return gpr_op + UD_R_EAX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
185 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
186
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
187 return gpr_op + UD_R_RAX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
188 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
189
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
190 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
191 * resolve_gpr32 () - 32bit General Purpose Register-Selection.
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
192 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
193 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
194 static enum ud_type
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
195 resolve_gpr32(struct ud* u, enum map_operand_type gpr_op)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
196 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
197 gpr_op = gpr_op - OP_eAX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
198
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
199 if (u->opr_mode == 16)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
200 return gpr_op + UD_R_AX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
201
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
202 return gpr_op + UD_R_EAX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
203 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
204
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
205 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
206 * resolve_reg() - Resolves the register type
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
207 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
208 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
209 static enum ud_type
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
210 resolve_reg(struct ud* u, unsigned int type, unsigned char i)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
211 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
212 switch (type) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
213 case T_MMX : return UD_R_MM0 + (i & 7);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
214 case T_XMM : return UD_R_XMM0 + i;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
215 case T_CRG : return UD_R_CR0 + i;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
216 case T_DBG : return UD_R_DR0 + i;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
217 case T_SEG : return UD_R_ES + (i & 7);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
218 case T_NONE:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
219 default: return UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
220 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
221 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
222
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
223 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
224 * decode_imm() - Decodes Immediate values.
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
225 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
226 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
227 static void
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
228 decode_imm(struct ud* u, unsigned int s, struct ud_operand *op)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
229 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
230 op->size = resolve_oprsize(u, s);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
231 op->type = UD_OP_IMM;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
232
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
233 switch (op->size) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
234 case 8: op->lval.sbyte = inp_uint8(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
235 case 16: op->lval.uword = inp_uint16(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
236 case 32: op->lval.udword = inp_uint32(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
237 case 64: op->lval.uqword = inp_uint64(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
238 default: return;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
239 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
240 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
241
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
242 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
243 * decode_modrm() - Decodes ModRM Byte
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
244 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
245 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
246 static void
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
247 decode_modrm(struct ud* u, struct ud_operand *op, unsigned int s,
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
248 unsigned char rm_type, struct ud_operand *opreg,
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
249 unsigned char reg_size, unsigned char reg_type)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
250 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
251 unsigned char mod, rm, reg;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
252
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
253 inp_next(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
254
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
255 /* get mod, r/m and reg fields */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
256 mod = MODRM_MOD(inp_curr(u));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
257 rm = (P_REX_B(u->pfx_rex) << 3) | MODRM_RM(inp_curr(u));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
258 reg = (P_REX_R(u->pfx_rex) << 3) | MODRM_REG(inp_curr(u));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
259
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
260 op->size = resolve_oprsize(u, s);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
261
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
262 /* if mod is 11b, then the UD_R_m specifies a gpr/mmx/sse/control/debug */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
263 if (mod == 3) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
264 op->type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
265 if (rm_type == T_GPR)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
266 op->base = decode_gpr(u, op->size, rm);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
267 else op->base = resolve_reg(u, rm_type, (P_REX_R(u->pfx_rex) << 3) | (rm&7));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
268 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
269 /* else its memory addressing */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
270 else {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
271 op->type = UD_OP_MEM;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
272
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
273 /* 64bit addressing */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
274 if (u->adr_mode == 64) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
275
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
276 op->base = UD_R_RAX + rm;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
277
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
278 /* get offset type */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
279 if (mod == 1)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
280 op->offset = 8;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
281 else if (mod == 2)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
282 op->offset = 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
283 else if (mod == 0 && (rm & 7) == 5) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
284 op->base = UD_R_RIP;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
285 op->offset = 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
286 } else op->offset = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
287
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
288 /* Scale-Index-Base (SIB) */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
289 if ((rm & 7) == 4) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
290 inp_next(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
291
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
292 op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
293 op->index = UD_R_RAX + (SIB_I(inp_curr(u)) | (P_REX_X(u->pfx_rex) << 3));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
294 op->base = UD_R_RAX + (SIB_B(inp_curr(u)) | (P_REX_B(u->pfx_rex) << 3));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
295
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
296 /* special conditions for base reference */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
297 if (op->index == UD_R_RSP) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
298 op->index = UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
299 op->scale = UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
300 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
301
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
302 if (op->base == UD_R_RBP || op->base == UD_R_R13) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
303 if (mod == 0)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
304 op->base = UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
305 if (mod == 1)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
306 op->offset = 8;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
307 else op->offset = 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
308 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
309 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
310 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
311
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
312 /* 32-Bit addressing mode */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
313 else if (u->adr_mode == 32) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
314
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
315 /* get base */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
316 op->base = UD_R_EAX + rm;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
317
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
318 /* get offset type */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
319 if (mod == 1)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
320 op->offset = 8;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
321 else if (mod == 2)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
322 op->offset = 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
323 else if (mod == 0 && rm == 5) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
324 op->base = UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
325 op->offset = 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
326 } else op->offset = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
327
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
328 /* Scale-Index-Base (SIB) */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
329 if ((rm & 7) == 4) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
330 inp_next(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
331
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
332 op->scale = (1 << SIB_S(inp_curr(u))) & ~1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
333 op->index = UD_R_EAX + (SIB_I(inp_curr(u)) | (P_REX_X(u->pfx_rex) << 3));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
334 op->base = UD_R_EAX + (SIB_B(inp_curr(u)) | (P_REX_B(u->pfx_rex) << 3));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
335
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
336 if (op->index == UD_R_ESP) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
337 op->index = UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
338 op->scale = UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
339 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
340
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
341 /* special condition for base reference */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
342 if (op->base == UD_R_EBP) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
343 if (mod == 0)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
344 op->base = UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
345 if (mod == 1)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
346 op->offset = 8;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
347 else op->offset = 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
348 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
349 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
350 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
351
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
352 /* 16bit addressing mode */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
353 else {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
354 switch (rm) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
355 case 0: op->base = UD_R_BX; op->index = UD_R_SI; break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
356 case 1: op->base = UD_R_BX; op->index = UD_R_DI; break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
357 case 2: op->base = UD_R_BP; op->index = UD_R_SI; break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
358 case 3: op->base = UD_R_BP; op->index = UD_R_DI; break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
359 case 4: op->base = UD_R_SI; break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
360 case 5: op->base = UD_R_DI; break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
361 case 6: op->base = UD_R_BP; break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
362 case 7: op->base = UD_R_BX; break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
363 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
364
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
365 if (mod == 0 && rm == 6) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
366 op->offset= 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
367 op->base = UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
368 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
369 else if (mod == 1)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
370 op->offset = 8;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
371 else if (mod == 2)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
372 op->offset = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
373 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
374 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
375
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
376 /* extract offset, if any */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
377 switch(op->offset) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
378 case 8 : op->lval.ubyte = inp_uint8(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
379 case 16: op->lval.uword = inp_uint16(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
380 case 32: op->lval.udword = inp_uint32(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
381 case 64: op->lval.uqword = inp_uint64(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
382 default: break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
383 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
384
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
385 /* resolve register encoded in reg field */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
386 if (opreg) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
387 opreg->type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
388 opreg->size = resolve_oprsize(u, reg_size);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
389 if (reg_type == T_GPR)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
390 opreg->base = decode_gpr(u, opreg->size, reg);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
391 else opreg->base = resolve_reg(u, reg_type, reg);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
392 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
393 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
394
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
395 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
396 * decode_o() - Decodes offset
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
397 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
398 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
399 static void
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
400 decode_o(struct ud* u, unsigned int s, struct ud_operand *op)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
401 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
402 switch (u->adr_mode) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
403 case 64:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
404 op->offset = 64;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
405 op->lval.uqword = inp_uint64(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
406 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
407 case 32:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
408 op->offset = 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
409 op->lval.udword = inp_uint32(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
410 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
411 case 16:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
412 op->offset = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
413 op->lval.uword = inp_uint16(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
414 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
415 default:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
416 return;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
417 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
418 op->type = UD_OP_MEM;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
419 op->size = resolve_oprsize(u, s);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
420 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
421
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
422 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
423 * disasm_operands() - Disassembles Operands.
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
424 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
425 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
426 static void
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
427 disasm_operands(register struct ud* u)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
428 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
429
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
430
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
431 /* mopXt = map entry, operand X, type; */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
432 enum map_operand_type mop1t = u->mapen->operand1.type;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
433 enum map_operand_type mop2t = u->mapen->operand2.type;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
434 enum map_operand_type mop3t = u->mapen->operand3.type;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
435
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
436 /* mopXs = map entry, operand X, size */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
437 unsigned int mop1s = u->mapen->operand1.size;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
438 unsigned int mop2s = u->mapen->operand2.size;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
439 unsigned int mop3s = u->mapen->operand3.size;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
440
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
441 /* iop = instruction operand */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
442 register struct ud_operand* iop = u->operand;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
443
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
444 switch(mop1t) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
445
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
446 case OP_A :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
447 decode_a(u, &(iop[0]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
448 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
449
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
450 /* M[b] ... */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
451 case OP_M :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
452 if (MODRM_MOD(inp_peek(u)) == 3)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
453 u->error= 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
454 /* E, G/P/V/I/CL/1/S */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
455 case OP_E :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
456 if (mop2t == OP_G) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
457 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_GPR);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
458 if (mop3t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
459 decode_imm(u, mop3s, &(iop[2]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
460 else if (mop3t == OP_CL) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
461 iop[2].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
462 iop[2].base = UD_R_CL;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
463 iop[2].size = 8;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
464 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
465 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
466 else if (mop2t == OP_P)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
467 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_MMX);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
468 else if (mop2t == OP_V)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
469 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_XMM);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
470 else if (mop2t == OP_S)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
471 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_SEG);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
472 else {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
473 decode_modrm(u, &(iop[0]), mop1s, T_GPR, NULL, 0, T_NONE);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
474 if (mop2t == OP_CL) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
475 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
476 iop[1].base = UD_R_CL;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
477 iop[1].size = 8;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
478 } else if (mop2t == OP_I1) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
479 iop[1].type = UD_OP_CONST;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
480 u->operand[1].lval.udword = 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
481 } else if (mop2t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
482 decode_imm(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
483 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
484 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
485
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
486 /* G, E/PR[,I]/VR */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
487 case OP_G :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
488
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
489 if (mop2t == OP_M) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
490 if (MODRM_MOD(inp_peek(u)) == 3)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
491 u->error= 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
492 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
493 } else if (mop2t == OP_E) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
494 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_GPR);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
495 if (mop3t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
496 decode_imm(u, mop3s, &(iop[2]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
497 } else if (mop2t == OP_PR) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
498 decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_GPR);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
499 if (mop3t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
500 decode_imm(u, mop3s, &(iop[2]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
501 } else if (mop2t == OP_VR) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
502 if (MODRM_MOD(inp_peek(u)) != 3)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
503 u->error = 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
504 decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
505 } else if (mop2t == OP_W)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
506 decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_GPR);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
507 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
508
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
509 /* AL..BH, I/O/DX */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
510 case OP_AL : case OP_CL : case OP_DL : case OP_BL :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
511 case OP_AH : case OP_CH : case OP_DH : case OP_BH :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
512
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
513 iop[0].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
514 iop[0].base = UD_R_AL + (mop1t - OP_AL);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
515 iop[0].size = 8;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
516
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
517 if (mop2t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
518 decode_imm(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
519 else if (mop2t == OP_DX) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
520 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
521 iop[1].base = UD_R_DX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
522 iop[1].size = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
523 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
524 else if (mop2t == OP_O)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
525 decode_o(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
526 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
527
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
528 /* rAX[r8]..rDI[r15], I/rAX..rDI/O */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
529 case OP_rAXr8 : case OP_rCXr9 : case OP_rDXr10 : case OP_rBXr11 :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
530 case OP_rSPr12: case OP_rBPr13: case OP_rSIr14 : case OP_rDIr15 :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
531 case OP_rAX : case OP_rCX : case OP_rDX : case OP_rBX :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
532 case OP_rSP : case OP_rBP : case OP_rSI : case OP_rDI :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
533
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
534 iop[0].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
535 iop[0].base = resolve_gpr64(u, mop1t);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
536
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
537 if (mop2t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
538 decode_imm(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
539 else if (mop2t >= OP_rAX && mop2t <= OP_rDI) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
540 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
541 iop[1].base = resolve_gpr64(u, mop2t);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
542 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
543 else if (mop2t == OP_O) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
544 decode_o(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
545 iop[0].size = resolve_oprsize(u, mop2s);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
546 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
547 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
548
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
549 /* AL[r8b]..BH[r15b], I */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
550 case OP_ALr8b : case OP_CLr9b : case OP_DLr10b : case OP_BLr11b :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
551 case OP_AHr12b: case OP_CHr13b: case OP_DHr14b : case OP_BHr15b :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
552 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
553 ud_type_t gpr = (mop1t - OP_ALr8b) + UD_R_AL +
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
554 (P_REX_B(u->pfx_rex) << 3);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
555 if (UD_R_AH <= gpr && u->pfx_rex)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
556 gpr = gpr + 4;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
557 iop[0].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
558 iop[0].base = gpr;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
559 if (mop2t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
560 decode_imm(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
561 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
562 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
563
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
564 /* eAX..eDX, DX/I */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
565 case OP_eAX : case OP_eCX : case OP_eDX : case OP_eBX :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
566 case OP_eSP : case OP_eBP : case OP_eSI : case OP_eDI :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
567
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
568 iop[0].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
569 iop[0].base = resolve_gpr32(u, mop1t);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
570 if (mop2t == OP_DX) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
571 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
572 iop[1].base = UD_R_DX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
573 iop[1].size = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
574 } else if (mop2t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
575 decode_imm(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
576 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
577
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
578 /* ES..GS */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
579 case OP_ES : case OP_CS : case OP_DS :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
580 case OP_SS : case OP_FS : case OP_GS :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
581
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
582 /* in 64bits mode, only fs and gs are allowed */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
583 if (u->dis_mode == 64)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
584 if (mop1t != OP_FS && mop1t != OP_GS)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
585 u->error= 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
586 iop[0].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
587 iop[0].base = (mop1t - OP_ES) + UD_R_ES;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
588 iop[0].size = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
589
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
590 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
591
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
592 /* J */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
593 case OP_J :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
594 decode_imm(u, mop1s, &(iop[0]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
595 iop[0].type = UD_OP_JIMM;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
596 break ;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
597
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
598 /* PR, I */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
599 case OP_PR:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
600 if (MODRM_MOD(inp_peek(u)) != 3)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
601 u->error = 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
602 decode_modrm(u, &(iop[0]), mop1s, T_MMX, NULL, 0, T_NONE);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
603 if (mop2t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
604 decode_imm(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
605 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
606
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
607 /* VR, I */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
608 case OP_VR:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
609 if (MODRM_MOD(inp_peek(u)) != 3)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
610 u->error = 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
611 decode_modrm(u, &(iop[0]), mop1s, T_XMM, NULL, 0, T_NONE);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
612 if (mop2t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
613 decode_imm(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
614 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
615
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
616 /* P, Q[,I]/W/E[,I] */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
617 case OP_P :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
618 if (mop2t == OP_Q) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
619 decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_MMX);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
620 if (mop3t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
621 decode_imm(u, mop3s, &(iop[2]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
622 } else if (mop2t == OP_W)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
623 decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_MMX);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
624 else if (mop2t == OP_E) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
625 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_MMX);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
626 if (mop3t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
627 decode_imm(u, mop3s, &(iop[2]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
628 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
629 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
630
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
631 /* R, C/D */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
632 case OP_R :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
633 if (mop2t == OP_C)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
634 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_CRG);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
635 else if (mop2t == OP_D)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
636 decode_modrm(u, &(iop[0]), mop1s, T_GPR, &(iop[1]), mop2s, T_DBG);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
637 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
638
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
639 /* C, R */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
640 case OP_C :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
641 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_CRG);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
642 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
643
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
644 /* D, R */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
645 case OP_D :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
646 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_DBG);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
647 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
648
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
649 /* Q, P */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
650 case OP_Q :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
651 decode_modrm(u, &(iop[0]), mop1s, T_MMX, &(iop[1]), mop2s, T_MMX);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
652 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
653
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
654 /* S, E */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
655 case OP_S :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
656 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_SEG);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
657 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
658
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
659 /* W, V */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
660 case OP_W :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
661 decode_modrm(u, &(iop[0]), mop1s, T_XMM, &(iop[1]), mop2s, T_XMM);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
662 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
663
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
664 /* V, W[,I]/Q/M/E */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
665 case OP_V :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
666 if (mop2t == OP_W) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
667 /* special cases for movlps and movhps */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
668 if (MODRM_MOD(inp_peek(u)) == 3) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
669 if (u->mnemonic == UD_Imovlps)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
670 u->mnemonic = UD_Imovhlps;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
671 else
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
672 if (u->mnemonic == UD_Imovhps)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
673 u->mnemonic = UD_Imovlhps;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
674 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
675 decode_modrm(u, &(iop[1]), mop2s, T_XMM, &(iop[0]), mop1s, T_XMM);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
676 if (mop3t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
677 decode_imm(u, mop3s, &(iop[2]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
678 } else if (mop2t == OP_Q)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
679 decode_modrm(u, &(iop[1]), mop2s, T_MMX, &(iop[0]), mop1s, T_XMM);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
680 else if (mop2t == OP_M) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
681 if (MODRM_MOD(inp_peek(u)) == 3)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
682 u->error= 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
683 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
684 } else if (mop2t == OP_E) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
685 decode_modrm(u, &(iop[1]), mop2s, T_GPR, &(iop[0]), mop1s, T_XMM);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
686 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
687 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
688
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
689 /* DX, eAX/AL */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
690 case OP_DX :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
691 iop[0].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
692 iop[0].base = UD_R_DX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
693 iop[0].size = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
694
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
695 if (mop2t == OP_eAX) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
696 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
697 iop[1].base = resolve_gpr32(u, mop2t);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
698 } else if (mop2t == OP_AL) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
699 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
700 iop[1].base = UD_R_AL;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
701 iop[1].size = 8;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
702 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
703
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
704 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
705
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
706 /* I, I/AL/eAX */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
707 case OP_I :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
708 decode_imm(u, mop1s, &(iop[0]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
709 if (mop2t == OP_I)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
710 decode_imm(u, mop2s, &(iop[1]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
711 else if (mop2t == OP_AL) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
712 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
713 iop[1].base = UD_R_AL;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
714 iop[1].size = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
715 } else if (mop2t == OP_eAX) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
716 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
717 iop[1].base = resolve_gpr32(u, mop2t);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
718 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
719 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
720
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
721 /* O, AL/eAX */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
722 case OP_O :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
723 decode_o(u, mop1s, &(iop[0]));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
724 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
725 iop[1].size = resolve_oprsize(u, mop1s);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
726 if (mop2t == OP_AL)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
727 iop[1].base = UD_R_AL;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
728 else if (mop2t == OP_eAX)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
729 iop[1].base = resolve_gpr32(u, mop2t);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
730 else if (mop2t == OP_rAX)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
731 iop[1].base = resolve_gpr64(u, mop2t);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
732 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
733
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
734 /* 3 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
735 case OP_I3 :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
736 iop[0].type = UD_OP_CONST;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
737 iop[0].lval.sbyte = 3;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
738 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
739
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
740 /* ST(n), ST(n) */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
741 case OP_ST0 : case OP_ST1 : case OP_ST2 : case OP_ST3 :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
742 case OP_ST4 : case OP_ST5 : case OP_ST6 : case OP_ST7 :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
743
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
744 iop[0].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
745 iop[0].base = (mop1t-OP_ST0) + UD_R_ST0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
746 iop[0].size = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
747
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
748 if (mop2t >= OP_ST0 && mop2t <= OP_ST7) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
749 iop[1].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
750 iop[1].base = (mop2t-OP_ST0) + UD_R_ST0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
751 iop[1].size = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
752 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
753 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
754
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
755 /* AX */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
756 case OP_AX:
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
757 iop[0].type = UD_OP_REG;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
758 iop[0].base = UD_R_AX;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
759 iop[0].size = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
760 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
761
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
762 /* none */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
763 default :
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
764 iop[0].type = iop[1].type = iop[2].type = UD_NONE;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
765 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
766 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
767
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
768 /* -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
769 * clear_insn() - clear instruction pointer
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
770 * -----------------------------------------------------------------------------
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
771 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
772 void clear_insn(register struct ud* u)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
773 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
774 u->error = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
775 u->pfx_seg = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
776 u->pfx_opr = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
777 u->pfx_adr = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
778 u->pfx_lock = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
779 u->pfx_repne = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
780 u->pfx_rep = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
781 u->pfx_seg = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
782 u->pfx_rex = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
783 u->pfx_insn= 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
784 u->mnemonic = UD_Inone;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
785 u->mapen = NULL;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
786
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
787 memset(&u->operand[0], 0, sizeof(struct ud_operand));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
788 memset(&u->operand[1], 0, sizeof(struct ud_operand));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
789 memset(&u->operand[2], 0, sizeof(struct ud_operand));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
790 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
791
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
792 /* =============================================================================
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
793 * ud_decode() - Instruction decoder. Returns the number of bytes decoded.
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
794 * =============================================================================
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
795 */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
796 extern unsigned int ud_decode(register struct ud* u)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
797 {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
798 unsigned int p; /* (bool) denotes end of prefixes */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
799 unsigned int i; /* prefix counter */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
800 char* src_hex;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
801 unsigned char *src_ptr;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
802
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
803 inp_start(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
804
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
805 /* [1] Clear the decode/output fields */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
806
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
807 clear_insn(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
808
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
809 /* [2] Extract Prefixes */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
810
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
811 inp_next(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
812
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
813 for (i = 0, p = 0; p == 0; ++i) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
814 if ((inp_curr(u) & 0xF0) == 0x40) { /* REX */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
815 if (u->dis_mode == 64) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
816 u->pfx_rex = inp_curr(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
817 inp_next(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
818 } else p = 1; /* Bail out, its an inc/dec */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
819 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
820 else switch(inp_curr(u)) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
821 case 0x2E : u->pfx_seg = UD_R_CS; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
822 case 0x36 : u->pfx_seg = UD_R_SS; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
823 case 0x3E : u->pfx_seg = UD_R_DS; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
824 case 0x26 : u->pfx_seg = UD_R_ES; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
825 case 0x64 : u->pfx_seg = UD_R_FS; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
826 case 0x65 : u->pfx_seg = UD_R_GS; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
827 case 0x66 : u->pfx_insn = u->pfx_opr = 0x66; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
828 case 0x67 : u->pfx_adr = 0x67; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
829 case 0xF0 : u->pfx_lock= 0xF0; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
830 case 0xF2 : u->pfx_insn = u->pfx_repne=0xF2; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
831 case 0xF3 : u->pfx_insn = u->pfx_rep = 0xF3; inp_next(u); break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
832 default : p = 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
833 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
834
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
835 /* if >= MAX_PREFIXES, disintegrate */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
836 if (i >= MAX_PREFIXES) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
837 u->error= 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
838 break;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
839 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
840 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
841
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
842 /* rewind back one byte in stream */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
843 inp_back(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
844
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
845 /* [3] Search opcode map */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
846
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
847 ud_search_map(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
848
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
849 /* [4] Set mode flags */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
850
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
851 if (u->dis_mode == 64) { /* set 64bit-mode flags */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
852 u->pfx_rex = u->pfx_rex & P_REX_MASK(u->mapen->prefix);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
853 u->default64 = P_DEF64(u->mapen->prefix);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
854 u->error = P_INV64(u->mapen->prefix);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
855
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
856 if (P_REX(u->mapen->prefix) && P_REX_W(u->pfx_rex))
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
857 u->opr_mode = 64;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
858 else if (u->pfx_opr)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
859 u->opr_mode = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
860 else u->opr_mode = (u->default64) ? 64 : 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
861
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
862 u->adr_mode = (u->pfx_adr) ? 32 : 64;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
863 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
864 else if (u->dis_mode == 32) { /* set 32bit-mode flags */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
865 u->opr_mode = (u->pfx_opr) ? 16 : 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
866 u->adr_mode = (u->pfx_adr) ? 16 : 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
867 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
868 else if (u->dis_mode == 16) { /* set 16bit-mode flags */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
869 u->opr_mode = (u->pfx_opr) ? 32 : 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
870 u->adr_mode = (u->pfx_adr) ? 32 : 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
871 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
872
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
873 u->c1 = (P_C1(u->mapen->prefix)) ? 1 : 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
874 u->c2 = (P_C2(u->mapen->prefix)) ? 1 : 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
875 u->c3 = (P_C3(u->mapen->prefix)) ? 1 : 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
876
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
877 /* [5] Disassembled operands */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
878
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
879 disasm_operands(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
880
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
881 /* [6] Resolve mode related and other mnemonic issues */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
882
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
883 if (P_DEPM(u->mapen->prefix))
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
884 u->mnemonic = resolve_mnemonic(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
885
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
886 u->br_far = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
887 u->br_near = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
888
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
889 if (u->mnemonic == UD_Icall || u->mnemonic == UD_Ijmp) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
890 if (u->operand[0].size == SZ_WP) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
891 u->operand[0].size = 16;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
892 u->br_far = 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
893 u->br_near= 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
894 } else if (u->operand[0].size == SZ_DP) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
895 u->operand[0].size = 32;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
896 u->br_far = 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
897 u->br_near= 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
898 } else {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
899 u->br_far = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
900 u->br_near= 1;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
901 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
902 } else if (u->mnemonic == UD_I3dnow)
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
903 u->mnemonic = ud_map_get_3dnow(inp_curr(u));
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
904
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
905 /* [7] Check for errors */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
906
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
907 if (u->error) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
908 clear_insn(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
909 u->mapen = ud_me_invalid();
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
910 u->mnemonic = u->mapen->mnemonic;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
911 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
912
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
913 /* [8] Generate hexadecimal code */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
914
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
915 u->insn_offset = u->pc;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
916 u->insn_fill = 0;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
917 src_ptr = inp_sess(u);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
918
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
919 src_hex = (char*) u->insn_hexcode;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
920
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
921 for (i = 0; i < u->inp_ctr; ++i, ++src_ptr) {
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
922 sprintf(src_hex, "%02x", *src_ptr & 0xFF);
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
923 src_hex += 2;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
924 }
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
925
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
926 /* [9] Update program counter */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
927
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
928 u->pc += u->inp_ctr;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
929
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
930 /* [10] Return the number of bytes disassemled */
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
931
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
932 return u->inp_ctr;
4a9dcbd9e54f -files of 0.13 beta
marton@basel.hu
parents:
diff changeset
933 }