%module x86disasm %{ #ifdef _MSC_VER typedef __int64 qword; #else typedef long long qword; #endif #include <sys/types.h> #define MAX_REGNAME 8 #define MAX_PREFIX_STR 32 #define MAX_MNEM_STR 16 #define MAX_INSN_SIZE 20 #define MAX_OP_STRING 32 #define MAX_OP_RAW_STRING 64 #define MAX_OP_XML_STRING 256 #define MAX_NUM_OPERANDS 8 #define MAX_INSN_STRING 512 #define MAX_INSN_RAW_STRING 1024 #define MAX_INSN_XML_STRING 4096 #include "../../../config.h" const char * version_string( void ) { return PACKAGE_VERSION; } %} const char * version_string( void ); %rename(X86_Register) x86_reg_t; %rename(X86_EAddr) x86_ea_t; %rename(X86_Operand) x86_op_t; //%rename(X86_OpList) x86_oplist_t; %rename(X86_Insn) x86_insn_t; %rename(X86_InvOperand) x86_invariant_op_t; %rename(X86_Invariant) x86_invariant_t; %include "carrays.i" %array_class( unsigned char, byteArray ); %apply (unsigned char *STRING, int LENGTH) { (unsigned char *buf, size_t buf_len) }; %inline %{ enum x86_asm_format { unknown_syntax = 0, /* never use! */ native_syntax, /* header: 35 bytes */ intel_syntax, /* header: 23 bytes */ att_syntax, /* header: 23 bytes */ xml_syntax, /* header: 679 bytes */ raw_syntax /* header: 172 bytes */ }; %} /* ================================================================== */ /* operand class */ %inline %{ enum x86_reg_type { reg_gen = 0x00001, reg_in = 0x00002, reg_out = 0x00004, reg_local = 0x00008, reg_fpu = 0x00010, reg_seg = 0x00020, reg_simd = 0x00040, reg_sys = 0x00080, reg_sp = 0x00100, reg_fp = 0x00200, reg_pc = 0x00400, reg_retaddr = 0x00800, reg_cond = 0x01000, reg_zero = 0x02000, reg_ret = 0x04000, reg_src = 0x10000, reg_dest = 0x20000, reg_count = 0x40000 }; typedef struct { char name[MAX_REGNAME]; enum x86_reg_type type; unsigned int size; unsigned int id; unsigned int alias; unsigned int shift; } x86_reg_t; void x86_reg_from_id( unsigned int id, x86_reg_t * reg ); typedef struct { unsigned int scale; x86_reg_t index, base; long disp; char disp_sign; char disp_size; } x86_ea_t; enum x86_op_type { op_unused = 0, op_register = 1, op_immediate = 2, op_relative_near = 3, op_relative_far = 4, op_absolute = 5, op_expression = 6, op_offset = 7, op_unknown }; enum x86_op_datatype { op_byte = 1, op_word = 2, op_dword = 3, op_qword = 4, op_dqword = 5, op_sreal = 6, op_dreal = 7, op_extreal = 8, op_bcd = 9, op_ssimd = 10, op_dsimd = 11, op_sssimd = 12, op_sdsimd = 13, op_descr32 = 14, op_descr16 = 15, op_pdescr32 = 16, op_pdescr16 = 17, op_fpuenv = 18, op_fpregset = 19, }; enum x86_op_access { op_read = 1, op_write = 2, op_execute = 4 }; enum x86_op_flags { op_signed = 1, op_string = 2, op_constant = 4, op_pointer = 8, op_sysref = 0x010, op_implied = 0x020, op_hardcode = 0x40, op_es_seg = 0x100, op_cs_seg = 0x200, op_ss_seg = 0x300, op_ds_seg = 0x400, op_fs_seg = 0x500, op_gs_seg = 0x600 }; typedef struct { enum x86_op_type type; enum x86_op_datatype datatype; enum x86_op_access access; enum x86_op_flags flags; union { char sbyte; short sword; long sdword; qword sqword; unsigned char byte; unsigned short word; unsigned long dword; qword qword; float sreal; double dreal; unsigned char extreal[10]; unsigned char bcd[10]; qword dqword[2]; unsigned char simd[16]; unsigned char fpuenv[28]; void * address; unsigned long offset; x86_reg_t reg; char relative_near; long relative_far; x86_ea_t expression; } data; void * insn; } x86_op_t; unsigned int x86_operand_size( x86_op_t *op ); int x86_format_operand(x86_op_t *op, char *buf, int len, enum x86_asm_format format); %} %extend x86_reg_t{ x86_reg_t * aliased_reg( ) { x86_reg_t * reg = (x86_reg_t * ) calloc( sizeof(x86_reg_t), 1 ); x86_reg_from_id( self->id, reg ); return reg; } } %extend x86_op_t{ size_t size() { return x86_operand_size( self ); } char * format( enum x86_asm_format format ) { char *buf, *str; size_t len; switch ( format ) { case xml_syntax: len = MAX_OP_XML_STRING; break; case raw_syntax: len = MAX_OP_RAW_STRING; break; case native_syntax: case intel_syntax: case att_syntax: case unknown_syntax: default: len = MAX_OP_STRING; break; } buf = (char * ) calloc( len + 1, 1 ); x86_format_operand( self, buf, len, format ); /* drop buffer down to a reasonable size */ str = strdup( buf ); free(buf); return str; } int is_address( ) { if ( self->type == op_absolute || self->type == op_offset ) { return 1; } return 0; } int is_relative( ) { if ( self->type == op_relative_near || self->type == op_relative_far ) { return 1; } return 0; } %newobject copy; x86_op_t * copy() { x86_op_t *op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 ); if ( op ) { memcpy( op, self, sizeof(x86_op_t) ); } return op; } } /* ================================================================== */ /* operand list class */ %inline %{ typedef struct X86_OpListNode { x86_op_t *op; struct X86_OpListNode *next, *prev; } X86_OpListNode; typedef struct X86_OpList { size_t count; X86_OpListNode *head, *tail, *curr; } X86_OpList; %} %extend X86_OpList { X86_OpList () { X86_OpList *list = (X86_OpList *) calloc( sizeof(X86_OpList), 1 ); list->count = 0; return list; } ~X86_OpList() { X86_OpListNode *node, *next; node = self->head; while ( node ) { next = node->next; /* free( node->insn ); */ free( node ); node = next; } free( self ); } X86_OpListNode * first() { self->curr = self->head; return self->head; } X86_OpListNode * last() { self->curr = self->tail; return self->tail; } X86_OpListNode * next() { if (! self->curr ) { self->curr = self->head; return self->head; } self->curr = self->curr->next; return self->curr; } X86_OpListNode * prev() { if (! self->curr ) { self->curr = self->tail; return self->tail; } self->curr = self->curr->prev; return self->curr; } %newobject append; void append( x86_op_t *op ) { X86_OpListNode *node = (X86_OpListNode *) calloc( sizeof(X86_OpListNode) , 1 ); if (! node ) { return; } self->count++; if ( ! self->tail ) { self->head = self->tail = node; } else { self->tail->next = node; node->prev = self->tail; self->tail = node; } node->op = x86_op_t_copy( op ); } } %inline %{ typedef struct x86_operand_list { x86_op_t op; struct x86_operand_list *next; } x86_oplist_t; %} %extend x86_oplist_t { %newobject x86_oplist_node_copy; } /* ================================================================== */ /* instruction class */ %inline %{ x86_oplist_t * x86_oplist_node_copy( x86_oplist_t * list ) { x86_oplist_t *ptr; ptr = (x86_oplist_t *) calloc( sizeof(x86_oplist_t), 1 ); if ( ptr ) { memcpy( &ptr->op, &list->op, sizeof(x86_op_t) ); } return ptr; } enum x86_insn_group { insn_none = 0, insn_controlflow = 1, insn_arithmetic = 2, insn_logic = 3, insn_stack = 4, insn_comparison = 5, insn_move = 6, insn_string = 7, insn_bit_manip = 8, insn_flag_manip = 9, insn_fpu = 10, insn_interrupt = 13, insn_system = 14, insn_other = 15 }; enum x86_insn_type { insn_invalid = 0, insn_jmp = 0x1001, insn_jcc = 0x1002, insn_call = 0x1003, insn_callcc = 0x1004, insn_return = 0x1005, insn_add = 0x2001, insn_sub = 0x2002, insn_mul = 0x2003, insn_div = 0x2004, insn_inc = 0x2005, insn_dec = 0x2006, insn_shl = 0x2007, insn_shr = 0x2008, insn_rol = 0x2009, insn_ror = 0x200A, insn_and = 0x3001, insn_or = 0x3002, insn_xor = 0x3003, insn_not = 0x3004, insn_neg = 0x3005, insn_push = 0x4001, insn_pop = 0x4002, insn_pushregs = 0x4003, insn_popregs = 0x4004, insn_pushflags = 0x4005, insn_popflags = 0x4006, insn_enter = 0x4007, insn_leave = 0x4008, insn_test = 0x5001, insn_cmp = 0x5002, insn_mov = 0x6001, insn_movcc = 0x6002, insn_xchg = 0x6003, insn_xchgcc = 0x6004, insn_strcmp = 0x7001, insn_strload = 0x7002, insn_strmov = 0x7003, insn_strstore = 0x7004, insn_translate = 0x7005, insn_bittest = 0x8001, insn_bitset = 0x8002, insn_bitclear = 0x8003, insn_clear_carry = 0x9001, insn_clear_zero = 0x9002, insn_clear_oflow = 0x9003, insn_clear_dir = 0x9004, insn_clear_sign = 0x9005, insn_clear_parity = 0x9006, insn_set_carry = 0x9007, insn_set_zero = 0x9008, insn_set_oflow = 0x9009, insn_set_dir = 0x900A, insn_set_sign = 0x900B, insn_set_parity = 0x900C, insn_tog_carry = 0x9010, insn_tog_zero = 0x9020, insn_tog_oflow = 0x9030, insn_tog_dir = 0x9040, insn_tog_sign = 0x9050, insn_tog_parity = 0x9060, insn_fmov = 0xA001, insn_fmovcc = 0xA002, insn_fneg = 0xA003, insn_fabs = 0xA004, insn_fadd = 0xA005, insn_fsub = 0xA006, insn_fmul = 0xA007, insn_fdiv = 0xA008, insn_fsqrt = 0xA009, insn_fcmp = 0xA00A, insn_fcos = 0xA00C, insn_fldpi = 0xA00D, insn_fldz = 0xA00E, insn_ftan = 0xA00F, insn_fsine = 0xA010, insn_fsys = 0xA020, insn_int = 0xD001, insn_intcc = 0xD002, insn_iret = 0xD003, insn_bound = 0xD004, insn_debug = 0xD005, insn_trace = 0xD006, insn_invalid_op = 0xD007, insn_oflow = 0xD008, insn_halt = 0xE001, insn_in = 0xE002, insn_out = 0xE003, insn_cpuid = 0xE004, insn_nop = 0xF001, insn_bcdconv = 0xF002, insn_szconv = 0xF003 }; enum x86_insn_note { insn_note_ring0 = 1, insn_note_smm = 2, insn_note_serial = 4 }; enum x86_flag_status { insn_carry_set = 0x1, insn_zero_set = 0x2, insn_oflow_set = 0x4, insn_dir_set = 0x8, insn_sign_set = 0x10, insn_parity_set = 0x20, insn_carry_or_zero_set = 0x40, insn_zero_set_or_sign_ne_oflow = 0x80, insn_carry_clear = 0x100, insn_zero_clear = 0x200, insn_oflow_clear = 0x400, insn_dir_clear = 0x800, insn_sign_clear = 0x1000, insn_parity_clear = 0x2000, insn_sign_eq_oflow = 0x4000, insn_sign_ne_oflow = 0x8000 }; enum x86_insn_cpu { cpu_8086 = 1, cpu_80286 = 2, cpu_80386 = 3, cpu_80387 = 4, cpu_80486 = 5, cpu_pentium = 6, cpu_pentiumpro = 7, cpu_pentium2 = 8, cpu_pentium3 = 9, cpu_pentium4 = 10, cpu_k6 = 16, cpu_k7 = 32, cpu_athlon = 48 }; enum x86_insn_isa { isa_gp = 1, isa_fp = 2, isa_fpumgt = 3, isa_mmx = 4, isa_sse1 = 5, isa_sse2 = 6, isa_sse3 = 7, isa_3dnow = 8, isa_sys = 9 }; enum x86_insn_prefix { insn_no_prefix = 0, insn_rep_zero = 1, insn_rep_notzero = 2, insn_lock = 4 }; typedef struct { unsigned long addr; unsigned long offset; enum x86_insn_group group; enum x86_insn_type type; enum x86_insn_note note; unsigned char bytes[MAX_INSN_SIZE]; unsigned char size; unsigned char addr_size; unsigned char op_size; enum x86_insn_cpu cpu; enum x86_insn_isa isa; enum x86_flag_status flags_set; enum x86_flag_status flags_tested; unsigned char stack_mod; long stack_mod_val; enum x86_insn_prefix prefix; char prefix_string[MAX_PREFIX_STR]; char mnemonic[MAX_MNEM_STR]; x86_oplist_t *operands; size_t operand_count; size_t explicit_count; void *block; void *function; int tag; } x86_insn_t; typedef void (*x86_operand_fn)(x86_op_t *op, x86_insn_t *insn, void *arg); enum x86_op_foreach_type { op_any = 0, op_dest = 1, op_src = 2, op_ro = 3, op_wo = 4, op_xo = 5, op_rw = 6, op_implicit = 0x10, op_explicit = 0x20 }; size_t x86_operand_count( x86_insn_t *insn, enum x86_op_foreach_type type ); x86_op_t * x86_operand_1st( x86_insn_t *insn ); x86_op_t * x86_operand_2nd( x86_insn_t *insn ); x86_op_t * x86_operand_3rd( x86_insn_t *insn ); long x86_get_rel_offset( x86_insn_t *insn ); x86_op_t * x86_get_branch_target( x86_insn_t *insn ); x86_op_t * x86_get_imm( x86_insn_t *insn ); unsigned char * x86_get_raw_imm( x86_insn_t *insn ); void x86_set_insn_addr( x86_insn_t *insn, unsigned long addr ); int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len, enum x86_asm_format format); int x86_format_insn(x86_insn_t *insn, char *buf, int len, enum x86_asm_format); void x86_oplist_free( x86_insn_t *insn ); int x86_insn_is_valid( x86_insn_t *insn ); %} %extend x86_insn_t { x86_insn_t() { x86_insn_t *insn = (x86_insn_t *) calloc( sizeof(x86_insn_t), 1 ); return insn; } ~x86_insn_t() { x86_oplist_free( self ); free( self ); } int is_valid( ) { return x86_insn_is_valid( self ); } x86_op_t * operand_1st() { return x86_operand_1st( self ); } x86_op_t * operand_2nd() { return x86_operand_2nd( self ); } x86_op_t * operand_3rd() { return x86_operand_3rd( self ); } x86_op_t * operand_dest() { return x86_operand_1st( self ); } x86_op_t * operand_src() { return x86_operand_2nd( self ); } size_t num_operands( enum x86_op_foreach_type type ) { return x86_operand_count( self, type ); } long rel_offset() { return x86_get_rel_offset( self ); } x86_op_t * branch_target() { return x86_get_branch_target( self ); } x86_op_t * imm() { return x86_get_imm( self ); } unsigned char * raw_imm() { return x86_get_raw_imm( self ); } %newobject format; char * format( enum x86_asm_format format ) { char *buf, *str; size_t len; switch ( format ) { case xml_syntax: len = MAX_INSN_XML_STRING; break; case raw_syntax: len = MAX_INSN_RAW_STRING; break; case native_syntax: case intel_syntax: case att_syntax: case unknown_syntax: default: len = MAX_INSN_STRING; break; } buf = (char * ) calloc( len + 1, 1 ); x86_format_insn( self, buf, len, format ); /* drop buffer down to a reasonable size */ str = strdup( buf ); free(buf); return str; } %newobject format_mnemonic; char * format_mnemonic( enum x86_asm_format format ) { char *buf, *str; size_t len = MAX_MNEM_STR + MAX_PREFIX_STR + 4; buf = (char * ) calloc( len, 1 ); x86_format_mnemonic( self, buf, len, format ); /* drop buffer down to a reasonable size */ str = strdup( buf ); free(buf); return str; } %newobject copy; x86_insn_t * copy() { x86_oplist_t *ptr, *list, *last = NULL; x86_insn_t *insn = (x86_insn_t *) calloc( sizeof(x86_insn_t), 1 ); if ( insn ) { memcpy( insn, self, sizeof(x86_insn_t) ); insn->operands = NULL; insn->block = NULL; insn->function = NULL; /* copy operand list */ for ( list = self->operands; list; list = list->next ) { ptr = x86_oplist_node_copy( list ); if (! ptr ) { continue; } if ( insn->operands ) { last->next = ptr; } else { insn->operands = ptr; } last = ptr; } } return insn; } X86_OpList * operand_list( ) { x86_oplist_t *list = self->operands; X86_OpList *op_list = new_X86_OpList(); for ( list = self->operands; list; list = list->next ) { X86_OpList_append( op_list, &list->op ); } return op_list; } } /* ================================================================== */ /* invariant instruction class */ %inline %{ #define X86_WILDCARD_BYTE 0xF4 typedef struct { enum x86_op_type type; enum x86_op_datatype datatype; enum x86_op_access access; enum x86_op_flags flags; } x86_invariant_op_t; typedef struct { unsigned char bytes[64]; unsigned int size; enum x86_insn_group group; enum x86_insn_type type; x86_invariant_op_t operands[3]; } x86_invariant_t; %} %extend x86_invariant_t { x86_invariant_t() { x86_invariant_t *inv = (x86_invariant_t *) calloc( sizeof(x86_invariant_t), 1 ); return inv; } ~x86_invariant_t() { free( self ); } } /* ================================================================== */ /* instruction list class */ %inline %{ typedef struct X86_InsnListNode { x86_insn_t *insn; struct X86_InsnListNode *next, *prev; } X86_InsnListNode; typedef struct X86_InsnList { size_t count; X86_InsnListNode *head, *tail, *curr; } X86_InsnList; %} %extend X86_InsnList { X86_InsnList () { X86_InsnList *list = (X86_InsnList *) calloc( sizeof(X86_InsnList), 1 ); list->count = 0; return list; } ~X86_InsnList() { X86_InsnListNode *node, *next; node = self->head; while ( node ) { next = node->next; /* free( node->insn ); */ free( node ); node = next; } free( self ); } X86_InsnListNode * first() { return self->head; } X86_InsnListNode * last() { return self->tail; } X86_InsnListNode * next() { if (! self->curr ) { self->curr = self->head; return self->head; } self->curr = self->curr->next; return self->curr; } X86_InsnListNode * prev() { if (! self->curr ) { self->curr = self->tail; return self->tail; } self->curr = self->curr->prev; return self->curr; } %newobject append; void append( x86_insn_t *insn ) { X86_InsnListNode *node = (X86_InsnListNode *) calloc( sizeof(X86_InsnListNode) , 1 ); if (! node ) { return; } self->count++; if ( ! self->tail ) { self->head = self->tail = node; } else { self->tail->next = node; node->prev = self->tail; self->tail = node; } node->insn = x86_insn_t_copy( insn ); } } /* ================================================================== */ /* address table class */ /* slight TODO */ /* ================================================================== */ /* Main disassembler class */ %inline %{ enum x86_options { opt_none= 0, opt_ignore_nulls=1, opt_16_bit=2 }; enum x86_report_codes { report_disasm_bounds, report_insn_bounds, report_invalid_insn, report_unknown }; typedef struct { enum x86_report_codes last_error; void * last_error_data; void * disasm_callback; void * disasm_resolver; } X86_Disasm; typedef void (*DISASM_REPORTER)( enum x86_report_codes code, void *data, void *arg ); typedef void (*DISASM_CALLBACK)( x86_insn_t *insn, void * arg ); typedef long (*DISASM_RESOLVER)( x86_op_t *op, x86_insn_t * current_insn, void *arg ); void x86_report_error( enum x86_report_codes code, void *data ); int x86_init( enum x86_options options, DISASM_REPORTER reporter, void *arg); void x86_set_reporter( DISASM_REPORTER reporter, void *arg); void x86_set_options( enum x86_options options ); enum x86_options x86_get_options( void ); int x86_cleanup(void); int x86_format_header( char *buf, int len, enum x86_asm_format format); unsigned int x86_endian(void); unsigned int x86_addr_size(void); unsigned int x86_op_size(void); unsigned int x86_word_size(void); unsigned int x86_max_insn_size(void); unsigned int x86_sp_reg(void); unsigned int x86_fp_reg(void); unsigned int x86_ip_reg(void); size_t x86_invariant_disasm( unsigned char *buf, int buf_len, x86_invariant_t *inv ); size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len ); int x86_disasm( unsigned char *buf, unsigned int buf_len, unsigned long buf_rva, unsigned int offset, x86_insn_t * insn ); int x86_disasm_range( unsigned char *buf, unsigned long buf_rva, unsigned int offset, unsigned int len, DISASM_CALLBACK func, void *arg ); int x86_disasm_forward( unsigned char *buf, unsigned int buf_len, unsigned long buf_rva, unsigned int offset, DISASM_CALLBACK func, void *arg, DISASM_RESOLVER resolver, void *r_arg ); void x86_default_reporter( enum x86_report_codes code, void *data, void *arg ) { X86_Disasm *dis = (X86_Disasm *) arg; if ( dis ) { dis->last_error = code; dis->last_error_data = data; } } void x86_default_callback( x86_insn_t *insn, void *arg ) { X86_InsnList *list = (X86_InsnList *) arg; if ( list ) { X86_InsnList_append( list, insn ); } } /* TODO: resolver stack, maybe a callback */ long x86_default_resolver( x86_op_t *op, x86_insn_t *insn, void *arg ) { X86_Disasm *dis = (X86_Disasm *) arg; if ( dis ) { //return dis->resolver( op, insn ); return 0; } return 0; } %} %extend X86_Disasm { X86_Disasm( ) { X86_Disasm * dis = (X86_Disasm *) calloc( sizeof( X86_Disasm ), 1 ); x86_init( opt_none, x86_default_reporter, dis ); return dis; } X86_Disasm( enum x86_options options ) { X86_Disasm * dis = (X86_Disasm *) calloc( sizeof( X86_Disasm ), 1 ); x86_init( options, x86_default_reporter, dis ); return dis; } X86_Disasm( enum x86_options options, DISASM_REPORTER reporter ) { X86_Disasm * dis = (X86_Disasm *) calloc( sizeof( X86_Disasm ), 1 ); x86_init( options, reporter, NULL ); return dis; } X86_Disasm( enum x86_options options, DISASM_REPORTER reporter, void * arg ) { X86_Disasm * dis = (X86_Disasm *) calloc( sizeof( X86_Disasm ), 1 ); x86_init( options, reporter, arg ); return dis; } ~X86_Disasm() { x86_cleanup(); free( self ); } void set_options( enum x86_options options ) { return x86_set_options( options ); } enum x86_options options() { return x86_get_options(); } void set_callback( void * callback ) { self->disasm_callback = callback; } void set_resolver( void * callback ) { self->disasm_resolver = callback; } void report_error( enum x86_report_codes code ) { x86_report_error( code, NULL ); } %newobject disasm; x86_insn_t * disasm( unsigned char *buf, size_t buf_len, unsigned long buf_rva, unsigned int offset ) { x86_insn_t *insn = calloc( sizeof( x86_insn_t ), 1 ); x86_disasm( buf, buf_len, buf_rva, offset, insn ); return insn; } int disasm_range( unsigned char *buf, size_t buf_len, unsigned long buf_rva, unsigned int offset, unsigned int len ) { X86_InsnList *list = new_X86_InsnList(); if ( len > buf_len ) { len = buf_len; } return x86_disasm_range( buf, buf_rva, offset, len, x86_default_callback, list ); } int disasm_forward( unsigned char *buf, size_t buf_len, unsigned long buf_rva, unsigned int offset ) { X86_InsnList *list = new_X86_InsnList(); /* use default resolver: damn SWIG callbacks! */ return x86_disasm_forward( buf, buf_len, buf_rva, offset, x86_default_callback, list, x86_default_resolver, NULL ); } size_t disasm_invariant( unsigned char *buf, size_t buf_len, x86_invariant_t *inv ) { return x86_invariant_disasm( buf, buf_len, inv ); } size_t disasm_size( unsigned char *buf, size_t buf_len ) { return x86_size_disasm( buf, buf_len ); } %newobject format_header; char * format_header( enum x86_asm_format format) { char *buf, *str; size_t len; switch ( format ) { /* these were obtained from x86_format.c */ case xml_syntax: len = 679; break; case raw_syntax: len = 172; break; case native_syntax: len = 35; break; case intel_syntax: len = 23; break; case att_syntax: len = 23; break; case unknown_syntax: default: len = 23; break; } buf = (char * ) calloc( len + 1, 1 ); x86_format_header( buf, len, format ); return buf; } unsigned int endian() { return x86_endian(); } unsigned int addr_size() { return x86_addr_size(); } unsigned int op_size() { return x86_op_size(); } unsigned int word_size() { return x86_word_size(); } unsigned int max_insn_size() { return x86_max_insn_size(); } unsigned int sp_reg() { return x86_sp_reg(); } unsigned int fp_reg() { return x86_fp_reg(); } unsigned int ip_reg() { return x86_ip_reg(); } %newobject reg_from_id; x86_reg_t * reg_from_id( unsigned int id ) { x86_reg_t * reg = calloc( sizeof(x86_reg_t), 1 ); x86_reg_from_id( id, reg ); return reg; } unsigned char wildcard_byte() { return X86_WILDCARD_BYTE; } int max_register_string() { return MAX_REGNAME; } int max_prefix_string() { return MAX_PREFIX_STR; } int max_mnemonic_string() { return MAX_MNEM_STR; } int max_operand_string( enum x86_asm_format format ) { switch ( format ) { case xml_syntax: return MAX_OP_XML_STRING; break; case raw_syntax: return MAX_OP_RAW_STRING; break; case native_syntax: case intel_syntax: case att_syntax: case unknown_syntax: default: return MAX_OP_STRING; break; } } int max_insn_string( enum x86_asm_format format ) { switch ( format ) { case xml_syntax: return MAX_INSN_XML_STRING; break; case raw_syntax: return MAX_INSN_RAW_STRING; break; case native_syntax: case intel_syntax: case att_syntax: case unknown_syntax: default: return MAX_INSN_STRING; break; } } int max_num_operands( ) { return MAX_NUM_OPERANDS; } } /* python callback, per the manual */ /*%typemap(python,in) PyObject *pyfunc { if (!PyCallable_Check($source)) { PyErr_SetString(PyExc_TypeError, "Need a callable object!"); return NULL; } $target = $source; }*/ /* python FILE * callback, per the manual */ /* %typemap(python,in) FILE * { if (!PyFile_Check($source)) { PyErr_SetString(PyExc_TypeError, "Need a file!"); return NULL; } $target = PyFile_AsFile($source); }*/