bytecode.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /*
  2. * 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-stdint.h"
  29. #include "coretype.h"
  30. #include "errwarn.h"
  31. #include "intnum.h"
  32. #include "expr.h"
  33. #include "value.h"
  34. #include "symrec.h"
  35. #include "bytecode.h"
  36. void
  37. yasm_bc_set_multiple(yasm_bytecode *bc, yasm_expr *e)
  38. {
  39. if (bc->multiple)
  40. bc->multiple = yasm_expr_create_tree(bc->multiple, YASM_EXPR_MUL, e,
  41. e->line);
  42. else
  43. bc->multiple = e;
  44. }
  45. void
  46. yasm_bc_finalize_common(yasm_bytecode *bc, yasm_bytecode *prev_bc)
  47. {
  48. }
  49. int
  50. yasm_bc_calc_len_common(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
  51. void *add_span_data)
  52. {
  53. yasm_internal_error(N_("bytecode length cannot be calculated"));
  54. /*@unreached@*/
  55. return 0;
  56. }
  57. int
  58. yasm_bc_expand_common(yasm_bytecode *bc, int span, long old_val, long new_val,
  59. /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
  60. {
  61. yasm_internal_error(N_("bytecode does not have any dependent spans"));
  62. /*@unreached@*/
  63. return 0;
  64. }
  65. int
  66. yasm_bc_tobytes_common(yasm_bytecode *bc, unsigned char **buf,
  67. unsigned char *bufstart, void *d,
  68. yasm_output_value_func output_value,
  69. /*@null@*/ yasm_output_reloc_func output_reloc)
  70. {
  71. yasm_internal_error(N_("bytecode cannot be converted to bytes"));
  72. /*@unreached@*/
  73. return 0;
  74. }
  75. void
  76. yasm_bc_transform(yasm_bytecode *bc, const yasm_bytecode_callback *callback,
  77. void *contents)
  78. {
  79. if (bc->callback)
  80. bc->callback->destroy(bc->contents);
  81. bc->callback = callback;
  82. bc->contents = contents;
  83. }
  84. yasm_bytecode *
  85. yasm_bc_create_common(const yasm_bytecode_callback *callback, void *contents,
  86. unsigned long line)
  87. {
  88. yasm_bytecode *bc = yasm_xmalloc(sizeof(yasm_bytecode));
  89. bc->callback = callback;
  90. bc->section = NULL;
  91. bc->multiple = (yasm_expr *)NULL;
  92. bc->len = 0;
  93. bc->mult_int = 1;
  94. bc->line = line;
  95. bc->offset = ~0UL; /* obviously incorrect / uninitialized value */
  96. bc->symrecs = NULL;
  97. bc->contents = contents;
  98. return bc;
  99. }
  100. yasm_section *
  101. yasm_bc_get_section(yasm_bytecode *bc)
  102. {
  103. return bc->section;
  104. }
  105. void
  106. yasm_bc__add_symrec(yasm_bytecode *bc, yasm_symrec *sym)
  107. {
  108. if (!bc->symrecs) {
  109. bc->symrecs = yasm_xmalloc(2*sizeof(yasm_symrec *));
  110. bc->symrecs[0] = sym;
  111. bc->symrecs[1] = NULL;
  112. } else {
  113. /* Very inefficient implementation for large numbers of symbols. But
  114. * that would be very unusual, so use the simple algorithm instead.
  115. */
  116. size_t count = 1;
  117. while (bc->symrecs[count])
  118. count++;
  119. bc->symrecs = yasm_xrealloc(bc->symrecs,
  120. (count+2)*sizeof(yasm_symrec *));
  121. bc->symrecs[count] = sym;
  122. bc->symrecs[count+1] = NULL;
  123. }
  124. }
  125. void
  126. yasm_bc_destroy(yasm_bytecode *bc)
  127. {
  128. if (!bc)
  129. return;
  130. if (bc->callback)
  131. bc->callback->destroy(bc->contents);
  132. yasm_expr_destroy(bc->multiple);
  133. if (bc->symrecs)
  134. yasm_xfree(bc->symrecs);
  135. yasm_xfree(bc);
  136. }
  137. void
  138. yasm_bc_print(const yasm_bytecode *bc, FILE *f, int indent_level)
  139. {
  140. if (!bc->callback)
  141. fprintf(f, "%*s_Empty_\n", indent_level, "");
  142. else
  143. bc->callback->print(bc->contents, f, indent_level);
  144. fprintf(f, "%*sMultiple=", indent_level, "");
  145. if (!bc->multiple)
  146. fprintf(f, "nil (1)");
  147. else
  148. yasm_expr_print(bc->multiple, f);
  149. fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
  150. fprintf(f, "%*sLine Index=%lu\n", indent_level, "", bc->line);
  151. fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
  152. }
  153. void
  154. yasm_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
  155. {
  156. if (bc->callback)
  157. bc->callback->finalize(bc, prev_bc);
  158. if (bc->multiple) {
  159. yasm_value val;
  160. if (yasm_value_finalize_expr(&val, bc->multiple, prev_bc, 0))
  161. yasm_error_set(YASM_ERROR_TOO_COMPLEX,
  162. N_("multiple expression too complex"));
  163. else if (val.rel)
  164. yasm_error_set(YASM_ERROR_NOT_ABSOLUTE,
  165. N_("multiple expression not absolute"));
  166. /* Finalize creates NULL output if value=0, but bc->multiple is NULL
  167. * if value=1 (this difference is to make the common case small).
  168. * However, this means we need to set bc->multiple explicitly to 0
  169. * here if val.abs is NULL.
  170. */
  171. if (val.abs)
  172. bc->multiple = val.abs;
  173. else
  174. bc->multiple = yasm_expr_create_ident(
  175. yasm_expr_int(yasm_intnum_create_uint(0)), bc->line);
  176. }
  177. }
  178. /*@null@*/ yasm_intnum *
  179. yasm_calc_bc_dist(yasm_bytecode *precbc1, yasm_bytecode *precbc2)
  180. {
  181. unsigned long dist2, dist1;
  182. yasm_intnum *intn;
  183. if (precbc1->section != precbc2->section)
  184. return NULL;
  185. dist1 = yasm_bc_next_offset(precbc1);
  186. dist2 = yasm_bc_next_offset(precbc2);
  187. if (dist2 < dist1) {
  188. intn = yasm_intnum_create_uint(dist1 - dist2);
  189. yasm_intnum_calc(intn, YASM_EXPR_NEG, NULL);
  190. return intn;
  191. }
  192. dist2 -= dist1;
  193. return yasm_intnum_create_uint(dist2);
  194. }
  195. unsigned long
  196. yasm_bc_next_offset(yasm_bytecode *precbc)
  197. {
  198. return precbc->offset + precbc->len*precbc->mult_int;
  199. }
  200. int
  201. yasm_bc_elem_size(yasm_bytecode *bc)
  202. {
  203. if (!bc->callback) {
  204. yasm_internal_error(N_("got empty bytecode in yasm_bc_elem_size"));
  205. return 0;
  206. } else if (!bc->callback->elem_size)
  207. return 0;
  208. else
  209. return bc->callback->elem_size(bc);
  210. }
  211. int
  212. yasm_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
  213. void *add_span_data)
  214. {
  215. int retval = 0;
  216. bc->len = 0;
  217. if (!bc->callback)
  218. yasm_internal_error(N_("got empty bytecode in yasm_bc_calc_len"));
  219. else
  220. retval = bc->callback->calc_len(bc, add_span, add_span_data);
  221. /* Check for multiples */
  222. bc->mult_int = 1;
  223. if (bc->multiple) {
  224. /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
  225. num = yasm_expr_get_intnum(&bc->multiple, 0);
  226. if (num) {
  227. if (yasm_intnum_sign(num) < 0) {
  228. yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
  229. retval = -1;
  230. } else
  231. bc->mult_int = yasm_intnum_get_int(num);
  232. } else {
  233. if (yasm_expr__contains(bc->multiple, YASM_EXPR_FLOAT)) {
  234. yasm_error_set(YASM_ERROR_VALUE,
  235. N_("expression must not contain floating point value"));
  236. retval = -1;
  237. } else {
  238. yasm_value value;
  239. yasm_value_initialize(&value, bc->multiple, 0);
  240. add_span(add_span_data, bc, 0, &value, 0, 0);
  241. bc->mult_int = 0; /* assume 0 to start */
  242. }
  243. }
  244. }
  245. /* If we got an error somewhere along the line, clear out any calc len */
  246. if (retval < 0)
  247. bc->len = 0;
  248. return retval;
  249. }
  250. int
  251. yasm_bc_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
  252. /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
  253. {
  254. if (span == 0) {
  255. bc->mult_int = new_val;
  256. return 1;
  257. }
  258. if (!bc->callback) {
  259. yasm_internal_error(N_("got empty bytecode in yasm_bc_expand"));
  260. /*@unreached@*/
  261. return -1;
  262. } else
  263. return bc->callback->expand(bc, span, old_val, new_val, neg_thres,
  264. pos_thres);
  265. }
  266. /*@null@*/ /*@only@*/ unsigned char *
  267. yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
  268. /*@out@*/ int *gap, void *d,
  269. yasm_output_value_func output_value,
  270. /*@null@*/ yasm_output_reloc_func output_reloc)
  271. /*@sets *buf@*/
  272. {
  273. /*@only@*/ /*@null@*/ unsigned char *mybuf = NULL;
  274. unsigned char *bufstart;
  275. unsigned char *origbuf, *destbuf;
  276. long i;
  277. int error = 0;
  278. long mult;
  279. if (yasm_bc_get_multiple(bc, &mult, 1) || mult == 0) {
  280. *bufsize = 0;
  281. return NULL;
  282. }
  283. bc->mult_int = mult;
  284. /* special case for reserve bytecodes */
  285. if (bc->callback->special == YASM_BC_SPECIAL_RESERVE) {
  286. *bufsize = bc->len*bc->mult_int;
  287. *gap = 1;
  288. return NULL; /* we didn't allocate a buffer */
  289. }
  290. *gap = 0;
  291. if (*bufsize < bc->len*bc->mult_int) {
  292. mybuf = yasm_xmalloc(bc->len*bc->mult_int);
  293. destbuf = mybuf;
  294. } else
  295. destbuf = buf;
  296. bufstart = destbuf;
  297. *bufsize = bc->len*bc->mult_int;
  298. if (!bc->callback)
  299. yasm_internal_error(N_("got empty bytecode in bc_tobytes"));
  300. else for (i=0; i<bc->mult_int; i++) {
  301. origbuf = destbuf;
  302. error = bc->callback->tobytes(bc, &destbuf, bufstart, d, output_value,
  303. output_reloc);
  304. if (!error && ((unsigned long)(destbuf - origbuf) != bc->len))
  305. yasm_internal_error(
  306. N_("written length does not match optimized length"));
  307. }
  308. return mybuf;
  309. }
  310. int
  311. yasm_bc_get_multiple(yasm_bytecode *bc, long *multiple, int calc_bc_dist)
  312. {
  313. /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
  314. *multiple = 1;
  315. if (bc->multiple) {
  316. num = yasm_expr_get_intnum(&bc->multiple, calc_bc_dist);
  317. if (!num) {
  318. yasm_error_set(YASM_ERROR_VALUE,
  319. N_("could not determine multiple"));
  320. return 1;
  321. }
  322. if (yasm_intnum_sign(num) < 0) {
  323. yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative"));
  324. return 1;
  325. }
  326. *multiple = yasm_intnum_get_int(num);
  327. }
  328. return 0;
  329. }
  330. const yasm_expr *
  331. yasm_bc_get_multiple_expr(const yasm_bytecode *bc)
  332. {
  333. return bc->multiple;
  334. }
  335. yasm_insn *
  336. yasm_bc_get_insn(yasm_bytecode *bc)
  337. {
  338. if (bc->callback->special != YASM_BC_SPECIAL_INSN)
  339. return NULL;
  340. return (yasm_insn *)bc->contents;
  341. }