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
version_string(void)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{
aliased_reg()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{
size()187 size_t size() {
188 return x86_operand_size( self );
189 }
format(enum x86_asm_format format)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
is_address()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
is_relative()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;
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 {
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
~X86_OpList()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
first()285 X86_OpListNode * first() {
286 self->curr = self->head;
287 return self->head;
288 }
289
last()290 X86_OpListNode * last() {
291 self->curr = self->tail;
292 return self->tail;
293 }
294
next()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
prev()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;
append(x86_op_t * op)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 %{
x86_oplist_node_copy(x86_oplist_t * list)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 {
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 }
~x86_insn_t()536 ~x86_insn_t() {
537 x86_oplist_free( self );
538 free( self );
539 }
540
is_valid()541 int is_valid( ) {
542 return x86_insn_is_valid( self );
543 }
544
operand_1st()545 x86_op_t * operand_1st() {
546 return x86_operand_1st( self );
547 }
548
operand_2nd()549 x86_op_t * operand_2nd() {
550 return x86_operand_2nd( self );
551 }
552
operand_3rd()553 x86_op_t * operand_3rd() {
554 return x86_operand_3rd( self );
555 }
556
operand_dest()557 x86_op_t * operand_dest() {
558 return x86_operand_1st( self );
559 }
560
operand_src()561 x86_op_t * operand_src() {
562 return x86_operand_2nd( self );
563 }
564
num_operands(enum x86_op_foreach_type type)565 size_t num_operands( enum x86_op_foreach_type type ) {
566 return x86_operand_count( self, type );
567 }
568
rel_offset()569 long rel_offset() {
570 return x86_get_rel_offset( self );
571 }
572
branch_target()573 x86_op_t * branch_target() {
574 return x86_get_branch_target( self );
575 }
576
imm()577 x86_op_t * imm() {
578 return x86_get_imm( self );
579 }
580
raw_imm()581 unsigned char * raw_imm() {
582 return x86_get_raw_imm( self );
583 }
584
585 %newobject format;
format(enum x86_asm_format 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;
format_mnemonic(enum x86_asm_format format)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;
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
operand_list()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
x86_invariant_t()697 x86_invariant_t() {
698 x86_invariant_t *inv = (x86_invariant_t *)
699 calloc( sizeof(x86_invariant_t), 1 );
700 return inv;
701 }
702
~x86_invariant_t()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 {
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
~X86_InsnList()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
first()744 X86_InsnListNode * first() { return self->head; }
745
last()746 X86_InsnListNode * last() { return self->tail; }
747
next()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
prev()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;
append(x86_insn_t * insn)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
x86_default_reporter(enum x86_report_codes code,void * data,void * arg)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
x86_default_callback(x86_insn_t * insn,void * arg)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 */
x86_default_resolver(x86_op_t * op,x86_insn_t * insn,void * arg)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
X86_Disasm()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
X86_Disasm(enum x86_options options)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
X86_Disasm(enum x86_options options,DISASM_REPORTER reporter)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
X86_Disasm(enum x86_options options,DISASM_REPORTER reporter,void * arg)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
~X86_Disasm()914 ~X86_Disasm() {
915 x86_cleanup();
916 free( self );
917 }
918
set_options(enum x86_options options)919 void set_options( enum x86_options options ) {
920 return x86_set_options( options );
921 }
922
options()923 enum x86_options options() {
924 return x86_get_options();
925 }
926
set_callback(void * callback)927 void set_callback( void * callback ) {
928 self->disasm_callback = callback;
929 }
930
set_resolver(void * callback)931 void set_resolver( void * callback ) {
932 self->disasm_resolver = callback;
933 }
934
report_error(enum x86_report_codes code)935 void report_error( enum x86_report_codes code ) {
936 x86_report_error( code, NULL );
937 }
938
939 %newobject disasm;
disasm(unsigned char * buf,size_t buf_len,unsigned long buf_rva,unsigned int offset)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
disasm_range(unsigned char * buf,size_t buf_len,unsigned long buf_rva,unsigned int offset,unsigned int len)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
disasm_forward(unsigned char * buf,size_t buf_len,unsigned long buf_rva,unsigned int offset)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
disasm_invariant(unsigned char * buf,size_t buf_len,x86_invariant_t * inv)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
disasm_size(unsigned char * buf,size_t buf_len)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;
format_header(enum x86_asm_format format)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
endian()1008 unsigned int endian() {
1009 return x86_endian();
1010 }
1011
addr_size()1012 unsigned int addr_size() {
1013 return x86_addr_size();
1014 }
1015
op_size()1016 unsigned int op_size() {
1017 return x86_op_size();
1018 }
1019
word_size()1020 unsigned int word_size() {
1021 return x86_word_size();
1022 }
1023
max_insn_size()1024 unsigned int max_insn_size() {
1025 return x86_max_insn_size();
1026 }
1027
sp_reg()1028 unsigned int sp_reg() {
1029 return x86_sp_reg();
1030 }
1031
fp_reg()1032 unsigned int fp_reg() {
1033 return x86_fp_reg();
1034 }
1035
ip_reg()1036 unsigned int ip_reg() {
1037 return x86_ip_reg();
1038 }
1039
1040 %newobject reg_from_id;
reg_from_id(unsigned int 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
wildcard_byte()1047 unsigned char wildcard_byte() { return X86_WILDCARD_BYTE; }
1048
max_register_string()1049 int max_register_string() { return MAX_REGNAME; }
1050
max_prefix_string()1051 int max_prefix_string() { return MAX_PREFIX_STR; }
1052
max_mnemonic_string()1053 int max_mnemonic_string() { return MAX_MNEM_STR; }
1054
max_operand_string(enum x86_asm_format format)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
max_insn_string(enum x86_asm_format format)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
max_num_operands()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