Update udis86 to current version.
This commit is contained in:
parent
735ca4068d
commit
a358634d15
@ -1,33 +1,46 @@
|
||||
/* udis86 - libudis86/decode.h
|
||||
*
|
||||
* Copyright (c) 2002-2009 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef UD_DECODE_H
|
||||
#define UD_DECODE_H
|
||||
|
||||
#define MAX_INSN_LENGTH 15
|
||||
#include "types.h"
|
||||
#include "itab.h"
|
||||
|
||||
/* register classes */
|
||||
#define T_NONE 0
|
||||
#define T_GPR 1
|
||||
#define T_MMX 2
|
||||
#define T_CRG 3
|
||||
#define T_DBG 4
|
||||
#define T_SEG 5
|
||||
#define T_XMM 6
|
||||
#define MAX_INSN_LENGTH 15
|
||||
|
||||
/* itab prefix bits */
|
||||
#define P_none ( 0 )
|
||||
#define P_c1 ( 1 << 0 )
|
||||
#define P_C1(n) ( ( n >> 0 ) & 1 )
|
||||
#define P_cast ( 1 << 0 )
|
||||
#define P_CAST(n) ( ( n >> 0 ) & 1 )
|
||||
#define P_rexb ( 1 << 1 )
|
||||
#define P_REXB(n) ( ( n >> 1 ) & 1 )
|
||||
#define P_depM ( 1 << 2 )
|
||||
#define P_DEPM(n) ( ( n >> 2 ) & 1 )
|
||||
#define P_c3 ( 1 << 3 )
|
||||
#define P_C3(n) ( ( n >> 3 ) & 1 )
|
||||
#define P_inv64 ( 1 << 4 )
|
||||
#define P_INV64(n) ( ( n >> 4 ) & 1 )
|
||||
#define P_rexw ( 1 << 5 )
|
||||
#define P_REXW(n) ( ( n >> 5 ) & 1 )
|
||||
#define P_c2 ( 1 << 6 )
|
||||
#define P_C2(n) ( ( n >> 6 ) & 1 )
|
||||
#define P_def64 ( 1 << 7 )
|
||||
#define P_DEF64(n) ( ( n >> 7 ) & 1 )
|
||||
#define P_rexr ( 1 << 8 )
|
||||
@ -40,27 +53,12 @@
|
||||
#define P_REXX(n) ( ( n >> 11 ) & 1 )
|
||||
#define P_ImpAddr ( 1 << 12 )
|
||||
#define P_IMPADDR(n) ( ( n >> 12 ) & 1 )
|
||||
|
||||
/* rex prefix bits */
|
||||
#define REX_W(r) ( ( 0xF & ( r ) ) >> 3 )
|
||||
#define REX_R(r) ( ( 0x7 & ( r ) ) >> 2 )
|
||||
#define REX_X(r) ( ( 0x3 & ( r ) ) >> 1 )
|
||||
#define REX_B(r) ( ( 0x1 & ( r ) ) >> 0 )
|
||||
#define REX_PFX_MASK(n) ( ( P_REXW(n) << 3 ) | \
|
||||
( P_REXR(n) << 2 ) | \
|
||||
( P_REXX(n) << 1 ) | \
|
||||
( P_REXB(n) << 0 ) )
|
||||
|
||||
/* scable-index-base bits */
|
||||
#define SIB_S(b) ( ( b ) >> 6 )
|
||||
#define SIB_I(b) ( ( ( b ) >> 3 ) & 7 )
|
||||
#define SIB_B(b) ( ( b ) & 7 )
|
||||
|
||||
/* modrm bits */
|
||||
#define MODRM_REG(b) ( ( ( b ) >> 3 ) & 7 )
|
||||
#define MODRM_NNN(b) ( ( ( b ) >> 3 ) & 7 )
|
||||
#define MODRM_MOD(b) ( ( ( b ) >> 6 ) & 3 )
|
||||
#define MODRM_RM(b) ( ( b ) & 7 )
|
||||
#define P_seg ( 1 << 13 )
|
||||
#define P_SEG(n) ( ( n >> 13 ) & 1 )
|
||||
#define P_str ( 1 << 14 )
|
||||
#define P_STR(n) ( ( n >> 14 ) & 1 )
|
||||
#define P_strz ( 1 << 15 )
|
||||
#define P_STR_ZF(n) ( ( n >> 15 ) & 1 )
|
||||
|
||||
/* operand type constants -- order is important! */
|
||||
|
||||
@ -68,25 +66,15 @@ enum ud_operand_code {
|
||||
OP_NONE,
|
||||
|
||||
OP_A, OP_E, OP_M, OP_G,
|
||||
OP_I,
|
||||
OP_I, OP_F,
|
||||
|
||||
OP_AL, OP_CL, OP_DL, OP_BL,
|
||||
OP_AH, OP_CH, OP_DH, OP_BH,
|
||||
OP_R0, OP_R1, OP_R2, OP_R3,
|
||||
OP_R4, OP_R5, OP_R6, OP_R7,
|
||||
|
||||
OP_ALr8b, OP_CLr9b, OP_DLr10b, OP_BLr11b,
|
||||
OP_AHr12b, OP_CHr13b, OP_DHr14b, OP_BHr15b,
|
||||
|
||||
OP_AX, OP_CX, OP_DX, OP_BX,
|
||||
OP_SI, OP_DI, OP_SP, OP_BP,
|
||||
|
||||
OP_rAX, OP_rCX, OP_rDX, OP_rBX,
|
||||
OP_rSP, OP_rBP, OP_rSI, OP_rDI,
|
||||
|
||||
OP_rAXr8, OP_rCXr9, OP_rDXr10, OP_rBXr11,
|
||||
OP_rSPr12, OP_rBPr13, OP_rSIr14, OP_rDIr15,
|
||||
|
||||
OP_eAX, OP_eCX, OP_eDX, OP_eBX,
|
||||
OP_eSP, OP_eBP, OP_eSI, OP_eDI,
|
||||
OP_AL, OP_CL, OP_DL,
|
||||
OP_AX, OP_CX, OP_DX,
|
||||
OP_eAX, OP_eCX, OP_eDX,
|
||||
OP_rAX, OP_rCX, OP_rDX,
|
||||
|
||||
OP_ES, OP_CS, OP_SS, OP_DS,
|
||||
OP_FS, OP_GS,
|
||||
@ -95,12 +83,15 @@ enum ud_operand_code {
|
||||
OP_ST4, OP_ST5, OP_ST6, OP_ST7,
|
||||
|
||||
OP_J, OP_S, OP_O,
|
||||
OP_I1, OP_I3,
|
||||
OP_I1, OP_I3, OP_sI,
|
||||
|
||||
OP_V, OP_W, OP_Q, OP_P,
|
||||
OP_U, OP_N, OP_MU,
|
||||
|
||||
OP_R, OP_C, OP_D, OP_VR, OP_PR
|
||||
};
|
||||
OP_R, OP_C, OP_D,
|
||||
|
||||
OP_MR
|
||||
} UD_ATTR_PACKED;
|
||||
|
||||
|
||||
/* operand size constants */
|
||||
@ -109,10 +100,6 @@ enum ud_operand_size {
|
||||
SZ_NA = 0,
|
||||
SZ_Z = 1,
|
||||
SZ_V = 2,
|
||||
SZ_P = 3,
|
||||
SZ_WP = 4,
|
||||
SZ_DP = 5,
|
||||
SZ_MDQ = 6,
|
||||
SZ_RDQ = 7,
|
||||
|
||||
/* the following values are used as is,
|
||||
@ -124,123 +111,41 @@ enum ud_operand_size {
|
||||
SZ_D = 32,
|
||||
SZ_Q = 64,
|
||||
SZ_T = 80,
|
||||
};
|
||||
SZ_O = 128,
|
||||
|
||||
/* itab entry operand definitions */
|
||||
SZ_Y = 17,
|
||||
|
||||
#define O_rSPr12 { OP_rSPr12, SZ_NA }
|
||||
#define O_BL { OP_BL, SZ_NA }
|
||||
#define O_BH { OP_BH, SZ_NA }
|
||||
#define O_BP { OP_BP, SZ_NA }
|
||||
#define O_AHr12b { OP_AHr12b, SZ_NA }
|
||||
#define O_BX { OP_BX, SZ_NA }
|
||||
#define O_Jz { OP_J, SZ_Z }
|
||||
#define O_Jv { OP_J, SZ_V }
|
||||
#define O_Jb { OP_J, SZ_B }
|
||||
#define O_rSIr14 { OP_rSIr14, SZ_NA }
|
||||
#define O_GS { OP_GS, SZ_NA }
|
||||
#define O_D { OP_D, SZ_NA }
|
||||
#define O_rBPr13 { OP_rBPr13, SZ_NA }
|
||||
#define O_Ob { OP_O, SZ_B }
|
||||
#define O_P { OP_P, SZ_NA }
|
||||
#define O_Ow { OP_O, SZ_W }
|
||||
#define O_Ov { OP_O, SZ_V }
|
||||
#define O_Gw { OP_G, SZ_W }
|
||||
#define O_Gv { OP_G, SZ_V }
|
||||
#define O_rDX { OP_rDX, SZ_NA }
|
||||
#define O_Gx { OP_G, SZ_MDQ }
|
||||
#define O_Gd { OP_G, SZ_D }
|
||||
#define O_Gb { OP_G, SZ_B }
|
||||
#define O_rBXr11 { OP_rBXr11, SZ_NA }
|
||||
#define O_rDI { OP_rDI, SZ_NA }
|
||||
#define O_rSI { OP_rSI, SZ_NA }
|
||||
#define O_ALr8b { OP_ALr8b, SZ_NA }
|
||||
#define O_eDI { OP_eDI, SZ_NA }
|
||||
#define O_Gz { OP_G, SZ_Z }
|
||||
#define O_eDX { OP_eDX, SZ_NA }
|
||||
#define O_DHr14b { OP_DHr14b, SZ_NA }
|
||||
#define O_rSP { OP_rSP, SZ_NA }
|
||||
#define O_PR { OP_PR, SZ_NA }
|
||||
#define O_NONE { OP_NONE, SZ_NA }
|
||||
#define O_rCX { OP_rCX, SZ_NA }
|
||||
#define O_jWP { OP_J, SZ_WP }
|
||||
#define O_rDXr10 { OP_rDXr10, SZ_NA }
|
||||
#define O_Md { OP_M, SZ_D }
|
||||
#define O_C { OP_C, SZ_NA }
|
||||
#define O_G { OP_G, SZ_NA }
|
||||
#define O_Mb { OP_M, SZ_B }
|
||||
#define O_Mt { OP_M, SZ_T }
|
||||
#define O_S { OP_S, SZ_NA }
|
||||
#define O_Mq { OP_M, SZ_Q }
|
||||
#define O_W { OP_W, SZ_NA }
|
||||
#define O_ES { OP_ES, SZ_NA }
|
||||
#define O_rBX { OP_rBX, SZ_NA }
|
||||
#define O_Ed { OP_E, SZ_D }
|
||||
#define O_DLr10b { OP_DLr10b, SZ_NA }
|
||||
#define O_Mw { OP_M, SZ_W }
|
||||
#define O_Eb { OP_E, SZ_B }
|
||||
#define O_Ex { OP_E, SZ_MDQ }
|
||||
#define O_Ez { OP_E, SZ_Z }
|
||||
#define O_Ew { OP_E, SZ_W }
|
||||
#define O_Ev { OP_E, SZ_V }
|
||||
#define O_Ep { OP_E, SZ_P }
|
||||
#define O_FS { OP_FS, SZ_NA }
|
||||
#define O_Ms { OP_M, SZ_W }
|
||||
#define O_rAXr8 { OP_rAXr8, SZ_NA }
|
||||
#define O_eBP { OP_eBP, SZ_NA }
|
||||
#define O_Isb { OP_I, SZ_SB }
|
||||
#define O_eBX { OP_eBX, SZ_NA }
|
||||
#define O_rCXr9 { OP_rCXr9, SZ_NA }
|
||||
#define O_jDP { OP_J, SZ_DP }
|
||||
#define O_CH { OP_CH, SZ_NA }
|
||||
#define O_CL { OP_CL, SZ_NA }
|
||||
#define O_R { OP_R, SZ_RDQ }
|
||||
#define O_V { OP_V, SZ_NA }
|
||||
#define O_CS { OP_CS, SZ_NA }
|
||||
#define O_CHr13b { OP_CHr13b, SZ_NA }
|
||||
#define O_eCX { OP_eCX, SZ_NA }
|
||||
#define O_eSP { OP_eSP, SZ_NA }
|
||||
#define O_SS { OP_SS, SZ_NA }
|
||||
#define O_SP { OP_SP, SZ_NA }
|
||||
#define O_BLr11b { OP_BLr11b, SZ_NA }
|
||||
#define O_SI { OP_SI, SZ_NA }
|
||||
#define O_eSI { OP_eSI, SZ_NA }
|
||||
#define O_DL { OP_DL, SZ_NA }
|
||||
#define O_DH { OP_DH, SZ_NA }
|
||||
#define O_DI { OP_DI, SZ_NA }
|
||||
#define O_DX { OP_DX, SZ_NA }
|
||||
#define O_rBP { OP_rBP, SZ_NA }
|
||||
#define O_Gvw { OP_G, SZ_MDQ }
|
||||
#define O_I1 { OP_I1, SZ_NA }
|
||||
#define O_I3 { OP_I3, SZ_NA }
|
||||
#define O_DS { OP_DS, SZ_NA }
|
||||
#define O_ST4 { OP_ST4, SZ_NA }
|
||||
#define O_ST5 { OP_ST5, SZ_NA }
|
||||
#define O_ST6 { OP_ST6, SZ_NA }
|
||||
#define O_ST7 { OP_ST7, SZ_NA }
|
||||
#define O_ST0 { OP_ST0, SZ_NA }
|
||||
#define O_ST1 { OP_ST1, SZ_NA }
|
||||
#define O_ST2 { OP_ST2, SZ_NA }
|
||||
#define O_ST3 { OP_ST3, SZ_NA }
|
||||
#define O_E { OP_E, SZ_NA }
|
||||
#define O_AH { OP_AH, SZ_NA }
|
||||
#define O_M { OP_M, SZ_NA }
|
||||
#define O_AL { OP_AL, SZ_NA }
|
||||
#define O_CLr9b { OP_CLr9b, SZ_NA }
|
||||
#define O_Q { OP_Q, SZ_NA }
|
||||
#define O_eAX { OP_eAX, SZ_NA }
|
||||
#define O_VR { OP_VR, SZ_NA }
|
||||
#define O_AX { OP_AX, SZ_NA }
|
||||
#define O_rAX { OP_rAX, SZ_NA }
|
||||
#define O_Iz { OP_I, SZ_Z }
|
||||
#define O_rDIr15 { OP_rDIr15, SZ_NA }
|
||||
#define O_Iw { OP_I, SZ_W }
|
||||
#define O_Iv { OP_I, SZ_V }
|
||||
#define O_Ap { OP_A, SZ_P }
|
||||
#define O_CX { OP_CX, SZ_NA }
|
||||
#define O_Ib { OP_I, SZ_B }
|
||||
#define O_BHr15b { OP_BHr15b, SZ_NA }
|
||||
/*
|
||||
* complex size types, that encode sizes for operands
|
||||
* of type MR (memory or register), for internal use
|
||||
* only. Id space 256 and above.
|
||||
*/
|
||||
SZ_BD = (SZ_B << 8) | SZ_D,
|
||||
SZ_BV = (SZ_B << 8) | SZ_V,
|
||||
SZ_WD = (SZ_W << 8) | SZ_D,
|
||||
SZ_WV = (SZ_W << 8) | SZ_V,
|
||||
SZ_WY = (SZ_W << 8) | SZ_Y,
|
||||
SZ_DY = (SZ_D << 8) | SZ_Y,
|
||||
SZ_WO = (SZ_W << 8) | SZ_O,
|
||||
SZ_DO = (SZ_D << 8) | SZ_O,
|
||||
SZ_QO = (SZ_Q << 8) | SZ_O,
|
||||
|
||||
} UD_ATTR_PACKED;
|
||||
|
||||
|
||||
/* resolve complex size type.
|
||||
*/
|
||||
static inline enum ud_operand_size
|
||||
Mx_mem_size(enum ud_operand_size size)
|
||||
{
|
||||
return (size >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static inline enum ud_operand_size
|
||||
Mx_reg_size(enum ud_operand_size size)
|
||||
{
|
||||
return size & 0xff;
|
||||
}
|
||||
|
||||
/* A single operand of an entry in the instruction table.
|
||||
* (internal use only)
|
||||
@ -264,7 +169,22 @@ struct ud_itab_entry
|
||||
uint32_t prefix;
|
||||
};
|
||||
|
||||
extern const char * ud_lookup_mnemonic( enum ud_mnemonic_code c );
|
||||
struct ud_lookup_table_list_entry {
|
||||
const uint16_t *table;
|
||||
enum ud_table_type type;
|
||||
const char *meta;
|
||||
};
|
||||
|
||||
|
||||
|
||||
static inline int
|
||||
ud_opcode_field_sext(uint8_t primary_opcode)
|
||||
{
|
||||
return (primary_opcode & 0x02) != 0;
|
||||
}
|
||||
|
||||
extern struct ud_itab_entry ud_itab[];
|
||||
extern struct ud_lookup_table_list_entry ud_lookup_table_list[];
|
||||
|
||||
#endif /* UD_DECODE_H */
|
||||
|
||||
|
@ -1,9 +1,27 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* extern.h
|
||||
/* udis86 - libudis86/extern.h
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com>
|
||||
* All rights reserved. See LICENSE
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2009, 2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef UD_EXTERN_H
|
||||
#define UD_EXTERN_H
|
||||
@ -12,7 +30,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "types.h"
|
||||
|
||||
/* ============================= PUBLIC API ================================= */
|
||||
@ -25,7 +42,7 @@ extern void ud_set_pc(struct ud*, uint64_t);
|
||||
|
||||
extern void ud_set_input_hook(struct ud*, int (*)(struct ud*));
|
||||
|
||||
extern void ud_set_input_buffer(struct ud*, uint8_t*, size_t);
|
||||
extern void ud_set_input_buffer(struct ud*, const uint8_t*, size_t);
|
||||
|
||||
#ifndef __UD_STANDALONE__
|
||||
extern void ud_set_input_file(struct ud*, FILE*);
|
||||
@ -37,7 +54,7 @@ extern void ud_set_syntax(struct ud*, void (*)(struct ud*));
|
||||
|
||||
extern void ud_input_skip(struct ud*, size_t);
|
||||
|
||||
extern int ud_input_end(struct ud*);
|
||||
extern int ud_input_end(const struct ud*);
|
||||
|
||||
extern unsigned int ud_decode(struct ud*);
|
||||
|
||||
@ -47,21 +64,42 @@ extern void ud_translate_intel(struct ud*);
|
||||
|
||||
extern void ud_translate_att(struct ud*);
|
||||
|
||||
extern char* ud_insn_asm(struct ud* u);
|
||||
extern const char* ud_insn_asm(const struct ud* u);
|
||||
|
||||
extern uint8_t* ud_insn_ptr(struct ud* u);
|
||||
extern const uint8_t* ud_insn_ptr(const struct ud* u);
|
||||
|
||||
extern uint64_t ud_insn_off(struct ud*);
|
||||
extern uint64_t ud_insn_off(const struct ud*);
|
||||
|
||||
extern char* ud_insn_hex(struct ud*);
|
||||
extern const char* ud_insn_hex(struct ud*);
|
||||
|
||||
extern unsigned int ud_insn_len(struct ud* u);
|
||||
extern unsigned int ud_insn_len(const struct ud* u);
|
||||
|
||||
extern const struct ud_operand* ud_insn_opr(const struct ud *u, unsigned int n);
|
||||
|
||||
extern int ud_opr_is_sreg(const struct ud_operand *opr);
|
||||
|
||||
extern int ud_opr_is_gpr(const struct ud_operand *opr);
|
||||
|
||||
extern enum ud_mnemonic_code ud_insn_mnemonic(const struct ud *u);
|
||||
|
||||
extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c);
|
||||
|
||||
extern void ud_set_user_opaque_data(struct ud*, void*);
|
||||
|
||||
extern void* ud_get_user_opaque_data(const struct ud*);
|
||||
|
||||
extern uint64_t ud_insn_sext_imm(const struct ud*, const struct ud_operand*);
|
||||
|
||||
extern void ud_set_asm_buffer(struct ud *u, char *buf, size_t size);
|
||||
|
||||
extern void ud_set_sym_resolver(struct ud *u,
|
||||
const char* (*resolver)(struct ud*,
|
||||
uint64_t addr,
|
||||
int64_t *offset));
|
||||
|
||||
/* ========================================================================== */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* UD_EXTERN_H */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,25 +1,53 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* syn.h
|
||||
/* udis86 - libudis86/syn.h
|
||||
*
|
||||
* Copyright (c) 2006, Vivek Mohan <vivek@sig9.com>
|
||||
* All rights reserved. See LICENSE
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2009
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef UD_SYN_H
|
||||
#define UD_SYN_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "types.h"
|
||||
#ifndef __UD_STANDALONE__
|
||||
# include <stdarg.h>
|
||||
#endif /* __UD_STANDALONE__ */
|
||||
|
||||
extern const char* ud_reg_tab[];
|
||||
|
||||
static void mkasm(struct ud* u, const char* fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
u->insn_fill += vsprintf((char*) u->insn_buffer + u->insn_fill, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*);
|
||||
|
||||
#ifdef __GNUC__
|
||||
int ud_asmprintf(struct ud *u, const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
#else
|
||||
int ud_asmprintf(struct ud *u, const char *fmt, ...);
|
||||
#endif
|
||||
|
||||
void ud_syn_print_addr(struct ud *u, uint64_t addr);
|
||||
void ud_syn_print_imm(struct ud* u, const struct ud_operand *op);
|
||||
void ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *, int sign);
|
||||
|
||||
#endif /* UD_SYN_H */
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
|
@ -1,31 +1,58 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* types.h
|
||||
/* udis86 - libudis86/types.h
|
||||
*
|
||||
* Copyright (c) 2006, Vivek Mohan <vivek@sig9.com>
|
||||
* All rights reserved. See LICENSE
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef UD_TYPES_H
|
||||
#define UD_TYPES_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define FMT64 "%I64"
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
#else
|
||||
# define FMT64 "%ll"
|
||||
# include <inttypes.h>
|
||||
#ifdef __KERNEL__
|
||||
/* -D__KERNEL__ is automatically passed on the command line when
|
||||
building something as part of the Linux kernel */
|
||||
# include <linux/kernel.h>
|
||||
# include <linux/string.h>
|
||||
# ifndef __UD_STANDALONE__
|
||||
# define __UD_STANDALONE__ 1
|
||||
#endif
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# include <stdint.h>
|
||||
# include <stdio.h>
|
||||
# define inline __inline /* MS Visual Studio requires __inline
|
||||
instead of inline for C code */
|
||||
#elif !defined(__UD_STANDALONE__) || defined(__HAIKU__)
|
||||
# include <stdio.h>
|
||||
# include <inttypes.h>
|
||||
#endif /* !__UD_STANDALONE__ */
|
||||
|
||||
/* gcc specific extensions */
|
||||
#if defined(__GNUC__) && __GNUC__ > 2
|
||||
# define UD_ATTR_PACKED __attribute__((packed))
|
||||
#else
|
||||
# define UD_ATTR_PACKED
|
||||
#endif /* UD_ATTR_PACKED */
|
||||
|
||||
#include "itab.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* All possible "types" of objects in udis86. Order is Important!
|
||||
@ -36,95 +63,101 @@ enum ud_type
|
||||
UD_NONE,
|
||||
|
||||
/* 8 bit GPRs */
|
||||
UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL,
|
||||
UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH,
|
||||
UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL,
|
||||
UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B,
|
||||
UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B,
|
||||
UD_R_AL, UD_R_CL, UD_R_DL, UD_R_BL,
|
||||
UD_R_AH, UD_R_CH, UD_R_DH, UD_R_BH,
|
||||
UD_R_SPL, UD_R_BPL, UD_R_SIL, UD_R_DIL,
|
||||
UD_R_R8B, UD_R_R9B, UD_R_R10B, UD_R_R11B,
|
||||
UD_R_R12B, UD_R_R13B, UD_R_R14B, UD_R_R15B,
|
||||
|
||||
/* 16 bit GPRs */
|
||||
UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX,
|
||||
UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI,
|
||||
UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W,
|
||||
UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W,
|
||||
|
||||
UD_R_AX, UD_R_CX, UD_R_DX, UD_R_BX,
|
||||
UD_R_SP, UD_R_BP, UD_R_SI, UD_R_DI,
|
||||
UD_R_R8W, UD_R_R9W, UD_R_R10W, UD_R_R11W,
|
||||
UD_R_R12W, UD_R_R13W, UD_R_R14W, UD_R_R15W,
|
||||
|
||||
/* 32 bit GPRs */
|
||||
UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX,
|
||||
UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI,
|
||||
UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D,
|
||||
UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D,
|
||||
|
||||
UD_R_EAX, UD_R_ECX, UD_R_EDX, UD_R_EBX,
|
||||
UD_R_ESP, UD_R_EBP, UD_R_ESI, UD_R_EDI,
|
||||
UD_R_R8D, UD_R_R9D, UD_R_R10D, UD_R_R11D,
|
||||
UD_R_R12D, UD_R_R13D, UD_R_R14D, UD_R_R15D,
|
||||
|
||||
/* 64 bit GPRs */
|
||||
UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX,
|
||||
UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI,
|
||||
UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11,
|
||||
UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15,
|
||||
UD_R_RAX, UD_R_RCX, UD_R_RDX, UD_R_RBX,
|
||||
UD_R_RSP, UD_R_RBP, UD_R_RSI, UD_R_RDI,
|
||||
UD_R_R8, UD_R_R9, UD_R_R10, UD_R_R11,
|
||||
UD_R_R12, UD_R_R13, UD_R_R14, UD_R_R15,
|
||||
|
||||
/* segment registers */
|
||||
UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS,
|
||||
UD_R_FS, UD_R_GS,
|
||||
UD_R_ES, UD_R_CS, UD_R_SS, UD_R_DS,
|
||||
UD_R_FS, UD_R_GS,
|
||||
|
||||
/* control registers*/
|
||||
UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3,
|
||||
UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7,
|
||||
UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11,
|
||||
UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15,
|
||||
|
||||
UD_R_CR0, UD_R_CR1, UD_R_CR2, UD_R_CR3,
|
||||
UD_R_CR4, UD_R_CR5, UD_R_CR6, UD_R_CR7,
|
||||
UD_R_CR8, UD_R_CR9, UD_R_CR10, UD_R_CR11,
|
||||
UD_R_CR12, UD_R_CR13, UD_R_CR14, UD_R_CR15,
|
||||
|
||||
/* debug registers */
|
||||
UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3,
|
||||
UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7,
|
||||
UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11,
|
||||
UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15,
|
||||
UD_R_DR0, UD_R_DR1, UD_R_DR2, UD_R_DR3,
|
||||
UD_R_DR4, UD_R_DR5, UD_R_DR6, UD_R_DR7,
|
||||
UD_R_DR8, UD_R_DR9, UD_R_DR10, UD_R_DR11,
|
||||
UD_R_DR12, UD_R_DR13, UD_R_DR14, UD_R_DR15,
|
||||
|
||||
/* mmx registers */
|
||||
UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3,
|
||||
UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7,
|
||||
UD_R_MM0, UD_R_MM1, UD_R_MM2, UD_R_MM3,
|
||||
UD_R_MM4, UD_R_MM5, UD_R_MM6, UD_R_MM7,
|
||||
|
||||
/* x87 registers */
|
||||
UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3,
|
||||
UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7,
|
||||
UD_R_ST0, UD_R_ST1, UD_R_ST2, UD_R_ST3,
|
||||
UD_R_ST4, UD_R_ST5, UD_R_ST6, UD_R_ST7,
|
||||
|
||||
/* extended multimedia registers */
|
||||
UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3,
|
||||
UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7,
|
||||
UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11,
|
||||
UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15,
|
||||
UD_R_XMM0, UD_R_XMM1, UD_R_XMM2, UD_R_XMM3,
|
||||
UD_R_XMM4, UD_R_XMM5, UD_R_XMM6, UD_R_XMM7,
|
||||
UD_R_XMM8, UD_R_XMM9, UD_R_XMM10, UD_R_XMM11,
|
||||
UD_R_XMM12, UD_R_XMM13, UD_R_XMM14, UD_R_XMM15,
|
||||
|
||||
UD_R_RIP,
|
||||
|
||||
/* Operand Types */
|
||||
UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM,
|
||||
UD_OP_JIMM, UD_OP_CONST
|
||||
UD_OP_REG, UD_OP_MEM, UD_OP_PTR, UD_OP_IMM,
|
||||
UD_OP_JIMM, UD_OP_CONST
|
||||
};
|
||||
|
||||
#include "itab.h"
|
||||
|
||||
union ud_lval {
|
||||
int8_t sbyte;
|
||||
uint8_t ubyte;
|
||||
int16_t sword;
|
||||
uint16_t uword;
|
||||
int32_t sdword;
|
||||
uint32_t udword;
|
||||
int64_t sqword;
|
||||
uint64_t uqword;
|
||||
struct {
|
||||
uint16_t seg;
|
||||
uint32_t off;
|
||||
} ptr;
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* struct ud_operand - Disassembled instruction Operand.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
struct ud_operand
|
||||
{
|
||||
enum ud_type type;
|
||||
uint8_t size;
|
||||
union {
|
||||
int8_t sbyte;
|
||||
uint8_t ubyte;
|
||||
int16_t sword;
|
||||
uint16_t uword;
|
||||
int32_t sdword;
|
||||
uint32_t udword;
|
||||
int64_t sqword;
|
||||
uint64_t uqword;
|
||||
|
||||
struct {
|
||||
uint16_t seg;
|
||||
uint32_t off;
|
||||
} ptr;
|
||||
} lval;
|
||||
|
||||
enum ud_type base;
|
||||
enum ud_type index;
|
||||
uint8_t offset;
|
||||
uint8_t scale;
|
||||
struct ud_operand {
|
||||
enum ud_type type;
|
||||
uint8_t size;
|
||||
enum ud_type base;
|
||||
enum ud_type index;
|
||||
uint8_t scale;
|
||||
uint8_t offset;
|
||||
union ud_lval lval;
|
||||
/*
|
||||
* internal use only
|
||||
*/
|
||||
uint64_t _legacy; /* this will be removed in 1.8 */
|
||||
uint8_t _oprcode;
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
@ -133,68 +166,85 @@ struct ud_operand
|
||||
*/
|
||||
struct ud
|
||||
{
|
||||
int (*inp_hook) (struct ud*);
|
||||
uint8_t inp_curr;
|
||||
uint8_t inp_fill;
|
||||
FILE* inp_file;
|
||||
uint8_t inp_ctr;
|
||||
uint8_t* inp_buff;
|
||||
uint8_t* inp_buff_end;
|
||||
uint8_t inp_end;
|
||||
void (*translator)(struct ud*);
|
||||
uint64_t insn_offset;
|
||||
char insn_hexcode[32];
|
||||
char insn_buffer[64];
|
||||
unsigned int insn_fill;
|
||||
uint8_t dis_mode;
|
||||
uint64_t pc;
|
||||
uint8_t vendor;
|
||||
struct map_entry* mapen;
|
||||
enum ud_mnemonic_code mnemonic;
|
||||
struct ud_operand operand[3];
|
||||
uint8_t error;
|
||||
uint8_t pfx_rex;
|
||||
uint8_t pfx_seg;
|
||||
uint8_t pfx_opr;
|
||||
uint8_t pfx_adr;
|
||||
uint8_t pfx_lock;
|
||||
uint8_t pfx_rep;
|
||||
uint8_t pfx_repe;
|
||||
uint8_t pfx_repne;
|
||||
uint8_t pfx_insn;
|
||||
uint8_t default64;
|
||||
uint8_t opr_mode;
|
||||
uint8_t adr_mode;
|
||||
uint8_t br_far;
|
||||
uint8_t br_near;
|
||||
uint8_t implicit_addr;
|
||||
uint8_t c1;
|
||||
uint8_t c2;
|
||||
uint8_t c3;
|
||||
uint8_t inp_cache[256];
|
||||
uint8_t inp_sess[64];
|
||||
/*
|
||||
* input buffering
|
||||
*/
|
||||
int (*inp_hook) (struct ud*);
|
||||
#ifndef __UD_STANDALONE__
|
||||
FILE* inp_file;
|
||||
#endif
|
||||
const uint8_t* inp_buf;
|
||||
size_t inp_buf_size;
|
||||
size_t inp_buf_index;
|
||||
uint8_t inp_curr;
|
||||
size_t inp_ctr;
|
||||
uint8_t inp_sess[64];
|
||||
int inp_end;
|
||||
|
||||
void (*translator)(struct ud*);
|
||||
uint64_t insn_offset;
|
||||
char insn_hexcode[64];
|
||||
|
||||
/*
|
||||
* Assembly output buffer
|
||||
*/
|
||||
char *asm_buf;
|
||||
size_t asm_buf_size;
|
||||
size_t asm_buf_fill;
|
||||
char asm_buf_int[128];
|
||||
|
||||
/*
|
||||
* Symbol resolver for use in the translation phase.
|
||||
*/
|
||||
const char* (*sym_resolver)(struct ud*, uint64_t addr, int64_t *offset);
|
||||
|
||||
uint8_t dis_mode;
|
||||
uint64_t pc;
|
||||
uint8_t vendor;
|
||||
enum ud_mnemonic_code mnemonic;
|
||||
struct ud_operand operand[3];
|
||||
uint8_t error;
|
||||
uint8_t pfx_rex;
|
||||
uint8_t pfx_seg;
|
||||
uint8_t pfx_opr;
|
||||
uint8_t pfx_adr;
|
||||
uint8_t pfx_lock;
|
||||
uint8_t pfx_str;
|
||||
uint8_t pfx_rep;
|
||||
uint8_t pfx_repe;
|
||||
uint8_t pfx_repne;
|
||||
uint8_t opr_mode;
|
||||
uint8_t adr_mode;
|
||||
uint8_t br_far;
|
||||
uint8_t br_near;
|
||||
uint8_t have_modrm;
|
||||
uint8_t modrm;
|
||||
uint8_t primary_opcode;
|
||||
void * user_opaque_data;
|
||||
struct ud_itab_entry * itab_entry;
|
||||
struct ud_lookup_table_list_entry *le;
|
||||
};
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Type-definitions
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
typedef enum ud_type ud_type_t;
|
||||
typedef enum ud_mnemonic_code ud_mnemonic_code_t;
|
||||
typedef enum ud_type ud_type_t;
|
||||
typedef enum ud_mnemonic_code ud_mnemonic_code_t;
|
||||
|
||||
typedef struct ud ud_t;
|
||||
typedef struct ud_operand ud_operand_t;
|
||||
typedef struct ud ud_t;
|
||||
typedef struct ud_operand ud_operand_t;
|
||||
|
||||
#define UD_SYN_INTEL ud_translate_intel
|
||||
#define UD_SYN_ATT ud_translate_att
|
||||
#define UD_EOI -1
|
||||
#define UD_INP_CACHE_SZ 32
|
||||
#define UD_VENDOR_AMD 0
|
||||
#define UD_VENDOR_INTEL 1
|
||||
|
||||
#define bail_out(ud,error_code) longjmp( (ud)->bailout, error_code )
|
||||
#define try_decode(ud) if ( setjmp( (ud)->bailout ) == 0 )
|
||||
#define catch_error() else
|
||||
#define UD_SYN_INTEL ud_translate_intel
|
||||
#define UD_SYN_ATT ud_translate_att
|
||||
#define UD_EOI (-1)
|
||||
#define UD_INP_CACHE_SZ 32
|
||||
#define UD_VENDOR_AMD 0
|
||||
#define UD_VENDOR_INTEL 1
|
||||
#define UD_VENDOR_ANY 2
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
|
89
headers/libs/udis86/libudis86/udint.h
Normal file
89
headers/libs/udis86/libudis86/udint.h
Normal file
@ -0,0 +1,89 @@
|
||||
/* udis86 - libudis86/udint.h -- definitions for internal use only
|
||||
*
|
||||
* Copyright (c) 2002-2009 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _UDINT_H_
|
||||
#define _UDINT_H_
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#if defined(UD_DEBUG) && HAVE_ASSERT_H
|
||||
# include <assert.h>
|
||||
# define UD_ASSERT(_x) assert(_x)
|
||||
#else
|
||||
# define UD_ASSERT(_x)
|
||||
#endif /* !HAVE_ASSERT_H */
|
||||
|
||||
#if defined(UD_DEBUG)
|
||||
#define UDERR(u, msg) \
|
||||
do { \
|
||||
(u)->error = 1; \
|
||||
fprintf(stderr, "decode-error: %s:%d: %s", \
|
||||
__FILE__, __LINE__, (msg)); \
|
||||
} while (0)
|
||||
#else
|
||||
#define UDERR(u, m) \
|
||||
do { \
|
||||
(u)->error = 1; \
|
||||
} while (0)
|
||||
#endif /* !LOGERR */
|
||||
|
||||
#define UD_RETURN_ON_ERROR(u) \
|
||||
do { \
|
||||
if ((u)->error != 0) { \
|
||||
return (u)->error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define UD_RETURN_WITH_ERROR(u, m) \
|
||||
do { \
|
||||
UDERR(u, m); \
|
||||
return (u)->error; \
|
||||
} while (0)
|
||||
|
||||
#ifndef __UD_STANDALONE__
|
||||
# define UD_NON_STANDALONE(x) x
|
||||
#else
|
||||
# define UD_NON_STANDALONE(x)
|
||||
#endif
|
||||
|
||||
/* printf formatting int64 specifier */
|
||||
#ifdef FMT64
|
||||
# undef FMT64
|
||||
#endif
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
# define FMT64 "I64"
|
||||
#else
|
||||
# if defined(__APPLE__)
|
||||
# define FMT64 "ll"
|
||||
# elif defined(__amd64__) || defined(__x86_64__)
|
||||
# define FMT64 "l"
|
||||
# else
|
||||
# define FMT64 "ll"
|
||||
# endif /* !x64 */
|
||||
#endif
|
||||
|
||||
#endif /* _UDINT_H_ */
|
@ -1,11 +1,28 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* udis86.h
|
||||
/* udis86 - udis86.h
|
||||
*
|
||||
* Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com>
|
||||
* All rights reserved. See (LICENSE)
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2009 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef UDIS86_H
|
||||
#define UDIS86_H
|
||||
|
||||
|
@ -11,7 +11,6 @@ DEFINES += __assert_fail=disasm_arch_assert ;
|
||||
|
||||
local libUdis86Sources =
|
||||
decode.c
|
||||
input.c
|
||||
itab.c
|
||||
syn-att.c
|
||||
syn.c
|
||||
|
@ -7,7 +7,6 @@ UseHeaders [ LibraryHeaders [ FDirName udis86 libudis86 ] ] ;
|
||||
|
||||
StaticLibrary libudis86.a :
|
||||
decode.c
|
||||
input.c
|
||||
itab.c
|
||||
syn-att.c
|
||||
syn.c
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,226 +0,0 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* input.c
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com>
|
||||
* All rights reserved. See LICENSE
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
#include "extern.h"
|
||||
#include "types.h"
|
||||
#include "input.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* inp_buff_hook() - Hook for buffered inputs.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
inp_buff_hook(struct ud* u)
|
||||
{
|
||||
if (u->inp_buff < u->inp_buff_end)
|
||||
return *u->inp_buff++;
|
||||
else return -1;
|
||||
}
|
||||
|
||||
#ifndef __UD_STANDALONE__
|
||||
/* -----------------------------------------------------------------------------
|
||||
* inp_file_hook() - Hook for FILE inputs.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
static int
|
||||
inp_file_hook(struct ud* u)
|
||||
{
|
||||
return fgetc(u->inp_file);
|
||||
}
|
||||
#endif /* __UD_STANDALONE__*/
|
||||
|
||||
/* =============================================================================
|
||||
* ud_inp_set_hook() - Sets input hook.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
|
||||
{
|
||||
u->inp_hook = hook;
|
||||
inp_init(u);
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_inp_set_buffer() - Set buffer as input.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_set_input_buffer(register struct ud* u, uint8_t* buf, size_t len)
|
||||
{
|
||||
u->inp_hook = inp_buff_hook;
|
||||
u->inp_buff = buf;
|
||||
u->inp_buff_end = buf + len;
|
||||
inp_init(u);
|
||||
}
|
||||
|
||||
#ifndef __UD_STANDALONE__
|
||||
/* =============================================================================
|
||||
* ud_input_set_file() - Set buffer as input.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_set_input_file(register struct ud* u, FILE* f)
|
||||
{
|
||||
u->inp_hook = inp_file_hook;
|
||||
u->inp_file = f;
|
||||
inp_init(u);
|
||||
}
|
||||
#endif /* __UD_STANDALONE__ */
|
||||
|
||||
/* =============================================================================
|
||||
* ud_input_skip() - Skip n input bytes.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
ud_input_skip(struct ud* u, size_t n)
|
||||
{
|
||||
while (n--) {
|
||||
u->inp_hook(u);
|
||||
}
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_input_end() - Test for end of input.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern int
|
||||
ud_input_end(struct ud* u)
|
||||
{
|
||||
return (u->inp_curr == u->inp_fill) && u->inp_end;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* inp_next() - Loads and returns the next byte from input.
|
||||
*
|
||||
* inp_curr and inp_fill are pointers to the cache. The program is written based
|
||||
* on the property that they are 8-bits in size, and will eventually wrap around
|
||||
* forming a circular buffer. So, the size of the cache is 256 in size, kind of
|
||||
* unnecessary yet optimized.
|
||||
*
|
||||
* A buffer inp_sess stores the bytes disassembled for a single session.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
extern uint8_t inp_next(struct ud* u)
|
||||
{
|
||||
int c = -1;
|
||||
/* if current pointer is not upto the fill point in the
|
||||
* input cache.
|
||||
*/
|
||||
if ( u->inp_curr != u->inp_fill ) {
|
||||
c = u->inp_cache[ ++u->inp_curr ];
|
||||
/* if !end-of-input, call the input hook and get a byte */
|
||||
} else if ( u->inp_end || ( c = u->inp_hook( u ) ) == -1 ) {
|
||||
/* end-of-input, mark it as an error, since the decoder,
|
||||
* expected a byte more.
|
||||
*/
|
||||
u->error = 1;
|
||||
/* flag end of input */
|
||||
u->inp_end = 1;
|
||||
return 0;
|
||||
} else {
|
||||
/* increment pointers, we have a new byte. */
|
||||
u->inp_curr = ++u->inp_fill;
|
||||
/* add the byte to the cache */
|
||||
u->inp_cache[ u->inp_fill ] = c;
|
||||
}
|
||||
/* record bytes input per decode-session. */
|
||||
u->inp_sess[ u->inp_ctr++ ] = c;
|
||||
/* return byte */
|
||||
return ( uint8_t ) c;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* inp_back() - Move back a single byte in the stream.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
extern void
|
||||
inp_back(struct ud* u)
|
||||
{
|
||||
if ( u->inp_ctr > 0 ) {
|
||||
--u->inp_curr;
|
||||
--u->inp_ctr;
|
||||
}
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* inp_peek() - Peek into the next byte in source.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
extern uint8_t
|
||||
inp_peek(struct ud* u)
|
||||
{
|
||||
uint8_t r = inp_next(u);
|
||||
if ( !u->error ) inp_back(u); /* Don't backup if there was an error */
|
||||
return r;
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* inp_move() - Move ahead n input bytes.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
extern void
|
||||
inp_move(struct ud* u, size_t n)
|
||||
{
|
||||
while (n--)
|
||||
inp_next(u);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* inp_uintN() - return uintN from source.
|
||||
*------------------------------------------------------------------------------
|
||||
*/
|
||||
extern uint8_t
|
||||
inp_uint8(struct ud* u)
|
||||
{
|
||||
return inp_next(u);
|
||||
}
|
||||
|
||||
extern uint16_t
|
||||
inp_uint16(struct ud* u)
|
||||
{
|
||||
uint16_t r, ret;
|
||||
|
||||
ret = inp_next(u);
|
||||
r = inp_next(u);
|
||||
return ret | (r << 8);
|
||||
}
|
||||
|
||||
extern uint32_t
|
||||
inp_uint32(struct ud* u)
|
||||
{
|
||||
uint32_t r, ret;
|
||||
|
||||
ret = inp_next(u);
|
||||
r = inp_next(u);
|
||||
ret = ret | (r << 8);
|
||||
r = inp_next(u);
|
||||
ret = ret | (r << 16);
|
||||
r = inp_next(u);
|
||||
return ret | (r << 24);
|
||||
}
|
||||
|
||||
extern uint64_t
|
||||
inp_uint64(struct ud* u)
|
||||
{
|
||||
uint64_t r, ret;
|
||||
|
||||
ret = inp_next(u);
|
||||
r = inp_next(u);
|
||||
ret = ret | (r << 8);
|
||||
r = inp_next(u);
|
||||
ret = ret | (r << 16);
|
||||
r = inp_next(u);
|
||||
ret = ret | (r << 24);
|
||||
r = inp_next(u);
|
||||
ret = ret | (r << 32);
|
||||
r = inp_next(u);
|
||||
ret = ret | (r << 40);
|
||||
r = inp_next(u);
|
||||
ret = ret | (r << 48);
|
||||
r = inp_next(u);
|
||||
return ret | (r << 56);
|
||||
}
|
12061
src/libs/udis86/itab.c
12061
src/libs/udis86/itab.c
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,34 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* syn-att.c
|
||||
/* udis86 - libudis86/syn-att.c
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2006 Vivek Mohan <vivek@sig9.com>
|
||||
* All rights reserved. See (LICENSE)
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2009 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "extern.h"
|
||||
#include "decode.h"
|
||||
#include "itab.h"
|
||||
#include "syn.h"
|
||||
#include "udint.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* opr_cast() - Prints an operand cast.
|
||||
@ -20,9 +38,9 @@ static void
|
||||
opr_cast(struct ud* u, struct ud_operand* op)
|
||||
{
|
||||
switch(op->size) {
|
||||
case 16 : case 32 :
|
||||
mkasm(u, "*"); break;
|
||||
default: break;
|
||||
case 16 : case 32 :
|
||||
ud_asmprintf(u, "*"); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,79 +52,66 @@ static void
|
||||
gen_operand(struct ud* u, struct ud_operand* op)
|
||||
{
|
||||
switch(op->type) {
|
||||
case UD_OP_REG:
|
||||
mkasm(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
break;
|
||||
case UD_OP_CONST:
|
||||
ud_asmprintf(u, "$0x%x", op->lval.udword);
|
||||
break;
|
||||
|
||||
case UD_OP_MEM:
|
||||
if (u->br_far) opr_cast(u, op);
|
||||
if (u->pfx_seg)
|
||||
mkasm(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
||||
if (op->offset == 8) {
|
||||
if (op->lval.sbyte < 0)
|
||||
mkasm(u, "-0x%x", (-op->lval.sbyte) & 0xff);
|
||||
else mkasm(u, "0x%x", op->lval.sbyte);
|
||||
}
|
||||
else if (op->offset == 16)
|
||||
mkasm(u, "0x%x", op->lval.uword);
|
||||
else if (op->offset == 32)
|
||||
mkasm(u, "0x%lx", op->lval.udword);
|
||||
else if (op->offset == 64)
|
||||
mkasm(u, "0x" FMT64 "x", op->lval.uqword);
|
||||
case UD_OP_REG:
|
||||
ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
break;
|
||||
|
||||
if (op->base)
|
||||
mkasm(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
if (op->index) {
|
||||
if (op->base)
|
||||
mkasm(u, ",");
|
||||
else mkasm(u, "(");
|
||||
mkasm(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
|
||||
}
|
||||
if (op->scale)
|
||||
mkasm(u, ",%d", op->scale);
|
||||
if (op->base || op->index)
|
||||
mkasm(u, ")");
|
||||
break;
|
||||
case UD_OP_MEM:
|
||||
if (u->br_far) {
|
||||
opr_cast(u, op);
|
||||
}
|
||||
if (u->pfx_seg) {
|
||||
ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
||||
}
|
||||
if (op->offset != 0) {
|
||||
ud_syn_print_mem_disp(u, op, 0);
|
||||
}
|
||||
if (op->base) {
|
||||
ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
}
|
||||
if (op->index) {
|
||||
if (op->base) {
|
||||
ud_asmprintf(u, ",");
|
||||
} else {
|
||||
ud_asmprintf(u, "(");
|
||||
}
|
||||
ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
|
||||
}
|
||||
if (op->scale) {
|
||||
ud_asmprintf(u, ",%d", op->scale);
|
||||
}
|
||||
if (op->base || op->index) {
|
||||
ud_asmprintf(u, ")");
|
||||
}
|
||||
break;
|
||||
|
||||
case UD_OP_IMM:
|
||||
switch (op->size) {
|
||||
case 8: mkasm(u, "$0x%x", op->lval.ubyte); break;
|
||||
case 16: mkasm(u, "$0x%x", op->lval.uword); break;
|
||||
case 32: mkasm(u, "$0x%lx", op->lval.udword); break;
|
||||
case 64: mkasm(u, "$0x" FMT64 "x", op->lval.uqword); break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
case UD_OP_IMM:
|
||||
ud_asmprintf(u, "$");
|
||||
ud_syn_print_imm(u, op);
|
||||
break;
|
||||
|
||||
case UD_OP_JIMM:
|
||||
switch (op->size) {
|
||||
case 8:
|
||||
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
|
||||
break;
|
||||
case 16:
|
||||
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
|
||||
break;
|
||||
case 32:
|
||||
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
break;
|
||||
case UD_OP_JIMM:
|
||||
ud_syn_print_addr(u, ud_syn_rel_target(u, op));
|
||||
break;
|
||||
|
||||
case UD_OP_PTR:
|
||||
switch (op->size) {
|
||||
case 32:
|
||||
mkasm(u, "$0x%x, $0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off & 0xFFFF);
|
||||
break;
|
||||
case 48:
|
||||
mkasm(u, "$0x%x, $0x%lx", op->lval.ptr.seg,
|
||||
op->lval.ptr.off);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default: return;
|
||||
case UD_OP_PTR:
|
||||
switch (op->size) {
|
||||
case 32:
|
||||
ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off & 0xFFFF);
|
||||
break;
|
||||
case 48:
|
||||
ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,94 +123,102 @@ extern void
|
||||
ud_translate_att(struct ud *u)
|
||||
{
|
||||
int size = 0;
|
||||
int star = 0;
|
||||
|
||||
/* check if P_OSO prefix is used */
|
||||
if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16:
|
||||
mkasm(u, "o32 ");
|
||||
break;
|
||||
case 32:
|
||||
case 64:
|
||||
mkasm(u, "o16 ");
|
||||
break;
|
||||
}
|
||||
switch (u->dis_mode) {
|
||||
case 16:
|
||||
ud_asmprintf(u, "o32 ");
|
||||
break;
|
||||
case 32:
|
||||
case 64:
|
||||
ud_asmprintf(u, "o16 ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if P_ASO prefix was used */
|
||||
if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16:
|
||||
mkasm(u, "a32 ");
|
||||
break;
|
||||
case 32:
|
||||
mkasm(u, "a16 ");
|
||||
break;
|
||||
case 64:
|
||||
mkasm(u, "a32 ");
|
||||
break;
|
||||
}
|
||||
switch (u->dis_mode) {
|
||||
case 16:
|
||||
ud_asmprintf(u, "a32 ");
|
||||
break;
|
||||
case 32:
|
||||
ud_asmprintf(u, "a16 ");
|
||||
break;
|
||||
case 64:
|
||||
ud_asmprintf(u, "a32 ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (u->pfx_lock)
|
||||
mkasm(u, "lock ");
|
||||
if (u->pfx_rep)
|
||||
mkasm(u, "rep ");
|
||||
if (u->pfx_repne)
|
||||
mkasm(u, "repne ");
|
||||
ud_asmprintf(u, "lock ");
|
||||
if (u->pfx_rep) {
|
||||
ud_asmprintf(u, "rep ");
|
||||
} else if (u->pfx_rep) {
|
||||
ud_asmprintf(u, "repe ");
|
||||
} else if (u->pfx_repne) {
|
||||
ud_asmprintf(u, "repne ");
|
||||
}
|
||||
|
||||
/* special instructions */
|
||||
switch (u->mnemonic) {
|
||||
case UD_Iretf:
|
||||
mkasm(u, "lret ");
|
||||
break;
|
||||
case UD_Idb:
|
||||
mkasm(u, ".byte 0x%x", u->operand[0].lval.ubyte);
|
||||
return;
|
||||
case UD_Ijmp:
|
||||
case UD_Icall:
|
||||
if (u->br_far) mkasm(u, "l");
|
||||
mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic));
|
||||
break;
|
||||
case UD_Ibound:
|
||||
case UD_Ienter:
|
||||
if (u->operand[0].type != UD_NONE)
|
||||
gen_operand(u, &u->operand[0]);
|
||||
if (u->operand[1].type != UD_NONE) {
|
||||
mkasm(u, ",");
|
||||
gen_operand(u, &u->operand[1]);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
mkasm(u, "%s", ud_lookup_mnemonic(u->mnemonic));
|
||||
case UD_Iretf:
|
||||
ud_asmprintf(u, "lret ");
|
||||
break;
|
||||
case UD_Idb:
|
||||
ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte);
|
||||
return;
|
||||
case UD_Ijmp:
|
||||
case UD_Icall:
|
||||
if (u->br_far) ud_asmprintf(u, "l");
|
||||
if (u->operand[0].type == UD_OP_REG) {
|
||||
star = 1;
|
||||
}
|
||||
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
|
||||
break;
|
||||
case UD_Ibound:
|
||||
case UD_Ienter:
|
||||
if (u->operand[0].type != UD_NONE)
|
||||
gen_operand(u, &u->operand[0]);
|
||||
if (u->operand[1].type != UD_NONE) {
|
||||
ud_asmprintf(u, ",");
|
||||
gen_operand(u, &u->operand[1]);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
|
||||
}
|
||||
|
||||
if (u->c1)
|
||||
size = u->operand[0].size;
|
||||
else if (u->c2)
|
||||
size = u->operand[1].size;
|
||||
else if (u->c3)
|
||||
size = u->operand[2].size;
|
||||
|
||||
if (size == 8)
|
||||
mkasm(u, "b");
|
||||
ud_asmprintf(u, "b");
|
||||
else if (size == 16)
|
||||
mkasm(u, "w");
|
||||
ud_asmprintf(u, "w");
|
||||
else if (size == 64)
|
||||
mkasm(u, "q");
|
||||
ud_asmprintf(u, "q");
|
||||
|
||||
mkasm(u, " ");
|
||||
if (star) {
|
||||
ud_asmprintf(u, " *");
|
||||
} else {
|
||||
ud_asmprintf(u, " ");
|
||||
}
|
||||
|
||||
if (u->operand[2].type != UD_NONE) {
|
||||
gen_operand(u, &u->operand[2]);
|
||||
mkasm(u, ", ");
|
||||
gen_operand(u, &u->operand[2]);
|
||||
ud_asmprintf(u, ", ");
|
||||
}
|
||||
|
||||
if (u->operand[1].type != UD_NONE) {
|
||||
gen_operand(u, &u->operand[1]);
|
||||
mkasm(u, ", ");
|
||||
gen_operand(u, &u->operand[1]);
|
||||
ud_asmprintf(u, ", ");
|
||||
}
|
||||
|
||||
if (u->operand[0].type != UD_NONE)
|
||||
gen_operand(u, &u->operand[0]);
|
||||
gen_operand(u, &u->operand[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
|
@ -1,16 +1,34 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* syn-intel.c
|
||||
/* udis86 - libudis86/syn-intel.c
|
||||
*
|
||||
* Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com>
|
||||
* All rights reserved. See (LICENSE)
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "types.h"
|
||||
#include "extern.h"
|
||||
#include "decode.h"
|
||||
#include "itab.h"
|
||||
#include "syn.h"
|
||||
#include "udint.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* opr_cast() - Prints an operand cast.
|
||||
@ -19,18 +37,17 @@
|
||||
static void
|
||||
opr_cast(struct ud* u, struct ud_operand* op)
|
||||
{
|
||||
switch(op->size) {
|
||||
case 8: mkasm(u, "byte " ); break;
|
||||
case 16: mkasm(u, "word " ); break;
|
||||
case 32: mkasm(u, "dword "); break;
|
||||
case 64: mkasm(u, "qword "); break;
|
||||
case 80: mkasm(u, "tword "); break;
|
||||
default: break;
|
||||
if (u->br_far) {
|
||||
ud_asmprintf(u, "far ");
|
||||
}
|
||||
switch(op->size) {
|
||||
case 8: ud_asmprintf(u, "byte " ); break;
|
||||
case 16: ud_asmprintf(u, "word " ); break;
|
||||
case 32: ud_asmprintf(u, "dword "); break;
|
||||
case 64: ud_asmprintf(u, "qword "); break;
|
||||
case 80: ud_asmprintf(u, "tword "); break;
|
||||
default: break;
|
||||
}
|
||||
if (u->br_far)
|
||||
mkasm(u, "far ");
|
||||
else if (u->br_near)
|
||||
mkasm(u, "near ");
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
@ -40,105 +57,63 @@ opr_cast(struct ud* u, struct ud_operand* op)
|
||||
static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
|
||||
{
|
||||
switch(op->type) {
|
||||
case UD_OP_REG:
|
||||
mkasm(u, ud_reg_tab[op->base - UD_R_AL]);
|
||||
break;
|
||||
case UD_OP_REG:
|
||||
ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
break;
|
||||
|
||||
case UD_OP_MEM: {
|
||||
case UD_OP_MEM:
|
||||
if (syn_cast) {
|
||||
opr_cast(u, op);
|
||||
}
|
||||
ud_asmprintf(u, "[");
|
||||
if (u->pfx_seg) {
|
||||
ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
||||
}
|
||||
if (op->base) {
|
||||
ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
}
|
||||
if (op->index) {
|
||||
ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "",
|
||||
ud_reg_tab[op->index - UD_R_AL]);
|
||||
if (op->scale) {
|
||||
ud_asmprintf(u, "*%d", op->scale);
|
||||
}
|
||||
}
|
||||
if (op->offset != 0) {
|
||||
ud_syn_print_mem_disp(u, op, (op->base != UD_NONE ||
|
||||
op->index != UD_NONE) ? 1 : 0);
|
||||
}
|
||||
ud_asmprintf(u, "]");
|
||||
break;
|
||||
|
||||
case UD_OP_IMM:
|
||||
ud_syn_print_imm(u, op);
|
||||
break;
|
||||
|
||||
int op_f = 0;
|
||||
|
||||
if (syn_cast)
|
||||
opr_cast(u, op);
|
||||
case UD_OP_JIMM:
|
||||
ud_syn_print_addr(u, ud_syn_rel_target(u, op));
|
||||
break;
|
||||
|
||||
mkasm(u, "[");
|
||||
case UD_OP_PTR:
|
||||
switch (op->size) {
|
||||
case 32:
|
||||
ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off & 0xFFFF);
|
||||
break;
|
||||
case 48:
|
||||
ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
if (u->pfx_seg)
|
||||
mkasm(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
||||
case UD_OP_CONST:
|
||||
if (syn_cast) opr_cast(u, op);
|
||||
ud_asmprintf(u, "%d", op->lval.udword);
|
||||
break;
|
||||
|
||||
if (op->base) {
|
||||
mkasm(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
|
||||
op_f = 1;
|
||||
}
|
||||
|
||||
if (op->index) {
|
||||
if (op_f)
|
||||
mkasm(u, "+");
|
||||
mkasm(u, "%s", ud_reg_tab[op->index - UD_R_AL]);
|
||||
op_f = 1;
|
||||
}
|
||||
|
||||
if (op->scale)
|
||||
mkasm(u, "*%d", op->scale);
|
||||
|
||||
if (op->offset == 8) {
|
||||
if (op->lval.sbyte < 0)
|
||||
mkasm(u, "-0x%x", -op->lval.sbyte);
|
||||
else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sbyte);
|
||||
}
|
||||
else if (op->offset == 16)
|
||||
mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.uword);
|
||||
else if (op->offset == 32) {
|
||||
if (u->adr_mode == 64) {
|
||||
if (op->lval.sdword < 0)
|
||||
mkasm(u, "-0x%x", -op->lval.sdword);
|
||||
else mkasm(u, "%s0x%x", (op_f) ? "+" : "", op->lval.sdword);
|
||||
}
|
||||
else mkasm(u, "%s0x%lx", (op_f) ? "+" : "", op->lval.udword);
|
||||
}
|
||||
else if (op->offset == 64)
|
||||
mkasm(u, "%s0x" FMT64 "x", (op_f) ? "+" : "", op->lval.uqword);
|
||||
|
||||
mkasm(u, "]");
|
||||
break;
|
||||
}
|
||||
|
||||
case UD_OP_IMM:
|
||||
if (syn_cast) opr_cast(u, op);
|
||||
switch (op->size) {
|
||||
case 8: mkasm(u, "0x%x", op->lval.ubyte); break;
|
||||
case 16: mkasm(u, "0x%x", op->lval.uword); break;
|
||||
case 32: mkasm(u, "0x%lx", op->lval.udword); break;
|
||||
case 64: mkasm(u, "0x" FMT64 "x", op->lval.uqword); break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
|
||||
case UD_OP_JIMM:
|
||||
if (syn_cast) opr_cast(u, op);
|
||||
switch (op->size) {
|
||||
case 8:
|
||||
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sbyte);
|
||||
break;
|
||||
case 16:
|
||||
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sword);
|
||||
break;
|
||||
case 32:
|
||||
mkasm(u, "0x" FMT64 "x", u->pc + op->lval.sdword);
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
break;
|
||||
|
||||
case UD_OP_PTR:
|
||||
switch (op->size) {
|
||||
case 32:
|
||||
mkasm(u, "word 0x%x:0x%x", op->lval.ptr.seg,
|
||||
op->lval.ptr.off & 0xFFFF);
|
||||
break;
|
||||
case 48:
|
||||
mkasm(u, "dword 0x%x:0x%lx", op->lval.ptr.seg,
|
||||
op->lval.ptr.off);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case UD_OP_CONST:
|
||||
if (syn_cast) opr_cast(u, op);
|
||||
mkasm(u, "%d", op->lval.udword);
|
||||
break;
|
||||
|
||||
default: return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,63 +121,93 @@ static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
|
||||
* translates to intel syntax
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void ud_translate_intel(struct ud* u)
|
||||
extern void
|
||||
ud_translate_intel(struct ud* u)
|
||||
{
|
||||
/* -- prefixes -- */
|
||||
|
||||
/* check if P_OSO prefix is used */
|
||||
if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16:
|
||||
mkasm(u, "o32 ");
|
||||
break;
|
||||
case 32:
|
||||
case 64:
|
||||
mkasm(u, "o16 ");
|
||||
break;
|
||||
}
|
||||
if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16: ud_asmprintf(u, "o32 "); break;
|
||||
case 32:
|
||||
case 64: ud_asmprintf(u, "o16 "); break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if P_ASO prefix was used */
|
||||
if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16:
|
||||
mkasm(u, "a32 ");
|
||||
break;
|
||||
case 32:
|
||||
mkasm(u, "a16 ");
|
||||
break;
|
||||
case 64:
|
||||
mkasm(u, "a32 ");
|
||||
break;
|
||||
}
|
||||
if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
|
||||
switch (u->dis_mode) {
|
||||
case 16: ud_asmprintf(u, "a32 "); break;
|
||||
case 32: ud_asmprintf(u, "a16 "); break;
|
||||
case 64: ud_asmprintf(u, "a32 "); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (u->pfx_lock)
|
||||
mkasm(u, "lock ");
|
||||
if (u->pfx_rep)
|
||||
mkasm(u, "rep ");
|
||||
if (u->pfx_repne)
|
||||
mkasm(u, "repne ");
|
||||
if (u->implicit_addr && u->pfx_seg)
|
||||
mkasm(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
||||
if (u->pfx_seg &&
|
||||
u->operand[0].type != UD_OP_MEM &&
|
||||
u->operand[1].type != UD_OP_MEM ) {
|
||||
ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
|
||||
}
|
||||
|
||||
if (u->pfx_lock) {
|
||||
ud_asmprintf(u, "lock ");
|
||||
}
|
||||
if (u->pfx_rep) {
|
||||
ud_asmprintf(u, "rep ");
|
||||
} else if (u->pfx_repe) {
|
||||
ud_asmprintf(u, "repe ");
|
||||
} else if (u->pfx_repne) {
|
||||
ud_asmprintf(u, "repne ");
|
||||
}
|
||||
|
||||
/* print the instruction mnemonic */
|
||||
mkasm(u, "%s ", ud_lookup_mnemonic(u->mnemonic));
|
||||
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
|
||||
|
||||
/* operand 1 */
|
||||
if (u->operand[0].type != UD_NONE) {
|
||||
gen_operand(u, &u->operand[0], u->c1);
|
||||
}
|
||||
/* operand 2 */
|
||||
if (u->operand[1].type != UD_NONE) {
|
||||
mkasm(u, ", ");
|
||||
gen_operand(u, &u->operand[1], u->c2);
|
||||
int cast = 0;
|
||||
ud_asmprintf(u, " ");
|
||||
if (u->operand[0].type == UD_OP_MEM) {
|
||||
if (u->operand[1].type == UD_OP_IMM ||
|
||||
u->operand[1].type == UD_OP_CONST ||
|
||||
u->operand[1].type == UD_NONE ||
|
||||
(u->operand[0].size != u->operand[1].size &&
|
||||
u->operand[1].type != UD_OP_REG)) {
|
||||
cast = 1;
|
||||
} else if (u->operand[1].type == UD_OP_REG &&
|
||||
u->operand[1].base == UD_R_CL) {
|
||||
switch (u->mnemonic) {
|
||||
case UD_Ircl:
|
||||
case UD_Irol:
|
||||
case UD_Iror:
|
||||
case UD_Ircr:
|
||||
case UD_Ishl:
|
||||
case UD_Ishr:
|
||||
case UD_Isar:
|
||||
cast = 1;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
gen_operand(u, &u->operand[0], cast);
|
||||
}
|
||||
|
||||
if (u->operand[1].type != UD_NONE) {
|
||||
int cast = 0;
|
||||
ud_asmprintf(u, ", ");
|
||||
if (u->operand[1].type == UD_OP_MEM &&
|
||||
u->operand[0].size != u->operand[1].size &&
|
||||
!ud_opr_is_sreg(&u->operand[0])) {
|
||||
cast = 1;
|
||||
}
|
||||
gen_operand(u, &u->operand[1], cast);
|
||||
}
|
||||
|
||||
/* operand 3 */
|
||||
if (u->operand[2].type != UD_NONE) {
|
||||
mkasm(u, ", ");
|
||||
gen_operand(u, &u->operand[2], u->c3);
|
||||
ud_asmprintf(u, ", ");
|
||||
gen_operand(u, &u->operand[2], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
|
@ -1,10 +1,32 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* syn.c
|
||||
/* udis86 - libudis86/syn.c
|
||||
*
|
||||
* Copyright (c) 2002, 2003, 2004 Vivek Mohan <vivek@sig9.com>
|
||||
* All rights reserved. See (LICENSE)
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "types.h"
|
||||
#include "decode.h"
|
||||
#include "syn.h"
|
||||
#include "udint.h"
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Intel Register Table - Order Matters (types.h)!
|
||||
@ -12,50 +34,174 @@
|
||||
*/
|
||||
const char* ud_reg_tab[] =
|
||||
{
|
||||
"al", "cl", "dl", "bl",
|
||||
"ah", "ch", "dh", "bh",
|
||||
"spl", "bpl", "sil", "dil",
|
||||
"r8b", "r9b", "r10b", "r11b",
|
||||
"r12b", "r13b", "r14b", "r15b",
|
||||
"al", "cl", "dl", "bl",
|
||||
"ah", "ch", "dh", "bh",
|
||||
"spl", "bpl", "sil", "dil",
|
||||
"r8b", "r9b", "r10b", "r11b",
|
||||
"r12b", "r13b", "r14b", "r15b",
|
||||
|
||||
"ax", "cx", "dx", "bx",
|
||||
"sp", "bp", "si", "di",
|
||||
"r8w", "r9w", "r10w", "r11w",
|
||||
"r12w", "r13W" , "r14w", "r15w",
|
||||
|
||||
"eax", "ecx", "edx", "ebx",
|
||||
"esp", "ebp", "esi", "edi",
|
||||
"r8d", "r9d", "r10d", "r11d",
|
||||
"r12d", "r13d", "r14d", "r15d",
|
||||
|
||||
"rax", "rcx", "rdx", "rbx",
|
||||
"rsp", "rbp", "rsi", "rdi",
|
||||
"r8", "r9", "r10", "r11",
|
||||
"r12", "r13", "r14", "r15",
|
||||
"ax", "cx", "dx", "bx",
|
||||
"sp", "bp", "si", "di",
|
||||
"r8w", "r9w", "r10w", "r11w",
|
||||
"r12w", "r13w" , "r14w", "r15w",
|
||||
|
||||
"eax", "ecx", "edx", "ebx",
|
||||
"esp", "ebp", "esi", "edi",
|
||||
"r8d", "r9d", "r10d", "r11d",
|
||||
"r12d", "r13d", "r14d", "r15d",
|
||||
|
||||
"rax", "rcx", "rdx", "rbx",
|
||||
"rsp", "rbp", "rsi", "rdi",
|
||||
"r8", "r9", "r10", "r11",
|
||||
"r12", "r13", "r14", "r15",
|
||||
|
||||
"es", "cs", "ss", "ds",
|
||||
"fs", "gs",
|
||||
"es", "cs", "ss", "ds",
|
||||
"fs", "gs",
|
||||
|
||||
"cr0", "cr1", "cr2", "cr3",
|
||||
"cr4", "cr5", "cr6", "cr7",
|
||||
"cr8", "cr9", "cr10", "cr11",
|
||||
"cr12", "cr13", "cr14", "cr15",
|
||||
|
||||
"dr0", "dr1", "dr2", "dr3",
|
||||
"dr4", "dr5", "dr6", "dr7",
|
||||
"dr8", "dr9", "dr10", "dr11",
|
||||
"dr12", "dr13", "dr14", "dr15",
|
||||
"cr0", "cr1", "cr2", "cr3",
|
||||
"cr4", "cr5", "cr6", "cr7",
|
||||
"cr8", "cr9", "cr10", "cr11",
|
||||
"cr12", "cr13", "cr14", "cr15",
|
||||
|
||||
"dr0", "dr1", "dr2", "dr3",
|
||||
"dr4", "dr5", "dr6", "dr7",
|
||||
"dr8", "dr9", "dr10", "dr11",
|
||||
"dr12", "dr13", "dr14", "dr15",
|
||||
|
||||
"mm0", "mm1", "mm2", "mm3",
|
||||
"mm4", "mm5", "mm6", "mm7",
|
||||
"mm0", "mm1", "mm2", "mm3",
|
||||
"mm4", "mm5", "mm6", "mm7",
|
||||
|
||||
"st0", "st1", "st2", "st3",
|
||||
"st4", "st5", "st6", "st7",
|
||||
"st0", "st1", "st2", "st3",
|
||||
"st4", "st5", "st6", "st7",
|
||||
|
||||
"xmm0", "xmm1", "xmm2", "xmm3",
|
||||
"xmm4", "xmm5", "xmm6", "xmm7",
|
||||
"xmm8", "xmm9", "xmm10", "xmm11",
|
||||
"xmm12", "xmm13", "xmm14", "xmm15",
|
||||
"xmm0", "xmm1", "xmm2", "xmm3",
|
||||
"xmm4", "xmm5", "xmm6", "xmm7",
|
||||
"xmm8", "xmm9", "xmm10", "xmm11",
|
||||
"xmm12", "xmm13", "xmm14", "xmm15",
|
||||
|
||||
"rip"
|
||||
};
|
||||
|
||||
|
||||
uint64_t
|
||||
ud_syn_rel_target(struct ud *u, struct ud_operand *opr)
|
||||
{
|
||||
const uint64_t trunc_mask = 0xffffffffffffffffull >> (64 - u->opr_mode);
|
||||
switch (opr->size) {
|
||||
case 8 : return (u->pc + opr->lval.sbyte) & trunc_mask;
|
||||
case 16: return (u->pc + opr->lval.sword) & trunc_mask;
|
||||
case 32: return (u->pc + opr->lval.sdword) & trunc_mask;
|
||||
default: UD_ASSERT(!"invalid relative offset size.");
|
||||
return 0ull;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* asmprintf
|
||||
* Printf style function for printing translated assembly
|
||||
* output. Returns the number of characters written and
|
||||
* moves the buffer pointer forward. On an overflow,
|
||||
* returns a negative number and truncates the output.
|
||||
*/
|
||||
int
|
||||
ud_asmprintf(struct ud *u, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
int avail;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
avail = u->asm_buf_size - u->asm_buf_fill - 1 /* nullchar */;
|
||||
ret = vsnprintf((char*) u->asm_buf + u->asm_buf_fill, avail, fmt, ap);
|
||||
if (ret < 0 || ret > avail) {
|
||||
u->asm_buf_fill = u->asm_buf_size - 1;
|
||||
} else {
|
||||
u->asm_buf_fill += ret;
|
||||
}
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ud_syn_print_addr(struct ud *u, uint64_t addr)
|
||||
{
|
||||
const char *name = NULL;
|
||||
if (u->sym_resolver) {
|
||||
int64_t offset = 0;
|
||||
name = u->sym_resolver(u, addr, &offset);
|
||||
if (name) {
|
||||
if (offset) {
|
||||
ud_asmprintf(u, "%s%+" FMT64 "d", name, offset);
|
||||
} else {
|
||||
ud_asmprintf(u, "%s", name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
ud_asmprintf(u, "0x%" FMT64 "x", addr);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ud_syn_print_imm(struct ud* u, const struct ud_operand *op)
|
||||
{
|
||||
uint64_t v;
|
||||
if (op->_oprcode == OP_sI && op->size != u->opr_mode) {
|
||||
if (op->size == 8) {
|
||||
v = (int64_t)op->lval.sbyte;
|
||||
} else {
|
||||
UD_ASSERT(op->size == 32);
|
||||
v = (int64_t)op->lval.sdword;
|
||||
}
|
||||
if (u->opr_mode < 64) {
|
||||
v = v & ((1ull << u->opr_mode) - 1ull);
|
||||
}
|
||||
} else {
|
||||
switch (op->size) {
|
||||
case 8 : v = op->lval.ubyte; break;
|
||||
case 16: v = op->lval.uword; break;
|
||||
case 32: v = op->lval.udword; break;
|
||||
case 64: v = op->lval.uqword; break;
|
||||
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
|
||||
}
|
||||
}
|
||||
ud_asmprintf(u, "0x%" FMT64 "x", v);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ud_syn_print_mem_disp(struct ud* u, const struct ud_operand *op, int sign)
|
||||
{
|
||||
UD_ASSERT(op->offset != 0);
|
||||
if (op->base == UD_NONE && op->index == UD_NONE) {
|
||||
uint64_t v;
|
||||
UD_ASSERT(op->scale == UD_NONE && op->offset != 8);
|
||||
/* unsigned mem-offset */
|
||||
switch (op->offset) {
|
||||
case 16: v = op->lval.uword; break;
|
||||
case 32: v = op->lval.udword; break;
|
||||
case 64: v = op->lval.uqword; break;
|
||||
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
|
||||
}
|
||||
ud_asmprintf(u, "0x%" FMT64 "x", v);
|
||||
} else {
|
||||
int64_t v;
|
||||
UD_ASSERT(op->offset != 64);
|
||||
switch (op->offset) {
|
||||
case 8 : v = op->lval.sbyte; break;
|
||||
case 16: v = op->lval.sword; break;
|
||||
case 32: v = op->lval.sdword; break;
|
||||
default: UD_ASSERT(!"invalid offset"); v = 0; /* keep cc happy */
|
||||
}
|
||||
if (v < 0) {
|
||||
ud_asmprintf(u, "-0x%" FMT64 "x", -v);
|
||||
} else if (v > 0) {
|
||||
ud_asmprintf(u, "%s0x%" FMT64 "x", sign? "+" : "", v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
vim: set ts=2 sw=2 expandtab
|
||||
*/
|
||||
|
@ -1,20 +1,44 @@
|
||||
/* -----------------------------------------------------------------------------
|
||||
* udis86.c
|
||||
/* udis86 - libudis86/udis86.c
|
||||
*
|
||||
* Copyright (c) 2004, 2005, 2006, Vivek Mohan <vivek@sig9.com>
|
||||
* All rights reserved. See LICENSE
|
||||
* -----------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2013 Vivek Thampi
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "udint.h"
|
||||
#include "extern.h"
|
||||
#include "decode.h"
|
||||
|
||||
#if !defined(__UD_STANDALONE__)
|
||||
# if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# endif
|
||||
#endif /* !__UD_STANDALONE__ */
|
||||
|
||||
static void ud_inp_init(struct ud *u);
|
||||
|
||||
/* =============================================================================
|
||||
* ud_init() - Initializes ud_t object.
|
||||
* ud_init
|
||||
* Initializes ud_t object.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern void
|
||||
@ -27,30 +51,34 @@ ud_init(struct ud* u)
|
||||
#ifndef __UD_STANDALONE__
|
||||
ud_set_input_file(u, stdin);
|
||||
#endif /* __UD_STANDALONE__ */
|
||||
|
||||
ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_disassemble() - disassembles one instruction and returns the number of
|
||||
* bytes disassembled. A zero means end of disassembly.
|
||||
* ud_disassemble
|
||||
* Disassembles one instruction and returns the number of
|
||||
* bytes disassembled. A zero means end of disassembly.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern unsigned int
|
||||
ud_disassemble(struct ud* u)
|
||||
{
|
||||
if (ud_input_end(u))
|
||||
return 0;
|
||||
|
||||
|
||||
u->insn_buffer[0] = u->insn_hexcode[0] = 0;
|
||||
|
||||
|
||||
if (ud_decode(u) == 0)
|
||||
return 0;
|
||||
if (u->translator)
|
||||
u->translator(u);
|
||||
return ud_insn_len(u);
|
||||
int len;
|
||||
if (u->inp_end) {
|
||||
return 0;
|
||||
}
|
||||
if ((len = ud_decode(u)) > 0) {
|
||||
if (u->translator != NULL) {
|
||||
u->asm_buf[0] = '\0';
|
||||
u->translator(u);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_mode() - Set Disassemly Mode.
|
||||
* =============================================================================
|
||||
@ -59,10 +87,10 @@ extern void
|
||||
ud_set_mode(struct ud* u, uint8_t m)
|
||||
{
|
||||
switch(m) {
|
||||
case 16:
|
||||
case 32:
|
||||
case 64: u->dis_mode = m ; return;
|
||||
default: u->dis_mode = 16; return;
|
||||
case 16:
|
||||
case 32:
|
||||
case 64: u->dis_mode = m ; return;
|
||||
default: u->dis_mode = 16; return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,11 +102,14 @@ extern void
|
||||
ud_set_vendor(struct ud* u, unsigned v)
|
||||
{
|
||||
switch(v) {
|
||||
case UD_VENDOR_INTEL:
|
||||
u->vendor = v;
|
||||
break;
|
||||
default:
|
||||
u->vendor = UD_VENDOR_AMD;
|
||||
case UD_VENDOR_INTEL:
|
||||
u->vendor = v;
|
||||
break;
|
||||
case UD_VENDOR_ANY:
|
||||
u->vendor = v;
|
||||
break;
|
||||
default:
|
||||
u->vendor = UD_VENDOR_AMD;
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,18 +137,18 @@ ud_set_syntax(struct ud* u, void (*t)(struct ud*))
|
||||
* ud_insn() - returns the disassembled instruction
|
||||
* =============================================================================
|
||||
*/
|
||||
extern char*
|
||||
ud_insn_asm(struct ud* u)
|
||||
const char*
|
||||
ud_insn_asm(const struct ud* u)
|
||||
{
|
||||
return u->insn_buffer;
|
||||
return u->asm_buf;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_offset() - Returns the offset.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern uint64_t
|
||||
ud_insn_off(struct ud* u)
|
||||
uint64_t
|
||||
ud_insn_off(const struct ud* u)
|
||||
{
|
||||
return u->insn_offset;
|
||||
}
|
||||
@ -127,28 +158,300 @@ ud_insn_off(struct ud* u)
|
||||
* ud_insn_hex() - Returns hex form of disassembled instruction.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern char*
|
||||
const char*
|
||||
ud_insn_hex(struct ud* u)
|
||||
{
|
||||
u->insn_hexcode[0] = 0;
|
||||
if (!u->error) {
|
||||
unsigned int i;
|
||||
const unsigned char *src_ptr = ud_insn_ptr(u);
|
||||
char* src_hex;
|
||||
src_hex = (char*) u->insn_hexcode;
|
||||
/* for each byte used to decode instruction */
|
||||
for (i = 0; i < ud_insn_len(u) && i < sizeof(u->insn_hexcode) / 2;
|
||||
++i, ++src_ptr) {
|
||||
sprintf(src_hex, "%02x", *src_ptr & 0xFF);
|
||||
src_hex += 2;
|
||||
}
|
||||
}
|
||||
return u->insn_hexcode;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_ptr() - Returns code disassembled.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern uint8_t*
|
||||
ud_insn_ptr(struct ud* u)
|
||||
{
|
||||
return u->inp_sess;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_len() - Returns the count of bytes disassembled.
|
||||
* ud_insn_ptr
|
||||
* Returns a pointer to buffer containing the bytes that were
|
||||
* disassembled.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern const uint8_t*
|
||||
ud_insn_ptr(const struct ud* u)
|
||||
{
|
||||
return (u->inp_buf == NULL) ?
|
||||
u->inp_sess : u->inp_buf + (u->inp_buf_index - u->inp_ctr);
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_len
|
||||
* Returns the count of bytes disassembled.
|
||||
* =============================================================================
|
||||
*/
|
||||
extern unsigned int
|
||||
ud_insn_len(struct ud* u)
|
||||
ud_insn_len(const struct ud* u)
|
||||
{
|
||||
return u->inp_ctr;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_get_opr
|
||||
* Return the operand struct representing the nth operand of
|
||||
* the currently disassembled instruction. Returns NULL if
|
||||
* there's no such operand.
|
||||
* =============================================================================
|
||||
*/
|
||||
const struct ud_operand*
|
||||
ud_insn_opr(const struct ud *u, unsigned int n)
|
||||
{
|
||||
if (n > 2 || u->operand[n].type == UD_NONE) {
|
||||
return NULL;
|
||||
} else {
|
||||
return &u->operand[n];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_opr_is_sreg
|
||||
* Returns non-zero if the given operand is of a segment register type.
|
||||
* =============================================================================
|
||||
*/
|
||||
int
|
||||
ud_opr_is_sreg(const struct ud_operand *opr)
|
||||
{
|
||||
return opr->type == UD_OP_REG &&
|
||||
opr->base >= UD_R_ES &&
|
||||
opr->base <= UD_R_GS;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_opr_is_sreg
|
||||
* Returns non-zero if the given operand is of a general purpose
|
||||
* register type.
|
||||
* =============================================================================
|
||||
*/
|
||||
int
|
||||
ud_opr_is_gpr(const struct ud_operand *opr)
|
||||
{
|
||||
return opr->type == UD_OP_REG &&
|
||||
opr->base >= UD_R_AL &&
|
||||
opr->base <= UD_R_R15;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_user_opaque_data
|
||||
* ud_get_user_opaque_data
|
||||
* Get/set user opaqute data pointer
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_user_opaque_data(struct ud * u, void* opaque)
|
||||
{
|
||||
u->user_opaque_data = opaque;
|
||||
}
|
||||
|
||||
void*
|
||||
ud_get_user_opaque_data(const struct ud *u)
|
||||
{
|
||||
return u->user_opaque_data;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_asm_buffer
|
||||
* Allow the user to set an assembler output buffer. If `buf` is NULL,
|
||||
* we switch back to the internal buffer.
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_asm_buffer(struct ud *u, char *buf, size_t size)
|
||||
{
|
||||
if (buf == NULL) {
|
||||
ud_set_asm_buffer(u, u->asm_buf_int, sizeof(u->asm_buf_int));
|
||||
} else {
|
||||
u->asm_buf = buf;
|
||||
u->asm_buf_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_set_sym_resolver
|
||||
* Set symbol resolver for relative targets used in the translation
|
||||
* phase.
|
||||
*
|
||||
* The resolver is a function that takes a uint64_t address and returns a
|
||||
* symbolic name for the that address. The function also takes a second
|
||||
* argument pointing to an integer that the client can optionally set to a
|
||||
* non-zero value for offsetted targets. (symbol+offset) The function may
|
||||
* also return NULL, in which case the translator only prints the target
|
||||
* address.
|
||||
*
|
||||
* The function pointer maybe NULL which resets symbol resolution.
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_sym_resolver(struct ud *u, const char* (*resolver)(struct ud*,
|
||||
uint64_t addr,
|
||||
int64_t *offset))
|
||||
{
|
||||
u->sym_resolver = resolver;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_insn_mnemonic
|
||||
* Return the current instruction mnemonic.
|
||||
* =============================================================================
|
||||
*/
|
||||
enum ud_mnemonic_code
|
||||
ud_insn_mnemonic(const struct ud *u)
|
||||
{
|
||||
return u->mnemonic;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_lookup_mnemonic
|
||||
* Looks up mnemonic code in the mnemonic string table.
|
||||
* Returns NULL if the mnemonic code is invalid.
|
||||
* =============================================================================
|
||||
*/
|
||||
const char*
|
||||
ud_lookup_mnemonic(enum ud_mnemonic_code c)
|
||||
{
|
||||
if (c < UD_MAX_MNEMONIC_CODE) {
|
||||
return ud_mnemonics_str[c];
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ud_inp_init
|
||||
* Initializes the input system.
|
||||
*/
|
||||
static void
|
||||
ud_inp_init(struct ud *u)
|
||||
{
|
||||
u->inp_hook = NULL;
|
||||
u->inp_buf = NULL;
|
||||
u->inp_buf_size = 0;
|
||||
u->inp_buf_index = 0;
|
||||
u->inp_curr = 0;
|
||||
u->inp_ctr = 0;
|
||||
u->inp_end = 0;
|
||||
UD_NON_STANDALONE(u->inp_file = NULL);
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_inp_set_hook
|
||||
* Sets input hook.
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_input_hook(register struct ud* u, int (*hook)(struct ud*))
|
||||
{
|
||||
ud_inp_init(u);
|
||||
u->inp_hook = hook;
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
* ud_inp_set_buffer
|
||||
* Set buffer as input.
|
||||
* =============================================================================
|
||||
*/
|
||||
void
|
||||
ud_set_input_buffer(register struct ud* u, const uint8_t* buf, size_t len)
|
||||
{
|
||||
ud_inp_init(u);
|
||||
u->inp_buf = buf;
|
||||
u->inp_buf_size = len;
|
||||
u->inp_buf_index = 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef __UD_STANDALONE__
|
||||
/* =============================================================================
|
||||
* ud_input_set_file
|
||||
* Set FILE as input.
|
||||
* =============================================================================
|
||||
*/
|
||||
static int
|
||||
inp_file_hook(struct ud* u)
|
||||
{
|
||||
return fgetc(u->inp_file);
|
||||
}
|
||||
|
||||
void
|
||||
ud_set_input_file(register struct ud* u, FILE* f)
|
||||
{
|
||||
ud_inp_init(u);
|
||||
u->inp_hook = inp_file_hook;
|
||||
u->inp_file = f;
|
||||
}
|
||||
#endif /* __UD_STANDALONE__ */
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_input_skip
|
||||
* Skip n input bytes.
|
||||
* ============================================================================
|
||||
*/
|
||||
void
|
||||
ud_input_skip(struct ud* u, size_t n)
|
||||
{
|
||||
if (u->inp_end) {
|
||||
return;
|
||||
}
|
||||
if (u->inp_buf == NULL) {
|
||||
while (n--) {
|
||||
int c = u->inp_hook(u);
|
||||
if (c == UD_EOI) {
|
||||
goto eoi;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if (n > u->inp_buf_size ||
|
||||
u->inp_buf_index > u->inp_buf_size - n) {
|
||||
u->inp_buf_index = u->inp_buf_size;
|
||||
goto eoi;
|
||||
}
|
||||
u->inp_buf_index += n;
|
||||
return;
|
||||
}
|
||||
eoi:
|
||||
u->inp_end = 1;
|
||||
UDERR(u, "cannot skip, eoi received\b");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* =============================================================================
|
||||
* ud_input_end
|
||||
* Returns non-zero on end-of-input.
|
||||
* =============================================================================
|
||||
*/
|
||||
int
|
||||
ud_input_end(const struct ud *u)
|
||||
{
|
||||
return u->inp_end;
|
||||
}
|
||||
|
||||
/* vim:set ts=2 sw=2 expandtab */
|
||||
|
Loading…
x
Reference in New Issue
Block a user