Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions libudis86/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,17 @@ 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*,
extern void ud_set_sym_resolver(struct ud *u,
const char* (*resolver)(struct ud*,
uint64_t addr,
int64_t *offset));

extern void ud_set_asmvprintf_hook(struct ud *u,
int (*asmvprintf_hook)(struct ud*,
enum ud_syn_class,
const char *,
va_list));

/* ========================================================================== */

#ifdef __cplusplus
Expand Down
100 changes: 53 additions & 47 deletions libudis86/syn-att.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@
* opr_cast() - Prints an operand cast.
* -----------------------------------------------------------------------------
*/
static void
static void
opr_cast(struct ud* u, struct ud_operand* op)
{
switch(op->size) {
case 16 : case 32 :
ud_asmprintf(u, "*"); break;
ud_asmprintf(u, UD_operator, "*"); break;
default: break;
}
}
Expand All @@ -48,49 +48,52 @@ opr_cast(struct ud* u, struct ud_operand* op)
* gen_operand() - Generates assembly output for each operand.
* -----------------------------------------------------------------------------
*/
static void
static void
gen_operand(struct ud* u, struct ud_operand* op)
{
switch(op->type) {
case UD_OP_CONST:
ud_asmprintf(u, "$0x%x", op->lval.udword);
ud_asmprintf(u, UD_immediate, "$0x%x", op->lval.udword);
break;

case UD_OP_REG:
ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
ud_asmprintf(u, UD_register, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
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]);
ud_asmprintf(u, UD_prefix, "%%%s", ud_reg_tab[u->pfx_seg - UD_R_AL]);
ud_asmprintf(u, UD_operator, ":");
}
if (op->offset != 0) {
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]);
ud_asmprintf(u, UD_operator, "(");
ud_asmprintf(u, UD_register, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
}
if (op->index) {
if (op->base) {
ud_asmprintf(u, ",");
ud_asmprintf(u, UD_operator, ",");
} else {
ud_asmprintf(u, "(");
ud_asmprintf(u, UD_operator, "(");
}
ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
ud_asmprintf(u, UD_register, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
}
if (op->scale) {
ud_asmprintf(u, ",%d", op->scale);
ud_asmprintf(u, UD_operator, ",");
ud_asmprintf(u, UD_immediate, "%d", op->scale);
}
if (op->base || op->index) {
ud_asmprintf(u, ")");
ud_asmprintf(u, UD_operator, ")");
}
break;

case UD_OP_IMM:
ud_asmprintf(u, "$");
ud_asmprintf(u, UD_immediate, "$");
ud_syn_print_imm(u, op);
break;

Expand All @@ -101,25 +104,27 @@ gen_operand(struct ud* u, struct ud_operand* op)
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);
ud_asmprintf(u, UD_address, "$0x%x", op->lval.ptr.seg);
ud_asmprintf(u, UD_operator, ", ");
ud_asmprintf(u, UD_address, "$0x%x", op->lval.ptr.off & 0xFFFF);
break;
case 48:
ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
op->lval.ptr.off);
ud_asmprintf(u, UD_address, "$0x%x", op->lval.ptr.seg);
ud_asmprintf(u, UD_operator, ", ");
ud_asmprintf(u, UD_address, "$0x%x", op->lval.ptr.off);
break;
}
break;

default: return;
}
}

/* =============================================================================
* translates to AT&T syntax
* translates to AT&T syntax
* =============================================================================
*/
extern void
extern void
ud_translate_att(struct ud *u)
{
int size = 0;
Expand All @@ -128,95 +133,96 @@ ud_translate_att(struct ud *u)
/* check if P_OSO prefix is used */
if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
switch (u->dis_mode) {
case 16:
ud_asmprintf(u, "o32 ");
case 16:
ud_asmprintf(u, UD_prefix, "o32 ");
break;
case 32:
case 64:
ud_asmprintf(u, "o16 ");
ud_asmprintf(u, UD_prefix, "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:
ud_asmprintf(u, "a32 ");
case 16:
ud_asmprintf(u, UD_prefix, "a32 ");
break;
case 32:
ud_asmprintf(u, "a16 ");
ud_asmprintf(u, UD_prefix, "a16 ");
break;
case 64:
ud_asmprintf(u, "a32 ");
ud_asmprintf(u, UD_prefix, "a32 ");
break;
}
}

if (u->pfx_lock)
ud_asmprintf(u, "lock ");
ud_asmprintf(u, UD_prefix, "lock ");
if (u->pfx_rep) {
ud_asmprintf(u, "rep ");
ud_asmprintf(u, UD_prefix, "rep ");
} else if (u->pfx_rep) {
ud_asmprintf(u, "repe ");
ud_asmprintf(u, UD_prefix, "repe ");
} else if (u->pfx_repne) {
ud_asmprintf(u, "repne ");
ud_asmprintf(u, UD_prefix, "repne ");
}

/* special instructions */
switch (u->mnemonic) {
case UD_Iretf:
ud_asmprintf(u, "lret ");
case UD_Iretf:
ud_asmprintf(u, UD_opcode, "lret ");
break;
case UD_Idb:
ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte);
ud_asmprintf(u, UD_opcode, ".byte ");
ud_asmprintf(u, UD_immediate, "0x%x", u->operand[0].lval.ubyte);
return;
case UD_Ijmp:
case UD_Icall:
if (u->br_far) ud_asmprintf(u, "l");
if (u->br_far) ud_asmprintf(u, UD_opsize, "l");
if (u->operand[0].type == UD_OP_REG) {
star = 1;
}
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
ud_asmprintf(u, UD_opcode, "%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, ",");
ud_asmprintf(u, UD_operator, ",");
gen_operand(u, &u->operand[1]);
}
return;
default:
ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
ud_asmprintf(u, UD_opcode, "%s", ud_lookup_mnemonic(u->mnemonic));
}

if (size == 8) {
ud_asmprintf(u, "b");
ud_asmprintf(u, UD_opsize, "b");
} else if (size == 16) {
ud_asmprintf(u, "w");
ud_asmprintf(u, UD_opsize, "w");
} else if (size == 64) {
ud_asmprintf(u, "q");
ud_asmprintf(u, UD_opsize, "q");
}

if (star) {
ud_asmprintf(u, " *");
ud_asmprintf(u, UD_operator, " *");
} else {
ud_asmprintf(u, " ");
ud_asmprintf(u, UD_operator, " ");
}

if (u->operand[3].type != UD_NONE) {
gen_operand(u, &u->operand[3]);
ud_asmprintf(u, ", ");
ud_asmprintf(u, UD_operator, ", ");
}
if (u->operand[2].type != UD_NONE) {
gen_operand(u, &u->operand[2]);
ud_asmprintf(u, ", ");
ud_asmprintf(u, UD_operator, ", ");
}
if (u->operand[1].type != UD_NONE) {
gen_operand(u, &u->operand[1]);
ud_asmprintf(u, ", ");
ud_asmprintf(u, UD_operator, ", ");
}
if (u->operand[0].type != UD_NONE) {
gen_operand(u, &u->operand[0]);
Expand Down
Loading