1%module x86disasm
2%{
3#include "../../libdis.h"
4#include "../../../config.h"
5%}
6
7%rename(version_string) x86_version_string;
8%include "../../libdis.h"
9#include "../../../config.h"
10
11%inline %{
12	const char * x86_version_string( void ) {
13		return PACKAGE_VERSION;
14	}
15%}
16
17%rename(report_codes) x86_report_codes;
18%rename(report_error) x86_report_error;
19%rename(options) x86_options;
20%rename(init) x86_init;
21%rename(set_reporter) x86_set_reporter;
22%rename(set_options) x86_set_options;
23%rename(options) x86_get_options;
24%rename(cleanup) x86_cleanup;
25%rename(reg_type) x86_reg_type;
26%rename(reg) x86_reg_t;
27%rename(eaddr) x86_ea_t;
28%rename(op_type) x86_op_type;
29%rename(optype_is_address) x86_optype_is_address;
30%rename(optype_is_relative) x86_optype_is_relative;
31%rename(op_datatype) x86_op_datatype;
32%rename(op_access) x86_op_access;
33%rename(op_flags) x86_op_flags;
34%rename(operand) x86_op_t;
35%rename(insn_group) x86_insn_group;
36%rename(insn_type) x86_insn_type;
37%rename(insn_note) x86_insn_note ;
38%rename(flag_status) x86_flag_status;
39%rename(insn_cpu) x86_insn_cpu ;
40%rename(insn_isa) x86_insn_isa ;
41%rename(insn_prefix) x86_insn_prefix ;
42%rename(insn) x86_insn_t;
43%rename(insn_is_valid) x86_insn_is_valid;
44%rename(i_disasm) x86_disasm;
45%rename(i_disasm_range) x86_disasm_range;
46%rename(i_disasm_forward) x86_disasm_forward;
47%rename(insn_operand_count) x86_operand_count;
48%rename(insn_operand_1st) x86_operand_1st;
49%rename(insn_operand_2nd) x86_operand_2nd;
50%rename(insn_operand_3rd) x86_operand_3rd;
51%rename(insn_dest_operand) x86_get_dest_operand;
52%rename(insn_src_operand) x86_get_src_operand;
53%rename(insn_imm_operand) x86_get_imm_operand;
54%rename(operand_size) x86_operand_size;
55%rename(insn_rel_offset) x86_get_rel_offset;
56%rename(insn_branch_target) x86_get_branch_target;
57%rename(insn_imm) x86_get_imm;
58%rename(insn_raw_imm) x86_get_raw_imm;
59%rename(insn_set_addr) x86_set_insn_addr;
60%rename(insn_set_offset) x86_set_insn_offset;
61%rename(insn_set_function) x86_set_insn_function;
62%rename(insn_set_block) x86_set_insn_block;
63%rename(insn_tag) x86_tag_insn;
64%rename(insn_untag) x86_untag_insn;
65%rename(insn_is_tagged) x86_insn_is_tagged;
66%rename(asm_format) x86_asm_format;
67%rename(operand_format) x86_format_operand;
68%rename(insn_format_mnemonic) x86_format_mnemonic;
69%rename(insn_format) x86_format_insn;
70%rename(header_format) x86_format_header;
71%rename(endian) x86_endian;
72%rename(size_default_address) x86_addr_size;
73%rename(size_default_operand) x86_op_size;
74%rename(size_machine_word) x86_word_size;
75%rename(size_max_insn) x86_max_insn_size;
76%rename(reg_sp) x86_sp_reg;
77%rename(reg_fp) x86_fp_reg;
78%rename(reg_ip) x86_ip_reg;
79%rename(reg_from_id) x86_reg_from_id;
80%rename(reg_from_alias) x86_get_aliased_reg;
81%rename(invariant_op) x86_invariant_op_t;
82%rename(invariant) x86_invariant_t;
83%rename(disasm_invariant) x86_invariant_disasm;
84%rename(disasm_size) x86_size_disasm;
85
86%include "carrays.i"
87
88%array_class( unsigned char, byteArray );
89
90
91%apply (unsigned char *STRING, int LENGTH) {
92	(unsigned char *buf, size_t buf_len)
93};
94
95
96%newobject x86_op_copy;
97%inline %{
98	x86_op_t * x86_op_copy( x86_op_t * src ) {
99		x86_op_t *op;
100
101		if (! src ) {
102			return NULL;
103		}
104
105		op = (x86_op_t *) calloc( sizeof(x86_op_t), 1 );
106		if ( op ) {
107			memcpy( op, src, sizeof(x86_op_t) );
108		}
109
110		return op;
111	}
112
113	typedef struct x86_op_list_node {
114		x86_op_t *op;
115		struct x86_op_list_node *next, *prev;
116	} x86_op_list_node;
117
118	typedef struct x86_op_list {
119		size_t count;
120		x86_op_list_node *head, *tail, *curr;
121	} x86_op_list;
122
123	x86_op_list * x86_op_list_new () {
124		x86_op_list *list = (x86_op_list *)
125				calloc( sizeof(x86_op_list), 1 );
126		list->count = 0;
127		return list;
128	}
129
130	void x86_op_list_free(x86_op_list *list) {
131		x86_op_list_node *node, *next;
132
133		node = list->head;
134		while ( node ) {
135			next = node->next;
136			/* free( node->insn ); */
137			free( node );
138			node = next;
139		}
140
141		free( list );
142	}
143
144	x86_op_list_node * x86_op_list_first(x86_op_list *list) {
145		return list->head;
146	}
147
148	x86_op_list_node * x86_op_list_last(x86_op_list *list) {
149		return list->tail;
150	}
151
152	x86_op_list_node * x86_op_list_next(x86_op_list *list) {
153		if (! list->curr ) {
154			list->curr = list->head;
155			return list->head;
156		}
157
158		list->curr = list->curr->next;
159		return list->curr;
160	}
161
162	x86_op_list_node * x86_op_list_prev(x86_op_list *list) {
163		if (! list->curr ) {
164			list->curr = list->tail;
165			return list->tail;
166		}
167
168		list->curr = list->curr->prev;
169		return list->curr;
170	}
171
172%}
173
174%newobject x86_op_list_append;
175
176%inline %{
177	void x86_op_list_append( x86_op_list * list, x86_op_t *op ) {
178		x86_op_list_node *node = (x86_op_list_node *)
179					calloc( sizeof(x86_op_list_node) , 1 );
180		if (! node ) {
181			return;
182		}
183
184		list->count++;
185		if ( ! list->tail ) {
186			list->head = list->tail = node;
187		} else {
188			list->tail->next = node;
189			node->prev = list->tail;
190			list->tail = node;
191		}
192
193		node->op = x86_op_copy( op );
194	}
195
196	x86_oplist_t * x86_op_list_node_copy( x86_oplist_t * list ) {
197		x86_oplist_t *ptr;
198		ptr = (x86_oplist_t *) calloc( sizeof(x86_oplist_t), 1 );
199		if ( ptr ) {
200			memcpy( &ptr->op, &list->op, sizeof(x86_op_t) );
201		}
202
203		return ptr;
204	}
205
206	x86_insn_t * x86_insn_new() {
207		x86_insn_t *insn = (x86_insn_t *)
208				   calloc( sizeof(x86_insn_t), 1 );
209		return insn;
210	}
211
212	void x86_insn_free( x86_insn_t *insn ) {
213		x86_oplist_free( insn );
214		free( insn );
215	}
216%}
217
218%newobject x86_insn_copy;
219
220%inline %{
221	x86_insn_t * x86_insn_copy( x86_insn_t *src) {
222		x86_oplist_t *ptr, *list, *last = NULL;
223		x86_insn_t *insn = (x86_insn_t *)
224				   calloc( sizeof(x86_insn_t), 1 );
225
226		if ( insn ) {
227			memcpy( insn, src, sizeof(x86_insn_t) );
228			insn->operands = NULL;
229			insn->block = NULL;
230			insn->function = NULL;
231
232			/* copy operand list */
233			for ( list = src->operands; list; list = list->next ) {
234				ptr = x86_op_list_node_copy( list );
235
236				if (! ptr ) {
237					continue;
238				}
239
240				if ( insn->operands ) {
241					last->next = ptr;
242				} else {
243					insn->operands = ptr;
244				}
245				last = ptr;
246			}
247		}
248
249		return insn;
250	}
251
252	x86_op_list * x86_insn_op_list( x86_insn_t *insn ) {
253		x86_oplist_t *list = insn->operands;
254		x86_op_list *op_list = x86_op_list_new();
255
256		for ( list = insn->operands; list; list = list->next ) {
257			x86_op_list_append( op_list, &list->op );
258		}
259
260		return op_list;
261	}
262
263	typedef struct x86_insn_list_node {
264		x86_insn_t *insn;
265		struct x86_insn_list_node *next, *prev;
266	} x86_insn_list_node;
267
268	typedef struct x86_insn_list {
269		size_t count;
270		x86_insn_list_node *head, *tail, *curr;
271	} x86_insn_list;
272
273%}
274
275%newobject x86_insn_list_new;
276
277%inline %{
278	x86_insn_list * x86_insn_list_new () {
279		x86_insn_list *list = (x86_insn_list *)
280				calloc( sizeof(x86_insn_list), 1 );
281		list->count = 0;
282		return list;
283	}
284
285	void x86_insn_list_free( x86_insn_list * list ) {
286		x86_insn_list_node *node, *next;
287
288		if (! list ) {
289			return;
290		}
291
292		node = list->head;
293		while ( node ) {
294			next = node->next;
295			/* free( node->insn ); */
296			free( node );
297			node = next;
298		}
299
300		free( list );
301	}
302
303	x86_insn_list_node * x86_insn_list_first( x86_insn_list *list ) {
304		if (! list ) {
305			return NULL;
306		}
307		return list->head;
308	}
309
310	x86_insn_list_node * x86_insn_list_last( x86_insn_list *list ) {
311		if (! list ) {
312			return NULL;
313		}
314		return list->tail;
315	}
316
317	x86_insn_list_node * x86_insn_list_next( x86_insn_list *list ) {
318		if (! list ) {
319			return NULL;
320		}
321		if (! list->curr ) {
322			list->curr = list->head;
323			return list->head;
324		}
325
326		list->curr = list->curr->next;
327		return list->curr;
328	}
329
330	x86_insn_list_node * x86_insn_list_prev( x86_insn_list *list ) {
331		if (! list ) {
332			return NULL;
333		}
334		if (! list->curr ) {
335			list->curr = list->tail;
336			return list->tail;
337		}
338
339		list->curr = list->curr->prev;
340		return list->curr;
341	}
342
343%}
344
345%newobject x86_insn_list_append;
346
347%inline %{
348	void x86_insn_list_append( x86_insn_list *list, x86_insn_t *insn ) {
349		x86_insn_list_node *node;
350		if (! list ) {
351			return;
352		}
353
354		node = (x86_insn_list_node *)
355					calloc( sizeof(x86_insn_list_node) , 1 );
356
357		if (! node ) {
358			return;
359		}
360
361		list->count++;
362		if ( ! list->tail ) {
363			list->head = list->tail = node;
364		} else {
365			list->tail->next = node;
366			node->prev = list->tail;
367			list->tail = node;
368		}
369
370		node->insn = x86_insn_copy( insn );
371	}
372
373	typedef struct {
374		enum x86_report_codes last_error;
375		void * last_error_data;
376		void * disasm_callback;
377		void * disasm_resolver;
378	} x86disasm;
379
380	void x86_default_reporter( enum x86_report_codes code,
381				   void *data, void *arg ) {
382		x86disasm *dis = (x86disasm *) arg;
383		if ( dis ) {
384			dis->last_error = code;
385			dis->last_error_data = data;
386		}
387	}
388
389	void x86_default_callback( x86_insn_t *insn, void *arg ) {
390		x86_insn_list *list = (x86_insn_list *) arg;
391		if ( list ) {
392			x86_insn_list_append( list, insn );
393		}
394	}
395
396	/* TODO: resolver stack, maybe a callback */
397	long x86_default_resolver( x86_op_t *op, x86_insn_t *insn, void *arg ) {
398		x86disasm *dis = (x86disasm *) arg;
399		if ( dis ) {
400			//return dis->resolver( op, insn );
401			return 0;
402		}
403
404		return 0;
405	}
406
407
408%}
409
410%newobject x86disasm_new;
411
412%inline %{
413	x86disasm * x86disasm_new ( enum x86_options options ) {
414		x86disasm * dis = (x86disasm *)
415				calloc( sizeof( x86disasm ), 1 );
416		x86_init( options, x86_default_reporter, dis );
417		return dis;
418	}
419
420	void x86disasm_free( x86disasm * dis ) {
421		x86_cleanup();
422		free( dis );
423	}
424%}
425
426%newobject x86_disasm;
427
428%inline %{
429	x86_insn_t * disasm( unsigned char *buf, size_t buf_len,
430		           unsigned long buf_rva, unsigned int offset ) {
431		x86_insn_t *insn = calloc( sizeof( x86_insn_t ), 1 );
432		x86_disasm( buf, buf_len, buf_rva, offset, insn );
433		return insn;
434	}
435
436	int disasm_range( unsigned char *buf, size_t buf_len,
437	              unsigned long buf_rva, unsigned int offset,
438		      unsigned int len ) {
439
440		x86_insn_list *list = x86_insn_list_new();
441
442		if ( len > buf_len ) {
443			len = buf_len;
444		}
445
446		return x86_disasm_range( buf, buf_rva, offset, len,
447				x86_default_callback, list );
448	}
449
450	int disasm_forward( unsigned char *buf, size_t buf_len,
451			    unsigned long buf_rva, unsigned int offset ) {
452		x86_insn_list *list = x86_insn_list_new();
453
454		/* use default resolver: damn SWIG callbacks! */
455		return x86_disasm_forward( buf, buf_len, buf_rva, offset,
456			                   x86_default_callback, list,
457					   x86_default_resolver, NULL );
458	}
459
460	size_t disasm_invariant( unsigned char *buf, size_t buf_len,
461			  x86_invariant_t *inv ) {
462		return x86_invariant_disasm( buf, buf_len, inv );
463	}
464
465	size_t disasm_size( unsigned char *buf, size_t buf_len ) {
466		return x86_size_disasm( buf, buf_len );
467	}
468
469	int x86_max_operand_string( enum x86_asm_format format ) {
470		switch ( format ) {
471			case xml_syntax:
472				return  MAX_OP_XML_STRING;
473				break;
474			case raw_syntax:
475				return MAX_OP_RAW_STRING;
476				break;
477			case native_syntax:
478			case intel_syntax:
479			case att_syntax:
480			case unknown_syntax:
481			default:
482				return MAX_OP_STRING;
483				break;
484		}
485	}
486
487
488	int x86_max_insn_string( enum x86_asm_format format ) {
489		switch ( format ) {
490			case xml_syntax:
491				return  MAX_INSN_XML_STRING;
492				break;
493			case raw_syntax:
494				return MAX_INSN_RAW_STRING;
495				break;
496			case native_syntax:
497			case intel_syntax:
498			case att_syntax:
499			case unknown_syntax:
500			default:
501				return MAX_INSN_STRING;
502				break;
503		}
504	}
505
506	int x86_max_num_operands( ) { return MAX_NUM_OPERANDS; }
507%}
508
509