PageRenderTime 179ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

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