PageRenderTime 31ms CodeModel.GetById 13ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 1ms

/thirdparty/breakpad/third_party/libdisasm/swig/libdisasm_oop.i

http://github.com/tomahawk-player/tomahawk
Swig | 1114 lines | 896 code | 177 blank | 41 comment | 0 complexity | bc7986e8ded5057c0a756924976d281b MD5 | raw file
   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
  26const char * version_string( void ) {
  27	return PACKAGE_VERSION;
  28}
  29
  30%}
  31
  32const 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
  55enum 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