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 "udint.h"
28#include "extern.h"
29#include "decode.h"
30
31#include <string.h>
32
33static void ud_inp_init(struct ud *u);
34
35/* =============================================================================
36 * ud_init
37 *    Initializes ud_t object.
38 * =============================================================================
39 */
40extern void
41ud_init(struct ud* u)
42{
43  memset((void*)u, 0, sizeof(struct ud));
44  ud_set_mode(u, 16);
45  u->mnemonic = UD_Iinvalid;
46  ud_set_pc(u, 0);
47#ifndef __UD_STANDALONE__
48  ud_set_input_file(u, stdin);
49#endif /* __UD_STANDALONE__ */
50
51  ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
52}
53
54
55/* =============================================================================
56 * ud_disassemble
57 *    Disassembles one instruction and returns the number of
58 *    bytes disassembled. A zero means end of disassembly.
59 * =============================================================================
60 */
61extern unsigned int
62ud_disassemble(struct ud* u)
63{
64  int len;
65  if (u->inp_end) {
66    return 0;
67  }
68  if ((len = ud_decode(u)) > 0) {
69    if (u->translator != NULL) {
70      u->asm_buf[0] = '\0';
71      u->translator(u);
72    }
73  }
74  return len;
75}
76
77
78/* =============================================================================
79 * ud_set_mode() - Set Disassemly Mode.
80 * =============================================================================
81 */
82extern void
83ud_set_mode(struct ud* u, uint8_t m)
84{
85  switch(m) {
86  case 16:
87  case 32:
88  case 64: u->dis_mode = m ; return;
89  default: u->dis_mode = 16; return;
90  }
91}
92
93/* =============================================================================
94 * ud_set_vendor() - Set vendor.
95 * =============================================================================
96 */
97extern void
98ud_set_vendor(struct ud* u, unsigned v)
99{
100  switch(v) {
101  case UD_VENDOR_INTEL:
102    u->vendor = v;
103    break;
104  case UD_VENDOR_ANY:
105    u->vendor = v;
106    break;
107  default:
108    u->vendor = UD_VENDOR_AMD;
109  }
110}
111
112/* =============================================================================
113 * ud_set_pc() - Sets code origin.
114 * =============================================================================
115 */
116extern void
117ud_set_pc(struct ud* u, uint64_t o)
118{
119  u->pc = o;
120}
121
122/* =============================================================================
123 * ud_set_syntax() - Sets the output syntax.
124 * =============================================================================
125 */
126extern void
127ud_set_syntax(struct ud* u, void (*t)(struct ud*))
128{
129  u->translator = t;
130}
131
132/* =============================================================================
133 * ud_insn() - returns the disassembled instruction
134 * =============================================================================
135 */
136const char*
137ud_insn_asm(const struct ud* u)
138{
139  return u->asm_buf;
140}
141
142/* =============================================================================
143 * ud_insn_offset() - Returns the offset.
144 * =============================================================================
145 */
146uint64_t
147ud_insn_off(const struct ud* u)
148{
149  return u->insn_offset;
150}
151
152
153/* =============================================================================
154 * ud_insn_hex() - Returns hex form of disassembled instruction.
155 * =============================================================================
156 */
157const char*
158ud_insn_hex(struct ud* u)
159{
160  u->insn_hexcode[0] = 0;
161  if (!u->error) {
162    unsigned int i;
163    const unsigned char *src_ptr = ud_insn_ptr(u);
164    char* src_hex;
165    src_hex = (char*) u->insn_hexcode;
166    /* for each byte used to decode instruction */
167    for (i = 0; i < ud_insn_len(u) && i < sizeof(u->insn_hexcode) / 2;
168         ++i, ++src_ptr) {
169      sprintf(src_hex, "%02x", *src_ptr & 0xFF);
170      src_hex += 2;
171    }
172  }
173  return u->insn_hexcode;
174}
175
176
177/* =============================================================================
178 * ud_insn_ptr
179 *    Returns a pointer to buffer containing the bytes that were
180 *    disassembled.
181 * =============================================================================
182 */
183extern const uint8_t*
184ud_insn_ptr(const struct ud* u)
185{
186  return (u->inp_buf == NULL) ?
187            u->inp_sess : u->inp_buf + (u->inp_buf_index - u->inp_ctr);
188}
189
190
191/* =============================================================================
192 * ud_insn_len
193 *    Returns the count of bytes disassembled.
194 * =============================================================================
195 */
196extern unsigned int
197ud_insn_len(const struct ud* u)
198{
199  return u->inp_ctr;
200}
201
202
203/* =============================================================================
204 * ud_insn_get_opr
205 *    Return the operand struct representing the nth operand of
206 *    the currently disassembled instruction. Returns NULL if
207 *    there's no such operand.
208 * =============================================================================
209 */
210const struct ud_operand*
211ud_insn_opr(const struct ud *u, unsigned int n)
212{
213  if (n > 3 || u->operand[n].type == UD_NONE) {
214    return NULL;
215  } else {
216    return &u->operand[n];
217  }
218}
219
220
221/* =============================================================================
222 * ud_opr_is_sreg
223 *    Returns non-zero if the given operand is of a segment register type.
224 * =============================================================================
225 */
226int
227ud_opr_is_sreg(const struct ud_operand *opr)
228{
229  return opr->type == UD_OP_REG &&
230         opr->base >= UD_R_ES   &&
231         opr->base <= UD_R_GS;
232}
233
234
235/* =============================================================================
236 * ud_opr_is_sreg
237 *    Returns non-zero if the given operand is of a general purpose
238 *    register type.
239 * =============================================================================
240 */
241int
242ud_opr_is_gpr(const struct ud_operand *opr)
243{
244  return opr->type == UD_OP_REG &&
245         opr->base >= UD_R_AL   &&
246         opr->base <= UD_R_R15;
247}
248
249
250/* =============================================================================
251 * ud_set_user_opaque_data
252 * ud_get_user_opaque_data
253 *    Get/set user opaqute data pointer
254 * =============================================================================
255 */
256void
257ud_set_user_opaque_data(struct ud * u, void* opaque)
258{
259  u->user_opaque_data = opaque;
260}
261
262void*
263ud_get_user_opaque_data(const struct ud *u)
264{
265  return u->user_opaque_data;
266}
267
268
269/* =============================================================================
270 * ud_set_asm_buffer
271 *    Allow the user to set an assembler output buffer. If `buf` is NULL,
272 *    we switch back to the internal buffer.
273 * =============================================================================
274 */
275void
276ud_set_asm_buffer(struct ud *u, char *buf, size_t size)
277{
278  if (buf == NULL) {
279    ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
280  } else {
281    u->asm_buf = buf;
282    u->asm_buf_size = size;
283  }
284}
285
286
287/* =============================================================================
288 * ud_set_sym_resolver
289 *    Set symbol resolver for relative targets used in the translation
290 *    phase.
291 *
292 *    The resolver is a function that takes a uint64_t address and returns a
293 *    symbolic name for the that address. The function also takes a second
294 *    argument pointing to an integer that the client can optionally set to a
295 *    non-zero value for offsetted targets. (symbol+offset) The function may
296 *    also return NULL, in which case the translator only prints the target
297 *    address.
298 *
299 *    The function pointer maybe NULL which resets symbol resolution.
300 * =============================================================================
301 */
302void
303ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*,
304                                                          uint64_t addr,
305                                                          int64_t *offset))
306{
307  u->sym_resolver = resolver;
308}
309
310
311/* =============================================================================
312 * ud_insn_mnemonic
313 *    Return the current instruction mnemonic.
314 * =============================================================================
315 */
316enum ud_mnemonic_code
317ud_insn_mnemonic(const struct ud *u)
318{
319  return u->mnemonic;
320}
321
322
323/* =============================================================================
324 * ud_lookup_mnemonic
325 *    Looks up mnemonic code in the mnemonic string table.
326 *    Returns NULL if the mnemonic code is invalid.
327 * =============================================================================
328 */
329const char*
330ud_lookup_mnemonic(enum ud_mnemonic_code c)
331{
332  if (c < UD_MAX_MNEMONIC_CODE) {
333    return ud_mnemonics_str[c];
334  } else {
335    return NULL;
336  }
337}
338
339
340/*
341 * ud_inp_init
342 *    Initializes the input system.
343 */
344static void
345ud_inp_init(struct ud *u)
346{
347  u->inp_hook      = NULL;
348  u->inp_buf       = NULL;
349  u->inp_buf_size  = 0;
350  u->inp_buf_index = 0;
351  u->inp_curr      = 0;
352  u->inp_ctr       = 0;
353  u->inp_end       = 0;
354  u->inp_peek      = UD_EOI;
355  UD_NON_STANDALONE(u->inp_file = NULL);
356}
357
358
359/* =============================================================================
360 * ud_inp_set_hook
361 *    Sets input hook.
362 * =============================================================================
363 */
364void
365ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
366{
367  ud_inp_init(u);
368  u->inp_hook = hook;
369}
370
371/* =============================================================================
372 * ud_inp_set_buffer
373 *    Set buffer as input.
374 * =============================================================================
375 */
376void
377ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len)
378{
379  ud_inp_init(u);
380  u->inp_buf = buf;
381  u->inp_buf_size = len;
382  u->inp_buf_index = 0;
383}
384
385
386#ifndef __UD_STANDALONE__
387/* =============================================================================
388 * ud_input_set_file
389 *    Set FILE as input.
390 * =============================================================================
391 */
392static int
393inp_file_hook(struct ud* u)
394{
395  return fgetc(u->inp_file);
396}
397
398void
399ud_set_input_file(register struct ud* u, FILE* f)
400{
401  ud_inp_init(u);
402  u->inp_hook = inp_file_hook;
403  u->inp_file = f;
404}
405#endif /* __UD_STANDALONE__ */
406
407
408/* =============================================================================
409 * ud_input_skip
410 *    Skip n input bytes.
411 * ============================================================================
412 */
413void
414ud_input_skip(struct ud* u, size_t n)
415{
416  if (u->inp_end) {
417    return;
418  }
419  if (u->inp_buf == NULL) {
420    while (n--) {
421      int c = u->inp_hook(u);
422      if (c == UD_EOI) {
423        goto eoi;
424      }
425    }
426    return;
427  } else {
428    if (n > u->inp_buf_size ||
429        u->inp_buf_index > u->inp_buf_size - n) {
430      u->inp_buf_index = u->inp_buf_size;
431      goto eoi;
432    }
433    u->inp_buf_index += n;
434    return;
435  }
436eoi:
437  u->inp_end = 1;
438  UDERR(u, "cannot skip, eoi received\b");
439  return;
440}
441
442
443/* =============================================================================
444 * ud_input_end
445 *    Returns non-zero on end-of-input.
446 * =============================================================================
447 */
448int
449ud_input_end(const struct ud *u)
450{
451  return u->inp_end;
452}
453
454/* vim:set ts=2 sw=2 expandtab */
455