1/* ----------------------------------------------------------------------------- 2 * syn-att.c 3 * 4 * Copyright (c) 2004, 2005, 2006 Vivek Mohan <vivek@sig9.com> 5 * All rights reserved. See (LICENSE) 6 * ----------------------------------------------------------------------------- 7 */ 8 9#include "types.h" 10#include "extern.h" 11#include "decode.h" 12#include "itab.h" 13#include "syn.h" 14 15/* ----------------------------------------------------------------------------- 16 * opr_cast() - Prints an operand cast. 17 * ----------------------------------------------------------------------------- 18 */ 19static void 20opr_cast(struct ud* u, struct ud_operand* op) 21{ 22 switch(op->size) { 23 case 16 : case 32 : 24 mkasm(u, "*"); break; 25 default: break; 26 } 27} 28 29/* ----------------------------------------------------------------------------- 30 * gen_operand() - Generates assembly output for each operand. 31 * ----------------------------------------------------------------------------- 32 */ 33static void 34gen_operand(struct ud* u, struct ud_operand* op) 35{ 36 switch(op->type) { 37 case UD_OP_REG: 38 mkasm(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]); 39 break; 40 41 case UD_OP_MEM: 42 if (u->br_far) opr_cast(u, op); 43 if (u->pfx_seg) 44 mkasm(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]); 45 if (op->offset == 8) { 46 if (op->lval.sbyte < 0) 47 mkasm(u, "-0x%x", (-op->lval.sbyte) & 0xff); 48 else mkasm(u, "0x%x", op->lval.sbyte); 49 } 50 else if (op->offset == 16) 51 mkasm(u, "0x%x", op->lval.uword); 52 else if (op->offset == 32) 53 mkasm(u, "0x%lx", op->lval.udword); 54 else if (op->offset == 64) 55 mkasm(u, "0x" FMT64 "x", op->lval.uqword); 56 57 if (op->base) 58 mkasm(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]); 59 if (op->index) { 60 if (op->base) 61 mkasm(u, ","); 62 else mkasm(u, "("); 63 mkasm(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]); 64 } 65 if (op->scale) 66 mkasm(u, ",%d", op->scale); 67 if (op->base || op->index) 68 mkasm(u, ")"); 69 break; 70 71 case UD_OP_IMM: 72 switch (op->size) { 73 case 8: mkasm(u, "$0x%x", op->lval.ubyte); break; 74 case 16: mkasm(u, "$0x%x", op->lval.uword); break; 75 case 32: mkasm(u, "$0x%lx", op->lval.udword); break; 76 case 64: mkasm(u, "$0x" FMT64 "x", op->lval.uqword); break; 77 default: break; 78 } 79 break; 80 81 case UD_OP_JIMM: 82 switch (op->size) { 83 case 8: 84 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte); 85 break; 86 case 16: 87 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword); 88 break; 89 case 32: 90 mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword); 91 break; 92 default:break; 93 } 94 break; 95 96 case UD_OP_PTR: 97 switch (op->size) { 98 case 32: 99 mkasm(u, "$0x%x, $0x%x", op->lval.ptr.seg, 100 op->lval.ptr.off & 0xFFFF); 101 break; 102 case 48: 103 mkasm(u, "$0x%x, $0x%lx", op->lval.ptr.seg, 104 op->lval.ptr.off); 105 break; 106 } 107 break; 108 109 default: return; 110 } 111} 112 113/* ============================================================================= 114 * translates to AT&T syntax 115 * ============================================================================= 116 */ 117extern void 118ud_translate_att(struct ud *u) 119{ 120 int size = 0; 121 122 /* check if P_OSO prefix is used */ 123 if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) { 124 switch (u->dis_mode) { 125 case 16: 126 mkasm(u, "o32 "); 127 break; 128 case 32: 129 case 64: 130 mkasm(u, "o16 "); 131 break; 132 } 133 } 134 135 /* check if P_ASO prefix was used */ 136 if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) { 137 switch (u->dis_mode) { 138 case 16: 139 mkasm(u, "a32 "); 140 break; 141 case 32: 142 mkasm(u, "a16 "); 143 break; 144 case 64: 145 mkasm(u, "a32 "); 146 break; 147 } 148 } 149 150 if (u->pfx_lock) 151 mkasm(u, "lock "); 152 if (u->pfx_rep) 153 mkasm(u, "rep "); 154 if (u->pfx_repne) 155 mkasm(u, "repne "); 156 157 /* special instructions */ 158 switch (u->mnemonic) { 159 case UD_Iretf: 160 mkasm(u, "lret "); 161 break; 162 case UD_Idb: 163 mkasm(u, ".byte 0x%x", u->operand[0].lval.ubyte); 164 return; 165 case UD_Ijmp: 166 case UD_Icall: 167 if (u->br_far) mkasm(u, "l"); 168 mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic)); 169 break; 170 case UD_Ibound: 171 case UD_Ienter: 172 if (u->operand[0].type != UD_NONE) 173 gen_operand(u, &u->operand[0]); 174 if (u->operand[1].type != UD_NONE) { 175 mkasm(u, ","); 176 gen_operand(u, &u->operand[1]); 177 } 178 return; 179 default: 180 mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic)); 181 } 182 183 if (u->c1) 184 size = u->operand[0].size; 185 else if (u->c2) 186 size = u->operand[1].size; 187 else if (u->c3) 188 size = u->operand[2].size; 189 190 if (size == 8) 191 mkasm(u, "b"); 192 else if (size == 16) 193 mkasm(u, "w"); 194 else if (size == 64) 195 mkasm(u, "q"); 196 197 mkasm(u, " "); 198 199 if (u->operand[2].type != UD_NONE) { 200 gen_operand(u, &u->operand[2]); 201 mkasm(u, ", "); 202 } 203 204 if (u->operand[1].type != UD_NONE) { 205 gen_operand(u, &u->operand[1]); 206 mkasm(u, ", "); 207 } 208 209 if (u->operand[0].type != UD_NONE) 210 gen_operand(u, &u->operand[0]); 211} 212