/thirdparty/breakpad/third_party/libdisasm/x86_insn.c

http://github.com/tomahawk-player/tomahawk · C · 182 lines · 146 code · 32 blank · 4 comment · 50 complexity · 9a1f1002b683b94dedb8a292c505d3b6 MD5 · raw file

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "libdis.h"
  4. #ifdef _MSC_VER
  5. #define snprintf _snprintf
  6. #define inline __inline
  7. #endif
  8. int x86_insn_is_valid( x86_insn_t *insn ) {
  9. if ( insn && insn->type != insn_invalid && insn->size > 0 ) {
  10. return 1;
  11. }
  12. return 0;
  13. }
  14. uint32_t x86_get_address( x86_insn_t *insn ) {
  15. x86_oplist_t *op_lst;
  16. if (! insn || ! insn->operands ) {
  17. return 0;
  18. }
  19. for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
  20. if ( op_lst->op.type == op_offset ) {
  21. return op_lst->op.data.offset;
  22. } else if ( op_lst->op.type == op_absolute ) {
  23. if ( op_lst->op.datatype == op_descr16 ) {
  24. return (uint32_t)
  25. op_lst->op.data.absolute.offset.off16;
  26. }
  27. return op_lst->op.data.absolute.offset.off32;
  28. }
  29. }
  30. return 0;
  31. }
  32. int32_t x86_get_rel_offset( x86_insn_t *insn ) {
  33. x86_oplist_t *op_lst;
  34. if (! insn || ! insn->operands ) {
  35. return 0;
  36. }
  37. for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
  38. if ( op_lst->op.type == op_relative_near ) {
  39. return (int32_t) op_lst->op.data.relative_near;
  40. } else if ( op_lst->op.type == op_relative_far ) {
  41. return op_lst->op.data.relative_far;
  42. }
  43. }
  44. return 0;
  45. }
  46. x86_op_t * x86_get_branch_target( x86_insn_t *insn ) {
  47. x86_oplist_t *op_lst;
  48. if (! insn || ! insn->operands ) {
  49. return NULL;
  50. }
  51. for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
  52. if ( op_lst->op.access & op_execute ) {
  53. return &(op_lst->op);
  54. }
  55. }
  56. return NULL;
  57. }
  58. x86_op_t * x86_get_imm( x86_insn_t *insn ) {
  59. x86_oplist_t *op_lst;
  60. if (! insn || ! insn->operands ) {
  61. return NULL;
  62. }
  63. for (op_lst = insn->operands; op_lst; op_lst = op_lst->next ) {
  64. if ( op_lst->op.type == op_immediate ) {
  65. return &(op_lst->op);
  66. }
  67. }
  68. return NULL;
  69. }
  70. #define IS_PROPER_IMM( x ) \
  71. x->op.type == op_immediate && ! (x->op.flags & op_hardcode)
  72. /* if there is an immediate value in the instruction, return a pointer to
  73. * it */
  74. unsigned char * x86_get_raw_imm( x86_insn_t *insn ) {
  75. int size, offset;
  76. x86_op_t *op = NULL;
  77. if (! insn || ! insn->operands ) {
  78. return(NULL);
  79. }
  80. /* a bit inelegant, but oh well... */
  81. if ( IS_PROPER_IMM( insn->operands ) ) {
  82. op = &insn->operands->op;
  83. } else if ( insn->operands->next ) {
  84. if ( IS_PROPER_IMM( insn->operands->next ) ) {
  85. op = &insn->operands->next->op;
  86. } else if ( insn->operands->next->next &&
  87. IS_PROPER_IMM( insn->operands->next->next ) ) {
  88. op = &insn->operands->next->next->op;
  89. }
  90. }
  91. if (! op ) {
  92. return( NULL );
  93. }
  94. /* immediate data is at the end of the insn */
  95. size = x86_operand_size( op );
  96. offset = insn->size - size;
  97. return( &insn->bytes[offset] );
  98. }
  99. unsigned int x86_operand_size( x86_op_t *op ) {
  100. switch (op->datatype ) {
  101. case op_byte: return 1;
  102. case op_word: return 2;
  103. case op_dword: return 4;
  104. case op_qword: return 8;
  105. case op_dqword: return 16;
  106. case op_sreal: return 4;
  107. case op_dreal: return 8;
  108. case op_extreal: return 10;
  109. case op_bcd: return 10;
  110. case op_ssimd: return 16;
  111. case op_dsimd: return 16;
  112. case op_sssimd: return 4;
  113. case op_sdsimd: return 8;
  114. case op_descr32: return 6;
  115. case op_descr16: return 4;
  116. case op_pdescr32: return 6;
  117. case op_pdescr16: return 6;
  118. case op_bounds16: return 4;
  119. case op_bounds32: return 8;
  120. case op_fpuenv16: return 14;
  121. case op_fpuenv32: return 28;
  122. case op_fpustate16: return 94;
  123. case op_fpustate32: return 108;
  124. case op_fpregset: return 512;
  125. case op_fpreg: return 10;
  126. case op_none: return 0;
  127. }
  128. return(4); /* default size */
  129. }
  130. void x86_set_insn_addr( x86_insn_t *insn, uint32_t addr ) {
  131. if ( insn ) insn->addr = addr;
  132. }
  133. void x86_set_insn_offset( x86_insn_t *insn, unsigned int offset ){
  134. if ( insn ) insn->offset = offset;
  135. }
  136. void x86_set_insn_function( x86_insn_t *insn, void * func ){
  137. if ( insn ) insn->function = func;
  138. }
  139. void x86_set_insn_block( x86_insn_t *insn, void * block ){
  140. if ( insn ) insn->block = block;
  141. }
  142. void x86_tag_insn( x86_insn_t *insn ){
  143. if ( insn ) insn->tag = 1;
  144. }
  145. void x86_untag_insn( x86_insn_t *insn ){
  146. if ( insn ) insn->tag = 0;
  147. }
  148. int x86_insn_is_tagged( x86_insn_t *insn ){
  149. return insn->tag;
  150. }