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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /* udis86 - libudis86/syn-att.c
  2. *
  3. * Copyright (c) 2002-2009 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. switch(op->size) {
  40. case 16 : case 32 :
  41. ud_asmprintf(u, "*"); break;
  42. default: break;
  43. }
  44. }
  45. /* -----------------------------------------------------------------------------
  46. * gen_operand() - Generates assembly output for each operand.
  47. * -----------------------------------------------------------------------------
  48. */
  49. static void
  50. gen_operand(struct ud* u, struct ud_operand* op)
  51. {
  52. switch(op->type) {
  53. case UD_OP_CONST:
  54. ud_asmprintf(u, "$0x%x", op->lval.udword);
  55. break;
  56. case UD_OP_REG:
  57. ud_asmprintf(u, "%%%s", ud_reg_tab[op->base - UD_R_AL]);
  58. break;
  59. case UD_OP_MEM:
  60. if (u->br_far) {
  61. opr_cast(u, op);
  62. }
  63. if (u->pfx_seg) {
  64. ud_asmprintf(u, "%%%s:", ud_reg_tab[u->pfx_seg - UD_R_AL]);
  65. }
  66. if (op->offset != 0) {
  67. ud_syn_print_mem_disp(u, op, 0);
  68. }
  69. if (op->base) {
  70. ud_asmprintf(u, "(%%%s", ud_reg_tab[op->base - UD_R_AL]);
  71. }
  72. if (op->index) {
  73. if (op->base) {
  74. ud_asmprintf(u, ",");
  75. } else {
  76. ud_asmprintf(u, "(");
  77. }
  78. ud_asmprintf(u, "%%%s", ud_reg_tab[op->index - UD_R_AL]);
  79. }
  80. if (op->scale) {
  81. ud_asmprintf(u, ",%d", op->scale);
  82. }
  83. if (op->base || op->index) {
  84. ud_asmprintf(u, ")");
  85. }
  86. break;
  87. case UD_OP_IMM:
  88. ud_asmprintf(u, "$");
  89. ud_syn_print_imm(u, op);
  90. break;
  91. case UD_OP_JIMM:
  92. ud_syn_print_addr(u, ud_syn_rel_target(u, op));
  93. break;
  94. case UD_OP_PTR:
  95. switch (op->size) {
  96. case 32:
  97. ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
  98. op->lval.ptr.off & 0xFFFF);
  99. break;
  100. case 48:
  101. ud_asmprintf(u, "$0x%x, $0x%x", op->lval.ptr.seg,
  102. op->lval.ptr.off);
  103. break;
  104. }
  105. break;
  106. default: return;
  107. }
  108. }
  109. /* =============================================================================
  110. * translates to AT&T syntax
  111. * =============================================================================
  112. */
  113. extern void
  114. ud_translate_att(struct ud *u)
  115. {
  116. int size = 0;
  117. int star = 0;
  118. /* check if P_OSO prefix is used */
  119. if (! P_OSO(u->itab_entry->prefix) && u->pfx_opr) {
  120. switch (u->dis_mode) {
  121. case 16:
  122. ud_asmprintf(u, "o32 ");
  123. break;
  124. case 32:
  125. case 64:
  126. ud_asmprintf(u, "o16 ");
  127. break;
  128. }
  129. }
  130. /* check if P_ASO prefix was used */
  131. if (! P_ASO(u->itab_entry->prefix) && u->pfx_adr) {
  132. switch (u->dis_mode) {
  133. case 16:
  134. ud_asmprintf(u, "a32 ");
  135. break;
  136. case 32:
  137. ud_asmprintf(u, "a16 ");
  138. break;
  139. case 64:
  140. ud_asmprintf(u, "a32 ");
  141. break;
  142. }
  143. }
  144. if (u->pfx_lock)
  145. ud_asmprintf(u, "lock ");
  146. if (u->pfx_rep) {
  147. ud_asmprintf(u, "rep ");
  148. } else if (u->pfx_rep) {
  149. ud_asmprintf(u, "repe ");
  150. } else if (u->pfx_repne) {
  151. ud_asmprintf(u, "repne ");
  152. }
  153. /* special instructions */
  154. switch (u->mnemonic) {
  155. case UD_Iretf:
  156. ud_asmprintf(u, "lret ");
  157. break;
  158. case UD_Idb:
  159. ud_asmprintf(u, ".byte 0x%x", u->operand[0].lval.ubyte);
  160. return;
  161. case UD_Ijmp:
  162. case UD_Icall:
  163. if (u->br_far) ud_asmprintf(u, "l");
  164. if (u->operand[0].type == UD_OP_REG) {
  165. star = 1;
  166. }
  167. ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
  168. break;
  169. case UD_Ibound:
  170. case UD_Ienter:
  171. if (u->operand[0].type != UD_NONE)
  172. gen_operand(u, &u->operand[0]);
  173. if (u->operand[1].type != UD_NONE) {
  174. ud_asmprintf(u, ",");
  175. gen_operand(u, &u->operand[1]);
  176. }
  177. return;
  178. default:
  179. ud_asmprintf(u, "%s", ud_lookup_mnemonic(u->mnemonic));
  180. }
  181. if (size == 8)
  182. ud_asmprintf(u, "b");
  183. else if (size == 16)
  184. ud_asmprintf(u, "w");
  185. else if (size == 64)
  186. ud_asmprintf(u, "q");
  187. if (star) {
  188. ud_asmprintf(u, " *");
  189. } else {
  190. ud_asmprintf(u, " ");
  191. }
  192. if (u->operand[2].type != UD_NONE) {
  193. gen_operand(u, &u->operand[2]);
  194. ud_asmprintf(u, ", ");
  195. }
  196. if (u->operand[1].type != UD_NONE) {
  197. gen_operand(u, &u->operand[1]);
  198. ud_asmprintf(u, ", ");
  199. }
  200. if (u->operand[0].type != UD_NONE)
  201. gen_operand(u, &u->operand[0]);
  202. }
  203. /*
  204. vim: set ts=2 sw=2 expandtab
  205. */