1/* 2 * NASM-compatible parser 3 * 4 * Copyright (C) 2001-2007 Peter Johnson, Michael Urman 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.h> 30 31#include <math.h> 32 33#include "modules/parsers/nasm/nasm-parser.h" 34#include "modules/preprocs/nasm/nasm.h" 35 36typedef enum { 37 NORM_EXPR, 38 DIR_EXPR, /* Can't have seg:off or WRT anywhere */ 39 DV_EXPR /* Can't have registers anywhere */ 40} expr_type; 41 42static yasm_bytecode *parse_line(yasm_parser_nasm *parser_nasm); 43static int parse_directive_valparams(yasm_parser_nasm *parser_nasm, 44 /*@out@*/ yasm_valparamhead *vps); 45static yasm_bytecode *parse_times(yasm_parser_nasm *parser_nasm); 46static yasm_bytecode *parse_exp(yasm_parser_nasm *parser_nasm); 47static yasm_bytecode *parse_instr(yasm_parser_nasm *parser_nasm); 48static yasm_insn_operand *parse_operand(yasm_parser_nasm *parser_nasm); 49static yasm_insn_operand *parse_memaddr(yasm_parser_nasm *parser_nasm); 50static yasm_expr *parse_expr(yasm_parser_nasm *parser_nasm, expr_type type); 51static yasm_expr *parse_bexpr(yasm_parser_nasm *parser_nasm, expr_type type); 52static yasm_expr *parse_expr0(yasm_parser_nasm *parser_nasm, expr_type type); 53static yasm_expr *parse_expr1(yasm_parser_nasm *parser_nasm, expr_type type); 54static yasm_expr *parse_expr2(yasm_parser_nasm *parser_nasm, expr_type type); 55static yasm_expr *parse_expr3(yasm_parser_nasm *parser_nasm, expr_type type); 56static yasm_expr *parse_expr4(yasm_parser_nasm *parser_nasm, expr_type type); 57static yasm_expr *parse_expr5(yasm_parser_nasm *parser_nasm, expr_type type); 58static yasm_expr *parse_expr6(yasm_parser_nasm *parser_nasm, expr_type type); 59 60static void nasm_parser_directive 61 (yasm_parser_nasm *parser_nasm, const char *name, 62 /*@null@*/ yasm_valparamhead *valparams, 63 /*@null@*/ yasm_valparamhead *objext_valparams); 64static void set_nonlocal_label(yasm_parser_nasm *parser_nasm, const char *name); 65static void define_label(yasm_parser_nasm *parser_nasm, /*@only@*/ char *name, 66 unsigned int size); 67 68static void yasm_ea_set_implicit_size_segment(yasm_parser_nasm *parser_nasm, 69 yasm_effaddr *ea, yasm_expr *e) 70{ 71 if (parser_nasm->tasm) { 72 const char *segment = yasm_expr_segment(e); 73 ea->data_len = yasm_expr_size(e); 74 if (segment) { 75 const char *segreg = tasm_get_segment_register(segment); 76 if (segreg) 77 yasm_arch_parse_check_regtmod(p_object->arch, segreg, 78 strlen(segreg), &ea->segreg); 79 } 80 } 81} 82 83 84#define is_eol_tok(tok) ((tok) == 0) 85#define is_eol() is_eol_tok(curtok) 86 87#define get_next_token() (curtok = nasm_parser_lex(&curval, parser_nasm)) 88 89static void 90get_peek_token(yasm_parser_nasm *parser_nasm) 91{ 92 char savech = parser_nasm->tokch; 93 if (parser_nasm->peek_token != NONE) 94 yasm_internal_error(N_("only can have one token of lookahead")); 95 parser_nasm->peek_token = 96 nasm_parser_lex(&parser_nasm->peek_tokval, parser_nasm); 97 parser_nasm->peek_tokch = parser_nasm->tokch; 98 parser_nasm->tokch = savech; 99} 100 101static void 102destroy_curtok_(yasm_parser_nasm *parser_nasm) 103{ 104 if (curtok < 256) 105 ; 106 else switch ((enum tokentype)curtok) { 107 case INTNUM: 108 yasm_intnum_destroy(curval.intn); 109 break; 110 case FLTNUM: 111 yasm_floatnum_destroy(curval.flt); 112 break; 113 case DIRECTIVE_NAME: 114 case FILENAME: 115 case ID: 116 case LOCAL_ID: 117 case SPECIAL_ID: 118 case NONLOCAL_ID: 119 yasm_xfree(curval.str_val); 120 break; 121 case STRING: 122 yasm_xfree(curval.str.contents); 123 break; 124 case INSN: 125 yasm_bc_destroy(curval.bc); 126 break; 127 default: 128 break; 129 } 130 curtok = NONE; /* sanity */ 131} 132#define destroy_curtok() destroy_curtok_(parser_nasm) 133 134/* Eat all remaining tokens to EOL, discarding all of them. If there's any 135 * intervening tokens, generates an error (junk at end of line). 136 */ 137static void 138demand_eol_(yasm_parser_nasm *parser_nasm) 139{ 140 if (is_eol()) 141 return; 142 143 yasm_error_set(YASM_ERROR_SYNTAX, 144 N_("junk at end of line, first unrecognized character is `%c'"), 145 parser_nasm->tokch); 146 147 do { 148 destroy_curtok(); 149 get_next_token(); 150 } while (!is_eol()); 151} 152#define demand_eol() demand_eol_(parser_nasm) 153 154static const char * 155describe_token(int token) 156{ 157 static char strch[] = "` '"; 158 const char *str; 159 160 switch (token) { 161 case 0: str = "end of line"; break; 162 case INTNUM: str = "integer"; break; 163 case FLTNUM: str = "floating point value"; break; 164 case DIRECTIVE_NAME: str = "directive name"; break; 165 case FILENAME: str = "filename"; break; 166 case STRING: str = "string"; break; 167 case SIZE_OVERRIDE: str = "size override"; break; 168 case DECLARE_DATA: str = "DB/DW/etc."; break; 169 case RESERVE_SPACE: str = "RESB/RESW/etc."; break; 170 case INCBIN: str = "INCBIN"; break; 171 case EQU: str = "EQU"; break; 172 case TIMES: str = "TIMES"; break; 173 case SEG: str = "SEG"; break; 174 case WRT: str = "WRT"; break; 175 case NOSPLIT: str = "NOSPLIT"; break; 176 case STRICT: str = "STRICT"; break; 177 case INSN: str = "instruction"; break; 178 case PREFIX: str = "instruction prefix"; break; 179 case REG: str = "register"; break; 180 case REGGROUP: str = "register group"; break; 181 case SEGREG: str = "segment register"; break; 182 case TARGETMOD: str = "target modifier"; break; 183 case LEFT_OP: str = "<<"; break; 184 case RIGHT_OP: str = ">>"; break; 185 case SIGNDIV: str = "//"; break; 186 case SIGNMOD: str = "%%"; break; 187 case START_SECTION_ID: str = "$$"; break; 188 case ID: str = "identifier"; break; 189 case LOCAL_ID: str = ".identifier"; break; 190 case SPECIAL_ID: str = "..identifier"; break; 191 case NONLOCAL_ID: str = "..@identifier"; break; 192 case LINE: str = "%line"; break; 193 default: 194 strch[1] = token; 195 str = strch; 196 break; 197 } 198 199 return str; 200} 201 202static int 203expect_(yasm_parser_nasm *parser_nasm, int token) 204{ 205 if (curtok == token) 206 return 1; 207 208 yasm_error_set(YASM_ERROR_PARSE, "expected %s", describe_token(token)); 209 destroy_curtok(); 210 return 0; 211} 212#define expect(token) expect_(parser_nasm, token) 213 214void 215nasm_parser_parse(yasm_parser_nasm *parser_nasm) 216{ 217 unsigned char *line; 218 while ((line = (unsigned char *) 219 yasm_preproc_get_line(parser_nasm->preproc)) != NULL) { 220 yasm_bytecode *bc = NULL, *temp_bc; 221 222 parser_nasm->s.bot = line; 223 parser_nasm->s.tok = line; 224 parser_nasm->s.ptr = line; 225 parser_nasm->s.cur = line; 226 parser_nasm->s.lim = line + strlen((char *)line)+1; 227 parser_nasm->s.top = parser_nasm->s.lim; 228 229 get_next_token(); 230 if (!is_eol()) { 231 bc = parse_line(parser_nasm); 232 demand_eol(); 233 } 234 235 if (parser_nasm->abspos) { 236 /* If we're inside an absolute section, just add to the absolute 237 * position rather than appending bytecodes to a section. 238 * Only RES* are allowed in an absolute section, so this is easy. 239 */ 240 if (bc) { 241 /*@null@*/ const yasm_expr *numitems, *multiple; 242 unsigned int itemsize; 243 numitems = yasm_bc_reserve_numitems(bc, &itemsize); 244 if (numitems) { 245 yasm_expr *e; 246 e = yasm_expr_create(YASM_EXPR_MUL, 247 yasm_expr_expr(yasm_expr_copy(numitems)), 248 yasm_expr_int(yasm_intnum_create_uint(itemsize)), 249 cur_line); 250 multiple = yasm_bc_get_multiple_expr(bc); 251 if (multiple) 252 e = yasm_expr_create_tree(e, YASM_EXPR_MUL, 253 yasm_expr_copy(multiple), 254 cur_line); 255 parser_nasm->abspos = yasm_expr_create_tree( 256 parser_nasm->abspos, YASM_EXPR_ADD, e, cur_line); 257 } else 258 yasm_error_set(YASM_ERROR_SYNTAX, 259 N_("only RES* allowed within absolute section")); 260 yasm_bc_destroy(bc); 261 } 262 temp_bc = NULL; 263 } else if (bc) { 264 temp_bc = yasm_section_bcs_append(cursect, bc); 265 if (temp_bc) 266 parser_nasm->prev_bc = temp_bc; 267 } else 268 temp_bc = NULL; 269 yasm_errwarn_propagate(parser_nasm->errwarns, cur_line); 270 271 if (parser_nasm->save_input) 272 yasm_linemap_add_source(parser_nasm->linemap, temp_bc, 273 (char *)line); 274 yasm_linemap_goto_next(parser_nasm->linemap); 275 yasm_xfree(line); 276 } 277} 278 279/* All parse_* functions expect to be called with curtok being their first 280 * token. They should return with curtok being the token *after* their 281 * information. 282 */ 283 284static yasm_bytecode * 285parse_line(yasm_parser_nasm *parser_nasm) 286{ 287 yasm_bytecode *bc; 288 289 bc = parse_exp(parser_nasm); 290 if (bc) 291 return bc; 292 293 switch (curtok) { 294 case LINE: /* LINE INTNUM '+' INTNUM FILENAME */ 295 { 296 yasm_intnum *line, *incr; 297 char *filename; 298 299 get_next_token(); 300 301 if (!expect(INTNUM)) return NULL; 302 line = INTNUM_val; 303 get_next_token(); 304 305 if (!expect('+')) return NULL; 306 get_next_token(); 307 308 if (!expect(INTNUM)) return NULL; 309 incr = INTNUM_val; 310 get_next_token(); 311 312 if (!expect(FILENAME)) return NULL; 313 filename = FILENAME_val; 314 get_next_token(); 315 316 /* %line indicates the line number of the *next* line, so subtract 317 * out the increment when setting the line number. 318 */ 319 yasm_linemap_set(parser_nasm->linemap, filename, 0, 320 yasm_intnum_get_uint(line) - yasm_intnum_get_uint(incr), 321 yasm_intnum_get_uint(incr)); 322 yasm_intnum_destroy(line); 323 yasm_intnum_destroy(incr); 324 yasm_xfree(filename); 325 return NULL; 326 } 327 case '[': /* [ directive ] */ 328 { 329 char *dirname; 330 yasm_valparamhead dir_vps; 331 int have_vps = 1; 332 333 parser_nasm->state = DIRECTIVE; 334 get_next_token(); 335 336 if (!expect(DIRECTIVE_NAME)) 337 return NULL; 338 dirname = DIRECTIVE_NAME_val; 339 get_next_token(); 340 341 /* ignore [warning]. TODO: actually implement */ 342 if (yasm__strcasecmp(dirname, "warning") == 0) { 343 yasm_warn_set(YASM_WARN_GENERAL, 344 N_("[warning] directive not supported; ignored")); 345 346 /* throw away the rest of the directive tokens */ 347 while (!is_eol() && curtok != ']') 348 { 349 destroy_curtok(); 350 get_next_token(); 351 } 352 expect(']'); 353 get_next_token(); 354 return NULL; 355 } 356 357 if (curtok == ']' || curtok == ':') 358 have_vps = 0; 359 else if (!parse_directive_valparams(parser_nasm, &dir_vps)) { 360 yasm_error_set(YASM_ERROR_SYNTAX, 361 N_("invalid arguments to [%s]"), dirname); 362 yasm_xfree(dirname); 363 return NULL; 364 } 365 if (curtok == ':') { 366 yasm_valparamhead ext_vps; 367 get_next_token(); 368 if (!parse_directive_valparams(parser_nasm, &ext_vps)) { 369 yasm_error_set(YASM_ERROR_SYNTAX, 370 N_("invalid arguments to [%s]"), dirname); 371 yasm_xfree(dirname); 372 return NULL; 373 } 374 nasm_parser_directive(parser_nasm, dirname, 375 have_vps ? &dir_vps : NULL, &ext_vps); 376 } else 377 nasm_parser_directive(parser_nasm, dirname, 378 have_vps ? &dir_vps : NULL, NULL); 379 yasm_xfree(dirname); 380 expect(']'); 381 get_next_token(); 382 return NULL; 383 } 384 case TIMES: /* TIMES expr exp */ 385 get_next_token(); 386 return parse_times(parser_nasm); 387 case ID: 388 case SPECIAL_ID: 389 case NONLOCAL_ID: 390 case LOCAL_ID: 391 { 392 char *name = ID_val; 393 int local = parser_nasm->tasm 394 ? (curtok == ID || curtok == LOCAL_ID || 395 (curtok == SPECIAL_ID && name[0] == '@')) 396 : (curtok != ID); 397 unsigned int size = 0; 398 399 get_next_token(); 400 if (is_eol()) { 401 /* label alone on the line */ 402 yasm_warn_set(YASM_WARN_ORPHAN_LABEL, 403 N_("label alone on a line without a colon might be in error")); 404 if (!local) 405 set_nonlocal_label(parser_nasm, name); 406 define_label(parser_nasm, name, 0); 407 return NULL; 408 } 409 if (curtok == ':') 410 get_next_token(); 411 412 if (curtok == EQU || (parser_nasm->tasm && curtok == '=')) { 413 /* label EQU expr */ 414 yasm_expr *e; 415 get_next_token(); 416 417 if (parser_nasm->tasm && curtok == SIZE_OVERRIDE) { 418 size = SIZE_OVERRIDE_val; 419 get_next_token(); 420 } 421 422 e = parse_expr(parser_nasm, NORM_EXPR); 423 if (!e) { 424 yasm_error_set(YASM_ERROR_SYNTAX, 425 N_("expression expected after %s"), "EQU"); 426 yasm_xfree(name); 427 return NULL; 428 } 429 yasm_symtab_define_equ(p_symtab, name, e, cur_line); 430 yasm_xfree(name); 431 return NULL; 432 } 433 434 if (parser_nasm->tasm && curtok == LABEL) 435 get_next_token(); 436 437 if (parser_nasm->tasm && curtok == SIZE_OVERRIDE) { 438 size = SIZE_OVERRIDE_val; 439 get_next_token(); 440 } 441 442 if (!local) 443 set_nonlocal_label(parser_nasm, name); 444 445 if (is_eol()) { 446 define_label(parser_nasm, name, size); 447 return NULL; 448 } 449 if (curtok == TIMES) { 450 define_label(parser_nasm, name, size); 451 get_next_token(); 452 return parse_times(parser_nasm); 453 } 454 bc = parse_exp(parser_nasm); 455 if (!parser_nasm->tasm && !bc) 456 yasm_error_set(YASM_ERROR_SYNTAX, 457 N_("instruction expected after label")); 458 if (parser_nasm->tasm && bc && !size) 459 size = yasm_bc_elem_size(bc); 460 define_label(parser_nasm, name, size); 461 return bc; 462 } 463 default: 464 yasm_error_set(YASM_ERROR_SYNTAX, 465 N_("label or instruction expected at start of line")); 466 return NULL; 467 } 468} 469 470static int 471parse_directive_valparams(yasm_parser_nasm *parser_nasm, 472 /*@out@*/ yasm_valparamhead *vps) 473{ 474 yasm_vps_initialize(vps); 475 for (;;) { 476 yasm_valparam *vp; 477 yasm_expr *e; 478 char *id = NULL; 479 480 /* Look for value first */ 481 if (curtok == ID) { 482 get_peek_token(parser_nasm); 483 if (parser_nasm->peek_token == '=') { 484 id = ID_val; 485 get_next_token(); /* id */ 486 get_next_token(); /* '=' */ 487 } 488 } 489 490 /* Look for parameter */ 491 switch (curtok) { 492 case STRING: 493 vp = yasm_vp_create_string(id, STRING_val.contents); 494 get_next_token(); 495 break; 496 case ID: 497 /* We need a peek token, but avoid error if we have one 498 * already; we need to work whether or not we hit the 499 * "value=" if test above. 500 * 501 * We cheat and peek ahead to see if this is just an ID or 502 * the ID is part of an expression. We assume a + or - means 503 * that it's part of an expression (e.g. "x+y" is parsed as 504 * the expression "x+y" and not as "x", "+y"). 505 */ 506 if (parser_nasm->peek_token == NONE) 507 get_peek_token(parser_nasm); 508 switch (parser_nasm->peek_token) { 509 case '|': case '^': case '&': case LEFT_OP: case RIGHT_OP: 510 case '+': case '-': 511 case '*': case '/': case '%': case SIGNDIV: case SIGNMOD: 512 break; 513 default: 514 /* Just an id */ 515 vp = yasm_vp_create_id(id, ID_val, '$'); 516 get_next_token(); 517 goto next; 518 } 519 /*@fallthrough@*/ 520 default: 521 e = parse_expr(parser_nasm, DIR_EXPR); 522 if (!e) { 523 yasm_vps_delete(vps); 524 return 0; 525 } 526 vp = yasm_vp_create_expr(id, e); 527 break; 528 } 529next: 530 yasm_vps_append(vps, vp); 531 if (curtok == ',') 532 get_next_token(); 533 if (curtok == ']' || curtok == ':' || is_eol()) 534 return 1; 535 } 536} 537 538static yasm_bytecode * 539parse_times(yasm_parser_nasm *parser_nasm) 540{ 541 yasm_expr *multiple; 542 yasm_bytecode *bc; 543 544 multiple = parse_bexpr(parser_nasm, DV_EXPR); 545 if (!multiple) { 546 yasm_error_set(YASM_ERROR_SYNTAX, N_("expression expected after %s"), 547 "TIMES"); 548 return NULL; 549 } 550 bc = parse_exp(parser_nasm); 551 if (!bc) { 552 yasm_error_set(YASM_ERROR_SYNTAX, 553 N_("instruction expected after TIMES expression")); 554 yasm_expr_destroy(multiple); 555 return NULL; 556 } 557 yasm_bc_set_multiple(bc, multiple); 558 return bc; 559} 560 561static yasm_bytecode * 562parse_exp(yasm_parser_nasm *parser_nasm) 563{ 564 yasm_bytecode *bc; 565 566 bc = parse_instr(parser_nasm); 567 if (bc) 568 return bc; 569 570 switch (curtok) { 571 case DECLARE_DATA: 572 { 573 unsigned int size = DECLARE_DATA_val/8; 574 yasm_datavalhead dvs; 575 yasm_dataval *dv; 576 yasm_expr *e, *e2; 577 578 get_next_token(); 579 580 yasm_dvs_initialize(&dvs); 581 for (;;) { 582 if (curtok == STRING) { 583 /* Peek ahead to see if we're in an expr. If we're not, 584 * then generate a real string dataval. 585 */ 586 get_peek_token(parser_nasm); 587 if (parser_nasm->peek_token == ',' 588 || is_eol_tok(parser_nasm->peek_token)) { 589 dv = yasm_dv_create_string(STRING_val.contents, 590 STRING_val.len); 591 get_next_token(); 592 goto dv_done; 593 } 594 } 595 if (curtok == '?') { 596 yasm_dvs_delete(&dvs); 597 get_next_token(); 598 if (! is_eol_tok(curtok)) { 599 yasm_error_set(YASM_ERROR_SYNTAX, 600 N_("can not handle more than one '?'")); 601 return NULL; 602 } 603 return yasm_bc_create_reserve( 604 p_expr_new_ident(yasm_expr_int( 605 yasm_intnum_create_uint(1))), 606 size, cur_line); 607 } 608 if (!(e = parse_bexpr(parser_nasm, DV_EXPR))) { 609 yasm_error_set(YASM_ERROR_SYNTAX, 610 N_("expression or string expected")); 611 yasm_dvs_delete(&dvs); 612 return NULL; 613 } 614 if (curtok == DUP) { 615 get_next_token(); 616 if (curtok != '(') { 617 yasm_error_set(YASM_ERROR_SYNTAX, 618 N_("expected ( after DUP")); 619 goto error; 620 } 621 get_next_token(); 622 if (curtok == '?') { 623 get_next_token(); 624 if (curtok != ')') { 625 yasm_error_set(YASM_ERROR_SYNTAX, 626 N_("expected ) after DUPlicated expression")); 627 goto error; 628 } 629 get_next_token(); 630 if (! is_eol_tok(curtok)) { 631 yasm_error_set(YASM_ERROR_SYNTAX, 632 N_("can not handle more than one '?'")); 633 goto error; 634 } 635 yasm_dvs_delete(&dvs); 636 return yasm_bc_create_reserve(e, size, cur_line); 637 } else if ((e2 = parse_bexpr(parser_nasm, DV_EXPR))) { 638 if (curtok != ')') { 639 yasm_expr_destroy(e2); 640 yasm_error_set(YASM_ERROR_SYNTAX, 641 N_("expected ) after DUPlicated expression")); 642 goto error; 643 } 644 get_next_token(); 645 dv = yasm_dv_create_expr(e2); 646 yasm_dv_set_multiple(dv, e); 647 } else { 648 yasm_error_set(YASM_ERROR_SYNTAX, 649 N_("expression or string expected")); 650error: 651 yasm_expr_destroy(e); 652 yasm_dvs_delete(&dvs); 653 return NULL; 654 } 655 } else 656 dv = yasm_dv_create_expr(e); 657dv_done: 658 yasm_dvs_append(&dvs, dv); 659 if (is_eol()) 660 break; 661 if (!expect(',')) { 662 yasm_dvs_delete(&dvs); 663 return NULL; 664 } 665 get_next_token(); 666 if (is_eol()) /* allow trailing , on list */ 667 break; 668 } 669 return yasm_bc_create_data(&dvs, size, 0, p_object->arch, 670 cur_line); 671 } 672 case RESERVE_SPACE: 673 { 674 unsigned int size = RESERVE_SPACE_val/8; 675 yasm_expr *e; 676 get_next_token(); 677 e = parse_bexpr(parser_nasm, DV_EXPR); 678 if (!e) { 679 yasm_error_set(YASM_ERROR_SYNTAX, 680 N_("expression expected after %s"), "RESx"); 681 return NULL; 682 } 683 return yasm_bc_create_reserve(e, size, cur_line); 684 } 685 case INCBIN: 686 { 687 char *filename; 688 yasm_expr *start = NULL, *maxlen = NULL; 689 690 get_next_token(); 691 692 if (!expect(STRING)) { 693 yasm_error_set(YASM_ERROR_SYNTAX, 694 N_("filename string expected after INCBIN")); 695 return NULL; 696 } 697 filename = STRING_val.contents; 698 get_next_token(); 699 700 /* optional start expression */ 701 if (curtok == ',') 702 get_next_token(); 703 if (is_eol()) 704 goto incbin_done; 705 start = parse_bexpr(parser_nasm, DV_EXPR); 706 if (!start) { 707 yasm_error_set(YASM_ERROR_SYNTAX, 708 N_("expression expected for INCBIN start")); 709 return NULL; 710 } 711 712 /* optional maxlen expression */ 713 if (curtok == ',') 714 get_next_token(); 715 if (is_eol()) 716 goto incbin_done; 717 maxlen = parse_bexpr(parser_nasm, DV_EXPR); 718 if (!maxlen) { 719 yasm_error_set(YASM_ERROR_SYNTAX, 720 N_("expression expected for INCBIN maximum length")); 721 return NULL; 722 } 723 724incbin_done: 725 return yasm_bc_create_incbin(filename, start, maxlen, 726 parser_nasm->linemap, cur_line); 727 } 728 default: 729 return NULL; 730 } 731} 732 733static yasm_bytecode * 734parse_instr(yasm_parser_nasm *parser_nasm) 735{ 736 yasm_bytecode *bc; 737 738 switch (curtok) { 739 case INSN: 740 { 741 yasm_insn *insn; 742 bc = INSN_val; 743 insn = yasm_bc_get_insn(bc); 744 745 get_next_token(); 746 if (is_eol()) 747 return bc; /* no operands */ 748 749 /* parse operands */ 750 for (;;) { 751 yasm_insn_operand *op = parse_operand(parser_nasm); 752 if (!op) { 753 if (insn->num_operands == 0) 754 yasm_error_set(YASM_ERROR_SYNTAX, 755 N_("unexpected %s after instruction"), 756 describe_token(curtok)); 757 else 758 yasm_error_set(YASM_ERROR_SYNTAX, 759 N_("expected operand, got %s"), 760 describe_token(curtok)); 761 yasm_bc_destroy(bc); 762 return NULL; 763 } 764 yasm_insn_ops_append(insn, op); 765 766 if (is_eol()) 767 break; 768 if (!expect(',')) { 769 yasm_bc_destroy(bc); 770 return NULL; 771 } 772 get_next_token(); 773 } 774 return bc; 775 } 776 case PREFIX: 777 { 778 uintptr_t prefix = PREFIX_val; 779 get_next_token(); 780 bc = parse_instr(parser_nasm); 781 if (!bc) 782 bc = yasm_arch_create_empty_insn(p_object->arch, cur_line); 783 yasm_insn_add_prefix(yasm_bc_get_insn(bc), prefix); 784 return bc; 785 } 786 case SEGREG: 787 { 788 uintptr_t segreg = SEGREG_val; 789 get_next_token(); 790 bc = parse_instr(parser_nasm); 791 if (!bc) 792 bc = yasm_arch_create_empty_insn(p_object->arch, cur_line); 793 yasm_insn_add_seg_prefix(yasm_bc_get_insn(bc), segreg); 794 return bc; 795 } 796 default: 797 return NULL; 798 } 799} 800 801static yasm_insn_operand * 802parse_operand(yasm_parser_nasm *parser_nasm) 803{ 804 yasm_insn_operand *op; 805 switch (curtok) { 806 case '[': 807 { 808 get_next_token(); 809 op = parse_memaddr(parser_nasm); 810 811 expect(']'); 812 get_next_token(); 813 814 if (!op) { 815 yasm_error_set(YASM_ERROR_SYNTAX, 816 N_("memory address expected")); 817 return NULL; 818 } 819 820 if (parser_nasm->tasm && !is_eol() && curtok != ',') { 821 yasm_expr *e = NULL, *f; 822 yasm_effaddr *ea; 823 824 switch (op->type) { 825 case YASM_INSN__OPERAND_IMM: 826 e = op->data.val; 827 break; 828 case YASM_INSN__OPERAND_MEMORY: 829 if (op->data.ea->disp.rel) { 830 yasm_error_set(YASM_ERROR_SYNTAX, 831 N_("relative adressing not supported\n")); 832 return NULL; 833 } 834 e = yasm_expr_copy(op->data.ea->disp.abs); 835 yasm_arch_ea_destroy(p_object->arch, op->data.ea); 836 break; 837 case YASM_INSN__OPERAND_REG: 838 case YASM_INSN__OPERAND_SEGREG: 839 yasm_error_set(YASM_ERROR_SYNTAX, 840 N_("register adressing not supported\n")); 841 return NULL; 842 } 843 yasm_xfree(op); 844 f = parse_bexpr(parser_nasm, NORM_EXPR); 845 if (!f) { 846 yasm_expr_destroy(e); 847 yasm_error_set(YASM_ERROR_SYNTAX, 848 N_("expected expression after ]")); 849 return NULL; 850 } 851 e = p_expr_new_tree(e, YASM_EXPR_ADD, f); 852 ea = yasm_arch_ea_create(p_object->arch, e); 853 yasm_ea_set_implicit_size_segment(parser_nasm, ea, e); 854 op = yasm_operand_create_mem(ea); 855 } 856 return op; 857 } 858 case OFFSET: 859 { 860 yasm_insn_operand *op2; 861 get_next_token(); 862 if (parser_nasm->masm && curtok == ID && !yasm__strcasecmp(ID_val, "flat")) { 863 get_next_token(); 864 if (curtok == ':') { 865 get_next_token(); 866 } 867 } 868 op = parse_operand(parser_nasm); 869 if (!op) { 870 yasm_error_set(YASM_ERROR_SYNTAX, 871 N_("memory address expected")); 872 return NULL; 873 } 874 if (op->type == YASM_INSN__OPERAND_IMM) 875 return op; 876 if (op->type != YASM_INSN__OPERAND_MEMORY) { 877 yasm_error_set(YASM_ERROR_SYNTAX, 878 N_("OFFSET applied to non-memory operand")); 879 return NULL; 880 } 881 if (op->data.ea->disp.rel) { 882 yasm_error_set(YASM_ERROR_SYNTAX, 883 N_("OFFSET applied to non-absolute memory operand")); 884 return NULL; 885 } 886 if (op->data.ea->disp.abs) 887 op2 = yasm_operand_create_imm(op->data.ea->disp.abs); 888 else 889 op2 = yasm_operand_create_imm(p_expr_new_ident( 890 yasm_expr_int(yasm_intnum_create_uint(0)))); 891 yasm_xfree(op); 892 return op2; 893 } 894 case SEGREG: 895 { 896 uintptr_t segreg = SEGREG_val; 897 get_next_token(); 898 if (parser_nasm->tasm && curtok == ':') { 899 get_next_token(); 900 op = parse_operand(parser_nasm); 901 if (!op) 902 return NULL; 903 if (op->type == YASM_INSN__OPERAND_IMM) { 904 yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch, 905 op->data.val); 906 yasm_insn_operand *op2; 907 yasm_ea_set_implicit_size_segment(parser_nasm, ea, 908 op->data.val); 909 op2 = yasm_operand_create_mem(ea); 910 op2->size = op->size; 911 yasm_xfree(op); 912 op = op2; 913 } 914 if (op->type != YASM_INSN__OPERAND_MEMORY) { 915 yasm_error_set(YASM_ERROR_SYNTAX, 916 N_("segment applied to non-memory operand")); 917 return NULL; 918 } 919 yasm_ea_set_segreg(op->data.ea, segreg); 920 return op; 921 } 922 op = yasm_operand_create_segreg(segreg); 923 return op; 924 } 925 case REG: 926 op = yasm_operand_create_reg(REG_val); 927 get_next_token(); 928 return op; 929 case REGGROUP: 930 { 931 unsigned long regindex; 932 uintptr_t reg = REGGROUP_val; 933 get_next_token(); /* REGGROUP */ 934 if (curtok != '(') 935 return yasm_operand_create_reg(reg); 936 get_next_token(); /* '(' */ 937 if (!expect(INTNUM)) { 938 yasm_error_set(YASM_ERROR_SYNTAX, 939 N_("integer register index expected")); 940 return NULL; 941 } 942 regindex = yasm_intnum_get_uint(INTNUM_val); 943 get_next_token(); /* INTNUM */ 944 if (!expect(')')) { 945 yasm_error_set(YASM_ERROR_SYNTAX, 946 N_("missing closing parenthesis for register index")); 947 return NULL; 948 } 949 get_next_token(); /* ')' */ 950 reg = yasm_arch_reggroup_get_reg(p_object->arch, reg, regindex); 951 if (reg == 0) { 952 yasm_error_set(YASM_ERROR_SYNTAX, N_("bad register index `%u'"), 953 regindex); 954 return NULL; 955 } 956 return yasm_operand_create_reg(reg); 957 } 958 case STRICT: 959 get_next_token(); 960 op = parse_operand(parser_nasm); 961 if (op) 962 op->strict = 1; 963 return op; 964 case SIZE_OVERRIDE: 965 { 966 unsigned int size = SIZE_OVERRIDE_val; 967 get_next_token(); 968 if (parser_nasm->masm && curtok == ID && !yasm__strcasecmp(ID_val, "ptr")) { 969 get_next_token(); 970 } 971 op = parse_operand(parser_nasm); 972 if (!op) 973 return NULL; 974 if (op->type == YASM_INSN__OPERAND_REG && 975 yasm_arch_get_reg_size(p_object->arch, op->data.reg) != size) 976 yasm_error_set(YASM_ERROR_TYPE, 977 N_("cannot override register size")); 978 else { 979 /* Silently override others unless a warning is turned on. 980 * This is to allow overrides such as: 981 * %define arg1 dword [bp+4] 982 * cmp word arg1, 2 983 * Which expands to: 984 * cmp word dword [bp+4], 2 985 */ 986 if (op->size != 0) { 987 if (op->size != size) 988 yasm_warn_set(YASM_WARN_SIZE_OVERRIDE, 989 N_("overriding operand size from %u-bit to %u-bit"), 990 op->size, size); 991 else 992 yasm_warn_set(YASM_WARN_SIZE_OVERRIDE, 993 N_("double operand size override")); 994 } 995 op->size = size; 996 } 997 return op; 998 } 999 case TARGETMOD: 1000 { 1001 uintptr_t tmod = TARGETMOD_val; 1002 get_next_token(); 1003 op = parse_operand(parser_nasm); 1004 if (op) 1005 op->targetmod = tmod; 1006 return op; 1007 } 1008 case ID: 1009 case LOCAL_ID: 1010 case NONLOCAL_ID: 1011 if (parser_nasm->tasm) { 1012 get_peek_token(parser_nasm); 1013 if (parser_nasm->peek_token == '[') { 1014 yasm_symrec *sym = yasm_symtab_use(p_symtab, ID_val, 1015 cur_line); 1016 yasm_expr *e = p_expr_new_ident(yasm_expr_sym(sym)), *f; 1017 yasm_effaddr *ea; 1018 yasm_xfree(ID_val); 1019 get_next_token(); 1020 get_next_token(); 1021 f = parse_bexpr(parser_nasm, NORM_EXPR); 1022 if (!f) { 1023 yasm_error_set(YASM_ERROR_SYNTAX, 1024 N_("expected expression after [")); 1025 return NULL; 1026 } 1027 e = p_expr_new_tree(e, YASM_EXPR_ADD, f); 1028 if (!expect(']')) { 1029 yasm_error_set(YASM_ERROR_SYNTAX, N_("missing closing bracket")); 1030 return NULL; 1031 } 1032 get_next_token(); 1033 ea = yasm_arch_ea_create(p_object->arch, e); 1034 yasm_ea_set_implicit_size_segment(parser_nasm, ea, e); 1035 op = yasm_operand_create_mem(ea); 1036 return op; 1037 } 1038 } 1039 /* Fallthrough */ 1040 default: 1041 { 1042 yasm_expr *e = parse_bexpr(parser_nasm, NORM_EXPR); 1043 if (!e) 1044 return NULL; 1045 if (curtok != ':') { 1046 if (parser_nasm->tasm && yasm_expr_size(e)) { 1047 yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch, e); 1048 yasm_ea_set_implicit_size_segment(parser_nasm, ea, e); 1049 op = yasm_operand_create_mem(ea); 1050 return op; 1051 } else if (curtok == '[') { 1052 yasm_expr *f; 1053 yasm_effaddr *ea; 1054 yasm_insn_operand *op2; 1055 1056 op = parse_operand(parser_nasm); 1057 if (!op) 1058 return NULL; 1059 1060 f = op->data.ea->disp.abs; 1061 e = p_expr_new_tree(e, YASM_EXPR_ADD, f); 1062 ea = yasm_arch_ea_create(p_object->arch, e); 1063 yasm_ea_set_implicit_size_segment(parser_nasm, ea, e); 1064 op2 = yasm_operand_create_mem(ea); 1065 1066 yasm_xfree(op); 1067 1068 return op2; 1069 } else { 1070 return yasm_operand_create_imm(e); 1071 } 1072 } else { 1073 yasm_expr *off; 1074 get_next_token(); 1075 off = parse_bexpr(parser_nasm, NORM_EXPR); 1076 if (!off) { 1077 yasm_expr_destroy(e); 1078 return NULL; 1079 } 1080 op = yasm_operand_create_imm(off); 1081 op->seg = e; 1082 return op; 1083 } 1084 } 1085 } 1086} 1087 1088/* memory addresses */ 1089static yasm_insn_operand * 1090parse_memaddr(yasm_parser_nasm *parser_nasm) 1091{ 1092 yasm_insn_operand *op; 1093 switch (curtok) { 1094 case SEGREG: 1095 { 1096 uintptr_t segreg = SEGREG_val; 1097 get_next_token(); 1098 if (!expect(':')) { 1099 yasm_error_set(YASM_ERROR_SYNTAX, 1100 N_("`:' required after segment register")); 1101 return NULL; 1102 } 1103 get_next_token(); 1104 op = parse_memaddr(parser_nasm); 1105 if (op) 1106 yasm_ea_set_segreg(op->data.ea, segreg); 1107 return op; 1108 } 1109 case SIZE_OVERRIDE: 1110 { 1111 unsigned int size = SIZE_OVERRIDE_val; 1112 get_next_token(); 1113 op = parse_memaddr(parser_nasm); 1114 if (op) 1115 op->data.ea->disp.size = size; 1116 return op; 1117 } 1118 case NOSPLIT: 1119 get_next_token(); 1120 op = parse_memaddr(parser_nasm); 1121 if (op) 1122 op->data.ea->nosplit = 1; 1123 return op; 1124 case REL: 1125 get_next_token(); 1126 op = parse_memaddr(parser_nasm); 1127 if (op) { 1128 op->data.ea->pc_rel = 1; 1129 op->data.ea->not_pc_rel = 0; 1130 } 1131 return op; 1132 case ABS: 1133 get_next_token(); 1134 op = parse_memaddr(parser_nasm); 1135 if (op) { 1136 op->data.ea->pc_rel = 0; 1137 op->data.ea->not_pc_rel = 1; 1138 } 1139 return op; 1140 default: 1141 { 1142 yasm_expr *e = parse_bexpr(parser_nasm, NORM_EXPR); 1143 if (!e) 1144 return NULL; 1145 if (curtok != ':') { 1146 yasm_effaddr *ea = yasm_arch_ea_create(p_object->arch, e); 1147 yasm_ea_set_implicit_size_segment(parser_nasm, ea, e); 1148 return yasm_operand_create_mem(ea); 1149 } else { 1150 yasm_effaddr *ea; 1151 yasm_expr *off; 1152 get_next_token(); 1153 off = parse_bexpr(parser_nasm, NORM_EXPR); 1154 if (!off) { 1155 yasm_expr_destroy(e); 1156 return NULL; 1157 } 1158 ea = yasm_arch_ea_create(p_object->arch, off); 1159 yasm_ea_set_implicit_size_segment(parser_nasm, ea, off); 1160 op = yasm_operand_create_mem(ea); 1161 op->seg = e; 1162 return op; 1163 } 1164 } 1165 } 1166} 1167 1168/* Expression grammar parsed is: 1169 * 1170 * expr : bexpr [ : bexpr ] 1171 * bexpr : expr0 [ WRT expr6 ] 1172 * expr0 : expr1 [ {|} expr1...] 1173 * expr1 : expr2 [ {^} expr2...] 1174 * expr2 : expr3 [ {&} expr3...] 1175 * expr3 : expr4 [ {<<,>>} expr4...] 1176 * expr4 : expr5 [ {+,-} expr5...] 1177 * expr5 : expr6 [ {*,/,%,//,%%} expr6...] 1178 * expr6 : { ~,+,-,SEG } expr6 1179 * | (expr) 1180 * | symbol 1181 * | $ 1182 * | number 1183 */ 1184 1185#define parse_expr_common(leftfunc, tok, rightfunc, op) \ 1186 do { \ 1187 yasm_expr *e, *f; \ 1188 e = leftfunc(parser_nasm, type); \ 1189 if (!e) \ 1190 return NULL; \ 1191 \ 1192 while (curtok == tok) { \ 1193 get_next_token(); \ 1194 f = rightfunc(parser_nasm, type); \ 1195 if (!f) { \ 1196 yasm_error_set(YASM_ERROR_SYNTAX, \ 1197 N_("expected expression after %s"), \ 1198 describe_token(op)); \ 1199 yasm_expr_destroy(e); \ 1200 return NULL; \ 1201 } \ 1202 e = p_expr_new_tree(e, op, f); \ 1203 } \ 1204 return e; \ 1205 } while(0) 1206 1207static yasm_expr * 1208parse_expr(yasm_parser_nasm *parser_nasm, expr_type type) 1209{ 1210 switch (type) { 1211 case DIR_EXPR: 1212 /* directive expressions can't handle seg:off or WRT */ 1213 return parse_expr0(parser_nasm, type); 1214 default: 1215 parse_expr_common(parse_bexpr, ':', parse_bexpr, YASM_EXPR_SEGOFF); 1216 } 1217 /*@notreached@*/ 1218 return NULL; 1219} 1220 1221static yasm_expr * 1222parse_bexpr(yasm_parser_nasm *parser_nasm, expr_type type) 1223{ 1224 parse_expr_common(parse_expr0, WRT, parse_expr6, YASM_EXPR_WRT); 1225} 1226 1227static yasm_expr * 1228parse_expr0(yasm_parser_nasm *parser_nasm, expr_type type) 1229{ 1230 parse_expr_common(parse_expr1, '|', parse_expr1, YASM_EXPR_OR); 1231} 1232 1233static yasm_expr * 1234parse_expr1(yasm_parser_nasm *parser_nasm, expr_type type) 1235{ 1236 parse_expr_common(parse_expr2, '^', parse_expr2, YASM_EXPR_XOR); 1237} 1238 1239static yasm_expr * 1240parse_expr2(yasm_parser_nasm *parser_nasm, expr_type type) 1241{ 1242 parse_expr_common(parse_expr3, '&', parse_expr3, YASM_EXPR_AND); 1243} 1244 1245static yasm_expr * 1246parse_expr3(yasm_parser_nasm *parser_nasm, expr_type type) 1247{ 1248 yasm_expr *e, *f; 1249 e = parse_expr4(parser_nasm, type); 1250 if (!e) 1251 return NULL; 1252 1253 while (curtok == LEFT_OP || curtok == RIGHT_OP) { 1254 int op = curtok; 1255 get_next_token(); 1256 f = parse_expr4(parser_nasm, type); 1257 if (!f) { 1258 yasm_error_set(YASM_ERROR_SYNTAX, 1259 N_("expected expression after %s"), 1260 describe_token(op)); 1261 yasm_expr_destroy(e); 1262 return NULL; 1263 } 1264 1265 switch (op) { 1266 case LEFT_OP: e = p_expr_new_tree(e, YASM_EXPR_SHL, f); break; 1267 case RIGHT_OP: e = p_expr_new_tree(e, YASM_EXPR_SHR, f); break; 1268 } 1269 } 1270 return e; 1271} 1272 1273static yasm_expr * 1274parse_expr4(yasm_parser_nasm *parser_nasm, expr_type type) 1275{ 1276 yasm_expr *e, *f; 1277 e = parse_expr5(parser_nasm, type); 1278 if (!e) 1279 return NULL; 1280 1281 while (curtok == '+' || curtok == '-') { 1282 int op = curtok; 1283 get_next_token(); 1284 f = parse_expr5(parser_nasm, type); 1285 if (!f) { 1286 yasm_error_set(YASM_ERROR_SYNTAX, 1287 N_("expected expression after %s"), 1288 describe_token(op)); 1289 yasm_expr_destroy(e); 1290 return NULL; 1291 } 1292 1293 switch (op) { 1294 case '+': e = p_expr_new_tree(e, YASM_EXPR_ADD, f); break; 1295 case '-': e = p_expr_new_tree(e, YASM_EXPR_SUB, f); break; 1296 } 1297 } 1298 return e; 1299} 1300 1301static yasm_expr * 1302parse_expr5(yasm_parser_nasm *parser_nasm, expr_type type) 1303{ 1304 yasm_expr *e, *f; 1305 e = parse_expr6(parser_nasm, type); 1306 if (!e) 1307 return NULL; 1308 1309 while (curtok == '*' || curtok == '/' || curtok == '%' 1310 || curtok == SIGNDIV || curtok == SIGNMOD) { 1311 int op = curtok; 1312 get_next_token(); 1313 f = parse_expr6(parser_nasm, type); 1314 if (!f) { 1315 yasm_error_set(YASM_ERROR_SYNTAX, 1316 N_("expected expression after %s"), 1317 describe_token(op)); 1318 yasm_expr_destroy(e); 1319 return NULL; 1320 } 1321 1322 switch (op) { 1323 case '*': e = p_expr_new_tree(e, YASM_EXPR_MUL, f); break; 1324 case '/': e = p_expr_new_tree(e, YASM_EXPR_DIV, f); break; 1325 case '%': e = p_expr_new_tree(e, YASM_EXPR_MOD, f); break; 1326 case SIGNDIV: e = p_expr_new_tree(e, YASM_EXPR_SIGNDIV, f); break; 1327 case SIGNMOD: e = p_expr_new_tree(e, YASM_EXPR_SIGNMOD, f); break; 1328 } 1329 } 1330 return e; 1331} 1332 1333static yasm_expr * 1334parse_expr6(yasm_parser_nasm *parser_nasm, expr_type type) 1335{ 1336 yasm_expr *e; 1337 yasm_symrec *sym; 1338 1339 switch (curtok) { 1340 case '+': 1341 get_next_token(); 1342 e = parse_expr6(parser_nasm, type); 1343 if (!e) { 1344 yasm_error_set(YASM_ERROR_SYNTAX, 1345 N_("expected expression after %s"), "`+'"); 1346 } 1347 return e; 1348 case '-': 1349 get_next_token(); 1350 e = parse_expr6(parser_nasm, type); 1351 if (!e) { 1352 yasm_error_set(YASM_ERROR_SYNTAX, 1353 N_("expected expression after %s"), "`-'"); 1354 return NULL; 1355 } 1356 return p_expr_new_branch(YASM_EXPR_NEG, e); 1357 case '~': 1358 get_next_token(); 1359 e = parse_expr6(parser_nasm, type); 1360 if (!e) { 1361 yasm_error_set(YASM_ERROR_SYNTAX, 1362 N_("expected expression after %s"), "`~'"); 1363 return NULL; 1364 } 1365 return p_expr_new_branch(YASM_EXPR_NOT, e); 1366 case LOW: 1367 get_next_token(); 1368 e = parse_expr6(parser_nasm, type); 1369 if (!e) { 1370 yasm_error_set(YASM_ERROR_SYNTAX, 1371 N_("expected expression after %s"), "LOW"); 1372 return NULL; 1373 } 1374 return p_expr_new_tree(e, YASM_EXPR_AND, 1375 p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0xff)))); 1376 case HIGH: 1377 get_next_token(); 1378 e = parse_expr6(parser_nasm, type); 1379 if (!e) { 1380 yasm_error_set(YASM_ERROR_SYNTAX, 1381 N_("expected expression after %s"), "HIGH"); 1382 return NULL; 1383 } 1384 return p_expr_new_tree( 1385 p_expr_new_tree(e, YASM_EXPR_SHR, 1386 p_expr_new_ident(yasm_expr_int( 1387 yasm_intnum_create_uint(8)))), 1388 YASM_EXPR_AND, 1389 p_expr_new_ident(yasm_expr_int(yasm_intnum_create_uint(0xff)))); 1390 case SEG: 1391 get_next_token(); 1392 e = parse_expr6(parser_nasm, type); 1393 if (!e) { 1394 yasm_error_set(YASM_ERROR_SYNTAX, 1395 N_("expected expression after %s"), "SEG"); 1396 return NULL; 1397 } 1398 return p_expr_new_branch(YASM_EXPR_SEG, e); 1399 case '(': 1400 get_next_token(); 1401 e = parse_expr(parser_nasm, type); 1402 if (!e) { 1403 yasm_error_set(YASM_ERROR_SYNTAX, 1404 N_("expected expression after %s"), "`('"); 1405 return NULL; 1406 } 1407 if (!expect(')')) { 1408 yasm_error_set(YASM_ERROR_SYNTAX, N_("missing parenthesis")); 1409 return NULL; 1410 } 1411 get_next_token(); 1412 return e; 1413 case INTNUM: 1414 e = p_expr_new_ident(yasm_expr_int(INTNUM_val)); 1415 get_next_token(); 1416 return e; 1417 case REG: 1418 if (type == DV_EXPR) { 1419 yasm_error_set(YASM_ERROR_SYNTAX, 1420 N_("data values can't have registers")); 1421 return NULL; 1422 } 1423 e = p_expr_new_ident(yasm_expr_reg(REG_val)); 1424 get_next_token(); 1425 return e; 1426 } 1427 1428 /* directives allow very little and handle IDs specially */ 1429 if (type == DIR_EXPR) { 1430 switch (curtok) { 1431 case ID: 1432 sym = yasm_symtab_use(p_symtab, ID_val, cur_line); 1433 e = p_expr_new_ident(yasm_expr_sym(sym)); 1434 yasm_xfree(ID_val); 1435 break; 1436 default: 1437 return NULL; 1438 } 1439 } else switch (curtok) { 1440 case FLTNUM: 1441 e = p_expr_new_ident(yasm_expr_float(FLTNUM_val)); 1442 break; 1443 case STRING: 1444 { 1445 yasm_intnum *intn; 1446 if (parser_nasm->tasm) 1447 intn = yasm_intnum_create_charconst_tasm(STRING_val.contents); 1448 else 1449 intn = yasm_intnum_create_charconst_nasm(STRING_val.contents); 1450 e = p_expr_new_ident(yasm_expr_int(intn)); 1451 yasm_xfree(STRING_val.contents); 1452 break; 1453 } 1454 case SPECIAL_ID: 1455 sym = yasm_objfmt_get_special_sym(p_object, ID_val+2, "nasm"); 1456 if (sym) { 1457 e = p_expr_new_ident(yasm_expr_sym(sym)); 1458 yasm_xfree(ID_val); 1459 break; 1460 } 1461 /*@fallthrough@*/ 1462 case ID: 1463 case LOCAL_ID: 1464 case NONLOCAL_ID: 1465 sym = yasm_symtab_use(p_symtab, ID_val, cur_line); 1466 e = p_expr_new_ident(yasm_expr_sym(sym)); 1467 yasm_xfree(ID_val); 1468 break; 1469 case '$': 1470 /* "$" references the current assembly position */ 1471 if (parser_nasm->abspos) 1472 e = yasm_expr_copy(parser_nasm->abspos); 1473 else { 1474 sym = yasm_symtab_define_curpos(p_symtab, "$", 1475 parser_nasm->prev_bc, cur_line); 1476 e = p_expr_new_ident(yasm_expr_sym(sym)); 1477 } 1478 break; 1479 case START_SECTION_ID: 1480 /* "$$" references the start of the current section */ 1481 if (parser_nasm->absstart) 1482 e = yasm_expr_copy(parser_nasm->absstart); 1483 else { 1484 sym = yasm_symtab_define_label(p_symtab, "$$", 1485 yasm_section_bcs_first(cursect), 0, cur_line); 1486 e = p_expr_new_ident(yasm_expr_sym(sym)); 1487 } 1488 break; 1489 default: 1490 return NULL; 1491 } 1492 1493 get_next_token(); 1494 return e; 1495} 1496 1497static void 1498set_nonlocal_label(yasm_parser_nasm *parser_nasm, const char *name) 1499{ 1500 if (!parser_nasm->tasm || tasm_locals) { 1501 if (parser_nasm->locallabel_base) 1502 yasm_xfree(parser_nasm->locallabel_base); 1503 parser_nasm->locallabel_base_len = strlen(name); 1504 parser_nasm->locallabel_base = 1505 yasm_xmalloc(parser_nasm->locallabel_base_len+1); 1506 strcpy(parser_nasm->locallabel_base, name); 1507 } 1508} 1509 1510static void 1511define_label(yasm_parser_nasm *parser_nasm, char *name, unsigned int size) 1512{ 1513 yasm_symrec *symrec; 1514 1515 if (parser_nasm->abspos) 1516 symrec = yasm_symtab_define_equ(p_symtab, name, 1517 yasm_expr_copy(parser_nasm->abspos), 1518 cur_line); 1519 else 1520 symrec = yasm_symtab_define_label(p_symtab, name, parser_nasm->prev_bc, 1521 1, cur_line); 1522 1523 yasm_symrec_set_size(symrec, size); 1524 yasm_symrec_set_segment(symrec, tasm_segment); 1525 1526 yasm_xfree(name); 1527} 1528 1529static void 1530dir_align(yasm_object *object, yasm_valparamhead *valparams, 1531 yasm_valparamhead *objext_valparams, unsigned long line) 1532{ 1533 yasm_valparam *vp = yasm_vps_first(valparams); 1534 yasm_expr *boundval = yasm_vp_expr(vp, object->symtab, line); 1535 /*@depedent@*/ yasm_intnum *boundintn; 1536 1537 /* Largest .align in the section specifies section alignment. 1538 * Note: this doesn't match NASM behavior, but is a lot more 1539 * intelligent! 1540 */ 1541 if (boundval && (boundintn = yasm_expr_get_intnum(&boundval, 0))) { 1542 unsigned long boundint = yasm_intnum_get_uint(boundintn); 1543 1544 /* Alignments must be a power of two. */ 1545 if (is_exp2(boundint)) { 1546 if (boundint > yasm_section_get_align(object->cur_section)) 1547 yasm_section_set_align(object->cur_section, boundint, line); 1548 } 1549 } 1550 1551 /* As this directive is called only when nop is used as fill, always 1552 * use arch (nop) fill. 1553 */ 1554 yasm_section_bcs_append(object->cur_section, 1555 yasm_bc_create_align(boundval, NULL, NULL, 1556 /*yasm_section_is_code(object->cur_section) ?*/ 1557 yasm_arch_get_fill(object->arch)/* : NULL*/, 1558 line)); 1559} 1560 1561static void 1562nasm_parser_directive(yasm_parser_nasm *parser_nasm, const char *name, 1563 yasm_valparamhead *valparams, 1564 yasm_valparamhead *objext_valparams) 1565{ 1566 unsigned long line = cur_line; 1567 yasm_valparam *vp; 1568 1569 if (!yasm_object_directive(p_object, name, "nasm", valparams, 1570 objext_valparams, line)) 1571 ; 1572 else if (yasm__strcasecmp(name, "absolute") == 0) { 1573 if (!valparams) { 1574 yasm_error_set(YASM_ERROR_SYNTAX, 1575 N_("directive `%s' requires an argument"), 1576 "absolute"); 1577 } else { 1578 vp = yasm_vps_first(valparams); 1579 if (parser_nasm->absstart) 1580 yasm_expr_destroy(parser_nasm->absstart); 1581 if (parser_nasm->abspos) 1582 yasm_expr_destroy(parser_nasm->abspos); 1583 parser_nasm->absstart = yasm_vp_expr(vp, p_object->symtab, line); 1584 parser_nasm->abspos = yasm_expr_copy(parser_nasm->absstart); 1585 cursect = NULL; 1586 parser_nasm->prev_bc = NULL; 1587 } 1588 } else if (yasm__strcasecmp(name, "align") == 0) { 1589 /* Really, we shouldn't end up with an align directive in an absolute 1590 * section (as it's supposed to be only used for nop fill), but handle 1591 * it gracefully anyway. 1592 */ 1593 if (parser_nasm->abspos) { 1594 yasm_expr *boundval, *e; 1595 vp = yasm_vps_first(valparams); 1596 boundval = yasm_vp_expr(vp, p_object->symtab, line); 1597 e = yasm_expr_create_tree( 1598 yasm_expr_create_tree(yasm_expr_copy(parser_nasm->absstart), 1599 YASM_EXPR_SUB, 1600 yasm_expr_copy(parser_nasm->abspos), 1601 cur_line), 1602 YASM_EXPR_AND, 1603 yasm_expr_create(YASM_EXPR_SUB, yasm_expr_expr(boundval), 1604 yasm_expr_int(yasm_intnum_create_uint(1)), 1605 cur_line), 1606 cur_line); 1607 parser_nasm->abspos = yasm_expr_create_tree( 1608 parser_nasm->abspos, YASM_EXPR_ADD, e, cur_line); 1609 } else if (!valparams) { 1610 yasm_error_set(YASM_ERROR_SYNTAX, 1611 N_("directive `%s' requires an argument"), "align"); 1612 } else 1613 dir_align(p_object, valparams, objext_valparams, line); 1614 } else if (yasm__strcasecmp(name, "default") == 0) { 1615 if (!valparams) 1616 ; 1617 else { 1618 vp = yasm_vps_first(valparams); 1619 while (vp) { 1620 const char *id = yasm_vp_id(vp); 1621 if (id) { 1622 if (yasm__strcasecmp(id, "rel") == 0) 1623 yasm_arch_set_var(p_object->arch, "default_rel", 1); 1624 else if (yasm__strcasecmp(id, "abs") == 0) 1625 yasm_arch_set_var(p_object->arch, "default_rel", 0); 1626 else 1627 yasm_error_set(YASM_ERROR_SYNTAX, 1628 N_("unrecognized default `%s'"), id); 1629 } else 1630 yasm_error_set(YASM_ERROR_SYNTAX, 1631 N_("unrecognized default value")); 1632 vp = yasm_vps_next(vp); 1633 } 1634 } 1635 } else 1636 yasm_error_set(YASM_ERROR_SYNTAX, N_("unrecognized directive `%s'"), 1637 name); 1638 1639 if (parser_nasm->absstart && cursect) { 1640 /* We switched to a new section. Get out of absolute section mode. */ 1641 yasm_expr_destroy(parser_nasm->absstart); 1642 parser_nasm->absstart = NULL; 1643 if (parser_nasm->abspos) { 1644 yasm_expr_destroy(parser_nasm->abspos); 1645 parser_nasm->abspos = NULL; 1646 } 1647 } 1648 1649 if (cursect) { 1650 /* In case cursect changed or a bytecode was added, update prev_bc. */ 1651 parser_nasm->prev_bc = yasm_section_bcs_last(cursect); 1652 } 1653 1654 if (valparams) 1655 yasm_vps_delete(valparams); 1656 if (objext_valparams) 1657 yasm_vps_delete(objext_valparams); 1658} 1659 1660yasm_bytecode * 1661gas_intel_syntax_parse_instr(yasm_parser_nasm *parser_nasm, unsigned char *instr) 1662{ 1663 yasm_bytecode *bc = NULL; 1664 char *sinstr = (char *) instr; 1665 1666 parser_nasm->s.bot = instr; 1667 parser_nasm->s.tok = instr; 1668 parser_nasm->s.ptr = instr; 1669 parser_nasm->s.cur = instr; 1670 parser_nasm->s.lim = instr + strlen(sinstr) + 1; 1671 parser_nasm->s.top = parser_nasm->s.lim; 1672 parser_nasm->peek_token = NONE; 1673 1674 get_next_token(); 1675 if (!is_eol()) { 1676 bc = parse_instr(parser_nasm); 1677 } 1678 1679 return bc; 1680} 1681