value.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771
  1. /*
  2. * Value handling
  3. *
  4. * Copyright (C) 2006-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 "bitvect.h"
  31. #include "errwarn.h"
  32. #include "intnum.h"
  33. #include "floatnum.h"
  34. #include "expr.h"
  35. #include "value.h"
  36. #include "symrec.h"
  37. #include "bytecode.h"
  38. #include "section.h"
  39. #include "arch.h"
  40. void
  41. yasm_value_initialize(/*@out@*/ yasm_value *value,
  42. /*@null@*/ /*@kept@*/ yasm_expr *e, unsigned int size)
  43. {
  44. value->abs = e;
  45. value->rel = NULL;
  46. value->wrt = NULL;
  47. value->seg_of = 0;
  48. value->rshift = 0;
  49. value->curpos_rel = 0;
  50. value->ip_rel = 0;
  51. value->jump_target = 0;
  52. value->section_rel = 0;
  53. value->no_warn = 0;
  54. value->sign = 0;
  55. value->size = size;
  56. }
  57. void
  58. yasm_value_init_sym(/*@out@*/ yasm_value *value, /*@null@*/ yasm_symrec *sym,
  59. unsigned int size)
  60. {
  61. value->abs = NULL;
  62. value->rel = sym;
  63. value->wrt = NULL;
  64. value->seg_of = 0;
  65. value->rshift = 0;
  66. value->curpos_rel = 0;
  67. value->ip_rel = 0;
  68. value->jump_target = 0;
  69. value->section_rel = 0;
  70. value->no_warn = 0;
  71. value->sign = 0;
  72. value->size = size;
  73. }
  74. void
  75. yasm_value_init_copy(yasm_value *value, const yasm_value *orig)
  76. {
  77. value->abs = orig->abs ? yasm_expr_copy(orig->abs) : NULL;
  78. value->rel = orig->rel;
  79. value->wrt = orig->wrt;
  80. value->seg_of = orig->seg_of;
  81. value->rshift = orig->rshift;
  82. value->curpos_rel = orig->curpos_rel;
  83. value->ip_rel = orig->ip_rel;
  84. value->jump_target = orig->jump_target;
  85. value->section_rel = orig->section_rel;
  86. value->no_warn = orig->no_warn;
  87. value->sign = orig->sign;
  88. value->size = orig->size;
  89. }
  90. void
  91. yasm_value_delete(yasm_value *value)
  92. {
  93. if (value->abs)
  94. yasm_expr_destroy(value->abs);
  95. value->abs = NULL;
  96. value->rel = NULL;
  97. }
  98. void
  99. yasm_value_set_curpos_rel(yasm_value *value, yasm_bytecode *bc,
  100. unsigned int ip_rel)
  101. {
  102. value->curpos_rel = 1;
  103. value->ip_rel = ip_rel;
  104. /* In order for us to correctly output curpos-relative values, we must
  105. * have a relative portion of the value. If one doesn't exist, point
  106. * to a custom absolute symbol.
  107. */
  108. if (!value->rel) {
  109. yasm_object *object = yasm_section_get_object(yasm_bc_get_section(bc));
  110. value->rel = yasm_symtab_abs_sym(object->symtab);
  111. }
  112. }
  113. static int
  114. value_finalize_scan(yasm_value *value, yasm_expr *e,
  115. /*@null@*/ yasm_bytecode *expr_precbc, int ssym_not_ok)
  116. {
  117. int i;
  118. /*@dependent@*/ yasm_section *sect;
  119. /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc;
  120. unsigned long shamt; /* for SHR */
  121. /* Yes, this has a maximum upper bound on 32 terms, based on an
  122. * "insane number of terms" (and ease of implementation) WAG.
  123. * The right way to do this would be a stack-based alloca, but that's
  124. * not ISO C. We really don't want to malloc here as this function is
  125. * hit a lot!
  126. *
  127. * This is a bitmask to keep things small, as this is a recursive
  128. * routine and we don't want to eat up stack space.
  129. */
  130. unsigned long used; /* for ADD */
  131. /* Thanks to this running after a simplify, we don't need to iterate
  132. * down through IDENTs or handle SUB.
  133. *
  134. * We scan for a single symrec, gathering info along the way. After
  135. * we've found the symrec, we keep scanning but error if we find
  136. * another one. We pull out the single symrec and any legal operations
  137. * performed on it.
  138. *
  139. * Also, if we find a float anywhere, we don't allow mixing of a single
  140. * symrec with it.
  141. */
  142. switch (e->op) {
  143. case YASM_EXPR_ADD:
  144. /* Okay for single symrec anywhere in expr.
  145. * Check for single symrec anywhere.
  146. * Handle symrec-symrec by checking for (-1*symrec)
  147. * and symrec term pairs (where both symrecs are in the same
  148. * segment).
  149. */
  150. if (e->numterms > 32)
  151. yasm__fatal(N_("expression on line %d has too many add terms;"
  152. " internal limit of 32"), e->line);
  153. used = 0;
  154. for (i=0; i<e->numterms; i++) {
  155. int j;
  156. yasm_expr *sube;
  157. yasm_intnum *intn;
  158. yasm_symrec *sym;
  159. /*@dependent@*/ yasm_section *sect2;
  160. /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc2;
  161. /* First look for an (-1*symrec) term */
  162. if (e->terms[i].type != YASM_EXPR_EXPR)
  163. continue;
  164. sube = e->terms[i].data.expn;
  165. if (sube->op != YASM_EXPR_MUL || sube->numterms != 2) {
  166. /* recurse instead */
  167. if (value_finalize_scan(value, sube, expr_precbc,
  168. ssym_not_ok))
  169. return 1;
  170. continue;
  171. }
  172. if (sube->terms[0].type == YASM_EXPR_INT &&
  173. sube->terms[1].type == YASM_EXPR_SYM) {
  174. intn = sube->terms[0].data.intn;
  175. sym = sube->terms[1].data.sym;
  176. } else if (sube->terms[0].type == YASM_EXPR_SYM &&
  177. sube->terms[1].type == YASM_EXPR_INT) {
  178. sym = sube->terms[0].data.sym;
  179. intn = sube->terms[1].data.intn;
  180. } else {
  181. if (value_finalize_scan(value, sube, expr_precbc,
  182. ssym_not_ok))
  183. return 1;
  184. continue;
  185. }
  186. if (!yasm_intnum_is_neg1(intn)) {
  187. if (value_finalize_scan(value, sube, expr_precbc,
  188. ssym_not_ok))
  189. return 1;
  190. continue;
  191. }
  192. /* Look for the same symrec term; even if both are external,
  193. * they should cancel out.
  194. */
  195. for (j=0; j<e->numterms; j++) {
  196. if (e->terms[j].type == YASM_EXPR_SYM
  197. && e->terms[j].data.sym == sym
  198. && (used & (1<<j)) == 0) {
  199. /* Mark as used */
  200. used |= 1<<j;
  201. /* Replace both symrec portions with 0 */
  202. yasm_expr_destroy(sube);
  203. e->terms[i].type = YASM_EXPR_INT;
  204. e->terms[i].data.intn = yasm_intnum_create_uint(0);
  205. e->terms[j].type = YASM_EXPR_INT;
  206. e->terms[j].data.intn = yasm_intnum_create_uint(0);
  207. break; /* stop looking */
  208. }
  209. }
  210. if (j != e->numterms)
  211. continue;
  212. if (!yasm_symrec_get_label(sym, &precbc)) {
  213. if (value_finalize_scan(value, sube, expr_precbc,
  214. ssym_not_ok))
  215. return 1;
  216. continue;
  217. }
  218. sect2 = yasm_bc_get_section(precbc);
  219. /* Now look for a unused symrec term in the same segment */
  220. for (j=0; j<e->numterms; j++) {
  221. if (e->terms[j].type == YASM_EXPR_SYM
  222. && yasm_symrec_get_label(e->terms[j].data.sym,
  223. &precbc2)
  224. && (sect = yasm_bc_get_section(precbc2))
  225. && sect == sect2
  226. && (used & (1<<j)) == 0) {
  227. /* Mark as used */
  228. used |= 1<<j;
  229. break; /* stop looking */
  230. }
  231. }
  232. /* We didn't match in the same segment. If the
  233. * -1*symrec is actually -1*curpos, we can match
  234. * unused symrec terms in other segments and generate
  235. * a curpos-relative reloc.
  236. *
  237. * Similarly, handle -1*symrec in other segment via the
  238. * following transformation:
  239. * other-this = (other-.)+(.-this)
  240. * We can only do this transformation if "this" is in
  241. * this expr's segment.
  242. *
  243. * Don't do this if we've already become curpos-relative.
  244. * The unmatched symrec will be caught below.
  245. */
  246. if (j == e->numterms && !value->curpos_rel
  247. && (yasm_symrec_is_curpos(sym)
  248. || (expr_precbc
  249. && sect2 == yasm_bc_get_section(expr_precbc)))) {
  250. for (j=0; j<e->numterms; j++) {
  251. if (e->terms[j].type == YASM_EXPR_SYM
  252. && !yasm_symrec_get_equ(e->terms[j].data.sym)
  253. && !yasm_symrec_is_special(e->terms[j].data.sym)
  254. && (used & (1<<j)) == 0) {
  255. /* Mark as used */
  256. used |= 1<<j;
  257. /* Mark value as curpos-relative */
  258. if (value->rel || ssym_not_ok)
  259. return 1;
  260. value->rel = e->terms[j].data.sym;
  261. value->curpos_rel = 1;
  262. if (yasm_symrec_is_curpos(sym)) {
  263. /* Replace both symrec portions with 0 */
  264. yasm_expr_destroy(sube);
  265. e->terms[i].type = YASM_EXPR_INT;
  266. e->terms[i].data.intn =
  267. yasm_intnum_create_uint(0);
  268. e->terms[j].type = YASM_EXPR_INT;
  269. e->terms[j].data.intn =
  270. yasm_intnum_create_uint(0);
  271. } else {
  272. /* Replace positive portion with curpos */
  273. yasm_object *object =
  274. yasm_section_get_object(sect2);
  275. yasm_symtab *symtab = object->symtab;
  276. e->terms[j].data.sym =
  277. yasm_symtab_define_curpos
  278. (symtab, ".", expr_precbc, e->line);
  279. }
  280. break; /* stop looking */
  281. }
  282. }
  283. }
  284. if (j == e->numterms)
  285. return 1; /* We didn't find a match! */
  286. }
  287. /* Look for unmatched symrecs. If we've already found one or
  288. * we don't WANT to find one, error out.
  289. */
  290. for (i=0; i<e->numterms; i++) {
  291. if (e->terms[i].type == YASM_EXPR_SYM
  292. && (used & (1<<i)) == 0) {
  293. if (value->rel || ssym_not_ok)
  294. return 1;
  295. value->rel = e->terms[i].data.sym;
  296. /* and replace with 0 */
  297. e->terms[i].type = YASM_EXPR_INT;
  298. e->terms[i].data.intn = yasm_intnum_create_uint(0);
  299. }
  300. }
  301. break;
  302. case YASM_EXPR_SHR:
  303. /* Okay for single symrec in LHS and constant on RHS.
  304. * Single symrecs are not okay on RHS.
  305. * If RHS is non-constant, don't allow single symrec on LHS.
  306. * XXX: should rshift be an expr instead??
  307. */
  308. /* Check for single sym on LHS */
  309. if (e->terms[0].type != YASM_EXPR_SYM)
  310. break;
  311. /* If we already have a sym, we can't take another one */
  312. if (value->rel || ssym_not_ok)
  313. return 1;
  314. /* RHS must be a positive integer */
  315. if (e->terms[1].type != YASM_EXPR_INT)
  316. return 1; /* can't shift sym by non-constant integer */
  317. shamt = yasm_intnum_get_uint(e->terms[1].data.intn);
  318. if ((shamt + value->rshift) > YASM_VALUE_RSHIFT_MAX)
  319. return 1; /* total shift would be too large */
  320. /* Update value */
  321. value->rshift += shamt;
  322. value->rel = e->terms[0].data.sym;
  323. /* Replace symbol with 0 */
  324. e->terms[0].type = YASM_EXPR_INT;
  325. e->terms[0].data.intn = yasm_intnum_create_uint(0);
  326. /* Just leave SHR in place */
  327. break;
  328. case YASM_EXPR_SEG:
  329. /* Okay for single symrec (can only be done once).
  330. * Not okay for anything BUT a single symrec as an immediate
  331. * child.
  332. */
  333. if (e->terms[0].type != YASM_EXPR_SYM)
  334. return 1;
  335. if (value->seg_of)
  336. return 1; /* multiple SEG not legal */
  337. value->seg_of = 1;
  338. if (value->rel || ssym_not_ok)
  339. return 1; /* got a relative portion somewhere else? */
  340. value->rel = e->terms[0].data.sym;
  341. /* replace with ident'ed 0 */
  342. e->op = YASM_EXPR_IDENT;
  343. e->terms[0].type = YASM_EXPR_INT;
  344. e->terms[0].data.intn = yasm_intnum_create_uint(0);
  345. break;
  346. case YASM_EXPR_WRT:
  347. /* Okay for single symrec in LHS and either a register or single
  348. * symrec (as an immediate child) on RHS.
  349. * If a single symrec on RHS, can only be done once.
  350. * WRT reg is left in expr for arch to look at.
  351. */
  352. /* Handle RHS */
  353. switch (e->terms[1].type) {
  354. case YASM_EXPR_SYM:
  355. if (value->wrt)
  356. return 1;
  357. value->wrt = e->terms[1].data.sym;
  358. /* and drop the WRT portion */
  359. e->op = YASM_EXPR_IDENT;
  360. e->numterms = 1;
  361. break;
  362. case YASM_EXPR_REG:
  363. break; /* ignore */
  364. default:
  365. return 1;
  366. }
  367. /* Handle LHS */
  368. switch (e->terms[0].type) {
  369. case YASM_EXPR_SYM:
  370. if (value->rel || ssym_not_ok)
  371. return 1;
  372. value->rel = e->terms[0].data.sym;
  373. /* and replace with 0 */
  374. e->terms[0].type = YASM_EXPR_INT;
  375. e->terms[0].data.intn = yasm_intnum_create_uint(0);
  376. break;
  377. case YASM_EXPR_EXPR:
  378. /* recurse */
  379. return value_finalize_scan(value, e->terms[0].data.expn,
  380. expr_precbc, ssym_not_ok);
  381. default:
  382. break; /* ignore */
  383. }
  384. break;
  385. default:
  386. /* Single symrec not allowed anywhere */
  387. for (i=0; i<e->numterms; i++) {
  388. switch (e->terms[i].type) {
  389. case YASM_EXPR_SYM:
  390. return 1;
  391. case YASM_EXPR_EXPR:
  392. /* recurse */
  393. return value_finalize_scan(value,
  394. e->terms[i].data.expn,
  395. expr_precbc, 1);
  396. default:
  397. break;
  398. }
  399. }
  400. break;
  401. }
  402. return 0;
  403. }
  404. int
  405. yasm_value_finalize_expr(yasm_value *value, yasm_expr *e,
  406. yasm_bytecode *precbc, unsigned int size)
  407. {
  408. if (!e) {
  409. yasm_value_initialize(value, NULL, size);
  410. return 0;
  411. }
  412. yasm_value_initialize(value, e, size);
  413. return yasm_value_finalize(value, precbc);
  414. }
  415. int
  416. yasm_value_finalize(yasm_value *value, yasm_bytecode *precbc)
  417. {
  418. if (!value->abs)
  419. return 0;
  420. value->abs = yasm_expr__level_tree(value->abs, 1, 1, 0, 0, NULL, NULL);
  421. /* quit early if there was an issue in simplify() */
  422. if (yasm_error_occurred())
  423. return 1;
  424. /* Strip top-level AND masking to an all-1s mask the same size
  425. * of the value size. This allows forced avoidance of overflow warnings.
  426. */
  427. if (value->abs->op == YASM_EXPR_AND) {
  428. int term;
  429. /* Calculate 1<<size - 1 value */
  430. yasm_intnum *mask = yasm_intnum_create_uint(1);
  431. yasm_intnum *mask_tmp = yasm_intnum_create_uint(value->size);
  432. yasm_intnum_calc(mask, YASM_EXPR_SHL, mask_tmp);
  433. yasm_intnum_set_uint(mask_tmp, 1);
  434. yasm_intnum_calc(mask, YASM_EXPR_SUB, mask_tmp);
  435. yasm_intnum_destroy(mask_tmp);
  436. /* Walk terms and delete matching masks */
  437. for (term=value->abs->numterms-1; term>=0; term--) {
  438. if (value->abs->terms[term].type == YASM_EXPR_INT &&
  439. yasm_intnum_compare(value->abs->terms[term].data.intn,
  440. mask) == 0) {
  441. /* Delete the intnum */
  442. yasm_intnum_destroy(value->abs->terms[term].data.intn);
  443. /* Slide everything to its right over by 1 */
  444. if (term != value->abs->numterms-1) /* if it wasn't last.. */
  445. memmove(&value->abs->terms[term],
  446. &value->abs->terms[term+1],
  447. (value->abs->numterms-1-term)*
  448. sizeof(yasm_expr__item));
  449. /* Update numterms */
  450. value->abs->numterms--;
  451. /* Indicate warnings have been disabled */
  452. value->no_warn = 1;
  453. }
  454. }
  455. if (value->abs->numterms == 1)
  456. value->abs->op = YASM_EXPR_IDENT;
  457. yasm_intnum_destroy(mask);
  458. }
  459. /* Handle trivial (IDENT) cases immediately */
  460. if (value->abs->op == YASM_EXPR_IDENT) {
  461. switch (value->abs->terms[0].type) {
  462. case YASM_EXPR_INT:
  463. if (yasm_intnum_is_zero(value->abs->terms[0].data.intn)) {
  464. yasm_expr_destroy(value->abs);
  465. value->abs = NULL;
  466. }
  467. return 0;
  468. case YASM_EXPR_REG:
  469. case YASM_EXPR_FLOAT:
  470. return 0;
  471. case YASM_EXPR_SYM:
  472. value->rel = value->abs->terms[0].data.sym;
  473. yasm_expr_destroy(value->abs);
  474. value->abs = NULL;
  475. return 0;
  476. case YASM_EXPR_EXPR:
  477. /* Bring up lower values. */
  478. while (value->abs->op == YASM_EXPR_IDENT
  479. && value->abs->terms[0].type == YASM_EXPR_EXPR) {
  480. yasm_expr *sube = value->abs->terms[0].data.expn;
  481. yasm_xfree(value->abs);
  482. value->abs = sube;
  483. }
  484. break;
  485. default:
  486. yasm_internal_error(N_("unexpected expr term type"));
  487. }
  488. }
  489. if (value_finalize_scan(value, value->abs, precbc, 0))
  490. return 1;
  491. value->abs = yasm_expr__level_tree(value->abs, 1, 1, 0, 0, NULL, NULL);
  492. /* Simplify 0 in abs to NULL */
  493. if (value->abs->op == YASM_EXPR_IDENT
  494. && value->abs->terms[0].type == YASM_EXPR_INT
  495. && yasm_intnum_is_zero(value->abs->terms[0].data.intn)) {
  496. yasm_expr_destroy(value->abs);
  497. value->abs = NULL;
  498. }
  499. return 0;
  500. }
  501. yasm_intnum *
  502. yasm_value_get_intnum(yasm_value *value, yasm_bytecode *bc, int calc_bc_dist)
  503. {
  504. /*@dependent@*/ /*@null@*/ yasm_intnum *intn = NULL;
  505. /*@only@*/ yasm_intnum *outval;
  506. int sym_local;
  507. if (value->abs) {
  508. /* Handle integer expressions, if non-integer or too complex, return
  509. * NULL.
  510. */
  511. intn = yasm_expr_get_intnum(&value->abs, calc_bc_dist);
  512. if (!intn)
  513. return NULL;
  514. }
  515. if (value->rel) {
  516. /* If relative portion is not in bc section, return NULL.
  517. * Otherwise get the relative portion's offset.
  518. */
  519. /*@dependent@*/ yasm_bytecode *rel_prevbc;
  520. unsigned long dist;
  521. if (!bc)
  522. return NULL; /* Can't calculate relative value */
  523. sym_local = yasm_symrec_get_label(value->rel, &rel_prevbc);
  524. if (value->wrt || value->seg_of || value->section_rel || !sym_local)
  525. return NULL; /* we can't handle SEG, WRT, or external symbols */
  526. if (rel_prevbc->section != bc->section)
  527. return NULL; /* not in this section */
  528. if (!value->curpos_rel)
  529. return NULL; /* not PC-relative */
  530. /* Calculate value relative to current assembly position */
  531. dist = yasm_bc_next_offset(rel_prevbc);
  532. if (dist < bc->offset) {
  533. outval = yasm_intnum_create_uint(bc->offset - dist);
  534. yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL);
  535. } else {
  536. dist -= bc->offset;
  537. outval = yasm_intnum_create_uint(dist);
  538. }
  539. if (value->rshift > 0) {
  540. /*@only@*/ yasm_intnum *shamt =
  541. yasm_intnum_create_uint((unsigned long)value->rshift);
  542. yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt);
  543. yasm_intnum_destroy(shamt);
  544. }
  545. /* Add in absolute portion */
  546. if (intn)
  547. yasm_intnum_calc(outval, YASM_EXPR_ADD, intn);
  548. return outval;
  549. }
  550. if (intn)
  551. return yasm_intnum_copy(intn);
  552. /* No absolute or relative portions: output 0 */
  553. return yasm_intnum_create_uint(0);
  554. }
  555. int
  556. yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
  557. size_t destsize, yasm_bytecode *bc, int warn,
  558. yasm_arch *arch)
  559. {
  560. /*@dependent@*/ /*@null@*/ yasm_intnum *intn = NULL;
  561. /*@only@*/ yasm_intnum *outval;
  562. int sym_local;
  563. int retval = 1;
  564. unsigned int valsize = value->size;
  565. if (value->no_warn)
  566. warn = 0;
  567. if (value->abs) {
  568. /* Handle floating point expressions */
  569. if (!value->rel && value->abs->op == YASM_EXPR_IDENT
  570. && value->abs->terms[0].type == YASM_EXPR_FLOAT) {
  571. if (yasm_arch_floatnum_tobytes(arch, value->abs->terms[0].data.flt,
  572. buf, destsize, valsize, 0, warn))
  573. return -1;
  574. else
  575. return 1;
  576. }
  577. /* Check for complex float expressions */
  578. if (yasm_expr__contains(value->abs, YASM_EXPR_FLOAT)) {
  579. yasm_error_set(YASM_ERROR_FLOATING_POINT,
  580. N_("floating point expression too complex"));
  581. return -1;
  582. }
  583. /* Handle normal integer expressions */
  584. intn = yasm_expr_get_intnum(&value->abs, 1);
  585. if (!intn) {
  586. /* Second try before erroring: yasm_expr_get_intnum doesn't handle
  587. * SEG:OFF, so try simplifying out any to just the OFF portion,
  588. * then getting the intnum again.
  589. */
  590. yasm_expr *seg = yasm_expr_extract_deep_segoff(&value->abs);
  591. if (seg)
  592. yasm_expr_destroy(seg);
  593. intn = yasm_expr_get_intnum(&value->abs, 1);
  594. }
  595. if (!intn) {
  596. /* Still don't have an integer! */
  597. yasm_error_set(YASM_ERROR_TOO_COMPLEX,
  598. N_("expression too complex"));
  599. return -1;
  600. }
  601. }
  602. /* Adjust warn for signed/unsigned integer warnings */
  603. if (warn != 0)
  604. warn = value->sign ? -1 : 1;
  605. if (value->rel) {
  606. /* If relative portion is not in bc section, don't try to handle it
  607. * here. Otherwise get the relative portion's offset.
  608. */
  609. /*@dependent@*/ yasm_bytecode *rel_prevbc;
  610. unsigned long dist;
  611. sym_local = yasm_symrec_get_label(value->rel, &rel_prevbc);
  612. if (value->wrt || value->seg_of || value->section_rel || !sym_local)
  613. return 0; /* we can't handle SEG, WRT, or external symbols */
  614. if (rel_prevbc->section != bc->section)
  615. return 0; /* not in this section */
  616. if (!value->curpos_rel)
  617. return 0; /* not PC-relative */
  618. /* Calculate value relative to current assembly position */
  619. dist = yasm_bc_next_offset(rel_prevbc);
  620. if (dist < bc->offset) {
  621. outval = yasm_intnum_create_uint(bc->offset - dist);
  622. yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL);
  623. } else {
  624. dist -= bc->offset;
  625. outval = yasm_intnum_create_uint(dist);
  626. }
  627. if (value->rshift > 0) {
  628. /*@only@*/ yasm_intnum *shamt =
  629. yasm_intnum_create_uint((unsigned long)value->rshift);
  630. yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt);
  631. yasm_intnum_destroy(shamt);
  632. }
  633. /* Add in absolute portion */
  634. if (intn)
  635. yasm_intnum_calc(outval, YASM_EXPR_ADD, intn);
  636. /* Output! */
  637. if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0,
  638. bc, warn))
  639. retval = -1;
  640. yasm_intnum_destroy(outval);
  641. return retval;
  642. }
  643. if (value->seg_of || value->rshift || value->curpos_rel || value->ip_rel
  644. || value->section_rel)
  645. return 0; /* We can't handle this with just an absolute */
  646. if (intn) {
  647. /* Output just absolute portion */
  648. if (yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, 0, bc,
  649. warn))
  650. retval = -1;
  651. } else {
  652. /* No absolute or relative portions: output 0 */
  653. outval = yasm_intnum_create_uint(0);
  654. if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0,
  655. bc, warn))
  656. retval = -1;
  657. yasm_intnum_destroy(outval);
  658. }
  659. return retval;
  660. }
  661. void
  662. yasm_value_print(const yasm_value *value, FILE *f, int indent_level)
  663. {
  664. fprintf(f, "%*s%u-bit, %ssigned", indent_level, "", value->size,
  665. value->sign ? "" : "un");
  666. fprintf(f, "%*sAbsolute portion=", indent_level, "");
  667. yasm_expr_print(value->abs, f);
  668. fprintf(f, "\n");
  669. if (value->rel) {
  670. fprintf(f, "%*sRelative to=%s%s\n", indent_level, "",
  671. value->seg_of ? "SEG " : "",
  672. yasm_symrec_get_name(value->rel));
  673. if (value->wrt)
  674. fprintf(f, "%*s(With respect to=%s)\n", indent_level, "",
  675. yasm_symrec_get_name(value->wrt));
  676. if (value->rshift > 0)
  677. fprintf(f, "%*s(Right shifted by=%u)\n", indent_level, "",
  678. value->rshift);
  679. if (value->curpos_rel)
  680. fprintf(f, "%*s(Relative to current position)\n", indent_level,
  681. "");
  682. if (value->ip_rel)
  683. fprintf(f, "%*s(IP-relative)\n", indent_level, "");
  684. if (value->jump_target)
  685. fprintf(f, "%*s(Jump target)\n", indent_level, "");
  686. if (value->section_rel)
  687. fprintf(f, "%*s(Section-relative)\n", indent_level, "");
  688. if (value->no_warn)
  689. fprintf(f, "%*s(Overflow warnings disabled)\n", indent_level, "");
  690. }
  691. }