Home | History | Annotate | Download | only in swig
      1 %module x86disasm
      2 %{
      3 #ifdef _MSC_VER
      4 	typedef __int64         qword;
      5 #else
      6 	typedef long long       qword;
      7 #endif
      8 
      9 #include <sys/types.h>
     10 
     11 #define MAX_REGNAME 8
     12 #define MAX_PREFIX_STR 32
     13 #define MAX_MNEM_STR 16
     14 #define MAX_INSN_SIZE 20
     15 #define MAX_OP_STRING 32
     16 #define MAX_OP_RAW_STRING 64
     17 #define MAX_OP_XML_STRING 256
     18 #define MAX_NUM_OPERANDS 8
     19 #define MAX_INSN_STRING 512
     20 #define MAX_INSN_RAW_STRING 1024
     21 #define MAX_INSN_XML_STRING 4096
     22 
     23 #include "../../../config.h"
     24 
     25 
     26 const char * version_string( void ) {
     27 	return PACKAGE_VERSION;
     28 }
     29 
     30 %}
     31 
     32 const char * version_string( void );
     33 
     34 %rename(X86_Register) x86_reg_t;
     35 %rename(X86_EAddr) x86_ea_t;
     36 %rename(X86_Operand) x86_op_t;
     37 //%rename(X86_OpList) x86_oplist_t;
     38 %rename(X86_Insn) x86_insn_t;
     39 %rename(X86_InvOperand) x86_invariant_op_t;
     40 %rename(X86_Invariant) x86_invariant_t;
     41 
     42 %include "carrays.i"
     43 
     44 %array_class( unsigned char, byteArray );
     45 
     46 
     47 %apply (unsigned char *STRING, int LENGTH) {
     48 	(unsigned char *buf, size_t buf_len)
     49 };
     50 
     51 
     52 %inline %{
     53 
     54 
     55 enum x86_asm_format {
     56 	unknown_syntax = 0,		/* never use! */
     57 	native_syntax, 			/* header: 35 bytes */
     58 	intel_syntax, 			/* header: 23 bytes */
     59 	att_syntax,  			/* header: 23 bytes */
     60 	xml_syntax,			/* header: 679 bytes */
     61 	raw_syntax			/* header: 172 bytes */
     62 };
     63 %}
     64 
     65 /* ================================================================== */
     66 /* operand class */
     67 %inline %{
     68 	enum x86_reg_type {
     69 	        reg_gen         = 0x00001, reg_in          = 0x00002,
     70 	        reg_out         = 0x00004, reg_local       = 0x00008,
     71 	        reg_fpu         = 0x00010, reg_seg         = 0x00020,
     72 	        reg_simd        = 0x00040, reg_sys         = 0x00080,
     73 	        reg_sp          = 0x00100, reg_fp          = 0x00200,
     74 	        reg_pc          = 0x00400, reg_retaddr     = 0x00800,
     75 	        reg_cond        = 0x01000, reg_zero        = 0x02000,
     76 	        reg_ret         = 0x04000, reg_src         = 0x10000,
     77 	        reg_dest        = 0x20000, reg_count       = 0x40000
     78 	};
     79 
     80 	typedef struct {
     81        	 	char name[MAX_REGNAME];
     82 	        enum x86_reg_type type;
     83 	        unsigned int size;
     84 	        unsigned int id;
     85 		unsigned int alias;
     86 		unsigned int shift;
     87 	} x86_reg_t;
     88 
     89 	void x86_reg_from_id( unsigned int id, x86_reg_t * reg );
     90 
     91 	typedef struct {
     92 	        unsigned int     scale;
     93 	        x86_reg_t        index, base;
     94 	        long             disp;
     95 	        char             disp_sign;
     96 	        char             disp_size;
     97 	} x86_ea_t;
     98 
     99 	enum x86_op_type {
    100 	        op_unused = 0,
    101 	        op_register = 1,
    102 	        op_immediate = 2,
    103 	        op_relative_near = 3,
    104 	        op_relative_far = 4,
    105 	        op_absolute = 5,
    106 	        op_expression = 6,
    107 	        op_offset = 7,
    108 	        op_unknown
    109 	};
    110 
    111 	enum x86_op_datatype {
    112 	       	op_byte = 1, op_word = 2,
    113 	        op_dword = 3, op_qword = 4,
    114 	        op_dqword = 5, op_sreal = 6,
    115 	        op_dreal = 7, op_extreal = 8,
    116 	        op_bcd = 9,  op_ssimd = 10,
    117 	        op_dsimd = 11, op_sssimd = 12,
    118 	        op_sdsimd = 13, op_descr32 = 14,
    119 		op_descr16 = 15, op_pdescr32 = 16,
    120 		op_pdescr16 = 17, op_fpuenv = 18,
    121 		op_fpregset = 19,
    122 	};
    123 
    124 	enum x86_op_access {
    125 	        op_read = 1,
    126 	        op_write = 2,
    127 	        op_execute = 4
    128 	};
    129 
    130 	enum x86_op_flags {
    131 	        op_signed = 1, op_string = 2,
    132 	        op_constant = 4, op_pointer = 8,
    133 		op_sysref = 0x010, op_implied = 0x020,
    134 		op_hardcode = 0x40, op_es_seg = 0x100,
    135 	        op_cs_seg = 0x200, op_ss_seg = 0x300,
    136 	        op_ds_seg = 0x400, op_fs_seg = 0x500,
    137 	        op_gs_seg = 0x600
    138 	};
    139 
    140 	typedef struct {
    141 	        enum x86_op_type        type;
    142 	        enum x86_op_datatype    datatype;
    143 	        enum x86_op_access      access;
    144 	        enum x86_op_flags       flags;
    145 	        union {
    146 	                char            sbyte;
    147 	                short           sword;
    148 	                long            sdword;
    149 	                qword           sqword;
    150 	                unsigned char   byte;
    151 	       	         unsigned short  word;
    152 	                unsigned long   dword;
    153 	                qword           qword;
    154 	                float           sreal;
    155 	                double          dreal;
    156 	                unsigned char   extreal[10];
    157 	                unsigned char   bcd[10];
    158 	                qword           dqword[2];
    159 	                unsigned char   simd[16];
    160 	                unsigned char   fpuenv[28];
    161 	                void            * address;
    162 	                unsigned long   offset;
    163 	                x86_reg_t       reg;
    164 	                char            relative_near;
    165 	       	         long            relative_far;
    166        	         	x86_ea_t        expression;
    167         	} data;
    168 		void * insn;
    169 	} x86_op_t;
    170 
    171 	unsigned int x86_operand_size( x86_op_t *op );
    172 
    173 	int x86_format_operand(x86_op_t *op, char *buf, int len,
    174         	          enum x86_asm_format format);
    175 %}
    176 
    177 %extend x86_reg_t{
    178 	x86_reg_t * aliased_reg( ) {
    179 		x86_reg_t * reg = (x86_reg_t * )
    180 				  calloc( sizeof(x86_reg_t), 1 );
    181 		x86_reg_from_id( self->id, reg );
    182 		return reg;
    183 	}
    184 }
    185 
    186 %extend x86_op_t{
    187 	size_t size() {
    188 		return x86_operand_size( self );
    189 	}
    190 	char * format( enum x86_asm_format format ) {
    191 		char *buf, *str;
    192 		size_t len;
    193 
    194 		switch ( format ) {
    195 			case xml_syntax:
    196 				len = MAX_OP_XML_STRING;
    197 				break;
    198 			case raw_syntax:
    199 				len = MAX_OP_RAW_STRING;
    200 				break;
    201 			case native_syntax:
    202 			case intel_syntax:
    203 			case att_syntax:
    204 			case unknown_syntax:
    205 			default:
    206 				len = MAX_OP_STRING;
    207 				break;
    208 		}
    209 
    210 		buf = (char * ) calloc( len + 1, 1 );
    211 		x86_format_operand( self, buf, len, format );
    212 
    213 		/* drop buffer down to a reasonable size */
    214 		str = strdup( buf );
    215 		free(buf);
    216 		return str;
    217 	}
    218 
    219 	int is_address( ) {
    220 		if ( self->type == op_absolute ||
    221 		     self->type == op_offset ) {
    222 		     return 1;
    223 		}
    224 
    225 		return 0;
    226 	}
    227 
    228 	int is_relative( ) {
    229 		if ( self->type == op_relative_near ||
    230 		     self->type == op_relative_far ) {
    231 		     return 1;
    232 		}
    233 
    234 		return 0;
    235 	}
    236 
    237 	%newobject copy;
    238 	x86_op_t * copy() {
    239 		x86_op_t *op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 );
    240 
    241 		if ( op ) {
    242 			memcpy( op, self, sizeof(x86_op_t) );
    243 		}
    244 
    245 		return op;
    246 	}
    247 }
    248 
    249 /* ================================================================== */
    250 /* operand list class */
    251 %inline %{
    252 	typedef struct X86_OpListNode {
    253 		x86_op_t *op;
    254 		struct X86_OpListNode *next, *prev;
    255 	} X86_OpListNode;
    256 
    257 	typedef struct X86_OpList {
    258 		size_t count;
    259 		X86_OpListNode *head, *tail, *curr;
    260 	} X86_OpList;
    261 %}
    262 
    263 %extend X86_OpList {
    264 	X86_OpList () {
    265 		X86_OpList *list = (X86_OpList *)
    266 				calloc( sizeof(X86_OpList), 1 );
    267 		list->count = 0;
    268 		return list;
    269 	}
    270 
    271 	~X86_OpList() {
    272 		X86_OpListNode *node, *next;
    273 
    274 		node = self->head;
    275 		while ( node ) {
    276 			next = node->next;
    277 			/* free( node->insn ); */
    278 			free( node );
    279 			node = next;
    280 		}
    281 
    282 		free( self );
    283 	}
    284 
    285 	X86_OpListNode * first() {
    286 		self->curr = self->head;
    287 		return self->head;
    288 	}
    289 
    290 	X86_OpListNode * last() {
    291 		self->curr = self->tail;
    292 		return self->tail;
    293 	}
    294 
    295 	X86_OpListNode * next() {
    296 		if (! self->curr ) {
    297 			self->curr = self->head;
    298 			return self->head;
    299 		}
    300 
    301 		self->curr = self->curr->next;
    302 		return self->curr;
    303 	}
    304 
    305 	X86_OpListNode * prev() {
    306 		if (! self->curr ) {
    307 			self->curr = self->tail;
    308 			return self->tail;
    309 		}
    310 
    311 		self->curr = self->curr->prev;
    312 		return self->curr;
    313 	}
    314 
    315 	%newobject append;
    316 	void append( x86_op_t *op ) {
    317 		X86_OpListNode *node = (X86_OpListNode *)
    318 					calloc( sizeof(X86_OpListNode) , 1 );
    319 		if (! node ) {
    320 			return;
    321 		}
    322 
    323 		self->count++;
    324 		if ( ! self->tail ) {
    325 			self->head = self->tail = node;
    326 		} else {
    327 			self->tail->next = node;
    328 			node->prev = self->tail;
    329 			self->tail = node;
    330 		}
    331 
    332 		node->op = x86_op_t_copy( op );
    333 	}
    334 }
    335 
    336 %inline %{
    337 	typedef struct x86_operand_list {
    338 		x86_op_t op;
    339 		struct x86_operand_list *next;
    340 	} x86_oplist_t;
    341 %}
    342 
    343 %extend x86_oplist_t {
    344 	%newobject x86_oplist_node_copy;
    345 }
    346 
    347 /* ================================================================== */
    348 /* instruction class */
    349 %inline %{
    350 	x86_oplist_t * x86_oplist_node_copy( x86_oplist_t * list ) {
    351 		x86_oplist_t *ptr;
    352 		ptr = (x86_oplist_t *) calloc( sizeof(x86_oplist_t), 1 );
    353 		if ( ptr ) {
    354 			memcpy( &ptr->op, &list->op, sizeof(x86_op_t) );
    355 		}
    356 
    357 		return ptr;
    358 	}
    359 
    360 	enum x86_insn_group {
    361 		insn_none = 0, insn_controlflow = 1,
    362 	        insn_arithmetic = 2, insn_logic = 3,
    363 	        insn_stack = 4, insn_comparison = 5,
    364 	        insn_move = 6, insn_string = 7,
    365 	        insn_bit_manip = 8, insn_flag_manip = 9,
    366 	        insn_fpu = 10, insn_interrupt = 13,
    367 	        insn_system = 14, insn_other = 15
    368 	};
    369 
    370 	enum x86_insn_type {
    371 		insn_invalid = 0, insn_jmp = 0x1001,
    372 	        insn_jcc = 0x1002, insn_call = 0x1003,
    373 	        insn_callcc = 0x1004, insn_return = 0x1005,
    374 	        insn_add = 0x2001, insn_sub = 0x2002,
    375 	        insn_mul = 0x2003, insn_div = 0x2004,
    376 	        insn_inc = 0x2005, insn_dec = 0x2006,
    377 	        insn_shl = 0x2007, insn_shr = 0x2008,
    378 	        insn_rol = 0x2009, insn_ror = 0x200A,
    379 	        insn_and = 0x3001, insn_or = 0x3002,
    380 	        insn_xor = 0x3003, insn_not = 0x3004,
    381 	        insn_neg = 0x3005, insn_push = 0x4001,
    382 	        insn_pop = 0x4002, insn_pushregs = 0x4003,
    383 	        insn_popregs = 0x4004, insn_pushflags = 0x4005,
    384 	        insn_popflags = 0x4006, insn_enter = 0x4007,
    385 	        insn_leave = 0x4008, insn_test = 0x5001,
    386 	        insn_cmp = 0x5002, insn_mov = 0x6001,
    387 	        insn_movcc = 0x6002, insn_xchg = 0x6003,
    388 	        insn_xchgcc = 0x6004, insn_strcmp = 0x7001,
    389 	        insn_strload = 0x7002, insn_strmov = 0x7003,
    390 	        insn_strstore = 0x7004, insn_translate = 0x7005,
    391 	        insn_bittest = 0x8001, insn_bitset = 0x8002,
    392 	        insn_bitclear = 0x8003, insn_clear_carry = 0x9001,
    393 	        insn_clear_zero = 0x9002, insn_clear_oflow = 0x9003,
    394 	        insn_clear_dir = 0x9004, insn_clear_sign = 0x9005,
    395 	        insn_clear_parity = 0x9006, insn_set_carry = 0x9007,
    396 	        insn_set_zero = 0x9008, insn_set_oflow = 0x9009,
    397 	        insn_set_dir = 0x900A, insn_set_sign = 0x900B,
    398 	        insn_set_parity = 0x900C, insn_tog_carry = 0x9010,
    399 	        insn_tog_zero = 0x9020, insn_tog_oflow = 0x9030,
    400 	        insn_tog_dir = 0x9040, insn_tog_sign = 0x9050,
    401 	        insn_tog_parity = 0x9060, insn_fmov = 0xA001,
    402 	        insn_fmovcc = 0xA002, insn_fneg = 0xA003,
    403 	       	insn_fabs = 0xA004, insn_fadd = 0xA005,
    404 	        insn_fsub = 0xA006, insn_fmul = 0xA007,
    405 	        insn_fdiv = 0xA008, insn_fsqrt = 0xA009,
    406 	        insn_fcmp = 0xA00A, insn_fcos = 0xA00C,
    407 	        insn_fldpi = 0xA00D, insn_fldz = 0xA00E,
    408 	        insn_ftan = 0xA00F, insn_fsine = 0xA010,
    409 	        insn_fsys = 0xA020, insn_int = 0xD001,
    410 	        insn_intcc = 0xD002,   insn_iret = 0xD003,
    411 	        insn_bound = 0xD004, insn_debug = 0xD005,
    412 	        insn_trace = 0xD006, insn_invalid_op = 0xD007,
    413 	        insn_oflow = 0xD008, insn_halt = 0xE001,
    414 	        insn_in = 0xE002, insn_out = 0xE003,
    415 	        insn_cpuid = 0xE004, insn_nop = 0xF001,
    416 	        insn_bcdconv = 0xF002, insn_szconv = 0xF003
    417 	};
    418 
    419 	enum x86_insn_note {
    420 		insn_note_ring0		= 1,
    421 		insn_note_smm		= 2,
    422 		insn_note_serial	= 4
    423 	};
    424 
    425 	enum x86_flag_status {
    426 	        insn_carry_set = 0x1,
    427 	        insn_zero_set = 0x2,
    428 	        insn_oflow_set = 0x4,
    429 	        insn_dir_set = 0x8,
    430 	        insn_sign_set = 0x10,
    431 	        insn_parity_set = 0x20,
    432 	        insn_carry_or_zero_set = 0x40,
    433 	        insn_zero_set_or_sign_ne_oflow = 0x80,
    434 	        insn_carry_clear = 0x100,
    435 	        insn_zero_clear = 0x200,
    436 	        insn_oflow_clear = 0x400,
    437 	        insn_dir_clear = 0x800,
    438 	        insn_sign_clear = 0x1000,
    439 	        insn_parity_clear = 0x2000,
    440 	        insn_sign_eq_oflow = 0x4000,
    441 	        insn_sign_ne_oflow = 0x8000
    442 	};
    443 
    444 	enum x86_insn_cpu {
    445 		cpu_8086 	= 1, cpu_80286	= 2,
    446 		cpu_80386	= 3, cpu_80387	= 4,
    447 		cpu_80486	= 5, cpu_pentium	= 6,
    448 		cpu_pentiumpro	= 7, cpu_pentium2	= 8,
    449 		cpu_pentium3	= 9, cpu_pentium4	= 10,
    450 		cpu_k6		= 16, cpu_k7		= 32,
    451 		cpu_athlon	= 48
    452 	};
    453 
    454 	enum x86_insn_isa {
    455 		isa_gp		= 1, isa_fp		= 2,
    456 		isa_fpumgt	= 3, isa_mmx		= 4,
    457 		isa_sse1	= 5, isa_sse2	= 6,
    458 		isa_sse3	= 7, isa_3dnow	= 8,
    459 		isa_sys		= 9
    460 	};
    461 
    462 	enum x86_insn_prefix {
    463 	        insn_no_prefix = 0,
    464 	        insn_rep_zero = 1,
    465 	        insn_rep_notzero = 2,
    466 	        insn_lock = 4
    467 	};
    468 
    469 
    470 	typedef struct {
    471         	unsigned long addr;
    472 	        unsigned long offset;
    473 	        enum x86_insn_group group;
    474 	        enum x86_insn_type type;
    475 		enum x86_insn_note note;
    476 	        unsigned char bytes[MAX_INSN_SIZE];
    477 	        unsigned char size;
    478 		unsigned char addr_size;
    479 		unsigned char op_size;
    480 		enum x86_insn_cpu cpu;
    481 		enum x86_insn_isa isa;
    482 	        enum x86_flag_status flags_set;
    483 	        enum x86_flag_status flags_tested;
    484 		unsigned char stack_mod;
    485 		long stack_mod_val;
    486 	        enum x86_insn_prefix prefix;
    487 	        char prefix_string[MAX_PREFIX_STR];
    488 	        char mnemonic[MAX_MNEM_STR];
    489 	        x86_oplist_t *operands;
    490 		size_t operand_count;
    491 		size_t explicit_count;
    492 	        void *block;
    493 	        void *function;
    494 	        int tag;
    495 	} x86_insn_t;
    496 
    497 	typedef void (*x86_operand_fn)(x86_op_t *op, x86_insn_t *insn,
    498 		      void *arg);
    499 
    500 	enum x86_op_foreach_type {
    501 		op_any 	= 0,
    502 		op_dest = 1,
    503 		op_src 	= 2,
    504 		op_ro 	= 3,
    505 		op_wo 	= 4,
    506 		op_xo 	= 5,
    507 		op_rw 	= 6,
    508 		op_implicit = 0x10,
    509 		op_explicit = 0x20
    510 	};
    511 
    512 	size_t x86_operand_count( x86_insn_t *insn,
    513 				enum x86_op_foreach_type type );
    514 	x86_op_t * x86_operand_1st( x86_insn_t *insn );
    515 	x86_op_t * x86_operand_2nd( x86_insn_t *insn );
    516 	x86_op_t * x86_operand_3rd( x86_insn_t *insn );
    517 	long x86_get_rel_offset( x86_insn_t *insn );
    518 	x86_op_t * x86_get_branch_target( x86_insn_t *insn );
    519 	x86_op_t * x86_get_imm( x86_insn_t *insn );
    520 	unsigned char * x86_get_raw_imm( x86_insn_t *insn );
    521 	void x86_set_insn_addr( x86_insn_t *insn, unsigned long addr );
    522 	int x86_format_mnemonic(x86_insn_t *insn, char *buf, int len,
    523                         enum x86_asm_format format);
    524 	int x86_format_insn(x86_insn_t *insn, char *buf, int len,
    525 				enum x86_asm_format);
    526 	void x86_oplist_free( x86_insn_t *insn );
    527 	int x86_insn_is_valid( x86_insn_t *insn );
    528 %}
    529 
    530 %extend x86_insn_t {
    531 	x86_insn_t() {
    532 		x86_insn_t *insn = (x86_insn_t *)
    533 				   calloc( sizeof(x86_insn_t), 1 );
    534 		return insn;
    535 	}
    536 	~x86_insn_t() {
    537 		x86_oplist_free( self );
    538 		free( self );
    539 	}
    540 
    541 	int is_valid( ) {
    542 		return x86_insn_is_valid( self );
    543 	}
    544 
    545 	x86_op_t * operand_1st() {
    546 		return x86_operand_1st( self );
    547 	}
    548 
    549 	x86_op_t * operand_2nd() {
    550 		return x86_operand_2nd( self );
    551 	}
    552 
    553 	x86_op_t * operand_3rd() {
    554 		return x86_operand_3rd( self );
    555 	}
    556 
    557 	x86_op_t * operand_dest() {
    558 		return x86_operand_1st( self );
    559 	}
    560 
    561 	x86_op_t * operand_src() {
    562 		return x86_operand_2nd( self );
    563 	}
    564 
    565 	size_t num_operands( enum x86_op_foreach_type type ) {
    566 		return x86_operand_count( self, type );
    567 	}
    568 
    569 	long rel_offset() {
    570 		return x86_get_rel_offset( self );
    571 	}
    572 
    573 	x86_op_t * branch_target() {
    574 		return x86_get_branch_target( self );
    575 	}
    576 
    577 	x86_op_t * imm() {
    578 		return x86_get_imm( self );
    579 	}
    580 
    581 	unsigned char * raw_imm() {
    582 		return x86_get_raw_imm( self );
    583 	}
    584 
    585 	%newobject format;
    586 	char * format( enum x86_asm_format format ) {
    587 		char *buf, *str;
    588 		size_t len;
    589 
    590 		switch ( format ) {
    591 			case xml_syntax:
    592 				len = MAX_INSN_XML_STRING;
    593 				break;
    594 			case raw_syntax:
    595 				len = MAX_INSN_RAW_STRING;
    596 				break;
    597 			case native_syntax:
    598 			case intel_syntax:
    599 			case att_syntax:
    600 			case unknown_syntax:
    601 			default:
    602 				len = MAX_INSN_STRING;
    603 				break;
    604 		}
    605 
    606 		buf = (char * ) calloc( len + 1, 1 );
    607 		x86_format_insn( self, buf, len, format );
    608 
    609 		/* drop buffer down to a reasonable size */
    610 		str = strdup( buf );
    611 		free(buf);
    612 		return str;
    613 	}
    614 
    615 	%newobject format_mnemonic;
    616 	char * format_mnemonic( enum x86_asm_format format ) {
    617 		char *buf, *str;
    618 		size_t len = MAX_MNEM_STR + MAX_PREFIX_STR + 4;
    619 
    620 		buf = (char * ) calloc( len, 1 );
    621 		x86_format_mnemonic( self, buf, len, format );
    622 
    623 		/* drop buffer down to a reasonable size */
    624 		str = strdup( buf );
    625 		free(buf);
    626 
    627 		return str;
    628 	}
    629 
    630 	%newobject copy;
    631 	x86_insn_t * copy() {
    632 		x86_oplist_t *ptr, *list, *last = NULL;
    633 		x86_insn_t *insn = (x86_insn_t *)
    634 				   calloc( sizeof(x86_insn_t), 1 );
    635 
    636 		if ( insn ) {
    637 			memcpy( insn, self, sizeof(x86_insn_t) );
    638 			insn->operands = NULL;
    639 			insn->block = NULL;
    640 			insn->function = NULL;
    641 
    642 			/* copy operand list */
    643 			for ( list = self->operands; list; list = list->next ) {
    644 				ptr = x86_oplist_node_copy( list );
    645 
    646 				if (! ptr ) {
    647 					continue;
    648 				}
    649 
    650 				if ( insn->operands ) {
    651 					last->next = ptr;
    652 				} else {
    653 					insn->operands = ptr;
    654 				}
    655 				last = ptr;
    656 			}
    657 		}
    658 
    659 		return insn;
    660 	}
    661 
    662 	X86_OpList * operand_list( ) {
    663 		x86_oplist_t *list = self->operands;
    664 		X86_OpList *op_list = new_X86_OpList();
    665 
    666 		for ( list = self->operands; list; list = list->next ) {
    667 			X86_OpList_append( op_list, &list->op );
    668 		}
    669 
    670 		return op_list;
    671 	}
    672 }
    673 
    674 /* ================================================================== */
    675 /* invariant instruction class */
    676 %inline %{
    677 	#define X86_WILDCARD_BYTE 0xF4
    678 
    679 	typedef struct {
    680         	enum x86_op_type        type;
    681         	enum x86_op_datatype    datatype;
    682         	enum x86_op_access      access;
    683         	enum x86_op_flags       flags;
    684 	} x86_invariant_op_t;
    685 
    686 	typedef struct {
    687 		unsigned char bytes[64];
    688 		unsigned int  size;
    689         	enum x86_insn_group group;
    690         	enum x86_insn_type type;
    691 		x86_invariant_op_t operands[3];
    692 	} x86_invariant_t;
    693 %}
    694 
    695 %extend x86_invariant_t {
    696 
    697 	x86_invariant_t() {
    698 		x86_invariant_t *inv = (x86_invariant_t *)
    699 				calloc( sizeof(x86_invariant_t), 1 );
    700 		return inv;
    701 	}
    702 
    703 	~x86_invariant_t() {
    704 		free( self );
    705 	}
    706 }
    707 
    708 /* ================================================================== */
    709 /* instruction list class */
    710 %inline %{
    711 	typedef struct X86_InsnListNode {
    712 		x86_insn_t *insn;
    713 		struct X86_InsnListNode *next, *prev;
    714 	} X86_InsnListNode;
    715 
    716 	typedef struct X86_InsnList {
    717 		size_t count;
    718 		X86_InsnListNode *head, *tail, *curr;
    719 	} X86_InsnList;
    720 %}
    721 
    722 %extend X86_InsnList {
    723 	X86_InsnList () {
    724 		X86_InsnList *list = (X86_InsnList *)
    725 				calloc( sizeof(X86_InsnList), 1 );
    726 		list->count = 0;
    727 		return list;
    728 	}
    729 
    730 	~X86_InsnList() {
    731 		X86_InsnListNode *node, *next;
    732 
    733 		node = self->head;
    734 		while ( node ) {
    735 			next = node->next;
    736 			/* free( node->insn ); */
    737 			free( node );
    738 			node = next;
    739 		}
    740 
    741 		free( self );
    742 	}
    743 
    744 	X86_InsnListNode * first() { return self->head; }
    745 
    746 	X86_InsnListNode * last() { return self->tail; }
    747 
    748 	X86_InsnListNode * next() {
    749 		if (! self->curr ) {
    750 			self->curr = self->head;
    751 			return self->head;
    752 		}
    753 
    754 		self->curr = self->curr->next;
    755 		return self->curr;
    756 	}
    757 
    758 	X86_InsnListNode * prev() {
    759 		if (! self->curr ) {
    760 			self->curr = self->tail;
    761 			return self->tail;
    762 		}
    763 
    764 		self->curr = self->curr->prev;
    765 		return self->curr;
    766 	}
    767 
    768 	%newobject append;
    769 	void append( x86_insn_t *insn ) {
    770 		X86_InsnListNode *node = (X86_InsnListNode *)
    771 					calloc( sizeof(X86_InsnListNode) , 1 );
    772 		if (! node ) {
    773 			return;
    774 		}
    775 
    776 		self->count++;
    777 		if ( ! self->tail ) {
    778 			self->head = self->tail = node;
    779 		} else {
    780 			self->tail->next = node;
    781 			node->prev = self->tail;
    782 			self->tail = node;
    783 		}
    784 
    785 		node->insn = x86_insn_t_copy( insn );
    786 	}
    787 }
    788 
    789 /* ================================================================== */
    790 /* address table class */
    791 /* slight TODO */
    792 
    793 /* ================================================================== */
    794 /* Main disassembler class */
    795 %inline %{
    796 
    797 	enum x86_options {
    798 		opt_none= 0,
    799 		opt_ignore_nulls=1,
    800 		opt_16_bit=2
    801 		};
    802 	enum x86_report_codes {
    803         	report_disasm_bounds,
    804         	report_insn_bounds,
    805         	report_invalid_insn,
    806         	report_unknown
    807 	};
    808 
    809 
    810 	typedef struct {
    811 		enum x86_report_codes last_error;
    812 		void * last_error_data;
    813 		void * disasm_callback;
    814 		void * disasm_resolver;
    815 	} X86_Disasm;
    816 
    817 	typedef void (*DISASM_REPORTER)( enum x86_report_codes code,
    818 				 	 void *data, void *arg );
    819 	typedef void (*DISASM_CALLBACK)( x86_insn_t *insn, void * arg );
    820 	typedef long (*DISASM_RESOLVER)( x86_op_t *op,
    821 					 x86_insn_t * current_insn,
    822 				 	 void *arg );
    823 
    824 	void x86_report_error( enum x86_report_codes code, void *data );
    825 	int x86_init( enum x86_options options, DISASM_REPORTER reporter,
    826 		      void *arg);
    827 	void x86_set_reporter( DISASM_REPORTER reporter, void *arg);
    828 	void x86_set_options( enum x86_options options );
    829 	enum x86_options x86_get_options( void );
    830 	int x86_cleanup(void);
    831 	int x86_format_header( char *buf, int len, enum x86_asm_format format);
    832 	unsigned int x86_endian(void);
    833 	unsigned int x86_addr_size(void);
    834 	unsigned int x86_op_size(void);
    835 	unsigned int x86_word_size(void);
    836 	unsigned int x86_max_insn_size(void);
    837 	unsigned int x86_sp_reg(void);
    838 	unsigned int x86_fp_reg(void);
    839 	unsigned int x86_ip_reg(void);
    840 	size_t x86_invariant_disasm( unsigned char *buf, int buf_len,
    841 			  x86_invariant_t *inv );
    842 	size_t x86_size_disasm( unsigned char *buf, unsigned int buf_len );
    843 	int x86_disasm( unsigned char *buf, unsigned int buf_len,
    844 	                unsigned long buf_rva, unsigned int offset,
    845 	                x86_insn_t * insn );
    846 	int x86_disasm_range( unsigned char *buf, unsigned long buf_rva,
    847 	                      unsigned int offset, unsigned int len,
    848 	                      DISASM_CALLBACK func, void *arg );
    849 	int x86_disasm_forward( unsigned char *buf, unsigned int buf_len,
    850 	                        unsigned long buf_rva, unsigned int offset,
    851 	                        DISASM_CALLBACK func, void *arg,
    852 	                        DISASM_RESOLVER resolver, void *r_arg );
    853 
    854 	void x86_default_reporter( enum x86_report_codes code,
    855 				   void *data, void *arg ) {
    856 		X86_Disasm *dis = (X86_Disasm *) arg;
    857 		if ( dis ) {
    858 			dis->last_error = code;
    859 			dis->last_error_data = data;
    860 		}
    861 	}
    862 
    863 	void x86_default_callback( x86_insn_t *insn, void *arg ) {
    864 		X86_InsnList *list = (X86_InsnList *) arg;
    865 		if ( list ) {
    866 			X86_InsnList_append( list, insn );
    867 		}
    868 	}
    869 
    870 	/* TODO: resolver stack, maybe a callback */
    871 	long x86_default_resolver( x86_op_t *op, x86_insn_t *insn, void *arg ) {
    872 		X86_Disasm *dis = (X86_Disasm *) arg;
    873 		if ( dis ) {
    874 			//return dis->resolver( op, insn );
    875 			return 0;
    876 		}
    877 
    878 		return 0;
    879 	}
    880 
    881 %}
    882 
    883 %extend X86_Disasm {
    884 
    885 	X86_Disasm( ) {
    886 		X86_Disasm * dis = (X86_Disasm *)
    887 				calloc( sizeof( X86_Disasm ), 1 );
    888 		x86_init( opt_none, x86_default_reporter, dis );
    889 		return dis;
    890 	}
    891 
    892 	X86_Disasm( enum x86_options options ) {
    893 		X86_Disasm * dis = (X86_Disasm *)
    894 				calloc( sizeof( X86_Disasm ), 1 );
    895 		x86_init( options, x86_default_reporter, dis );
    896 		return dis;
    897 	}
    898 
    899 	X86_Disasm( enum x86_options options, DISASM_REPORTER reporter ) {
    900 		X86_Disasm * dis = (X86_Disasm *)
    901 				calloc( sizeof( X86_Disasm ), 1 );
    902 		x86_init( options, reporter, NULL );
    903 		return dis;
    904 	}
    905 
    906 	X86_Disasm( enum x86_options options, DISASM_REPORTER reporter,
    907 		    void * arg ) {
    908 		X86_Disasm * dis = (X86_Disasm *)
    909 				calloc( sizeof( X86_Disasm ), 1 );
    910 		x86_init( options, reporter, arg );
    911 		return dis;
    912 	}
    913 
    914 	~X86_Disasm() {
    915 		x86_cleanup();
    916 		free( self );
    917 	}
    918 
    919 	void set_options( enum x86_options options ) {
    920 		return x86_set_options( options );
    921 	}
    922 
    923 	enum x86_options options() {
    924 		return x86_get_options();
    925 	}
    926 
    927 	void set_callback( void * callback ) {
    928 		self->disasm_callback = callback;
    929 	}
    930 
    931 	void set_resolver( void * callback ) {
    932 		self->disasm_resolver = callback;
    933 	}
    934 
    935 	void report_error( enum x86_report_codes code ) {
    936 		x86_report_error( code, NULL );
    937 	}
    938 
    939 	%newobject disasm;
    940 	x86_insn_t * disasm( unsigned char *buf, size_t buf_len,
    941 		           unsigned long buf_rva, unsigned int offset ) {
    942 		x86_insn_t *insn = calloc( sizeof( x86_insn_t ), 1 );
    943 		x86_disasm( buf, buf_len, buf_rva, offset, insn );
    944 		return insn;
    945 	}
    946 
    947 	int disasm_range( unsigned char *buf, size_t buf_len,
    948 	              unsigned long buf_rva, unsigned int offset,
    949 		      unsigned int len ) {
    950 
    951 		X86_InsnList *list = new_X86_InsnList();
    952 
    953 		if ( len > buf_len ) {
    954 			len = buf_len;
    955 		}
    956 
    957 		return x86_disasm_range( buf, buf_rva, offset, len,
    958 				x86_default_callback, list );
    959 	}
    960 
    961 	int disasm_forward( unsigned char *buf, size_t buf_len,
    962 			    unsigned long buf_rva, unsigned int offset ) {
    963 		X86_InsnList *list = new_X86_InsnList();
    964 
    965 		/* use default resolver: damn SWIG callbacks! */
    966 		return x86_disasm_forward( buf, buf_len, buf_rva, offset,
    967 			                   x86_default_callback, list,
    968 					   x86_default_resolver, NULL );
    969 	}
    970 
    971 	size_t disasm_invariant( unsigned char *buf, size_t buf_len,
    972 			  x86_invariant_t *inv ) {
    973 		return x86_invariant_disasm( buf, buf_len, inv );
    974 	}
    975 
    976 	size_t disasm_size( unsigned char *buf, size_t buf_len ) {
    977 		return x86_size_disasm( buf, buf_len );
    978 	}
    979 
    980 	%newobject format_header;
    981 	char * format_header( enum x86_asm_format format) {
    982 		char *buf, *str;
    983 		size_t len;
    984 
    985 		switch ( format ) {
    986 			/* these were obtained from x86_format.c */
    987 			case xml_syntax:
    988 				len = 679; break;
    989 			case raw_syntax:
    990 				len = 172; break;
    991 			case native_syntax:
    992 				len = 35; break;
    993 			case intel_syntax:
    994 				len = 23; break;
    995 			case att_syntax:
    996 				len = 23; break;
    997 			case unknown_syntax:
    998 			default:
    999 				len = 23; break;
   1000 		}
   1001 
   1002 		buf = (char * ) calloc( len + 1, 1 );
   1003 		x86_format_header( buf, len, format );
   1004 
   1005 		return buf;
   1006 	}
   1007 
   1008 	unsigned int endian() {
   1009 		return x86_endian();
   1010 	}
   1011 
   1012 	unsigned int addr_size() {
   1013 		return x86_addr_size();
   1014 	}
   1015 
   1016 	unsigned int op_size() {
   1017 		return x86_op_size();
   1018 	}
   1019 
   1020 	unsigned int word_size() {
   1021 		return x86_word_size();
   1022 	}
   1023 
   1024 	unsigned int max_insn_size() {
   1025 		return x86_max_insn_size();
   1026 	}
   1027 
   1028 	unsigned int sp_reg() {
   1029 		return x86_sp_reg();
   1030 	}
   1031 
   1032 	unsigned int fp_reg() {
   1033 		return x86_fp_reg();
   1034 	}
   1035 
   1036 	unsigned int ip_reg() {
   1037 		return x86_ip_reg();
   1038 	}
   1039 
   1040 	%newobject reg_from_id;
   1041 	x86_reg_t * reg_from_id( unsigned int id ) {
   1042 		x86_reg_t * reg = calloc( sizeof(x86_reg_t), 1 );
   1043 		x86_reg_from_id( id, reg );
   1044 		return reg;
   1045 	}
   1046 
   1047 	unsigned char wildcard_byte() { return X86_WILDCARD_BYTE; }
   1048 
   1049 	int max_register_string() { return MAX_REGNAME; }
   1050 
   1051 	int max_prefix_string() { return MAX_PREFIX_STR; }
   1052 
   1053 	int max_mnemonic_string() { return MAX_MNEM_STR; }
   1054 
   1055 	int max_operand_string( enum x86_asm_format format ) {
   1056 		switch ( format ) {
   1057 			case xml_syntax:
   1058 				return  MAX_OP_XML_STRING;
   1059 				break;
   1060 			case raw_syntax:
   1061 				return MAX_OP_RAW_STRING;
   1062 				break;
   1063 			case native_syntax:
   1064 			case intel_syntax:
   1065 			case att_syntax:
   1066 			case unknown_syntax:
   1067 			default:
   1068 				return MAX_OP_STRING;
   1069 				break;
   1070 		}
   1071 	}
   1072 
   1073 
   1074 	int max_insn_string( enum x86_asm_format format ) {
   1075 		switch ( format ) {
   1076 			case xml_syntax:
   1077 				return  MAX_INSN_XML_STRING;
   1078 				break;
   1079 			case raw_syntax:
   1080 				return MAX_INSN_RAW_STRING;
   1081 				break;
   1082 			case native_syntax:
   1083 			case intel_syntax:
   1084 			case att_syntax:
   1085 			case unknown_syntax:
   1086 			default:
   1087 				return MAX_INSN_STRING;
   1088 				break;
   1089 		}
   1090 	}
   1091 
   1092 	int max_num_operands( ) { return MAX_NUM_OPERANDS; }
   1093 }
   1094 
   1095 /* python callback, per the manual */
   1096 /*%typemap(python,in) PyObject *pyfunc {
   1097 	if (!PyCallable_Check($source)) {
   1098 		PyErr_SetString(PyExc_TypeError, "Need a callable object!");
   1099  		return NULL;
   1100 	}
   1101 	$target = $source;
   1102 }*/
   1103 
   1104 /* python FILE * callback, per the manual */
   1105 /*
   1106 %typemap(python,in) FILE * {
   1107   if (!PyFile_Check($source)) {
   1108       PyErr_SetString(PyExc_TypeError, "Need a file!");
   1109       return NULL;
   1110   }
   1111   $target = PyFile_AsFile($source);
   1112 }*/
   1113 
   1114 
   1115