1 /* udis86 - libudis86/udis86.c
3 * Copyright (c) 2002-2013 Vivek Thampi
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
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.
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.
31 #if !defined(__UD_STANDALONE__)
33 #endif /* !__UD_STANDALONE__ */
35 static void ud_inp_init(struct ud
*u
);
37 /* =============================================================================
39 * Initializes ud_t object.
40 * =============================================================================
45 memset((void*)u
, 0, sizeof(struct ud
));
47 u
->mnemonic
= UD_Iinvalid
;
49 #ifndef __UD_STANDALONE__
50 ud_set_input_file(u
, stdin
);
51 #endif /* __UD_STANDALONE__ */
53 ud_set_asm_buffer(u
, u
->asm_buf_int
, sizeof(u
->asm_buf_int
));
57 /* =============================================================================
59 * Disassembles one instruction and returns the number of
60 * bytes disassembled. A zero means end of disassembly.
61 * =============================================================================
64 ud_disassemble(struct ud
* u
)
70 if ((len
= ud_decode(u
)) > 0) {
71 if (u
->translator
!= NULL
) {
80 /* =============================================================================
81 * ud_set_mode() - Set Disassemly Mode.
82 * =============================================================================
85 ud_set_mode(struct ud
* u
, uint8_t m
)
90 case 64: u
->dis_mode
= m
; return;
91 default: u
->dis_mode
= 16; return;
95 /* =============================================================================
96 * ud_set_vendor() - Set vendor.
97 * =============================================================================
100 ud_set_vendor(struct ud
* u
, unsigned v
)
103 case UD_VENDOR_INTEL
:
110 u
->vendor
= UD_VENDOR_AMD
;
114 /* =============================================================================
115 * ud_set_pc() - Sets code origin.
116 * =============================================================================
119 ud_set_pc(struct ud
* u
, uint64_t o
)
124 /* =============================================================================
125 * ud_set_syntax() - Sets the output syntax.
126 * =============================================================================
129 ud_set_syntax(struct ud
* u
, void (*t
)(struct ud
*))
134 /* =============================================================================
135 * ud_insn() - returns the disassembled instruction
136 * =============================================================================
139 ud_insn_asm(const struct ud
* u
)
144 /* =============================================================================
145 * ud_insn_offset() - Returns the offset.
146 * =============================================================================
149 ud_insn_off(const struct ud
* u
)
151 return u
->insn_offset
;
155 /* =============================================================================
156 * ud_insn_hex() - Returns hex form of disassembled instruction.
157 * =============================================================================
160 ud_insn_hex(struct ud
* u
)
162 u
->insn_hexcode
[0] = 0;
165 const unsigned char *src_ptr
= ud_insn_ptr(u
);
167 src_hex
= (char*) u
->insn_hexcode
;
168 /* for each byte used to decode instruction */
169 for (i
= 0; i
< ud_insn_len(u
) && i
< sizeof(u
->insn_hexcode
) / 2;
171 sprintf(src_hex
, "%02x", *src_ptr
& 0xFF);
175 return u
->insn_hexcode
;
179 /* =============================================================================
181 * Returns a pointer to buffer containing the bytes that were
183 * =============================================================================
185 extern const uint8_t*
186 ud_insn_ptr(const struct ud
* u
)
188 return (u
->inp_buf
== NULL
) ?
189 u
->inp_sess
: u
->inp_buf
+ (u
->inp_buf_index
- u
->inp_ctr
);
193 /* =============================================================================
195 * Returns the count of bytes disassembled.
196 * =============================================================================
199 ud_insn_len(const struct ud
* u
)
201 return (unsigned int)u
->inp_ctr
;
205 /* =============================================================================
207 * Return the operand struct representing the nth operand of
208 * the currently disassembled instruction. Returns NULL if
209 * there's no such operand.
210 * =============================================================================
212 const struct ud_operand
*
213 ud_insn_opr(const struct ud
*u
, unsigned int n
)
215 if (n
> 3 || u
->operand
[n
].type
== UD_NONE
) {
218 return &u
->operand
[n
];
223 /* =============================================================================
225 * Returns non-zero if the given operand is of a segment register type.
226 * =============================================================================
229 ud_opr_is_sreg(const struct ud_operand
*opr
)
231 return opr
->type
== UD_OP_REG
&&
232 opr
->base
>= UD_R_ES
&&
233 opr
->base
<= UD_R_GS
;
237 /* =============================================================================
239 * Returns non-zero if the given operand is of a general purpose
241 * =============================================================================
244 ud_opr_is_gpr(const struct ud_operand
*opr
)
246 return opr
->type
== UD_OP_REG
&&
247 opr
->base
>= UD_R_AL
&&
248 opr
->base
<= UD_R_R15
;
252 /* =============================================================================
253 * ud_set_user_opaque_data
254 * ud_get_user_opaque_data
255 * Get/set user opaqute data pointer
256 * =============================================================================
259 ud_set_user_opaque_data(struct ud
* u
, void* opaque
)
261 u
->user_opaque_data
= opaque
;
265 ud_get_user_opaque_data(const struct ud
*u
)
267 return u
->user_opaque_data
;
271 /* =============================================================================
273 * Allow the user to set an assembler output buffer. If `buf` is NULL,
274 * we switch back to the internal buffer.
275 * =============================================================================
278 ud_set_asm_buffer(struct ud
*u
, char *buf
, size_t size
)
281 ud_set_asm_buffer(u
, u
->asm_buf_int
, sizeof(u
->asm_buf_int
));
284 u
->asm_buf_size
= size
;
289 /* =============================================================================
290 * ud_set_sym_resolver
291 * Set symbol resolver for relative targets used in the translation
294 * The resolver is a function that takes a uint64_t address and returns a
295 * symbolic name for the that address. The function also takes a second
296 * argument pointing to an integer that the client can optionally set to a
297 * non-zero value for offsetted targets. (symbol+offset) The function may
298 * also return NULL, in which case the translator only prints the target
301 * The function pointer maybe NULL which resets symbol resolution.
302 * =============================================================================
305 ud_set_sym_resolver(struct ud
*u
, const char* (*resolver
)(struct ud
*,
309 u
->sym_resolver
= resolver
;
313 /* =============================================================================
315 * Return the current instruction mnemonic.
316 * =============================================================================
318 enum ud_mnemonic_code
319 ud_insn_mnemonic(const struct ud
*u
)
325 /* =============================================================================
327 * Looks up mnemonic code in the mnemonic string table.
328 * Returns NULL if the mnemonic code is invalid.
329 * =============================================================================
332 ud_lookup_mnemonic(enum ud_mnemonic_code c
)
334 if (c
< UD_MAX_MNEMONIC_CODE
) {
335 return ud_mnemonics_str
[c
];
344 * Initializes the input system.
347 ud_inp_init(struct ud
*u
)
352 u
->inp_buf_index
= 0;
356 u
->inp_peek
= UD_EOI
;
357 UD_NON_STANDALONE(u
->inp_file
= NULL
);
361 /* =============================================================================
364 * =============================================================================
367 ud_set_input_hook(register struct ud
* u
, int (*hook
)(struct ud
*))
373 /* =============================================================================
375 * Set buffer as input.
376 * =============================================================================
379 ud_set_input_buffer(register struct ud
* u
, const uint8_t* buf
, size_t len
)
383 u
->inp_buf_size
= len
;
384 u
->inp_buf_index
= 0;
388 #ifndef __UD_STANDALONE__
389 /* =============================================================================
392 * =============================================================================
395 inp_file_hook(struct ud
* u
)
397 return fgetc(u
->inp_file
);
401 ud_set_input_file(register struct ud
* u
, FILE* f
)
404 u
->inp_hook
= inp_file_hook
;
407 #endif /* __UD_STANDALONE__ */
410 /* =============================================================================
412 * Skip n input bytes.
413 * ============================================================================
416 ud_input_skip(struct ud
* u
, size_t n
)
421 if (u
->inp_buf
== NULL
) {
423 int c
= u
->inp_hook(u
);
430 if (n
> u
->inp_buf_size
||
431 u
->inp_buf_index
> u
->inp_buf_size
- n
) {
432 u
->inp_buf_index
= u
->inp_buf_size
;
435 u
->inp_buf_index
+= n
;
440 UDERR(u
, "cannot skip, eoi received\b");
445 /* =============================================================================
447 * Returns non-zero on end-of-input.
448 * =============================================================================
451 ud_input_end(const struct ud
*u
)
456 /* vim:set ts=2 sw=2 expandtab */