]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/udis86/lib/contrib/libudis86/syn-att.c
Update
[l4.git] / l4 / pkg / udis86 / lib / contrib / 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 #include "udint.h"
32
33 /* -----------------------------------------------------------------------------
34  * opr_cast() - Prints an operand cast.
35  * -----------------------------------------------------------------------------
36  */
37 static void 
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 
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_asmprintf(u, "$");
94     ud_syn_print_imm(u, op);
95     break;
96
97   case UD_OP_JIMM:
98     ud_syn_print_addr(u, ud_syn_rel_target(u, op));
99     break;
100
101   case UD_OP_PTR:
102     switch (op->size) {
103       case 32:
104         ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, 
105           op->lval.ptr.off & 0xFFFF);
106         break;
107       case 48:
108         ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg, 
109           op->lval.ptr.off);
110         break;
111     }
112     break;
113       
114   default: return;
115   }
116 }
117
118 /* =============================================================================
119  * translates to AT&T syntax 
120  * =============================================================================
121  */
122 extern void 
123 ud_translate_att(struct ud *u)
124 {
125   int size = 0;
126   int star = 0;
127
128   /* check if P_OSO prefix is used */
129   if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
130   switch (u->dis_mode) {
131     case 16: 
132       ud_asmprintf(u, "o32 ");
133       break;
134     case 32:
135     case 64:
136       ud_asmprintf(u, "o16 ");
137       break;
138   }
139   }
140
141   /* check if P_ASO prefix was used */
142   if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
143   switch (u->dis_mode) {
144     case 16: 
145       ud_asmprintf(u, "a32 ");
146       break;
147     case 32:
148       ud_asmprintf(u, "a16 ");
149       break;
150     case 64:
151       ud_asmprintf(u, "a32 ");
152       break;
153   }
154   }
155
156   if (u->pfx_lock)
157     ud_asmprintf(u,  "lock ");
158   if (u->pfx_rep) {
159     ud_asmprintf(u, "rep ");
160   } else if (u->pfx_rep) {
161     ud_asmprintf(u, "repe ");
162   } else if (u->pfx_repne) {
163     ud_asmprintf(u, "repne ");
164   }
165
166   /* special instructions */
167   switch (u->mnemonic) {
168   case UD_Iretf: 
169     ud_asmprintf(u, "lret "); 
170     break;
171   case UD_Idb:
172     ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte);
173     return;
174   case UD_Ijmp:
175   case UD_Icall:
176     if (u->br_far) ud_asmprintf(u,  "l");
177         if (u->operand[0].type == UD_OP_REG) {
178           star = 1;
179         }
180     ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
181     break;
182   case UD_Ibound:
183   case UD_Ienter:
184     if (u->operand[0].type != UD_NONE)
185       gen_operand(u, &u->operand[0]);
186     if (u->operand[1].type != UD_NONE) {
187       ud_asmprintf(u, ",");
188       gen_operand(u, &u->operand[1]);
189     }
190     return;
191   default:
192     ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
193   }
194
195   if (size == 8)
196   ud_asmprintf(u, "b");
197   else if (size == 16)
198   ud_asmprintf(u, "w");
199   else if (size == 64)
200   ud_asmprintf(u, "q");
201
202   if (star) {
203     ud_asmprintf(u, " *");
204   } else {
205     ud_asmprintf(u, " ");
206   }
207
208   if (u->operand[2].type != UD_NONE) {
209   gen_operand(u, &u->operand[2]);
210   ud_asmprintf(u, ", ");
211   }
212
213   if (u->operand[1].type != UD_NONE) {
214   gen_operand(u, &u->operand[1]);
215   ud_asmprintf(u, ", ");
216   }
217
218   if (u->operand[0].type != UD_NONE)
219   gen_operand(u, &u->operand[0]);
220 }
221
222 /*
223 vim: set ts=2 sw=2 expandtab
224 */