Home | History | Annotate | Download | only in swig
      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