You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 line
6.2KB

  1. /* udis86 - libudis86/syn-intel.c
  2. *
  3. * Copyright (c) 2002-2013 Vivek Thampi
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * * Redistributions of source code must retain the above copyright notice,
  10. * this list of conditions and the following disclaimer.
  11. * * Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  16. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  17. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  19. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  21. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  22. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include "types.h"
  27. #include "extern.h"
  28. #include "decode.h"
  29. #include "itab.h"
  30. #include "syn.h"
  31. #include "udint.h"
  32. /* -----------------------------------------------------------------------------
  33. * opr_cast() - Prints an operand cast.
  34. * -----------------------------------------------------------------------------
  35. */
  36. static void
  37. opr_cast(struct ud* u, struct ud_operand* op)
  38. {
  39. if (u->br_far) {
  40. ud_asmprintf(u, "far ");
  41. }
  42. switch(op->size) {
  43. case 8: ud_asmprintf(u, "byte " ); break;
  44. case 16: ud_asmprintf(u, "word " ); break;
  45. case 32: ud_asmprintf(u, "dword "); break;
  46. case 64: ud_asmprintf(u, "qword "); break;
  47. case 80: ud_asmprintf(u, "tword "); break;
  48. default: break;
  49. }
  50. }
  51. /* -----------------------------------------------------------------------------
  52. * gen_operand() - Generates assembly output for each operand.
  53. * -----------------------------------------------------------------------------
  54. */
  55. static void gen_operand(struct ud* u, struct ud_operand* op, int syn_cast)
  56. {
  57. switch(op->type) {
  58. case UD_OP_REG:
  59. ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
  60. break;
  61. case UD_OP_MEM:
  62. if (syn_cast) {
  63. opr_cast(u, op);
  64. }
  65. ud_asmprintf(u, "[");
  66. if (u->pfx_seg) {
  67. ud_asmprintf(u, "%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
  68. }
  69. if (op->base) {
  70. ud_asmprintf(u, "%s", ud_reg_tab[op->base - UD_R_AL]);
  71. }
  72. if (op->index) {
  73. ud_asmprintf(u, "%s%s", op->base != UD_NONE? "+" : "",
  74. ud_reg_tab[op->index - UD_R_AL]);
  75. if (op->scale) {
  76. ud_asmprintf(u, "*%d", op->scale);
  77. }
  78. }
  79. if (op->offset != 0) {
  80. ud_syn_print_mem_disp(u, op, (op->base != UD_NONE ||
  81. op->index != UD_NONE) ? 1 : 0);
  82. }
  83. ud_asmprintf(u, "]");
  84. break;
  85. case UD_OP_IMM:
  86. ud_syn_print_imm(u, op);
  87. break;
  88. case UD_OP_JIMM:
  89. ud_syn_print_addr(u, ud_syn_rel_target(u, op));
  90. break;
  91. case UD_OP_PTR:
  92. switch (op->size) {
  93. case 32:
  94. ud_asmprintf(u, "word 0x%x:0x%x", op->lval.ptr.seg,
  95. op->lval.ptr.off & 0xFFFF);
  96. break;
  97. case 48:
  98. ud_asmprintf(u, "dword 0x%x:0x%x", op->lval.ptr.seg,
  99. op->lval.ptr.off);
  100. break;
  101. }
  102. break;
  103. case UD_OP_CONST:
  104. if (syn_cast) opr_cast(u, op);
  105. ud_asmprintf(u, "%d", op->lval.udword);
  106. break;
  107. default: return;
  108. }
  109. }
  110. /* =============================================================================
  111. * translates to intel syntax
  112. * =============================================================================
  113. */
  114. extern void
  115. ud_translate_intel(struct ud* u)
  116. {
  117. /* check if P_OSO prefix is used */
  118. if (!P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
  119. switch (u->dis_mode) {
  120. case 16: ud_asmprintf(u, "o32 "); break;
  121. case 32:
  122. case 64: ud_asmprintf(u, "o16 "); break;
  123. }
  124. }
  125. /* check if P_ASO prefix was used */
  126. if (!P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
  127. switch (u->dis_mode) {
  128. case 16: ud_asmprintf(u, "a32 "); break;
  129. case 32: ud_asmprintf(u, "a16 "); break;
  130. case 64: ud_asmprintf(u, "a32 "); break;
  131. }
  132. }
  133. if (u->pfx_seg &&
  134. u->operand[0].type != UD_OP_MEM &&
  135. u->operand[1].type != UD_OP_MEM ) {
  136. ud_asmprintf(u, "%s ", ud_reg_tab[u->pfx_seg - UD_R_AL]);
  137. }
  138. if (u->pfx_lock) {
  139. ud_asmprintf(u, "lock ");
  140. }
  141. if (u->pfx_rep) {
  142. ud_asmprintf(u, "rep ");
  143. } else if (u->pfx_repe) {
  144. ud_asmprintf(u, "repe ");
  145. } else if (u->pfx_repne) {
  146. ud_asmprintf(u, "repne ");
  147. }
  148. /* print the instruction mnemonic */
  149. ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
  150. if (u->operand[0].type != UD_NONE) {
  151. int cast = 0;
  152. ud_asmprintf(u, " ");
  153. if (u->operand[0].type == UD_OP_MEM) {
  154. if (u->operand[1].type == UD_OP_IMM ||
  155. u->operand[1].type == UD_OP_CONST ||
  156. u->operand[1].type == UD_NONE ||
  157. (u->operand[0].size != u->operand[1].size &&
  158. u->operand[1].type != UD_OP_REG)) {
  159. cast = 1;
  160. } else if (u->operand[1].type == UD_OP_REG &&
  161. u->operand[1].base == UD_R_CL) {
  162. switch (u->mnemonic) {
  163. case UD_Ircl:
  164. case UD_Irol:
  165. case UD_Iror:
  166. case UD_Ircr:
  167. case UD_Ishl:
  168. case UD_Ishr:
  169. case UD_Isar:
  170. cast = 1;
  171. break;
  172. default: break;
  173. }
  174. }
  175. }
  176. gen_operand(u, &u->operand[0], cast);
  177. }
  178. if (u->operand[1].type != UD_NONE) {
  179. int cast = 0;
  180. ud_asmprintf(u, ", ");
  181. if (u->operand[1].type == UD_OP_MEM &&
  182. u->operand[0].size != u->operand[1].size &&
  183. !ud_opr_is_sreg(&u->operand[0])) {
  184. cast = 1;
  185. }
  186. gen_operand(u, &u->operand[1], cast);
  187. }
  188. if (u->operand[2].type != UD_NONE) {
  189. ud_asmprintf(u, ", ");
  190. gen_operand(u, &u->operand[2], 0);
  191. }
  192. }
  193. /*
  194. vim: set ts=2 sw=2 expandtab
  195. */