• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* udis86 - libudis86/syn-att.c
2  *
3  * Copyright (c) 2002-2009 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   switch(op->size) {
41   case 16 : case 32 :
42     ud_asmprintf(u, "*");   break;
43   default: break;
44   }
45 }
46 
47 /* -----------------------------------------------------------------------------
48  * gen_operand() - Generates assembly output for each operand.
49  * -----------------------------------------------------------------------------
50  */
51 static void
gen_operand(struct ud * u,struct ud_operand * op)52 gen_operand(struct ud* u, struct ud_operand* op)
53 {
54   switch(op->type) {
55   case UD_OP_CONST:
56     ud_asmprintf(u, "$0x%x", op->lval.udword);
57     break;
58 
59   case UD_OP_REG:
60     ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
61     break;
62 
63   case UD_OP_MEM:
64     if (u->br_far) {
65         opr_cast(u, op);
66     }
67     if (u->pfx_seg) {
68       ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
69     }
70     if (op->offset != 0) {
71       ud_syn_print_mem_disp(u, op, 0);
72     }
73     if (op->base) {
74       ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
75     }
76     if (op->index) {
77       if (op->base) {
78         ud_asmprintf(u, ",");
79       } else {
80         ud_asmprintf(u, "(");
81       }
82       ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
83     }
84     if (op->scale) {
85       ud_asmprintf(u, ",%d", op->scale);
86     }
87     if (op->base || op->index) {
88       ud_asmprintf(u, ")");
89     }
90     break;
91 
92   case UD_OP_IMM:
93     ud_syn_print_imm(u, op);
94     break;
95 
96   case UD_OP_JIMM:
97     ud_syn_print_addr(u, ud_syn_rel_target(u, op));
98     break;
99 
100   case UD_OP_PTR:
101     switch (op->size) {
102       case 32:
103         ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
104           op->lval.ptr.off & 0xFFFF);
105         break;
106       case 48:
107         ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
108           op->lval.ptr.off);
109         break;
110     }
111     break;
112 
113   default: return;
114   }
115 }
116 
117 /* =============================================================================
118  * translates to AT&T syntax
119  * =============================================================================
120  */
121 extern void
ud_translate_att(struct ud * u)122 ud_translate_att(struct ud *u)
123 {
124   int size = 0;
125   int star = 0;
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:
131       ud_asmprintf(u, "o32 ");
132       break;
133     case 32:
134     case 64:
135       ud_asmprintf(u, "o16 ");
136       break;
137   }
138   }
139 
140   /* check if P_ASO prefix was used */
141   if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
142   switch (u->dis_mode) {
143     case 16:
144       ud_asmprintf(u, "a32 ");
145       break;
146     case 32:
147       ud_asmprintf(u, "a16 ");
148       break;
149     case 64:
150       ud_asmprintf(u, "a32 ");
151       break;
152   }
153   }
154 
155   if (u->pfx_lock)
156     ud_asmprintf(u,  "lock ");
157   if (u->pfx_rep) {
158     ud_asmprintf(u, "rep ");
159   } else if (u->pfx_rep) {
160     ud_asmprintf(u, "repe ");
161   } else if (u->pfx_repne) {
162     ud_asmprintf(u, "repne ");
163   }
164 
165   /* special instructions */
166   switch (u->mnemonic) {
167   case UD_Iretf:
168     ud_asmprintf(u, "lret ");
169     break;
170   case UD_Idb:
171     ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte);
172     return;
173   case UD_Ijmp:
174   case UD_Icall:
175     if (u->br_far) ud_asmprintf(u,  "l");
176         if (u->operand[0].type == UD_OP_REG) {
177           star = 1;
178         }
179     ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
180     break;
181   case UD_Ibound:
182   case UD_Ienter:
183     if (u->operand[0].type != UD_NONE)
184       gen_operand(u, &u->operand[0]);
185     if (u->operand[1].type != UD_NONE) {
186       ud_asmprintf(u, ",");
187       gen_operand(u, &u->operand[1]);
188     }
189     return;
190   default:
191     ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
192   }
193 
194   if (size == 8)
195   ud_asmprintf(u, "b");
196   else if (size == 16)
197   ud_asmprintf(u, "w");
198   else if (size == 64)
199   ud_asmprintf(u, "q");
200 
201   if (star) {
202     ud_asmprintf(u, " *");
203   } else {
204     ud_asmprintf(u, " ");
205   }
206 
207   if (u->operand[2].type != UD_NONE) {
208   gen_operand(u, &u->operand[2]);
209   ud_asmprintf(u, ", ");
210   }
211 
212   if (u->operand[1].type != UD_NONE) {
213   gen_operand(u, &u->operand[1]);
214   ud_asmprintf(u, ", ");
215   }
216 
217   if (u->operand[0].type != UD_NONE)
218   gen_operand(u, &u->operand[0]);
219 }
220 
221 /*
222 vim: set ts=2 sw=2 expandtab
223 */
224