1 /* 2 * Data (and LEB128) bytecode 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 29 #include "libyasm-stdint.h" 30 #include "coretype.h" 31 32 #include "errwarn.h" 33 #include "intnum.h" 34 #include "expr.h" 35 #include "value.h" 36 37 #include "bytecode.h" 38 #include "arch.h" 39 40 41 struct yasm_dataval { 42 /*@reldef@*/ STAILQ_ENTRY(yasm_dataval) link; 43 44 enum { DV_EMPTY, DV_VALUE, DV_RAW, DV_ULEB128, DV_SLEB128, DV_RESERVE } 45 type; 46 47 union { 48 yasm_value val; 49 struct { 50 /*@only@*/ unsigned char *contents; 51 unsigned long len; 52 } raw; 53 } data; 54 55 /* number of times data is repeated, NULL=1. */ 56 /*@only@*/ /*@null@*/ yasm_expr *multiple; 57 }; 58 59 typedef struct bytecode_data { 60 /* converted data (linked list) */ 61 yasm_datavalhead datahead; 62 63 int item_size; 64 } bytecode_data; 65 66 static void bc_data_destroy(void *contents); 67 static void bc_data_print(const void *contents, FILE *f, int indent_level); 68 static void bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc); 69 static int bc_data_item_size(yasm_bytecode *bc); 70 static int bc_data_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 71 void *add_span_data); 72 static int bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, 73 unsigned char *bufstart, void *d, 74 yasm_output_value_func output_value, 75 /*@null@*/ yasm_output_reloc_func output_reloc); 76 77 static const yasm_bytecode_callback bc_data_callback = { 78 bc_data_destroy, 79 bc_data_print, 80 bc_data_finalize, 81 bc_data_item_size, 82 bc_data_calc_len, 83 yasm_bc_expand_common, 84 bc_data_tobytes, 85 0 86 }; 87 88 89 static void 90 bc_data_destroy(void *contents) 91 { 92 bytecode_data *bc_data = (bytecode_data *)contents; 93 yasm_dvs_delete(&bc_data->datahead); 94 yasm_xfree(contents); 95 } 96 97 static void 98 bc_data_print(const void *contents, FILE *f, int indent_level) 99 { 100 const bytecode_data *bc_data = (const bytecode_data *)contents; 101 fprintf(f, "%*s_Data_\n", indent_level, ""); 102 fprintf(f, "%*sElements:\n", indent_level+1, ""); 103 yasm_dvs_print(&bc_data->datahead, f, indent_level+2); 104 } 105 106 static void 107 bc_data_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc) 108 { 109 bytecode_data *bc_data = (bytecode_data *)bc->contents; 110 yasm_dataval *dv; 111 yasm_intnum *intn; 112 113 /* Convert values from simple expr to value. */ 114 STAILQ_FOREACH(dv, &bc_data->datahead, link) { 115 switch (dv->type) { 116 case DV_VALUE: 117 if (yasm_value_finalize(&dv->data.val, prev_bc)) { 118 yasm_error_set(YASM_ERROR_TOO_COMPLEX, 119 N_("data expression too complex")); 120 return; 121 } 122 break; 123 case DV_ULEB128: 124 case DV_SLEB128: 125 intn = yasm_expr_get_intnum(&dv->data.val.abs, 0); 126 if (!intn) { 127 yasm_error_set(YASM_ERROR_NOT_CONSTANT, 128 N_("LEB128 requires constant values")); 129 return; 130 } 131 /* Warn for negative values in unsigned environment. 132 * This could be an error instead: the likelihood this is 133 * desired is very low! 134 */ 135 if (yasm_intnum_sign(intn) == -1 && dv->type == DV_ULEB128) 136 yasm_warn_set(YASM_WARN_GENERAL, 137 N_("negative value in unsigned LEB128")); 138 break; 139 default: 140 break; 141 } 142 if (dv->multiple) { 143 yasm_value val; 144 if (yasm_value_finalize_expr(&val, dv->multiple, prev_bc, 0)) 145 yasm_error_set(YASM_ERROR_TOO_COMPLEX, 146 N_("multiple expression too complex")); 147 else if (val.rel) 148 yasm_error_set(YASM_ERROR_NOT_ABSOLUTE, 149 N_("multiple expression not absolute")); 150 dv->multiple = val.abs; 151 } 152 } 153 } 154 155 static int 156 bc_data_item_size(yasm_bytecode *bc) 157 { 158 bytecode_data *bc_data = (bytecode_data *)bc->contents; 159 return bc_data->item_size; 160 } 161 162 static int 163 bc_data_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span, 164 void *add_span_data) 165 { 166 bytecode_data *bc_data = (bytecode_data *)bc->contents; 167 yasm_dataval *dv; 168 yasm_intnum *intn; 169 unsigned long len = 0; 170 unsigned long multiple; 171 172 /* Count up element sizes, rounding up string length. */ 173 STAILQ_FOREACH(dv, &bc_data->datahead, link) { 174 switch (dv->type) { 175 case DV_EMPTY: 176 len = 0; 177 break; 178 case DV_VALUE: 179 len = dv->data.val.size/8; 180 break; 181 case DV_RAW: 182 len = dv->data.raw.len; 183 break; 184 case DV_ULEB128: 185 case DV_SLEB128: 186 intn = yasm_expr_get_intnum(&dv->data.val.abs, 0); 187 if (!intn) 188 yasm_internal_error(N_("non-constant in data_tobytes")); 189 len = yasm_intnum_size_leb128(intn, dv->type == DV_SLEB128); 190 break; 191 case DV_RESERVE: 192 len = dv->data.val.size/8; 193 break; 194 } 195 196 if (!yasm_dv_get_multiple(dv, &multiple)) 197 len *= multiple; 198 199 bc->len += len; 200 } 201 202 return 0; 203 } 204 205 static int 206 bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, 207 unsigned char *bufstart, void *d, 208 yasm_output_value_func output_value, 209 /*@unused@*/ yasm_output_reloc_func output_reloc) 210 { 211 bytecode_data *bc_data = (bytecode_data *)bc->contents; 212 yasm_dataval *dv; 213 yasm_intnum *intn; 214 unsigned int val_len; 215 unsigned long multiple, i; 216 217 STAILQ_FOREACH(dv, &bc_data->datahead, link) { 218 if (yasm_dv_get_multiple(dv, &multiple) || multiple == 0) 219 continue; 220 switch (dv->type) { 221 case DV_EMPTY: 222 break; 223 case DV_VALUE: 224 val_len = dv->data.val.size/8; 225 for (i=0; i<multiple; i++) { 226 if (output_value(&dv->data.val, *bufp, val_len, 227 (unsigned long)(*bufp-bufstart), bc, 1, 228 d)) 229 return 1; 230 *bufp += val_len; 231 } 232 break; 233 case DV_RAW: 234 for (i=0; i<multiple; i++) { 235 memcpy(*bufp, dv->data.raw.contents, dv->data.raw.len); 236 *bufp += dv->data.raw.len; 237 } 238 break; 239 case DV_ULEB128: 240 case DV_SLEB128: 241 intn = yasm_expr_get_intnum(&dv->data.val.abs, 234); 242 if (!intn) 243 yasm_internal_error(N_("non-constant in data_tobytes")); 244 for (i=0; i<multiple; i++) { 245 *bufp += 246 yasm_intnum_get_leb128(intn, *bufp, 247 dv->type == DV_SLEB128); 248 } 249 case DV_RESERVE: 250 val_len = dv->data.val.size/8; 251 for (i=0; i<multiple; i++) { 252 memset(*bufp, 0, val_len); 253 *bufp += val_len; 254 } 255 break; 256 } 257 } 258 259 return 0; 260 } 261 262 yasm_bytecode * 263 yasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size, 264 int append_zero, yasm_arch *arch, unsigned long line) 265 { 266 bytecode_data *data = yasm_xmalloc(sizeof(bytecode_data)); 267 yasm_bytecode *bc = yasm_bc_create_common(&bc_data_callback, data, line); 268 yasm_dataval *dv, *dv2, *dvo; 269 yasm_intnum *intn; 270 unsigned long len = 0, rlen, i; 271 272 273 yasm_dvs_initialize(&data->datahead); 274 data->item_size = size; 275 276 /* Prescan input data for length, etc. Careful: this needs to be 277 * precisely paired with the second loop. 278 */ 279 STAILQ_FOREACH(dv, datahead, link) { 280 if (dv->multiple && dv->type != DV_EMPTY && len > 0) { 281 /* Flush previous data */ 282 dvo = yasm_dv_create_raw(yasm_xmalloc(len), len); 283 STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 284 len = 0; 285 } 286 switch (dv->type) { 287 case DV_EMPTY: 288 break; 289 case DV_VALUE: 290 case DV_ULEB128: 291 case DV_SLEB128: 292 intn = yasm_expr_get_intnum(&dv->data.val.abs, 0); 293 if (intn && dv->type == DV_VALUE && (arch || size == 1)) 294 len += size; 295 else if (intn && dv->type == DV_ULEB128) 296 len += yasm_intnum_size_leb128(intn, 0); 297 else if (intn && dv->type == DV_SLEB128) 298 len += yasm_intnum_size_leb128(intn, 1); 299 else { 300 if (len > 0) { 301 /* Create bytecode for all previous len */ 302 dvo = yasm_dv_create_raw(yasm_xmalloc(len), len); 303 STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 304 len = 0; 305 } 306 307 /* Create bytecode for this value */ 308 dvo = yasm_xmalloc(sizeof(yasm_dataval)); 309 STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 310 dvo->multiple = dv->multiple; 311 } 312 break; 313 case DV_RAW: 314 rlen = dv->data.raw.len; 315 /* find count, rounding up to nearest multiple of size */ 316 rlen = (rlen + size - 1) / size; 317 len += rlen*size; 318 break; 319 case DV_RESERVE: 320 len += size; 321 break; 322 } 323 324 if (dv->multiple && dv->type != DV_EMPTY && len > 0) { 325 /* Flush this data */ 326 dvo = yasm_dv_create_raw(yasm_xmalloc(len), len); 327 STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 328 dvo->multiple = dv->multiple; 329 len = 0; 330 } 331 332 if (append_zero) 333 len++; 334 } 335 336 /* Create final dataval for any trailing length */ 337 if (len > 0) { 338 dvo = yasm_dv_create_raw(yasm_xmalloc(len), len); 339 STAILQ_INSERT_TAIL(&data->datahead, dvo, link); 340 } 341 342 /* Second iteration: copy data and delete input datavals. */ 343 dv = STAILQ_FIRST(datahead); 344 dvo = STAILQ_FIRST(&data->datahead); 345 len = 0; 346 while (dv && dvo) { 347 if (dv->multiple && dv->type != DV_EMPTY && len > 0) { 348 dvo = STAILQ_NEXT(dvo, link); 349 len = 0; 350 } 351 switch (dv->type) { 352 case DV_EMPTY: 353 break; 354 case DV_VALUE: 355 case DV_ULEB128: 356 case DV_SLEB128: 357 intn = yasm_expr_get_intnum(&dv->data.val.abs, 0); 358 if (intn && dv->type == DV_VALUE && (arch || size == 1)) { 359 if (size == 1) 360 yasm_intnum_get_sized(intn, 361 &dvo->data.raw.contents[len], 362 1, 8, 0, 0, 1); 363 else 364 yasm_arch_intnum_tobytes(arch, intn, 365 &dvo->data.raw.contents[len], 366 size, size*8, 0, bc, 1); 367 yasm_value_delete(&dv->data.val); 368 len += size; 369 } else if (intn && dv->type == DV_ULEB128) { 370 len += yasm_intnum_get_leb128(intn, 371 &dvo->data.raw.contents[len], 372 0); 373 yasm_value_delete(&dv->data.val); 374 } else if (intn && dv->type == DV_SLEB128) { 375 len += yasm_intnum_get_leb128(intn, 376 &dvo->data.raw.contents[len], 377 1); 378 yasm_value_delete(&dv->data.val); 379 } else { 380 if (len > 0) 381 dvo = STAILQ_NEXT(dvo, link); 382 dvo->type = dv->type; 383 dvo->data.val = dv->data.val; /* structure copy */ 384 dvo->data.val.size = size*8; /* remember size */ 385 dvo = STAILQ_NEXT(dvo, link); 386 len = 0; 387 } 388 break; 389 case DV_RAW: 390 rlen = dv->data.raw.len; 391 memcpy(&dvo->data.raw.contents[len], dv->data.raw.contents, 392 rlen); 393 yasm_xfree(dv->data.raw.contents); 394 len += rlen; 395 /* pad with 0's to nearest multiple of size */ 396 rlen %= size; 397 if (rlen > 0) { 398 rlen = size-rlen; 399 for (i=0; i<rlen; i++) 400 dvo->data.raw.contents[len++] = 0; 401 } 402 break; 403 case DV_RESERVE: 404 memset(&dvo->data.raw.contents[len], 0, size); 405 len += size; 406 break; 407 } 408 409 if (dv->multiple && dv->type != DV_EMPTY && len > 0) { 410 dvo = STAILQ_NEXT(dvo, link); 411 len = 0; 412 } 413 414 if (append_zero) 415 dvo->data.raw.contents[len++] = 0; 416 dv2 = STAILQ_NEXT(dv, link); 417 yasm_xfree(dv); 418 dv = dv2; 419 } 420 421 return bc; 422 } 423 424 yasm_bytecode * 425 yasm_bc_create_leb128(yasm_datavalhead *datahead, int sign, unsigned long line) 426 { 427 yasm_dataval *dv; 428 429 /* Convert all values into LEB type, error on strings/raws */ 430 STAILQ_FOREACH(dv, datahead, link) { 431 switch (dv->type) { 432 case DV_VALUE: 433 dv->type = sign ? DV_SLEB128 : DV_ULEB128; 434 break; 435 case DV_RAW: 436 yasm_error_set(YASM_ERROR_VALUE, 437 N_("LEB128 does not allow string constants")); 438 break; 439 default: 440 break; 441 } 442 } 443 444 return yasm_bc_create_data(datahead, 0, 0, 0, line); 445 } 446 447 yasm_dataval * 448 yasm_dv_create_expr(yasm_expr *e) 449 { 450 yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval)); 451 452 retval->type = DV_VALUE; 453 yasm_value_initialize(&retval->data.val, e, 0); 454 retval->multiple = NULL; 455 456 return retval; 457 } 458 459 yasm_dataval * 460 yasm_dv_create_raw(unsigned char *contents, unsigned long len) 461 { 462 yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval)); 463 464 retval->type = DV_RAW; 465 retval->data.raw.contents = contents; 466 retval->data.raw.len = len; 467 retval->multiple = NULL; 468 469 return retval; 470 } 471 472 yasm_dataval * 473 yasm_dv_create_reserve(void) 474 { 475 yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval)); 476 477 retval->type = DV_RESERVE; 478 retval->multiple = NULL; 479 480 return retval; 481 } 482 483 yasm_value * 484 yasm_dv_get_value(yasm_dataval *dv) 485 { 486 if (dv->type != DV_VALUE) 487 return NULL; 488 return &dv->data.val; 489 } 490 491 void 492 yasm_dv_set_multiple(yasm_dataval *dv, yasm_expr *e) 493 { 494 if (dv->multiple) 495 dv->multiple = yasm_expr_create_tree( dv->multiple, YASM_EXPR_MUL, e, 496 e->line); 497 else 498 dv->multiple = e; 499 } 500 501 int 502 yasm_dv_get_multiple(yasm_dataval *dv, unsigned long *multiple) 503 { 504 /*@dependent@*/ /*@null@*/ const yasm_intnum *num; 505 506 *multiple = 1; 507 if (dv->multiple) { 508 num = yasm_expr_get_intnum(&dv->multiple, 0); 509 if (!num) { 510 yasm_error_set(YASM_ERROR_VALUE, 511 N_("could not determine multiple")); 512 return 1; 513 } 514 if (yasm_intnum_sign(num) < 0) { 515 yasm_error_set(YASM_ERROR_VALUE, N_("multiple is negative")); 516 return 1; 517 } 518 *multiple = yasm_intnum_get_uint(num); 519 } 520 return 0; 521 } 522 523 void 524 yasm_dvs_delete(yasm_datavalhead *headp) 525 { 526 yasm_dataval *cur, *next; 527 528 cur = STAILQ_FIRST(headp); 529 while (cur) { 530 next = STAILQ_NEXT(cur, link); 531 switch (cur->type) { 532 case DV_VALUE: 533 yasm_value_delete(&cur->data.val); 534 break; 535 case DV_RAW: 536 yasm_xfree(cur->data.raw.contents); 537 break; 538 default: 539 break; 540 } 541 if (cur->multiple) 542 yasm_expr_destroy(cur->multiple); 543 yasm_xfree(cur); 544 cur = next; 545 } 546 STAILQ_INIT(headp); 547 } 548 549 yasm_dataval * 550 yasm_dvs_append(yasm_datavalhead *headp, yasm_dataval *dv) 551 { 552 if (dv) { 553 STAILQ_INSERT_TAIL(headp, dv, link); 554 return dv; 555 } 556 return (yasm_dataval *)NULL; 557 } 558 559 void 560 yasm_dvs_print(const yasm_datavalhead *head, FILE *f, int indent_level) 561 { 562 yasm_dataval *cur; 563 unsigned long i; 564 565 STAILQ_FOREACH(cur, head, link) { 566 fprintf(f, "%*sMultiple=", indent_level, ""); 567 if (!cur->multiple) 568 fprintf(f, "nil (1)"); 569 else 570 yasm_expr_print(cur->multiple, f); 571 switch (cur->type) { 572 case DV_EMPTY: 573 fprintf(f, "%*sEmpty\n", indent_level, ""); 574 break; 575 case DV_VALUE: 576 fprintf(f, "%*sValue:\n", indent_level, ""); 577 yasm_value_print(&cur->data.val, f, indent_level+1); 578 break; 579 case DV_RAW: 580 fprintf(f, "%*sLength=%lu\n", indent_level, "", 581 cur->data.raw.len); 582 fprintf(f, "%*sBytes=[", indent_level, ""); 583 for (i=0; i<cur->data.raw.len; i++) 584 fprintf(f, "0x%02x, ", cur->data.raw.contents[i]); 585 fprintf(f, "]\n"); 586 break; 587 case DV_ULEB128: 588 fprintf(f, "%*sULEB128 value:\n", indent_level, ""); 589 yasm_value_print(&cur->data.val, f, indent_level+1); 590 break; 591 case DV_SLEB128: 592 fprintf(f, "%*sSLEB128 value:\n", indent_level, ""); 593 yasm_value_print(&cur->data.val, f, indent_level+1); 594 break; 595 case DV_RESERVE: 596 fprintf(f, "%*sReserved\n", indent_level, ""); 597 break; 598 } 599 } 600 } 601