]> andersk Git - udis86.git/blob - libudis86/syn-att.c
new docbook/xml documentation, updated webpage
[udis86.git] / libudis86 / syn-att.c
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
32 /* -----------------------------------------------------------------------------
33  * opr_cast() - Prints an operand cast.
34  * -----------------------------------------------------------------------------
35  */
36 static void 
37 opr_cast(struct ud* u, struct ud_operand* op)
38 {
39   switch(op->size) {
40         case 16 : case 32 :
41                 mkasm(u, "*");   break;
42         default: break;
43   }
44 }
45
46 /* -----------------------------------------------------------------------------
47  * gen_operand() - Generates assembly output for each operand.
48  * -----------------------------------------------------------------------------
49  */
50 static void 
51 gen_operand(struct ud* u, struct ud_operand* op)
52 {
53   switch(op->type) {
54         case UD_OP_REG:
55                 mkasm(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
56                 break;
57
58         case UD_OP_MEM:
59                 if (u->br_far) opr_cast(u, op);
60                 if (u->pfx_seg)
61                         mkasm(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
62                 if (op->offset == 8) {
63                         if (op->lval.sbyte < 0)
64                                 mkasm(u, "-0x%x", (-op->lval.sbyte) & 0xff);
65                         else    mkasm(u, "0x%x", op->lval.sbyte);
66                 } 
67                 else if (op->offset == 16) 
68                         mkasm(u, "0x%x", op->lval.uword);
69                 else if (op->offset == 32) 
70                         mkasm(u, "0x%lx", op->lval.udword);
71                 else if (op->offset == 64) 
72                         mkasm(u, "0x" FMT64 "x", op->lval.uqword);
73
74                 if (op->base)
75                         mkasm(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
76                 if (op->index) {
77                         if (op->base)
78                                 mkasm(u, ",");
79                         else mkasm(u, "(");
80                         mkasm(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
81                 }
82                 if (op->scale)
83                         mkasm(u, ",%d", op->scale);
84                 if (op->base || op->index)
85                         mkasm(u, ")");
86                 break;
87
88         case UD_OP_IMM:
89                 switch (op->size) {
90                         case  8: mkasm(u, "$0x%x", op->lval.ubyte);    break;
91                         case 16: mkasm(u, "$0x%x", op->lval.uword);    break;
92                         case 32: mkasm(u, "$0x%lx", op->lval.udword);  break;
93                         case 64: mkasm(u, "$0x" FMT64 "x", op->lval.uqword); break;
94                         default: break;
95                 }
96                 break;
97
98         case UD_OP_JIMM:
99                 switch (op->size) {
100                         case  8:
101                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte); 
102                                 break;
103                         case 16:
104                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
105                                 break;
106                         case 32:
107                                 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
108                                 break;
109                         default:break;
110                 }
111                 break;
112
113         case UD_OP_PTR:
114                 switch (op->size) {
115                         case 32:
116                                 mkasm(u, "$0x%x, $0x%x", op->lval.ptr.seg, 
117                                         op->lval.ptr.off & 0xFFFF);
118                                 break;
119                         case 48:
120                                 mkasm(u, "$0x%x, $0x%lx", op->lval.ptr.seg, 
121                                         op->lval.ptr.off);
122                                 break;
123                 }
124                 break;
125                         
126         default: return;
127   }
128 }
129
130 /* =============================================================================
131  * translates to AT&T syntax 
132  * =============================================================================
133  */
134 extern void 
135 ud_translate_att(struct ud *u)
136 {
137   int size = 0;
138
139   /* check if P_OSO prefix is used */
140   if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
141         switch (u->dis_mode) {
142                 case 16: 
143                         mkasm(u, "o32 ");
144                         break;
145                 case 32:
146                 case 64:
147                         mkasm(u, "o16 ");
148                         break;
149         }
150   }
151
152   /* check if P_ASO prefix was used */
153   if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
154         switch (u->dis_mode) {
155                 case 16: 
156                         mkasm(u, "a32 ");
157                         break;
158                 case 32:
159                         mkasm(u, "a16 ");
160                         break;
161                 case 64:
162                         mkasm(u, "a32 ");
163                         break;
164         }
165   }
166
167   if (u->pfx_lock)
168         mkasm(u,  "lock ");
169   if (u->pfx_rep)
170         mkasm(u,  "rep ");
171   if (u->pfx_repne)
172                 mkasm(u,  "repne ");
173
174   /* special instructions */
175   switch (u->mnemonic) {
176         case UD_Iretf: 
177                 mkasm(u, "lret "); 
178                 break;
179         case UD_Idb:
180                 mkasm(u, ".byte 0x%x", u->operand[0].lval.ubyte);
181                 return;
182         case UD_Ijmp:
183         case UD_Icall:
184                 if (u->br_far) mkasm(u,  "l");
185                 mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic));
186                 break;
187         case UD_Ibound:
188         case UD_Ienter:
189                 if (u->operand[0].type != UD_NONE)
190                         gen_operand(u, &u->operand[0]);
191                 if (u->operand[1].type != UD_NONE) {
192                         mkasm(u, ",");
193                         gen_operand(u, &u->operand[1]);
194                 }
195                 return;
196         default:
197                 mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic));
198   }
199
200   if (u->c1)
201         size = u->operand[0].size;
202   else if (u->c2)
203         size = u->operand[1].size;
204   else if (u->c3)
205         size = u->operand[2].size;
206
207   if (size == 8)
208         mkasm(u, "b");
209   else if (size == 16)
210         mkasm(u, "w");
211   else if (size == 64)
212         mkasm(u, "q");
213
214   mkasm(u, " ");
215
216   if (u->operand[2].type != UD_NONE) {
217         gen_operand(u, &u->operand[2]);
218         mkasm(u, ", ");
219   }
220
221   if (u->operand[1].type != UD_NONE) {
222         gen_operand(u, &u->operand[1]);
223         mkasm(u, ", ");
224   }
225
226   if (u->operand[0].type != UD_NONE)
227         gen_operand(u, &u->operand[0]);
228 }
This page took 0.406207 seconds and 5 git commands to generate.