Home | History | Annotate | Download | only in libudis86
      1 /* udis86 - libudis86/udis86.c
      2  *
      3  * Copyright (c) 2002-2013 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 
     27 #include "input.h"
     28 #include "extern.h"
     29 #include "decode.h"
     30 
     31 #if !defined(__UD_STANDALONE__)
     32 # if HAVE_STRING_H
     33 #  include <string.h>
     34 # endif
     35 #endif /* !__UD_STANDALONE__ */
     36 
     37 /* =============================================================================
     38  * ud_init() - Initializes ud_t object.
     39  * =============================================================================
     40  */
     41 extern void
     42 ud_init(struct ud* u)
     43 {
     44   memset((void*)u, 0, sizeof(struct ud));
     45   ud_set_mode(u, 16);
     46   u->mnemonic = UD_Iinvalid;
     47   ud_set_pc(u, 0);
     48 #ifndef __UD_STANDALONE__
     49   ud_set_input_file(u, stdin);
     50 #endif /* __UD_STANDALONE__ */
     51 
     52   ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
     53 }
     54 
     55 /* =============================================================================
     56  * ud_disassemble() - disassembles one instruction and returns the number of
     57  * bytes disassembled. A zero means end of disassembly.
     58  * =============================================================================
     59  */
     60 extern unsigned int
     61 ud_disassemble(struct ud* u)
     62 {
     63   if (ud_input_end(u))
     64   return 0;
     65 
     66   u->asm_buf[0] = 0;
     67 
     68   if (ud_decode(u) == 0)
     69   return 0;
     70   if (u->translator)
     71   u->translator(u);
     72   return ud_insn_len(u);
     73 }
     74 
     75 /* =============================================================================
     76  * ud_set_mode() - Set Disassemly Mode.
     77  * =============================================================================
     78  */
     79 extern void
     80 ud_set_mode(struct ud* u, uint8_t m)
     81 {
     82   switch(m) {
     83   case 16:
     84   case 32:
     85   case 64: u->dis_mode = m ; return;
     86   default: u->dis_mode = 16; return;
     87   }
     88 }
     89 
     90 /* =============================================================================
     91  * ud_set_vendor() - Set vendor.
     92  * =============================================================================
     93  */
     94 extern void
     95 ud_set_vendor(struct ud* u, unsigned v)
     96 {
     97   switch(v) {
     98   case UD_VENDOR_INTEL:
     99     u->vendor = v;
    100     break;
    101   case UD_VENDOR_ANY:
    102     u->vendor = v;
    103     break;
    104   default:
    105     u->vendor = UD_VENDOR_AMD;
    106   }
    107 }
    108 
    109 /* =============================================================================
    110  * ud_set_pc() - Sets code origin.
    111  * =============================================================================
    112  */
    113 extern void
    114 ud_set_pc(struct ud* u, uint64_t o)
    115 {
    116   u->pc = o;
    117 }
    118 
    119 /* =============================================================================
    120  * ud_set_syntax() - Sets the output syntax.
    121  * =============================================================================
    122  */
    123 extern void
    124 ud_set_syntax(struct ud* u, void (*t)(struct ud*))
    125 {
    126   u->translator = t;
    127 }
    128 
    129 /* =============================================================================
    130  * ud_insn() - returns the disassembled instruction
    131  * =============================================================================
    132  */
    133 const char*
    134 ud_insn_asm(const struct ud* u)
    135 {
    136   return u->asm_buf;
    137 }
    138 
    139 /* =============================================================================
    140  * ud_insn_offset() - Returns the offset.
    141  * =============================================================================
    142  */
    143 uint64_t
    144 ud_insn_off(const struct ud* u)
    145 {
    146   return u->insn_offset;
    147 }
    148 
    149 
    150 /* =============================================================================
    151  * ud_insn_hex() - Returns hex form of disassembled instruction.
    152  * =============================================================================
    153  */
    154 const char*
    155 ud_insn_hex(struct ud* u)
    156 {
    157   u->insn_hexcode[0] = 0;
    158   if (!u->error) {
    159     unsigned int i;
    160     unsigned char *src_ptr = inp_sess(u);
    161     char* src_hex;
    162     src_hex = (char*) u->insn_hexcode;
    163     /* for each byte used to decode instruction */
    164     for (i = 0; i < u->inp_ctr && i < sizeof(u->insn_hexcode) / 2;
    165          ++i, ++src_ptr) {
    166       sprintf(src_hex, "%02x", *src_ptr & 0xFF);
    167       src_hex += 2;
    168     }
    169   }
    170   return u->insn_hexcode;
    171 }
    172 
    173 
    174 /* =============================================================================
    175  * ud_insn_ptr() - Returns code disassembled.
    176  * =============================================================================
    177  */
    178 extern const uint8_t*
    179 ud_insn_ptr(const struct ud* u)
    180 {
    181   return u->inp_sess;
    182 }
    183 
    184 /* =============================================================================
    185  * ud_insn_len() - Returns the count of bytes disassembled.
    186  * =============================================================================
    187  */
    188 extern unsigned int
    189 ud_insn_len(const struct ud* u)
    190 {
    191   return u->inp_ctr;
    192 }
    193 
    194 
    195 /* =============================================================================
    196  * ud_insn_get_opr
    197  *    Return the operand struct representing the nth operand of
    198  *    the currently disassembled instruction. Returns NULL if
    199  *    there's no such operand.
    200  * =============================================================================
    201  */
    202 const struct ud_operand*
    203 ud_insn_opr(const struct ud *u, unsigned int n)
    204 {
    205   if (n > 2 || u->operand[n].type == UD_NONE) {
    206     return NULL;
    207   } else {
    208     return &u->operand[n];
    209   }
    210 }
    211 
    212 
    213 /* =============================================================================
    214  * ud_opr_is_sreg
    215  *    Returns non-zero if the given operand is of a segment register type.
    216  * =============================================================================
    217  */
    218 int
    219 ud_opr_is_sreg(const struct ud_operand *opr)
    220 {
    221   return opr->type == UD_OP_REG &&
    222          opr->base >= UD_R_ES   &&
    223          opr->base <= UD_R_GS;
    224 }
    225 
    226 
    227 /* =============================================================================
    228  * ud_opr_is_sreg
    229  *    Returns non-zero if the given operand is of a general purpose
    230  *    register type.
    231  * =============================================================================
    232  */
    233 int
    234 ud_opr_is_gpr(const struct ud_operand *opr)
    235 {
    236   return opr->type == UD_OP_REG &&
    237          opr->base >= UD_R_AL   &&
    238          opr->base <= UD_R_R15;
    239 }
    240 
    241 
    242 /* =============================================================================
    243  * ud_set_user_opaque_data
    244  * ud_get_user_opaque_data
    245  *    Get/set user opaqute data pointer
    246  * =============================================================================
    247  */
    248 void
    249 ud_set_user_opaque_data(struct ud * u, void* opaque)
    250 {
    251   u->user_opaque_data = opaque;
    252 }
    253 
    254 void*
    255 ud_get_user_opaque_data(const struct ud *u)
    256 {
    257   return u->user_opaque_data;
    258 }
    259 
    260 
    261 /* =============================================================================
    262  * ud_set_asm_buffer
    263  *    Allow the user to set an assembler output buffer. If `buf` is NULL,
    264  *    we switch back to the internal buffer.
    265  * =============================================================================
    266  */
    267 void
    268 ud_set_asm_buffer(struct ud *u, char *buf, size_t size)
    269 {
    270   if (buf == NULL) {
    271     ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
    272   } else {
    273     u->asm_buf = buf;
    274     u->asm_buf_size = size;
    275   }
    276 }
    277 
    278 
    279 /* =============================================================================
    280  * ud_set_sym_resolver
    281  *    Set symbol resolver for relative targets used in the translation
    282  *    phase.
    283  *
    284  *    The resolver is a function that takes a uint64_t address and returns a
    285  *    symbolic name for the that address. The function also takes a second
    286  *    argument pointing to an integer that the client can optionally set to a
    287  *    non-zero value for offsetted targets. (symbol+offset) The function may
    288  *    also return NULL, in which case the translator only prints the target
    289  *    address.
    290  *
    291  *    The function pointer maybe NULL which resets symbol resolution.
    292  * =============================================================================
    293  */
    294 void
    295 ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*,
    296                                                           uint64_t addr,
    297                                                           int64_t *offset))
    298 {
    299   u->sym_resolver = resolver;
    300 }
    301 
    302 /*
    303 vim:set ts=2 sw=2 expandtab
    304 */
    305