static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) { int size = 0; char *suffix; if (! insn || ! buf || ! len ) return(0); memset( buf, 0, len ); /* do long jump/call prefix */ if ( insn->type == insn_jmp || insn->type == insn_call ) { if (! is_imm_jmp( x86_operand_1st(insn) ) || (x86_operand_1st(insn))->datatype != op_byte ) { /* far jump/call, use "l" prefix */ STRNCAT( buf, "l", len ); } STRNCAT( buf, insn->mnemonic, len ); return ( strlen( buf ) ); } /* do mnemonic */ STRNCAT( buf, insn->mnemonic, len ); /* do suffixes for memory operands */ if (!(insn->note & insn_note_nosuffix) && (insn->group == insn_arithmetic || insn->group == insn_logic || insn->group == insn_move || insn->group == insn_stack || insn->group == insn_string || insn->group == insn_comparison || insn->type == insn_in || insn->type == insn_out )) { if ( x86_operand_count( insn, op_explicit ) > 0 && is_memory_op( x86_operand_1st(insn) ) ){ size = x86_operand_size( x86_operand_1st( insn ) ); } else if ( x86_operand_count( insn, op_explicit ) > 1 && is_memory_op( x86_operand_2nd(insn) ) ){ size = x86_operand_size( x86_operand_2nd( insn ) ); } } if ( size == 1 ) suffix = "b"; else if ( size == 2 ) suffix = "w"; else if ( size == 4 ) suffix = "l"; else if ( size == 8 ) suffix = "q"; else suffix = ""; STRNCAT( buf, suffix, len ); return ( strlen( buf ) ); }
static int format_att_mnemonic( x86_insn_t *insn, char *buf, int len) { int size = 0; char *suffix; if (! insn || ! buf || ! len ) return(0); memset( buf, 0, len ); /* intel callf/call far is always an lcall */ if (! strcmp( "callf", insn->mnemonic ) ) { STRNCAT( buf, "lcall", len ); return ( strlen( buf ) ); } /* do long jump/call prefix */ if ( insn->type == insn_jmp || insn->type == insn_call ) { if (! is_imm_jmp( x86_operand_1st(insn) ) || (x86_operand_1st(insn))->datatype != op_byte ) { /* far jump/call, use "l" prefix */ STRNCAT( buf, "l", len ); } STRNCAT( buf, insn->mnemonic, len ); return ( strlen( buf ) ); } /* do mnemonic */ STRNCAT( buf, insn->mnemonic, len ); /* do suffixes for memory operands */ if ( x86_operand_count( insn, op_explicit ) > 0 && is_memory_op( x86_operand_1st(insn) ) ) { size = x86_operand_size( x86_operand_1st( insn ) ); } else if ( x86_operand_count( insn, op_explicit ) > 1 && is_memory_op( x86_operand_2nd(insn) ) ) { size = x86_operand_size( x86_operand_2nd( insn ) ); } if ( size == 1 ) suffix = "b"; else if ( size == 2 ) suffix = "w"; else if ( size == 4 ) suffix = "l"; else if ( size == 8 ) suffix = "q"; else suffix = ""; STRNCAT( buf, suffix, len ); return ( strlen( buf ) ); }
/* if there is an immediate value in the instruction, return a pointer to * it */ unsigned char * x86_get_raw_imm( x86_insn_t *insn ) { int size, offset; x86_op_t *op = NULL; if (! insn || ! insn->operands ) { return(NULL); } /* a bit inelegant, but oh well... */ if ( IS_PROPER_IMM( insn->operands ) ) { op = &insn->operands->op; } else if ( insn->operands->next ) { if ( IS_PROPER_IMM( insn->operands->next ) ) { op = &insn->operands->next->op; } else if ( insn->operands->next->next && IS_PROPER_IMM( insn->operands->next->next ) ) { op = &insn->operands->next->next->op; } } if (! op ) { return( NULL ); } /* immediate data is at the end of the insn */ size = x86_operand_size( op ); offset = insn->size - size; return( &insn->bytes[offset] ); }
static intptr_t addr_from_operand( x86_op_t *opnd ) { x86_insn_t *insn; intptr_t field = 0; int size = !opnd ? 0 : x86_operand_size(opnd); if (size <= 0 || size > sizeof(qword_t)) return 0; // compute operand field switch ( opnd->datatype ) { case op_byte: field = (intptr_t) opnd->data.sbyte; break; case op_word: field = (intptr_t) opnd->data.sword; break; case op_dword: field = (intptr_t) opnd->data.sdword; break; case op_qword: field = (intptr_t) opnd->data.sqword; if ((qword_t) field != opnd->data.sqword) return 0; // overflow in intptr_t break; default: return 0; } if (field && !(opnd->flags & op_signed) && size < sizeof(field)) { // clear unrepresented sign bits field &= ~( (intptr_t)-1 << (8 * size) ); } switch (opnd->type) { case op_immediate: return field; case op_relative_near: case op_relative_far: insn = (x86_insn_t*) opnd->insn; return insn->addr + insn->size + field; default: return 0; } }