x86bc.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  1. /*
  2. * x86 bytecode utility functions
  3. *
  4. * Copyright (C) 2001-2007 Peter Johnson
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
  19. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. * POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include <util.h>
  28. #include <libyasm.h>
  29. #include "x86arch.h"
  30. /* Bytecode callback function prototypes */
  31. static void x86_bc_insn_destroy(void *contents);
  32. static void x86_bc_insn_print(const void *contents, FILE *f,
  33. int indent_level);
  34. static int x86_bc_insn_calc_len(yasm_bytecode *bc,
  35. yasm_bc_add_span_func add_span,
  36. void *add_span_data);
  37. static int x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val,
  38. long new_val, /*@out@*/ long *neg_thres,
  39. /*@out@*/ long *pos_thres);
  40. static int x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
  41. unsigned char *bufstart,
  42. void *d, yasm_output_value_func output_value,
  43. /*@null@*/ yasm_output_reloc_func output_reloc);
  44. static void x86_bc_jmp_destroy(void *contents);
  45. static void x86_bc_jmp_print(const void *contents, FILE *f, int indent_level);
  46. static int x86_bc_jmp_calc_len(yasm_bytecode *bc,
  47. yasm_bc_add_span_func add_span,
  48. void *add_span_data);
  49. static int x86_bc_jmp_expand(yasm_bytecode *bc, int span, long old_val,
  50. long new_val, /*@out@*/ long *neg_thres,
  51. /*@out@*/ long *pos_thres);
  52. static int x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp,
  53. unsigned char *bufstart,
  54. void *d, yasm_output_value_func output_value,
  55. /*@null@*/ yasm_output_reloc_func output_reloc);
  56. static void x86_bc_jmpfar_destroy(void *contents);
  57. static void x86_bc_jmpfar_print(const void *contents, FILE *f,
  58. int indent_level);
  59. static int x86_bc_jmpfar_calc_len(yasm_bytecode *bc,
  60. yasm_bc_add_span_func add_span,
  61. void *add_span_data);
  62. static int x86_bc_jmpfar_tobytes
  63. (yasm_bytecode *bc, unsigned char **bufp, unsigned char *bufstart, void *d,
  64. yasm_output_value_func output_value,
  65. /*@null@*/ yasm_output_reloc_func output_reloc);
  66. /* Bytecode callback structures */
  67. static const yasm_bytecode_callback x86_bc_callback_insn = {
  68. x86_bc_insn_destroy,
  69. x86_bc_insn_print,
  70. yasm_bc_finalize_common,
  71. NULL,
  72. x86_bc_insn_calc_len,
  73. x86_bc_insn_expand,
  74. x86_bc_insn_tobytes,
  75. 0
  76. };
  77. static const yasm_bytecode_callback x86_bc_callback_jmp = {
  78. x86_bc_jmp_destroy,
  79. x86_bc_jmp_print,
  80. yasm_bc_finalize_common,
  81. NULL,
  82. x86_bc_jmp_calc_len,
  83. x86_bc_jmp_expand,
  84. x86_bc_jmp_tobytes,
  85. 0
  86. };
  87. static const yasm_bytecode_callback x86_bc_callback_jmpfar = {
  88. x86_bc_jmpfar_destroy,
  89. x86_bc_jmpfar_print,
  90. yasm_bc_finalize_common,
  91. NULL,
  92. x86_bc_jmpfar_calc_len,
  93. yasm_bc_expand_common,
  94. x86_bc_jmpfar_tobytes,
  95. 0
  96. };
  97. int
  98. yasm_x86__set_rex_from_reg(unsigned char *rex, unsigned char *low3,
  99. uintptr_t reg, unsigned int bits,
  100. x86_rex_bit_pos rexbit)
  101. {
  102. *low3 = (unsigned char)(reg&7);
  103. if (bits == 64) {
  104. x86_expritem_reg_size size = (x86_expritem_reg_size)(reg & ~0xFUL);
  105. if (size == X86_REG8X || (reg & 0xF) >= 8) {
  106. /* Check to make sure we can set it */
  107. if (*rex == 0xff) {
  108. yasm_error_set(YASM_ERROR_TYPE,
  109. N_("cannot use A/B/C/DH with instruction needing REX"));
  110. return 1;
  111. }
  112. *rex |= 0x40 | (((reg & 8) >> 3) << rexbit);
  113. } else if (size == X86_REG8 && (reg & 7) >= 4) {
  114. /* AH/BH/CH/DH, so no REX allowed */
  115. if (*rex != 0 && *rex != 0xff) {
  116. yasm_error_set(YASM_ERROR_TYPE,
  117. N_("cannot use A/B/C/DH with instruction needing REX"));
  118. return 1;
  119. }
  120. *rex = 0xff; /* Flag so we can NEVER set it (see above) */
  121. }
  122. }
  123. return 0;
  124. }
  125. void
  126. yasm_x86__bc_transform_insn(yasm_bytecode *bc, x86_insn *insn)
  127. {
  128. yasm_bc_transform(bc, &x86_bc_callback_insn, insn);
  129. }
  130. void
  131. yasm_x86__bc_transform_jmp(yasm_bytecode *bc, x86_jmp *jmp)
  132. {
  133. yasm_bc_transform(bc, &x86_bc_callback_jmp, jmp);
  134. }
  135. void
  136. yasm_x86__bc_transform_jmpfar(yasm_bytecode *bc, x86_jmpfar *jmpfar)
  137. {
  138. yasm_bc_transform(bc, &x86_bc_callback_jmpfar, jmpfar);
  139. }
  140. void
  141. yasm_x86__ea_init(x86_effaddr *x86_ea, unsigned int spare,
  142. yasm_bytecode *precbc)
  143. {
  144. if (yasm_value_finalize(&x86_ea->ea.disp, precbc))
  145. yasm_error_set(YASM_ERROR_TOO_COMPLEX,
  146. N_("effective address too complex"));
  147. x86_ea->modrm &= 0xC7; /* zero spare/reg bits */
  148. x86_ea->modrm |= (spare << 3) & 0x38; /* plug in provided bits */
  149. }
  150. void
  151. yasm_x86__ea_set_disponly(x86_effaddr *x86_ea)
  152. {
  153. x86_ea->valid_modrm = 0;
  154. x86_ea->need_modrm = 0;
  155. x86_ea->valid_sib = 0;
  156. x86_ea->need_sib = 0;
  157. }
  158. static x86_effaddr *
  159. ea_create(void)
  160. {
  161. x86_effaddr *x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
  162. yasm_value_initialize(&x86_ea->ea.disp, NULL, 0);
  163. x86_ea->ea.need_nonzero_len = 0;
  164. x86_ea->ea.need_disp = 0;
  165. x86_ea->ea.nosplit = 0;
  166. x86_ea->ea.strong = 0;
  167. x86_ea->ea.segreg = 0;
  168. x86_ea->ea.pc_rel = 0;
  169. x86_ea->ea.not_pc_rel = 0;
  170. x86_ea->ea.data_len = 0;
  171. x86_ea->vsib_mode = 0;
  172. x86_ea->modrm = 0;
  173. x86_ea->valid_modrm = 0;
  174. x86_ea->need_modrm = 0;
  175. x86_ea->sib = 0;
  176. x86_ea->valid_sib = 0;
  177. x86_ea->need_sib = 0;
  178. return x86_ea;
  179. }
  180. x86_effaddr *
  181. yasm_x86__ea_create_reg(x86_effaddr *x86_ea, unsigned long reg,
  182. unsigned char *rex, unsigned int bits)
  183. {
  184. unsigned char rm;
  185. if (yasm_x86__set_rex_from_reg(rex, &rm, reg, bits, X86_REX_B))
  186. return NULL;
  187. if (!x86_ea)
  188. x86_ea = ea_create();
  189. x86_ea->modrm = 0xC0 | rm; /* Mod=11, R/M=Reg, Reg=0 */
  190. x86_ea->valid_modrm = 1;
  191. x86_ea->need_modrm = 1;
  192. return x86_ea;
  193. }
  194. yasm_effaddr *
  195. yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
  196. {
  197. yasm_arch_x86 *arch_x86 = (yasm_arch_x86 *)arch;
  198. x86_effaddr *x86_ea;
  199. x86_ea = ea_create();
  200. if (arch_x86->parser == X86_PARSER_GAS) {
  201. /* Need to change foo+rip into foo wrt rip (even in .intel_syntax mode).
  202. * Note this assumes a particular ordering coming from the parser
  203. * to work (it's not very smart)!
  204. */
  205. if (e->op == YASM_EXPR_ADD && e->terms[0].type == YASM_EXPR_REG
  206. && e->terms[0].data.reg == X86_RIP) {
  207. /* replace register with 0 */
  208. e->terms[0].type = YASM_EXPR_INT;
  209. e->terms[0].data.intn = yasm_intnum_create_uint(0);
  210. /* build new wrt expression */
  211. e = yasm_expr_create(YASM_EXPR_WRT, yasm_expr_expr(e),
  212. yasm_expr_reg(X86_RIP), e->line);
  213. }
  214. }
  215. yasm_value_initialize(&x86_ea->ea.disp, e, 0);
  216. x86_ea->ea.need_disp = 1;
  217. x86_ea->need_modrm = 1;
  218. /* We won't know whether we need an SIB until we know more about expr and
  219. * the BITS/address override setting.
  220. */
  221. x86_ea->need_sib = 0xff;
  222. x86_ea->ea.data_len = 0;
  223. return (yasm_effaddr *)x86_ea;
  224. }
  225. /*@-compmempass@*/
  226. x86_effaddr *
  227. yasm_x86__ea_create_imm(x86_effaddr *x86_ea, yasm_expr *imm,
  228. unsigned int im_len)
  229. {
  230. if (!x86_ea)
  231. x86_ea = ea_create();
  232. yasm_value_initialize(&x86_ea->ea.disp, imm, im_len);
  233. x86_ea->ea.need_disp = 1;
  234. return x86_ea;
  235. }
  236. /*@=compmempass@*/
  237. void
  238. yasm_x86__bc_apply_prefixes(x86_common *common, unsigned char *rex,
  239. unsigned int def_opersize_64,
  240. unsigned int num_prefixes, uintptr_t *prefixes)
  241. {
  242. unsigned int i;
  243. int first = 1;
  244. for (i=0; i<num_prefixes; i++) {
  245. switch ((x86_parse_insn_prefix)(prefixes[i] & 0xff00)) {
  246. /*To be accurate, we should enforce that TSX hints come only with a
  247. predefined set of instructions, and in most cases only with F0
  248. prefix. Otherwise they will have completely different semantics.
  249. But F0 prefix can come only with a predefined set of instructions
  250. too. And if it comes with other instructions, CPU will #UD.
  251. Hence, F0-applicability should be enforced too. But it's not
  252. currently. Maybe it is the decision made, that user should know
  253. himself what he is doing with LOCK prefix. In this case, we should
  254. not enforce TSX hints applicability too. And let user take care of
  255. correct usage of TSX hints.
  256. That is what we are going to do.*/
  257. case X86_ACQREL:
  258. if (common->acqrel_pre != 0)
  259. yasm_warn_set(YASM_WARN_GENERAL,
  260. N_("multiple XACQUIRE/XRELEASE prefixes, "
  261. "using leftmost"));
  262. common->acqrel_pre = (unsigned char)prefixes[i] & 0xff;
  263. break;
  264. case X86_LOCKREP:
  265. if (common->lockrep_pre != 0)
  266. yasm_warn_set(YASM_WARN_GENERAL,
  267. N_("multiple LOCK or REP prefixes, using leftmost"));
  268. common->lockrep_pre = (unsigned char)prefixes[i] & 0xff;
  269. break;
  270. case X86_ADDRSIZE:
  271. common->addrsize = (unsigned char)prefixes[i] & 0xff;
  272. break;
  273. case X86_OPERSIZE:
  274. common->opersize = (unsigned char)prefixes[i] & 0xff;
  275. if (common->mode_bits == 64 && common->opersize == 64 &&
  276. def_opersize_64 != 64) {
  277. if (!rex)
  278. yasm_warn_set(YASM_WARN_GENERAL,
  279. N_("ignoring REX prefix on jump"));
  280. else if (*rex == 0xff)
  281. yasm_warn_set(YASM_WARN_GENERAL,
  282. N_("REX prefix not allowed on this instruction, ignoring"));
  283. else
  284. *rex = 0x48;
  285. }
  286. break;
  287. case X86_SEGREG:
  288. /* This is a hack.. we should really be putting this in the
  289. * the effective address!
  290. */
  291. common->lockrep_pre = (unsigned char)prefixes[i] & 0xff;
  292. break;
  293. case X86_REX:
  294. if (!rex)
  295. yasm_warn_set(YASM_WARN_GENERAL,
  296. N_("ignoring REX prefix on jump"));
  297. else if (*rex == 0xff)
  298. yasm_warn_set(YASM_WARN_GENERAL,
  299. N_("REX prefix not allowed on this instruction, ignoring"));
  300. else {
  301. if (*rex != 0) {
  302. if (first)
  303. yasm_warn_set(YASM_WARN_GENERAL,
  304. N_("overriding generated REX prefix"));
  305. else
  306. yasm_warn_set(YASM_WARN_GENERAL,
  307. N_("multiple REX prefixes, using leftmost"));
  308. }
  309. /* Here we assume that we can't get this prefix in non
  310. * 64 bit mode due to checks in parse_check_prefix().
  311. */
  312. common->mode_bits = 64;
  313. *rex = (unsigned char)prefixes[i] & 0xff;
  314. }
  315. first = 0;
  316. break;
  317. }
  318. }
  319. }
  320. static void
  321. x86_bc_insn_destroy(void *contents)
  322. {
  323. x86_insn *insn = (x86_insn *)contents;
  324. if (insn->x86_ea)
  325. yasm_x86__ea_destroy((yasm_effaddr *)insn->x86_ea);
  326. if (insn->imm) {
  327. yasm_value_delete(insn->imm);
  328. yasm_xfree(insn->imm);
  329. }
  330. yasm_xfree(contents);
  331. }
  332. static void
  333. x86_bc_jmp_destroy(void *contents)
  334. {
  335. x86_jmp *jmp = (x86_jmp *)contents;
  336. yasm_value_delete(&jmp->target);
  337. yasm_xfree(contents);
  338. }
  339. static void
  340. x86_bc_jmpfar_destroy(void *contents)
  341. {
  342. x86_jmpfar *jmpfar = (x86_jmpfar *)contents;
  343. yasm_value_delete(&jmpfar->segment);
  344. yasm_value_delete(&jmpfar->offset);
  345. yasm_xfree(contents);
  346. }
  347. void
  348. yasm_x86__ea_destroy(yasm_effaddr *ea)
  349. {
  350. yasm_value_delete(&ea->disp);
  351. yasm_xfree(ea);
  352. }
  353. void
  354. yasm_x86__ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
  355. {
  356. const x86_effaddr *x86_ea = (const x86_effaddr *)ea;
  357. fprintf(f, "%*sDisp:\n", indent_level, "");
  358. yasm_value_print(&ea->disp, f, indent_level+1);
  359. fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
  360. fprintf(f, "%*sSegmentOv=%02x\n", indent_level, "",
  361. (unsigned int)x86_ea->ea.segreg);
  362. fprintf(f, "%*sVSIBMode=%u\n", indent_level, "",
  363. (unsigned int)x86_ea->vsib_mode);
  364. fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n", indent_level, "",
  365. (unsigned int)x86_ea->modrm, (unsigned int)x86_ea->valid_modrm,
  366. (unsigned int)x86_ea->need_modrm);
  367. fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n", indent_level, "",
  368. (unsigned int)x86_ea->sib, (unsigned int)x86_ea->valid_sib,
  369. (unsigned int)x86_ea->need_sib);
  370. }
  371. static void
  372. x86_common_print(const x86_common *common, FILE *f, int indent_level)
  373. {
  374. fprintf(f, "%*sAddrSize=%u OperSize=%u LockRepPre=%02x "
  375. "ACQREL_Pre=%02x BITS=%u\n",
  376. indent_level, "",
  377. (unsigned int)common->addrsize,
  378. (unsigned int)common->opersize,
  379. (unsigned int)common->lockrep_pre,
  380. (unsigned int)common->acqrel_pre,
  381. (unsigned int)common->mode_bits);
  382. }
  383. static void
  384. x86_opcode_print(const x86_opcode *opcode, FILE *f, int indent_level)
  385. {
  386. fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level, "",
  387. (unsigned int)opcode->opcode[0],
  388. (unsigned int)opcode->opcode[1],
  389. (unsigned int)opcode->opcode[2],
  390. (unsigned int)opcode->len);
  391. }
  392. static void
  393. x86_bc_insn_print(const void *contents, FILE *f, int indent_level)
  394. {
  395. const x86_insn *insn = (const x86_insn *)contents;
  396. fprintf(f, "%*s_Instruction_\n", indent_level, "");
  397. fprintf(f, "%*sEffective Address:", indent_level, "");
  398. if (insn->x86_ea) {
  399. fprintf(f, "\n");
  400. yasm_x86__ea_print((yasm_effaddr *)insn->x86_ea, f, indent_level+1);
  401. } else
  402. fprintf(f, " (nil)\n");
  403. fprintf(f, "%*sImmediate Value:", indent_level, "");
  404. if (!insn->imm)
  405. fprintf(f, " (nil)\n");
  406. else {
  407. indent_level++;
  408. fprintf(f, "\n");
  409. yasm_value_print(insn->imm, f, indent_level);
  410. indent_level--;
  411. }
  412. x86_opcode_print(&insn->opcode, f, indent_level);
  413. x86_common_print(&insn->common, f, indent_level);
  414. fprintf(f, "%*sSpPre=%02x REX=%03o PostOp=%u\n", indent_level, "",
  415. (unsigned int)insn->special_prefix,
  416. (unsigned int)insn->rex,
  417. (unsigned int)insn->postop);
  418. }
  419. static void
  420. x86_bc_jmp_print(const void *contents, FILE *f, int indent_level)
  421. {
  422. const x86_jmp *jmp = (const x86_jmp *)contents;
  423. fprintf(f, "%*s_Jump_\n", indent_level, "");
  424. fprintf(f, "%*sTarget:\n", indent_level, "");
  425. yasm_value_print(&jmp->target, f, indent_level+1);
  426. /* FIXME
  427. fprintf(f, "%*sOrigin=\n", indent_level, "");
  428. yasm_symrec_print(jmp->origin, f, indent_level+1);
  429. */
  430. fprintf(f, "\n%*sShort Form:\n", indent_level, "");
  431. if (jmp->shortop.len == 0)
  432. fprintf(f, "%*sNone\n", indent_level+1, "");
  433. else
  434. x86_opcode_print(&jmp->shortop, f, indent_level+1);
  435. fprintf(f, "%*sNear Form:\n", indent_level, "");
  436. if (jmp->nearop.len == 0)
  437. fprintf(f, "%*sNone\n", indent_level+1, "");
  438. else
  439. x86_opcode_print(&jmp->nearop, f, indent_level+1);
  440. fprintf(f, "%*sOpSel=", indent_level, "");
  441. switch (jmp->op_sel) {
  442. case JMP_NONE:
  443. fprintf(f, "None");
  444. break;
  445. case JMP_SHORT:
  446. fprintf(f, "Short");
  447. break;
  448. case JMP_NEAR:
  449. fprintf(f, "Near");
  450. break;
  451. case JMP_SHORT_FORCED:
  452. fprintf(f, "Forced Short");
  453. break;
  454. case JMP_NEAR_FORCED:
  455. fprintf(f, "Forced Near");
  456. break;
  457. default:
  458. fprintf(f, "UNKNOWN!!");
  459. break;
  460. }
  461. x86_common_print(&jmp->common, f, indent_level);
  462. }
  463. static void
  464. x86_bc_jmpfar_print(const void *contents, FILE *f, int indent_level)
  465. {
  466. const x86_jmpfar *jmpfar = (const x86_jmpfar *)contents;
  467. fprintf(f, "%*s_Far_Jump_\n", indent_level, "");
  468. fprintf(f, "%*sSegment:\n", indent_level, "");
  469. yasm_value_print(&jmpfar->segment, f, indent_level+1);
  470. fprintf(f, "%*sOffset:\n", indent_level, "");
  471. yasm_value_print(&jmpfar->offset, f, indent_level+1);
  472. x86_opcode_print(&jmpfar->opcode, f, indent_level);
  473. x86_common_print(&jmpfar->common, f, indent_level);
  474. }
  475. static unsigned int
  476. x86_common_calc_len(const x86_common *common)
  477. {
  478. unsigned int len = 0;
  479. if (common->addrsize != 0 && common->addrsize != common->mode_bits)
  480. len++;
  481. if (common->opersize != 0 &&
  482. ((common->mode_bits != 64 && common->opersize != common->mode_bits) ||
  483. (common->mode_bits == 64 && common->opersize == 16)))
  484. len++;
  485. if (common->lockrep_pre != 0)
  486. len++;
  487. if (common->acqrel_pre != 0)
  488. len++;
  489. return len;
  490. }
  491. static int
  492. x86_bc_insn_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
  493. void *add_span_data)
  494. {
  495. x86_insn *insn = (x86_insn *)bc->contents;
  496. x86_effaddr *x86_ea = insn->x86_ea;
  497. yasm_value *imm = insn->imm;
  498. if (x86_ea) {
  499. /* Check validity of effective address and calc R/M bits of
  500. * Mod/RM byte and SIB byte. We won't know the Mod field
  501. * of the Mod/RM byte until we know more about the
  502. * displacement.
  503. */
  504. if (yasm_x86__expr_checkea(x86_ea, &insn->common.addrsize,
  505. insn->common.mode_bits, insn->postop == X86_POSTOP_ADDRESS16,
  506. &insn->rex, bc))
  507. /* failed, don't bother checking rest of insn */
  508. return -1;
  509. if (x86_ea->ea.disp.size == 0 && x86_ea->ea.need_nonzero_len) {
  510. /* Handle unknown case, default to byte-sized and set as
  511. * critical expression.
  512. */
  513. x86_ea->ea.disp.size = 8;
  514. add_span(add_span_data, bc, 1, &x86_ea->ea.disp, -128, 127);
  515. }
  516. bc->len += x86_ea->ea.disp.size/8;
  517. /* Handle address16 postop case */
  518. if (insn->postop == X86_POSTOP_ADDRESS16)
  519. insn->common.addrsize = 0;
  520. /* Compute length of ea and add to total */
  521. bc->len += x86_ea->need_modrm + (x86_ea->need_sib ? 1:0);
  522. bc->len += (x86_ea->ea.segreg != 0) ? 1 : 0;
  523. }
  524. if (imm) {
  525. unsigned int immlen = imm->size;
  526. /* TODO: check imm->len vs. sized len from expr? */
  527. /* Handle signext_imm8 postop special-casing */
  528. if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
  529. /*@null@*/ /*@only@*/ yasm_intnum *num;
  530. num = yasm_value_get_intnum(imm, NULL, 0);
  531. if (!num) {
  532. /* Unknown; default to byte form and set as critical
  533. * expression.
  534. */
  535. immlen = 8;
  536. add_span(add_span_data, bc, 2, imm, -128, 127);
  537. } else {
  538. if (yasm_intnum_in_range(num, -128, 127)) {
  539. /* We can use the sign-extended byte form: shorten
  540. * the immediate length to 1 and make the byte form
  541. * permanent.
  542. */
  543. imm->size = 8;
  544. imm->sign = 1;
  545. immlen = 8;
  546. } else {
  547. /* We can't. Copy over the word-sized opcode. */
  548. insn->opcode.opcode[0] =
  549. insn->opcode.opcode[insn->opcode.len];
  550. insn->opcode.len = 1;
  551. }
  552. insn->postop = X86_POSTOP_NONE;
  553. yasm_intnum_destroy(num);
  554. }
  555. }
  556. bc->len += immlen/8;
  557. }
  558. /* VEX and XOP prefixes never have REX (it's embedded in the opcode).
  559. * For VEX, we can come into this function with the three byte form,
  560. * so we need to see if we can optimize to the two byte form.
  561. * We can't do it earlier, as we don't know all of the REX byte until now.
  562. */
  563. if (insn->special_prefix == 0xC4) {
  564. /* See if we can shorten the VEX prefix to its two byte form.
  565. * In order to do this, REX.X, REX.B, and REX.W/VEX.W must all be 0,
  566. * and the VEX mmmmm field must be 1.
  567. */
  568. if ((insn->opcode.opcode[0] & 0x1F) == 1 &&
  569. (insn->opcode.opcode[1] & 0x80) == 0 &&
  570. (insn->rex == 0xff || (insn->rex & 0x0B) == 0)) {
  571. insn->opcode.opcode[0] = insn->opcode.opcode[1];
  572. insn->opcode.opcode[1] = insn->opcode.opcode[2];
  573. insn->opcode.opcode[2] = 0; /* sanity */
  574. insn->opcode.len = 2;
  575. insn->special_prefix = 0xC5; /* mark as two-byte VEX */
  576. }
  577. } else if (insn->rex != 0xff && insn->rex != 0 &&
  578. insn->special_prefix != 0xC5 && insn->special_prefix != 0x8F)
  579. bc->len++;
  580. bc->len += insn->opcode.len;
  581. bc->len += x86_common_calc_len(&insn->common);
  582. bc->len += (insn->special_prefix != 0) ? 1:0;
  583. return 0;
  584. }
  585. static int
  586. x86_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
  587. /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
  588. {
  589. x86_insn *insn = (x86_insn *)bc->contents;
  590. x86_effaddr *x86_ea = insn->x86_ea;
  591. yasm_effaddr *ea = &x86_ea->ea;
  592. yasm_value *imm = insn->imm;
  593. if (ea && span == 1) {
  594. /* Change displacement length into word-sized */
  595. if (ea->disp.size == 8) {
  596. ea->disp.size = (insn->common.addrsize == 16) ? 16 : 32;
  597. x86_ea->modrm &= ~0300;
  598. x86_ea->modrm |= 0200;
  599. bc->len--;
  600. bc->len += ea->disp.size/8;
  601. }
  602. }
  603. if (imm && span == 2) {
  604. if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
  605. /* Update bc->len for new opcode and immediate size */
  606. bc->len -= insn->opcode.len;
  607. bc->len += imm->size/8;
  608. /* Change to the word-sized opcode */
  609. insn->opcode.opcode[0] = insn->opcode.opcode[insn->opcode.len];
  610. insn->opcode.len = 1;
  611. insn->postop = X86_POSTOP_NONE;
  612. }
  613. }
  614. return 0;
  615. }
  616. static int
  617. x86_bc_jmp_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
  618. void *add_span_data)
  619. {
  620. x86_jmp *jmp = (x86_jmp *)bc->contents;
  621. yasm_bytecode *target_prevbc;
  622. unsigned char opersize;
  623. /* As opersize may be 0, figure out its "real" value. */
  624. opersize = (jmp->common.opersize == 0) ?
  625. jmp->common.mode_bits : jmp->common.opersize;
  626. bc->len += x86_common_calc_len(&jmp->common);
  627. if (jmp->op_sel == JMP_NEAR_FORCED || jmp->shortop.len == 0) {
  628. if (jmp->nearop.len == 0) {
  629. yasm_error_set(YASM_ERROR_TYPE, N_("near jump does not exist"));
  630. return -1;
  631. }
  632. /* Near jump, no spans needed */
  633. if (jmp->shortop.len == 0)
  634. jmp->op_sel = JMP_NEAR;
  635. bc->len += jmp->nearop.len;
  636. bc->len += (opersize == 16) ? 2 : 4;
  637. return 0;
  638. }
  639. if (jmp->op_sel == JMP_SHORT_FORCED || jmp->nearop.len == 0) {
  640. if (jmp->shortop.len == 0) {
  641. yasm_error_set(YASM_ERROR_TYPE, N_("short jump does not exist"));
  642. return -1;
  643. }
  644. /* We want to be sure to error if we exceed short length, so
  645. * put it in as a dependent expression (falling through).
  646. */
  647. }
  648. if (jmp->target.rel
  649. && (!yasm_symrec_get_label(jmp->target.rel, &target_prevbc)
  650. || target_prevbc->section != bc->section)) {
  651. /* External or out of segment, so we can't check distance.
  652. * Allowing short jumps depends on the objfmt supporting
  653. * 8-bit relocs. While most don't, some might, so allow it here.
  654. * Otherwise default to word-sized.
  655. * The objfmt will error if not supported.
  656. */
  657. if (jmp->op_sel == JMP_SHORT_FORCED || jmp->nearop.len == 0) {
  658. if (jmp->op_sel == JMP_NONE)
  659. jmp->op_sel = JMP_SHORT;
  660. bc->len += jmp->shortop.len + 1;
  661. } else {
  662. jmp->op_sel = JMP_NEAR;
  663. bc->len += jmp->nearop.len;
  664. bc->len += (opersize == 16) ? 2 : 4;
  665. }
  666. return 0;
  667. }
  668. /* Default to short jump and generate span */
  669. if (jmp->op_sel == JMP_NONE)
  670. jmp->op_sel = JMP_SHORT;
  671. bc->len += jmp->shortop.len + 1;
  672. add_span(add_span_data, bc, 1, &jmp->target, -128+(long)bc->len,
  673. 127+(long)bc->len);
  674. return 0;
  675. }
  676. static int
  677. x86_bc_jmp_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
  678. /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
  679. {
  680. x86_jmp *jmp = (x86_jmp *)bc->contents;
  681. unsigned char opersize;
  682. if (span != 1)
  683. yasm_internal_error(N_("unrecognized span id"));
  684. /* As opersize may be 0, figure out its "real" value. */
  685. opersize = (jmp->common.opersize == 0) ?
  686. jmp->common.mode_bits : jmp->common.opersize;
  687. if (jmp->op_sel == JMP_SHORT_FORCED || jmp->nearop.len == 0) {
  688. yasm_error_set(YASM_ERROR_VALUE, N_("short jump out of range"));
  689. return -1;
  690. }
  691. if (jmp->op_sel == JMP_NEAR)
  692. yasm_internal_error(N_("trying to expand an already-near jump"));
  693. /* Upgrade to a near jump */
  694. jmp->op_sel = JMP_NEAR;
  695. bc->len -= jmp->shortop.len + 1;
  696. bc->len += jmp->nearop.len;
  697. bc->len += (opersize == 16) ? 2 : 4;
  698. return 0;
  699. }
  700. static int
  701. x86_bc_jmpfar_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
  702. void *add_span_data)
  703. {
  704. x86_jmpfar *jmpfar = (x86_jmpfar *)bc->contents;
  705. unsigned char opersize;
  706. opersize = (jmpfar->common.opersize == 0) ?
  707. jmpfar->common.mode_bits : jmpfar->common.opersize;
  708. bc->len += jmpfar->opcode.len;
  709. bc->len += 2; /* segment */
  710. bc->len += (opersize == 16) ? 2 : 4;
  711. bc->len += x86_common_calc_len(&jmpfar->common);
  712. return 0;
  713. }
  714. static void
  715. x86_common_tobytes(const x86_common *common, unsigned char **bufp,
  716. unsigned int segreg)
  717. {
  718. if (segreg != 0)
  719. YASM_WRITE_8(*bufp, (unsigned char)segreg);
  720. if (common->addrsize != 0 && common->addrsize != common->mode_bits)
  721. YASM_WRITE_8(*bufp, 0x67);
  722. if (common->opersize != 0 &&
  723. ((common->mode_bits != 64 && common->opersize != common->mode_bits) ||
  724. (common->mode_bits == 64 && common->opersize == 16)))
  725. YASM_WRITE_8(*bufp, 0x66);
  726. /*TSX hints come before lock prefix*/
  727. if (common->acqrel_pre != 0)
  728. YASM_WRITE_8(*bufp, common->acqrel_pre);
  729. if (common->lockrep_pre != 0)
  730. YASM_WRITE_8(*bufp, common->lockrep_pre);
  731. }
  732. static void
  733. x86_opcode_tobytes(const x86_opcode *opcode, unsigned char **bufp)
  734. {
  735. unsigned int i;
  736. for (i=0; i<opcode->len; i++)
  737. YASM_WRITE_8(*bufp, opcode->opcode[i]);
  738. }
  739. static int
  740. x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
  741. unsigned char *bufstart, void *d,
  742. yasm_output_value_func output_value,
  743. /*@unused@*/ yasm_output_reloc_func output_reloc)
  744. {
  745. x86_insn *insn = (x86_insn *)bc->contents;
  746. /*@null@*/ x86_effaddr *x86_ea = (x86_effaddr *)insn->x86_ea;
  747. yasm_value *imm = insn->imm;
  748. /* Prefixes */
  749. x86_common_tobytes(&insn->common, bufp,
  750. x86_ea ? (unsigned int)(x86_ea->ea.segreg>>8) : 0);
  751. if (insn->special_prefix != 0)
  752. YASM_WRITE_8(*bufp, insn->special_prefix);
  753. if (insn->special_prefix == 0xC4 || insn->special_prefix == 0x8F) {
  754. /* 3-byte VEX/XOP; merge in 1s complement of REX.R, REX.X, REX.B */
  755. insn->opcode.opcode[0] &= 0x1F;
  756. if (insn->rex != 0xff)
  757. insn->opcode.opcode[0] |= ((~insn->rex) & 0x07) << 5;
  758. /* merge REX.W via ORing; there should never be a case in which REX.W
  759. * is important when VEX.W is already set by the instruction.
  760. */
  761. if (insn->rex != 0xff && (insn->rex & 0x8) != 0)
  762. insn->opcode.opcode[1] |= 0x80;
  763. } else if (insn->special_prefix == 0xC5) {
  764. /* 2-byte VEX; merge in 1s complement of REX.R */
  765. insn->opcode.opcode[0] &= 0x7F;
  766. if (insn->rex != 0xff && (insn->rex & 0x4) == 0)
  767. insn->opcode.opcode[0] |= 0x80;
  768. /* No other REX bits should be set */
  769. if (insn->rex != 0xff && (insn->rex & 0xB) != 0)
  770. yasm_internal_error(N_("x86: REX.WXB set, but 2-byte VEX"));
  771. } else if (insn->rex != 0xff && insn->rex != 0) {
  772. if (insn->common.mode_bits != 64)
  773. yasm_internal_error(N_("x86: got a REX prefix in non-64-bit mode"));
  774. YASM_WRITE_8(*bufp, insn->rex);
  775. }
  776. /* Opcode */
  777. x86_opcode_tobytes(&insn->opcode, bufp);
  778. /* Effective address: ModR/M (if required), SIB (if required), and
  779. * displacement (if required).
  780. */
  781. if (x86_ea) {
  782. if (x86_ea->need_modrm) {
  783. if (!x86_ea->valid_modrm)
  784. yasm_internal_error(N_("invalid Mod/RM in x86 tobytes_insn"));
  785. YASM_WRITE_8(*bufp, x86_ea->modrm);
  786. }
  787. if (x86_ea->need_sib) {
  788. if (!x86_ea->valid_sib)
  789. yasm_internal_error(N_("invalid SIB in x86 tobytes_insn"));
  790. YASM_WRITE_8(*bufp, x86_ea->sib);
  791. }
  792. if (x86_ea->ea.need_disp) {
  793. unsigned int disp_len = x86_ea->ea.disp.size/8;
  794. if (x86_ea->ea.disp.ip_rel) {
  795. /* Adjust relative displacement to end of bytecode */
  796. /*@only@*/ yasm_intnum *delta;
  797. delta = yasm_intnum_create_int(-(long)bc->len);
  798. if (!x86_ea->ea.disp.abs)
  799. x86_ea->ea.disp.abs =
  800. yasm_expr_create_ident(yasm_expr_int(delta), bc->line);
  801. else
  802. x86_ea->ea.disp.abs =
  803. yasm_expr_create(YASM_EXPR_ADD,
  804. yasm_expr_expr(x86_ea->ea.disp.abs),
  805. yasm_expr_int(delta), bc->line);
  806. }
  807. if (output_value(&x86_ea->ea.disp, *bufp, disp_len,
  808. (unsigned long)(*bufp-bufstart), bc, 1, d))
  809. return 1;
  810. *bufp += disp_len;
  811. }
  812. }
  813. /* Immediate (if required) */
  814. if (imm) {
  815. unsigned int imm_len;
  816. if (insn->postop == X86_POSTOP_SIGNEXT_IMM8) {
  817. /* If we got here with this postop still set, we need to force
  818. * imm size to 8 here.
  819. */
  820. imm->size = 8;
  821. imm->sign = 1;
  822. imm_len = 1;
  823. } else
  824. imm_len = imm->size/8;
  825. if (output_value(imm, *bufp, imm_len, (unsigned long)(*bufp-bufstart),
  826. bc, 1, d))
  827. return 1;
  828. *bufp += imm_len;
  829. }
  830. return 0;
  831. }
  832. static int
  833. x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp,
  834. unsigned char *bufstart, void *d,
  835. yasm_output_value_func output_value,
  836. /*@unused@*/ yasm_output_reloc_func output_reloc)
  837. {
  838. x86_jmp *jmp = (x86_jmp *)bc->contents;
  839. unsigned char opersize;
  840. unsigned int i;
  841. /*@only@*/ yasm_intnum *delta;
  842. /* Prefixes */
  843. x86_common_tobytes(&jmp->common, bufp, 0);
  844. /* As opersize may be 0, figure out its "real" value. */
  845. opersize = (jmp->common.opersize == 0) ?
  846. jmp->common.mode_bits : jmp->common.opersize;
  847. /* Check here again to see if forms are actually legal. */
  848. switch (jmp->op_sel) {
  849. case JMP_SHORT_FORCED:
  850. case JMP_SHORT:
  851. /* 1 byte relative displacement */
  852. if (jmp->shortop.len == 0)
  853. yasm_internal_error(N_("short jump does not exist"));
  854. /* Opcode */
  855. x86_opcode_tobytes(&jmp->shortop, bufp);
  856. /* Adjust relative displacement to end of bytecode */
  857. delta = yasm_intnum_create_int(-(long)bc->len);
  858. if (!jmp->target.abs)
  859. jmp->target.abs = yasm_expr_create_ident(yasm_expr_int(delta),
  860. bc->line);
  861. else
  862. jmp->target.abs =
  863. yasm_expr_create(YASM_EXPR_ADD,
  864. yasm_expr_expr(jmp->target.abs),
  865. yasm_expr_int(delta), bc->line);
  866. jmp->target.size = 8;
  867. jmp->target.sign = 1;
  868. if (output_value(&jmp->target, *bufp, 1,
  869. (unsigned long)(*bufp-bufstart), bc, 1, d))
  870. return 1;
  871. *bufp += 1;
  872. break;
  873. case JMP_NEAR_FORCED:
  874. case JMP_NEAR:
  875. /* 2/4 byte relative displacement (depending on operand size) */
  876. if (jmp->nearop.len == 0) {
  877. yasm_error_set(YASM_ERROR_TYPE,
  878. N_("near jump does not exist"));
  879. return 1;
  880. }
  881. /* Opcode */
  882. x86_opcode_tobytes(&jmp->nearop, bufp);
  883. i = (opersize == 16) ? 2 : 4;
  884. /* Adjust relative displacement to end of bytecode */
  885. delta = yasm_intnum_create_int(-(long)bc->len);
  886. if (!jmp->target.abs)
  887. jmp->target.abs = yasm_expr_create_ident(yasm_expr_int(delta),
  888. bc->line);
  889. else
  890. jmp->target.abs =
  891. yasm_expr_create(YASM_EXPR_ADD,
  892. yasm_expr_expr(jmp->target.abs),
  893. yasm_expr_int(delta), bc->line);
  894. jmp->target.size = i*8;
  895. jmp->target.sign = 1;
  896. if (output_value(&jmp->target, *bufp, i,
  897. (unsigned long)(*bufp-bufstart), bc, 1, d))
  898. return 1;
  899. *bufp += i;
  900. break;
  901. case JMP_NONE:
  902. yasm_internal_error(N_("jump op_sel cannot be JMP_NONE in tobytes"));
  903. default:
  904. yasm_internal_error(N_("unrecognized relative jump op_sel"));
  905. }
  906. return 0;
  907. }
  908. static int
  909. x86_bc_jmpfar_tobytes(yasm_bytecode *bc, unsigned char **bufp,
  910. unsigned char *bufstart, void *d,
  911. yasm_output_value_func output_value,
  912. /*@unused@*/ yasm_output_reloc_func output_reloc)
  913. {
  914. x86_jmpfar *jmpfar = (x86_jmpfar *)bc->contents;
  915. unsigned int i;
  916. unsigned char opersize;
  917. x86_common_tobytes(&jmpfar->common, bufp, 0);
  918. x86_opcode_tobytes(&jmpfar->opcode, bufp);
  919. /* As opersize may be 0, figure out its "real" value. */
  920. opersize = (jmpfar->common.opersize == 0) ?
  921. jmpfar->common.mode_bits : jmpfar->common.opersize;
  922. /* Absolute displacement: segment and offset */
  923. i = (opersize == 16) ? 2 : 4;
  924. jmpfar->offset.size = i*8;
  925. if (output_value(&jmpfar->offset, *bufp, i,
  926. (unsigned long)(*bufp-bufstart), bc, 1, d))
  927. return 1;
  928. *bufp += i;
  929. jmpfar->segment.size = 16;
  930. if (output_value(&jmpfar->segment, *bufp, 2,
  931. (unsigned long)(*bufp-bufstart), bc, 1, d))
  932. return 1;
  933. *bufp += 2;
  934. return 0;
  935. }
  936. int
  937. yasm_x86__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
  938. unsigned char *buf, size_t destsize, size_t valsize,
  939. int shift, const yasm_bytecode *bc, int warn)
  940. {
  941. /* Write value out. */
  942. yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn);
  943. return 0;
  944. }