• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* udis86 - libudis86/syn-intel.c
2  *
3  * Copyright (c) 2002-2013 Vivek Thampi
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without modification,
7  * are permitted provided that the following conditions are met:
8  *
9  *     * Redistributions of source code must retain the above copyright notice,
10  *       this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above copyright notice,
12  *       this list of conditions and the following disclaimer in the documentation
13  *       and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
22  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 #include "types.h"
27 #include "extern.h"
28 #include "decode.h"
29 #include "itab.h"
30 #include "syn.h"
31 #include "udint.h"
32 
33 /* -----------------------------------------------------------------------------
34  * opr_cast() - Prints an operand cast.
35  * -----------------------------------------------------------------------------
36  */
37 static void
opr_cast(struct ud * u,struct ud_operand * op)38 opr_cast(struct ud* u, struct ud_operand* op)
39 {
40   if (u->br_far) {
41     ud_asmprintf(u, "far ");
42   }
43   switch(op->size) {
44   case  8: ud_asmprintf(u, "byte " ); break;
45   case 16: ud_asmprintf(u, "word " ); break;
46   case 32: ud_asmprintf(u, "dword "); break;
47   case 64: ud_asmprintf(u, "qword "); break;
48   case 80: ud_asmprintf(u, "tword "); break;
49   default: break;
50   }
51 }
52 
53 /* -----------------------------------------------------------------------------
54  * gen_operand() - Generates assembly output for each operand.
55  * -----------------------------------------------------------------------------
56  */
gen_operand(struct ud * u,struct ud_operand * op,int syn_cast)57 static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
58 {
59   switch(op->type) {
60   case UD_OP_REG:
61     ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
62     break;
63 
64   case UD_OP_MEM:
65     if (syn_cast) {
66       opr_cast(u, op);
67     }
68     ud_asmprintf(u, "[");
69     if (u->pfx_seg) {
70       ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
71     }
72     if (op->base) {
73       ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
74     }
75     if (op->index) {
76       ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "",
77                               ud_reg_tab[op->index - UD_R_AL]);
78       if (op->scale) {
79         ud_asmprintf(u, "*%d", op->scale);
80       }
81     }
82     if (op->offset != 0) {
83       ud_syn_print_mem_disp(u, op, (op->base  != UD_NONE ||
84                                     op->index != UD_NONE) ? 1 : 0);
85     }
86     ud_asmprintf(u, "]");
87     break;
88 
89   case UD_OP_IMM:
90     ud_syn_print_imm(u, op);
91     break;
92 
93 
94   case UD_OP_JIMM:
95     ud_syn_print_addr(u, ud_syn_rel_target(u, op));
96     break;
97 
98   case UD_OP_PTR:
99     switch (op->size) {
100       case 32:
101         ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg,
102           op->lval.ptr.off & 0xFFFF);
103         break;
104       case 48:
105         ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg,
106           op->lval.ptr.off);
107         break;
108     }
109     break;
110 
111   case UD_OP_CONST:
112     if (syn_cast) opr_cast(u, op);
113     ud_asmprintf(u, "%d", op->lval.udword);
114     break;
115 
116   default: return;
117   }
118 }
119 
120 /* =============================================================================
121  * translates to intel syntax
122  * =============================================================================
123  */
124 extern void
ud_translate_intel(struct ud * u)125 ud_translate_intel(struct ud* u)
126 {
127   /* check if P_OSO prefix is used */
128   if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
129     switch (u->dis_mode) {
130     case 16: ud_asmprintf(u, "o32 "); break;
131     case 32:
132     case 64: ud_asmprintf(u, "o16 "); break;
133     }
134   }
135 
136   /* check if P_ASO prefix was used */
137   if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
138     switch (u->dis_mode) {
139     case 16: ud_asmprintf(u, "a32 "); break;
140     case 32: ud_asmprintf(u, "a16 "); break;
141     case 64: ud_asmprintf(u, "a32 "); break;
142     }
143   }
144 
145   if (u->pfx_seg &&
146       u->operand[0].type != UD_OP_MEM &&
147       u->operand[1].type != UD_OP_MEM ) {
148     ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
149   }
150 
151   if (u->pfx_lock) {
152     ud_asmprintf(u, "lock ");
153   }
154   if (u->pfx_rep) {
155     ud_asmprintf(u, "rep ");
156   } else if (u->pfx_repe) {
157     ud_asmprintf(u, "repe ");
158   } else if (u->pfx_repne) {
159     ud_asmprintf(u, "repne ");
160   }
161 
162   /* print the instruction mnemonic */
163   ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
164 
165   if (u->operand[0].type != UD_NONE) {
166     int cast = 0;
167     ud_asmprintf(u, " ");
168     if (u->operand[0].type == UD_OP_MEM) {
169       if (u->operand[1].type == UD_OP_IMM   ||
170           u->operand[1].type == UD_OP_CONST ||
171           u->operand[1].type == UD_NONE     ||
172           (u->operand[0].size != u->operand[1].size &&
173            u->operand[1].type != UD_OP_REG)) {
174           cast = 1;
175       } else if (u->operand[1].type == UD_OP_REG &&
176                  u->operand[1].base == UD_R_CL) {
177           switch (u->mnemonic) {
178           case UD_Ircl:
179           case UD_Irol:
180           case UD_Iror:
181           case UD_Ircr:
182           case UD_Ishl:
183           case UD_Ishr:
184           case UD_Isar:
185               cast = 1;
186               break;
187           default: break;
188           }
189       }
190     }
191     gen_operand(u, &u->operand[0], cast);
192   }
193 
194   if (u->operand[1].type != UD_NONE) {
195     int cast = 0;
196     ud_asmprintf(u, ", ");
197     if (u->operand[1].type == UD_OP_MEM &&
198         u->operand[0].size != u->operand[1].size &&
199         !ud_opr_is_sreg(&u->operand[0])) {
200       cast = 1;
201     }
202     gen_operand(u, &u->operand[1], cast);
203   }
204 
205   if (u->operand[2].type != UD_NONE) {
206     ud_asmprintf(u, ", ");
207     gen_operand(u, &u->operand[2], 0);
208   }
209 }
210 
211 /*
212 vim: set ts=2 sw=2 expandtab
213 */
214