Update udis86 from git. Fix #97

This commit is contained in:
pancake 2013-06-10 00:28:55 +02:00
parent dd8d2c9df3
commit 5e0871485c
15 changed files with 6480 additions and 3525 deletions

View File

@ -43,6 +43,9 @@ sdb-sync sync-sdb:
$(TCCLIB) libr_tcc/libr_tcc.a:
cd libr_tcc ; ${MAKE}
udis-sync udis86-sync sync-udis sync-udis86:
cd udis86 ; ${MAKE} sync
tcc-clean tccclean:
cd libr_tcc ; ${MAKE} clean

View File

@ -179,103 +179,70 @@ ud_lookup_mnemonic(enum ud_mnemonic_code c)
static int
decode_prefixes(struct ud *u)
{
unsigned int have_pfx = 1;
unsigned int i;
uint8_t curr;
int done = 0;
uint8_t curr;
UD_RETURN_ON_ERROR(u);
/* if in error state, bail out */
if ( u->error )
return -1;
/* keep going as long as there are prefixes available */
for ( i = 0; have_pfx ; ++i ) {
/* Get next byte. */
ud_inp_next(u);
if ( u->error )
return -1;
curr = inp_curr( u );
/* rex prefixes in 64bit mode */
if ( u->dis_mode == 64 && ( curr & 0xF0 ) == 0x40 ) {
u->pfx_rex = curr;
} else {
switch ( curr )
{
case 0x2E :
u->pfx_seg = UD_R_CS;
u->pfx_rex = 0;
break;
case 0x36 :
u->pfx_seg = UD_R_SS;
u->pfx_rex = 0;
break;
case 0x3E :
u->pfx_seg = UD_R_DS;
u->pfx_rex = 0;
break;
case 0x26 :
u->pfx_seg = UD_R_ES;
u->pfx_rex = 0;
break;
case 0x64 :
u->pfx_seg = UD_R_FS;
u->pfx_rex = 0;
break;
case 0x65 :
u->pfx_seg = UD_R_GS;
u->pfx_rex = 0;
break;
case 0x67 : /* adress-size override prefix */
u->pfx_adr = 0x67;
u->pfx_rex = 0;
break;
case 0xF0 :
u->pfx_lock = 0xF0;
u->pfx_rex = 0;
break;
case 0x66:
/* the 0x66 sse prefix is only effective if no other sse prefix
* has already been specified.
*/
if ( !u->pfx_insn ) u->pfx_insn = 0x66;
u->pfx_opr = 0x66;
u->pfx_rex = 0;
break;
case 0xF2:
u->pfx_insn = 0xF2;
u->pfx_repne = 0xF2;
u->pfx_rex = 0;
break;
case 0xF3:
u->pfx_insn = 0xF3;
u->pfx_rep = 0xF3;
u->pfx_repe = 0xF3;
u->pfx_rex = 0;
break;
default :
/* No more prefixes */
have_pfx = 0;
break;
}
}
/* check if we reached max instruction length */
if ( i + 1 == MAX_INSN_LENGTH ) {
UDERR(u, "max instruction length");
break;
}
do {
ud_inp_next(u);
UD_RETURN_ON_ERROR(u);
if (inp_len(u) == MAX_INSN_LENGTH) {
UD_RETURN_WITH_ERROR(u, "max instruction length");
}
curr = inp_curr(u);
/* return status */
if ( u->error )
return -1;
switch (curr)
{
case 0x2E :
u->pfx_seg = UD_R_CS;
break;
case 0x36 :
u->pfx_seg = UD_R_SS;
break;
case 0x3E :
u->pfx_seg = UD_R_DS;
break;
case 0x26 :
u->pfx_seg = UD_R_ES;
break;
case 0x64 :
u->pfx_seg = UD_R_FS;
break;
case 0x65 :
u->pfx_seg = UD_R_GS;
break;
case 0x67 : /* adress-size override prefix */
u->pfx_adr = 0x67;
break;
case 0xF0 :
u->pfx_lock = 0xF0;
break;
case 0x66:
u->pfx_opr = 0x66;
break;
case 0xF2:
u->pfx_str = 0xf2;
break;
case 0xF3:
u->pfx_str = 0xf3;
break;
default:
done = 1;
break;
}
} while (!done);
if (u->dis_mode == 64 && (curr & 0xF0) == 0x40) {
/* rex prefixes in 64bit mode, must be the last prefix
*/
u->pfx_rex = curr;
} else {
/* rewind back one byte in stream, since the above loop
* stops with a non-prefix byte.
*/
inp_back(u);
return 0;
}
return 0;
}
@ -331,8 +298,8 @@ static int resolve_mnemonic( struct ud* u )
}
}
if (u->mnemonic == UD_Inop && u->pfx_rep) {
u->pfx_rep = 0;
if (u->mnemonic == UD_Inop && u->pfx_repe) {
u->pfx_repe = 0;
u->mnemonic = UD_Ipause;
}
return 0;
@ -663,9 +630,7 @@ decode_operand(struct ud *u,
Mx_reg_size(size) : Mx_mem_size(size));
break;
case OP_F:
if (type == OP_F) {
u->br_far = 1;
}
u->br_far = 1;
/* intended fall through */
case OP_M:
if (MODRM_MOD(modrm(u)) == 3) {
@ -767,6 +732,9 @@ decode_operand(struct ud *u,
operand->type = UD_OP_JIMM;
break ;
case OP_R :
if (MODRM_MOD(modrm(u)) != 3) {
UDERR(u, "expected modrm.mod == 3");
}
decode_modrm_rm(u, operand, REGCLASS_GPR, size);
break;
case OP_C:
@ -836,7 +804,7 @@ clear_insn(register struct ud* u)
u->pfx_rep = 0;
u->pfx_repe = 0;
u->pfx_rex = 0;
u->pfx_insn = 0;
u->pfx_str = 0;
u->mnemonic = UD_Inone;
u->itab_entry = NULL;
u->have_modrm = 0;
@ -847,6 +815,23 @@ clear_insn(register struct ud* u)
memset( &u->operand[ 2 ], 0, sizeof( struct ud_operand ) );
}
static inline int
resolve_pfx_str(struct ud* u)
{
if (u->pfx_str == 0xf3) {
if (P_STR(u->itab_entry->prefix)) {
u->pfx_rep = 0xf3;
} else {
u->pfx_repe = 0xf3;
}
} else if (u->pfx_str == 0xf2) {
u->pfx_repne = 0xf3;
}
return 0;
}
static int
resolve_mode( struct ud* u )
{
@ -908,7 +893,8 @@ decode_insn(struct ud *u, uint16_t ptr)
UD_ASSERT((ptr & 0x8000) == 0);
u->itab_entry = &ud_itab[ ptr ];
u->mnemonic = u->itab_entry->mnemonic;
return (resolve_mode(u) == 0 &&
return (resolve_pfx_str(u) == 0 &&
resolve_mode(u) == 0 &&
decode_operands(u) == 0 &&
resolve_mnemonic(u) == 0) ? 0 : -1;
}
@ -946,7 +932,18 @@ decode_3dnow(struct ud* u)
static int
decode_ssepfx(struct ud *u)
{
uint8_t idx = ((u->pfx_insn & 0xf) + 1) / 2;
uint8_t idx;
uint8_t pfx;
/*
* String prefixes (f2, f3) take precedence over operand
* size prefix (66).
*/
pfx = u->pfx_str;
if (pfx == 0) {
pfx = u->pfx_opr;
}
idx = ((pfx & 0xf) + 1) / 2;
if (u->le->table[idx] == 0) {
idx = 0;
}
@ -955,17 +952,14 @@ decode_ssepfx(struct ud *u)
* "Consume" the prefix as a part of the opcode, so it is no
* longer exported as an instruction prefix.
*/
switch (u->pfx_insn) {
case 0xf2:
u->pfx_repne = 0;
break;
case 0xf3:
u->pfx_rep = 0;
u->pfx_repe = 0;
break;
case 0x66:
u->pfx_str = 0;
if (pfx == 0x66) {
/*
* consume "66" only if it was used for decoding, leaving
* it to be used as an operands size override for some
* simd instructions.
*/
u->pfx_opr = 0;
break;
}
}
return decode_ext(u, u->le->table[idx]);
@ -1036,7 +1030,7 @@ decode_ext(struct ud *u, uint16_t ptr)
}
static inline int
static int
decode_opcode(struct ud *u)
{
uint16_t ptr;

View File

@ -55,6 +55,10 @@
#define P_IMPADDR(n) ( ( n >> 12 ) & 1 )
#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! */
@ -118,6 +122,7 @@ enum ud_operand_size {
*/
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,

View File

@ -78,7 +78,7 @@ 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_isgpr(const struct ud_operand *opr);
extern int ud_opr_is_gpr(const struct ud_operand *opr);
extern const char* ud_lookup_mnemonic(enum ud_mnemonic_code c);

View File

@ -98,6 +98,18 @@ inp_peek(struct ud* u)
return r;
}
/*
* inp_len
* Returns the number of bytes input in the current
* session.
*/
static inline size_t
inp_len(const struct ud *u)
{
return u->inp_ctr;
}
#endif /* UD_INPUT_H */
/*
vim: set ts=2 sw=2 expandtab

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,8 @@ enum ud_table_type {
UD_TAB__OPC_TABLE,
UD_TAB__OPC_X87,
UD_TAB__OPC_MOD,
UD_TAB__OPC_VEX_M,
UD_TAB__OPC_VEX_P,
UD_TAB__OPC_RM,
UD_TAB__OPC_VENDOR,
UD_TAB__OPC_OSIZE,
@ -87,6 +89,7 @@ enum ud_mnemonic_code {
UD_Icmpss,
UD_Icmpxchg,
UD_Icmpxchg8b,
UD_Icmpxchg16b,
UD_Icomisd,
UD_Icomiss,
UD_Icpuid,
@ -163,7 +166,7 @@ enum ud_mnemonic_code {
UD_Ificom,
UD_Ificomp,
UD_Ifild,
UD_Ifncstp,
UD_Ifincstp,
UD_Ifninit,
UD_Ifiadd,
UD_Ifidivr,
@ -177,7 +180,7 @@ enum ud_mnemonic_code {
UD_Ifld1,
UD_Ifldl2t,
UD_Ifldl2e,
UD_Ifldlpi,
UD_Ifldpi,
UD_Ifldlg2,
UD_Ifldln2,
UD_Ifldz,
@ -220,7 +223,7 @@ enum ud_mnemonic_code {
UD_Ifxch7,
UD_Ifxrstor,
UD_Ifxsave,
UD_Ifpxtract,
UD_Ifxtract,
UD_Ifyl2x,
UD_Ifyl2xp1,
UD_Ihlt,
@ -284,7 +287,7 @@ enum ud_mnemonic_code {
UD_Ilodsw,
UD_Ilodsd,
UD_Ilodsq,
UD_Iloopnz,
UD_Iloopne,
UD_Iloope,
UD_Iloop,
UD_Ilsl,
@ -344,7 +347,6 @@ enum ud_mnemonic_code {
UD_Ioutsb,
UD_Ioutsw,
UD_Ioutsd,
UD_Ioutsq,
UD_Ipacksswb,
UD_Ipackssdw,
UD_Ipackuswb,
@ -478,7 +480,7 @@ enum ud_mnemonic_code {
UD_Iseto,
UD_Isetno,
UD_Isetb,
UD_Isetnb,
UD_Isetae,
UD_Isetz,
UD_Isetnz,
UD_Isetbe,
@ -554,6 +556,7 @@ enum ud_mnemonic_code {
UD_Iwrmsr,
UD_Ixadd,
UD_Ixchg,
UD_Ixgetbv,
UD_Ixlatb,
UD_Ixor,
UD_Ixorpd,
@ -563,10 +566,22 @@ enum ud_mnemonic_code {
UD_Ixcryptctr,
UD_Ixcryptcfb,
UD_Ixcryptofb,
UD_Ixrstor,
UD_Ixsave,
UD_Ixsetbv,
UD_Ixsha1,
UD_Ixsha256,
UD_Ixstore,
UD_Iaesdec,
UD_Iaesdeclast,
UD_Iaesenc,
UD_Iaesenclast,
UD_Iaesimc,
UD_Iaeskeygenassist,
UD_Ipclmulqdq,
UD_Igetsec,
UD_Imovdqa,
UD_Imaskmovdqu,
UD_Imovdq2q,
UD_Imovdqu,
UD_Imovq2dq,
@ -592,7 +607,7 @@ enum ud_mnemonic_code {
UD_Ipabsb,
UD_Ipabsw,
UD_Ipabsd,
UD_Ipsignb,
UD_Ipshufb,
UD_Iphaddw,
UD_Iphaddd,
UD_Iphaddsw,
@ -600,6 +615,7 @@ enum ud_mnemonic_code {
UD_Iphsubw,
UD_Iphsubd,
UD_Iphsubsw,
UD_Ipsignb,
UD_Ipsignd,
UD_Ipsignw,
UD_Ipmulhrsw,
@ -645,12 +661,14 @@ enum ud_mnemonic_code {
UD_Ipmovzxwq,
UD_Ipmovzxdq,
UD_Ipcmpeqq,
UD_Ipopcnt,
UD_Iptest,
UD_Ipcmpestri,
UD_Ipcmpestrm,
UD_Ipcmpgtq,
UD_Ipcmpistri,
UD_Ipcmpistrm,
UD_Imovbe,
UD_Icrc32,
UD_MAX_MNEMONIC_CODE
} UD_ATTR_PACKED;

View File

@ -90,11 +90,12 @@ gen_operand(struct ud* u, struct ud_operand* op)
break;
case UD_OP_IMM:
ud_asmprintf(u, "$");
ud_syn_print_imm(u, op);
break;
case UD_OP_JIMM:
ud_syn_print_addr(u, ud_syn_rel_target(u, op, u->dis_mode==16? 1: 0));
ud_syn_print_addr(u, ud_syn_rel_target(u, op));
break;
case UD_OP_PTR:
@ -154,10 +155,13 @@ ud_translate_att(struct ud *u)
if (u->pfx_lock)
ud_asmprintf(u, "lock ");
if (u->pfx_rep)
ud_asmprintf(u, "rep ");
if (u->pfx_repne)
ud_asmprintf(u, "repne ");
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) {

View File

@ -92,7 +92,7 @@ static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
case UD_OP_JIMM:
ud_syn_print_addr(u, ud_syn_rel_target(u, op, u->dis_mode==16? 1: 0));
ud_syn_print_addr(u, ud_syn_rel_target(u, op));
break;
case UD_OP_PTR:
@ -153,8 +153,9 @@ ud_translate_intel(struct ud* u)
}
if (u->pfx_rep) {
ud_asmprintf(u, "rep ");
}
if (u->pfx_repne) {
} else if (u->pfx_repe) {
ud_asmprintf(u, "repe ");
} else if (u->pfx_repne) {
ud_asmprintf(u, "repne ");
}

View File

@ -84,17 +84,15 @@ const char* ud_reg_tab[] =
uint64_t
ud_syn_rel_target(struct ud *u, struct ud_operand *opr, int mask)
ud_syn_rel_target(struct ud *u, struct ud_operand *opr)
{
uint64_t trunc_mask = 0xffffffffffffffffull;
if (mask) trunc_mask >>= (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;
case 8 : return (u->pc + opr->lval.sbyte);
case 16: return (u->pc + opr->lval.sword);
case 32: return (u->pc + opr->lval.sdword);
default: UD_ASSERT(!"invalid relative offset size.");
return 0;
}
return 0LL;
}
@ -106,7 +104,7 @@ ud_syn_rel_target(struct ud *u, struct ud_operand *opr, int mask)
* returns a negative number and truncates the output.
*/
int
ud_asmprintf(struct ud *u, char *fmt, ...)
ud_asmprintf(struct ud *u, const char *fmt, ...)
{
int ret;
int avail;
@ -133,11 +131,7 @@ ud_syn_print_addr(struct ud *u, uint64_t addr)
name = u->sym_resolver(u, addr, &offset);
if (name) {
if (offset) {
#if __WIN32__ || __CYGWIN__ || MINGW32
ud_asmprintf(u, "%s%+I64d", name, (long long)offset);
#else
ud_asmprintf(u, "%s%+lld", name, (long long)offset);
#endif
ud_asmprintf(u, "%s%+" FMT64 "d", name, offset);
} else {
ud_asmprintf(u, "%s", name);
}

View File

@ -33,13 +33,13 @@
extern const char* ud_reg_tab[];
uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*, int mask);
uint64_t ud_syn_rel_target(struct ud*, struct ud_operand*);
#ifdef __GNUC__
int ud_asmprintf(struct ud *u, char *fmt, ...)
int ud_asmprintf(struct ud *u, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
#else
int ud_asmprintf(struct ud *u, char *fmt, ...);
int ud_asmprintf(struct ud *u, const char *fmt, ...);
#endif
void ud_syn_print_addr(struct ud *u, uint64_t addr);

View File

@ -36,7 +36,7 @@
#endif
#endif /* __KERNEL__ */
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(__BORLANDC__)
# include <stdint.h>
# include <stdio.h>
# define inline __inline /* MS Visual Studio requires __inline
@ -202,7 +202,6 @@ struct ud
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;
@ -211,10 +210,10 @@ struct ud
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 pfx_insn;
uint8_t default64;
uint8_t opr_mode;
uint8_t adr_mode;

View File

@ -26,11 +26,11 @@
#ifndef _UDINT_H_
#define _UDINT_H_
#if HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#if HAVE_ASSERT_H
#ifdef HAVE_ASSERT_H
# include <assert.h>
# define UD_ASSERT(_x) assert(_x)
#else
@ -51,11 +51,24 @@
} 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)
/* printf formatting int64 specifier */
#ifdef FMT64
# undef FMT64
#endif
#ifdef _MSC_VER
#if defined(_MSC_VER) || defined(__BORLANDC__)
# define FMT64 "I64"
#else
# if defined(__APPLE__)

View File

@ -28,7 +28,6 @@
#include "extern.h"
#include "decode.h"
# include <string.h>
#if !defined(__UD_STANDALONE__)
# if HAVE_STRING_H
# include <string.h>

View File

@ -32,5 +32,6 @@ ${SUDO} make install-vapi DESTDIR=${DESTDIR} || exit 1
cd python
make clean
make PYTHON=${PYTHON}
[ ! "$1" = --no-install ] && \
${SUDO} make install PYTHON=${PYTHON} PYTHON_VERSION=${PYTHON_VERSION} DESTDIR=${DESTDIR}
[ "$1" != '--no-install' ] && \
${SUDO} make install PYTHON=${PYTHON} \
PYTHON_VERSION=${PYTHON_VERSION} DESTDIR=${DESTDIR}