Home | History | Annotate | Download | only in libudis86
      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_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
    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