| OLD | NEW |
| 1 /* | 1 /* |
| 2 * GAS-compatible parser | 2 * GAS-compatible parser |
| 3 * | 3 * |
| 4 * Copyright (C) 2005-2007 Peter Johnson | 4 * Copyright (C) 2005-2007 Peter Johnson |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
| 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 28 * POSSIBILITY OF SUCH DAMAGE. | 28 * POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 #include <util.h> | 30 #include <util.h> |
| 31 RCSID("$Id: gas-parse.c 2169 2009-01-02 20:46:57Z peter $"); | 31 RCSID("$Id: gas-parse.c 2279 2010-01-19 07:57:43Z peter $"); |
| 32 | 32 |
| 33 #include <libyasm.h> | 33 #include <libyasm.h> |
| 34 | 34 |
| 35 #include <ctype.h> | 35 #include <ctype.h> |
| 36 #include <limits.h> | 36 #include <limits.h> |
| 37 #include <math.h> | 37 #include <math.h> |
| 38 | 38 |
| 39 #include "modules/parsers/gas/gas-parser.h" | 39 #include "modules/parsers/gas/gas-parser.h" |
| 40 | 40 |
| 41 typedef struct dir_lookup { | 41 typedef struct dir_lookup { |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 while (curtok != '\n') | 314 while (curtok != '\n') |
| 315 get_next_token(); | 315 get_next_token(); |
| 316 | 316 |
| 317 return; | 317 return; |
| 318 } | 318 } |
| 319 | 319 |
| 320 filename = STRING_val.contents; | 320 filename = STRING_val.contents; |
| 321 get_next_token(); | 321 get_next_token(); |
| 322 | 322 |
| 323 /* Set linemap. */ | 323 /* Set linemap. */ |
| 324 yasm_linemap_set(parser_gas->linemap, filename, line, 1); | 324 yasm_linemap_set(parser_gas->linemap, filename, 0, line, 1); |
| 325 | 325 |
| 326 /* | 326 /* |
| 327 The first line marker in the file (which should be on the first line | 327 The first line marker in the file (which should be on the first line |
| 328 of the file) will give us the name of the source file. This information | 328 of the file) will give us the name of the source file. This information |
| 329 needs to be passed on to the debug format module. | 329 needs to be passed on to the debug format module. |
| 330 */ | 330 */ |
| 331 if (parser_gas->seen_line_marker == 0) { | 331 if (parser_gas->seen_line_marker == 0) { |
| 332 parser_gas->seen_line_marker = 1; | 332 parser_gas->seen_line_marker = 1; |
| 333 | 333 |
| 334 yasm_vps_initialize(&vps); | 334 yasm_vps_initialize(&vps); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 parser_gas->state = NASM_FILENAME; | 422 parser_gas->state = NASM_FILENAME; |
| 423 get_next_token(); /* INTNUM */ | 423 get_next_token(); /* INTNUM */ |
| 424 if (!expect(STRING)) { | 424 if (!expect(STRING)) { |
| 425 parser_gas->state = INITIAL; | 425 parser_gas->state = INITIAL; |
| 426 return; | 426 return; |
| 427 } | 427 } |
| 428 | 428 |
| 429 filename = STRING_val.contents; | 429 filename = STRING_val.contents; |
| 430 | 430 |
| 431 /* Set linemap. */ | 431 /* Set linemap. */ |
| 432 yasm_linemap_set(parser_gas->linemap, filename, line, incr); | 432 yasm_linemap_set(parser_gas->linemap, filename, 0, line, incr); |
| 433 | 433 |
| 434 /* | 434 /* |
| 435 The first line marker in the file (which should be on the first line | 435 The first line marker in the file (which should be on the first line |
| 436 of the file) will give us the name of the source file. This information | 436 of the file) will give us the name of the source file. This information |
| 437 needs to be passed on to the debug format module. | 437 needs to be passed on to the debug format module. |
| 438 */ | 438 */ |
| 439 if (parser_gas->seen_line_marker == 0) { | 439 if (parser_gas->seen_line_marker == 0) { |
| 440 parser_gas->seen_line_marker = 1; | 440 parser_gas->seen_line_marker = 1; |
| 441 | 441 |
| 442 yasm_vps_initialize(&vps); | 442 yasm_vps_initialize(&vps); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 465 N_("line number is negative")); | 465 N_("line number is negative")); |
| 466 return NULL; | 466 return NULL; |
| 467 } | 467 } |
| 468 | 468 |
| 469 parser_gas->dir_line = yasm_intnum_get_uint(INTNUM_val); | 469 parser_gas->dir_line = yasm_intnum_get_uint(INTNUM_val); |
| 470 yasm_intnum_destroy(INTNUM_val); | 470 yasm_intnum_destroy(INTNUM_val); |
| 471 get_next_token(); /* INTNUM */ | 471 get_next_token(); /* INTNUM */ |
| 472 | 472 |
| 473 if (parser_gas->dir_fileline == 3) { | 473 if (parser_gas->dir_fileline == 3) { |
| 474 /* Have both file and line */ | 474 /* Have both file and line */ |
| 475 yasm_linemap_set(parser_gas->linemap, NULL, | 475 yasm_linemap_set(parser_gas->linemap, NULL, 0, |
| 476 parser_gas->dir_line, 1); | 476 parser_gas->dir_line, 1); |
| 477 } else if (parser_gas->dir_fileline == 1) { | 477 } else if (parser_gas->dir_fileline == 1) { |
| 478 /* Had previous file directive only */ | 478 /* Had previous file directive only */ |
| 479 parser_gas->dir_fileline = 3; | 479 parser_gas->dir_fileline = 3; |
| 480 yasm_linemap_set(parser_gas->linemap, parser_gas->dir_file, | 480 yasm_linemap_set(parser_gas->linemap, parser_gas->dir_file, 0, |
| 481 parser_gas->dir_line, 1); | 481 parser_gas->dir_line, 1); |
| 482 } else { | 482 } else { |
| 483 /* Didn't see file yet */ | 483 /* Didn't see file yet */ |
| 484 parser_gas->dir_fileline = 2; | 484 parser_gas->dir_fileline = 2; |
| 485 } | 485 } |
| 486 return NULL; | 486 return NULL; |
| 487 } | 487 } |
| 488 | 488 |
| 489 /* Macro directives */ | |
| 490 | |
| 491 static yasm_bytecode * | |
| 492 dir_rept(yasm_parser_gas *parser_gas, unsigned int param) | |
| 493 { | |
| 494 yasm_intnum *intn; | |
| 495 yasm_expr *e = parse_expr(parser_gas); | |
| 496 | |
| 497 if (!e) { | |
| 498 yasm_error_set(YASM_ERROR_SYNTAX, | |
| 499 N_("expression expected after `%s'"), | |
| 500 ".rept"); | |
| 501 return NULL; | |
| 502 } | |
| 503 intn = yasm_expr_get_intnum(&e, 0); | |
| 504 | |
| 505 if (!intn) { | |
| 506 yasm_error_set(YASM_ERROR_NOT_ABSOLUTE, | |
| 507 N_("rept expression not absolute")); | |
| 508 } else if (yasm_intnum_sign(intn) < 0) { | |
| 509 yasm_error_set(YASM_ERROR_VALUE, | |
| 510 N_("rept expression is negative")); | |
| 511 } else { | |
| 512 gas_rept *rept = yasm_xmalloc(sizeof(gas_rept)); | |
| 513 STAILQ_INIT(&rept->lines); | |
| 514 rept->startline = cur_line; | |
| 515 rept->numrept = yasm_intnum_get_uint(intn); | |
| 516 rept->numdone = 0; | |
| 517 rept->line = NULL; | |
| 518 rept->linepos = 0; | |
| 519 rept->ended = 0; | |
| 520 rept->oldbuf = NULL; | |
| 521 rept->oldbuflen = 0; | |
| 522 rept->oldbufpos = 0; | |
| 523 parser_gas->rept = rept; | |
| 524 } | |
| 525 return NULL; | |
| 526 } | |
| 527 | |
| 528 static yasm_bytecode * | |
| 529 dir_endr(yasm_parser_gas *parser_gas, unsigned int param) | |
| 530 { | |
| 531 /* Shouldn't ever get here unless we didn't get a DIR_REPT first */ | |
| 532 yasm_error_set(YASM_ERROR_SYNTAX, N_("endr without matching rept")); | |
| 533 return NULL; | |
| 534 } | |
| 535 | |
| 536 /* Alignment directives */ | 489 /* Alignment directives */ |
| 537 | 490 |
| 538 static yasm_bytecode * | 491 static yasm_bytecode * |
| 539 dir_align(yasm_parser_gas *parser_gas, unsigned int param) | 492 dir_align(yasm_parser_gas *parser_gas, unsigned int param) |
| 540 { | 493 { |
| 541 yasm_expr *bound, *fill=NULL, *maxskip=NULL; | 494 yasm_expr *bound, *fill=NULL, *maxskip=NULL; |
| 542 | 495 |
| 543 bound = parse_expr(parser_gas); | 496 bound = parse_expr(parser_gas); |
| 544 if (!bound) { | 497 if (!bound) { |
| 545 yasm_error_set(YASM_ERROR_SYNTAX, | 498 yasm_error_set(YASM_ERROR_SYNTAX, |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 char *filename = STRING_val.contents; | 823 char *filename = STRING_val.contents; |
| 871 | 824 |
| 872 get_next_token(); /* STRING */ | 825 get_next_token(); /* STRING */ |
| 873 if (parser_gas->dir_fileline == 3) { | 826 if (parser_gas->dir_fileline == 3) { |
| 874 /* Have both file and line */ | 827 /* Have both file and line */ |
| 875 const char *old_fn; | 828 const char *old_fn; |
| 876 unsigned long old_line; | 829 unsigned long old_line; |
| 877 | 830 |
| 878 yasm_linemap_lookup(parser_gas->linemap, cur_line, &old_fn, | 831 yasm_linemap_lookup(parser_gas->linemap, cur_line, &old_fn, |
| 879 &old_line); | 832 &old_line); |
| 880 yasm_linemap_set(parser_gas->linemap, filename, old_line, | 833 yasm_linemap_set(parser_gas->linemap, filename, 0, old_line, |
| 881 1); | 834 1); |
| 882 } else if (parser_gas->dir_fileline == 2) { | 835 } else if (parser_gas->dir_fileline == 2) { |
| 883 /* Had previous line directive only */ | 836 /* Had previous line directive only */ |
| 884 parser_gas->dir_fileline = 3; | 837 parser_gas->dir_fileline = 3; |
| 885 yasm_linemap_set(parser_gas->linemap, filename, | 838 yasm_linemap_set(parser_gas->linemap, filename, 0, |
| 886 parser_gas->dir_line, 1); | 839 parser_gas->dir_line, 1); |
| 887 } else { | 840 } else { |
| 888 /* Didn't see line yet, save file */ | 841 /* Didn't see line yet, save file */ |
| 889 parser_gas->dir_fileline = 1; | 842 parser_gas->dir_fileline = 1; |
| 890 if (parser_gas->dir_file) | 843 if (parser_gas->dir_file) |
| 891 yasm_xfree(parser_gas->dir_file); | 844 yasm_xfree(parser_gas->dir_file); |
| 892 parser_gas->dir_file = yasm__xstrdup(filename); | 845 parser_gas->dir_file = yasm__xstrdup(filename); |
| 893 } | 846 } |
| 894 | 847 |
| 895 /* Pass change along to debug format */ | 848 /* Pass change along to debug format */ |
| (...skipping 25 matching lines...) Expand all Loading... |
| 921 yasm_vps_append(&vps, vp); | 874 yasm_vps_append(&vps, vp); |
| 922 get_next_token(); /* STRING */ | 875 get_next_token(); /* STRING */ |
| 923 | 876 |
| 924 yasm_object_directive(p_object, ".file", "gas", &vps, NULL, | 877 yasm_object_directive(p_object, ".file", "gas", &vps, NULL, |
| 925 cur_line); | 878 cur_line); |
| 926 | 879 |
| 927 yasm_vps_delete(&vps); | 880 yasm_vps_delete(&vps); |
| 928 return NULL; | 881 return NULL; |
| 929 } | 882 } |
| 930 | 883 |
| 884 |
| 885 static yasm_bytecode * |
| 886 dir_intel_syntax(yasm_parser_gas *parser_gas, unsigned int param) |
| 887 { |
| 888 parser_gas->intel_syntax = 1; |
| 889 |
| 890 do { |
| 891 destroy_curtok(); |
| 892 get_next_token(); |
| 893 } while (!is_eol()); |
| 894 return NULL; |
| 895 } |
| 896 |
| 897 static yasm_bytecode * |
| 898 dir_att_syntax(yasm_parser_gas *parser_gas, unsigned int param) |
| 899 { |
| 900 parser_gas->intel_syntax = 0; |
| 901 return NULL; |
| 902 } |
| 903 |
| 931 static yasm_bytecode * | 904 static yasm_bytecode * |
| 932 parse_instr(yasm_parser_gas *parser_gas) | 905 parse_instr(yasm_parser_gas *parser_gas) |
| 933 { | 906 { |
| 934 yasm_bytecode *bc; | 907 yasm_bytecode *bc; |
| 935 char *id; | 908 char *id; |
| 936 size_t id_len; | 909 size_t id_len; |
| 937 uintptr_t prefix; | 910 uintptr_t prefix; |
| 938 | 911 |
| 912 if (parser_gas->intel_syntax) { |
| 913 bc = parse_instr_intel(parser_gas); |
| 914 if (bc) { |
| 915 yasm_warn_disable(YASM_WARN_UNREC_CHAR); |
| 916 do { |
| 917 destroy_curtok(); |
| 918 get_next_token(); |
| 919 } while (!is_eol()); |
| 920 yasm_warn_enable(YASM_WARN_UNREC_CHAR); |
| 921 } |
| 922 return bc; |
| 923 } |
| 924 |
| 939 if (curtok != ID) | 925 if (curtok != ID) |
| 940 return NULL; | 926 return NULL; |
| 941 | 927 |
| 942 id = ID_val; | 928 id = ID_val; |
| 943 id_len = ID_len; | 929 id_len = ID_len; |
| 944 | 930 |
| 945 /* instructions/prefixes must start with a letter */ | 931 /* instructions/prefixes must start with a letter */ |
| 946 if (!isalpha(id[0])) | 932 if (!isalpha(id[0])) |
| 947 return NULL; | 933 return NULL; |
| 948 | 934 |
| (...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1708 /* floating point data declaration directives */ | 1694 /* floating point data declaration directives */ |
| 1709 {".float", dir_data, 4, INITIAL}, | 1695 {".float", dir_data, 4, INITIAL}, |
| 1710 {".single", dir_data, 4, INITIAL}, | 1696 {".single", dir_data, 4, INITIAL}, |
| 1711 {".double", dir_data, 8, INITIAL}, | 1697 {".double", dir_data, 8, INITIAL}, |
| 1712 {".tfloat", dir_data, 10, INITIAL}, | 1698 {".tfloat", dir_data, 10, INITIAL}, |
| 1713 /* section directives */ | 1699 /* section directives */ |
| 1714 {".bss", dir_bss_section, 0, INITIAL}, | 1700 {".bss", dir_bss_section, 0, INITIAL}, |
| 1715 {".data", dir_data_section, 0, INITIAL}, | 1701 {".data", dir_data_section, 0, INITIAL}, |
| 1716 {".text", dir_text_section, 0, INITIAL}, | 1702 {".text", dir_text_section, 0, INITIAL}, |
| 1717 {".section", dir_section, 0, SECTION_DIRECTIVE}, | 1703 {".section", dir_section, 0, SECTION_DIRECTIVE}, |
| 1718 /* macro directives */ | |
| 1719 {".rept", dir_rept, 0, INITIAL}, | |
| 1720 {".endr", dir_endr, 0, INITIAL}, | |
| 1721 /* empty space/fill directives */ | 1704 /* empty space/fill directives */ |
| 1722 {".skip", dir_skip, 0, INITIAL}, | 1705 {".skip", dir_skip, 0, INITIAL}, |
| 1723 {".space", dir_skip, 0, INITIAL}, | 1706 {".space", dir_skip, 0, INITIAL}, |
| 1724 {".fill", dir_fill, 0, INITIAL}, | 1707 {".fill", dir_fill, 0, INITIAL}, |
| 1725 {".zero", dir_zero, 0, INITIAL}, | 1708 {".zero", dir_zero, 0, INITIAL}, |
| 1709 /* syntax directives */ |
| 1710 {".intel_syntax", dir_intel_syntax, 0, INITIAL}, |
| 1711 {".att_syntax", dir_att_syntax, 0, INITIAL}, |
| 1726 /* other directives */ | 1712 /* other directives */ |
| 1727 {".equ", dir_equ, 0, INITIAL}, | 1713 {".equ", dir_equ, 0, INITIAL}, |
| 1728 {".file", dir_file, 0, INITIAL}, | 1714 {".file", dir_file, 0, INITIAL}, |
| 1729 {".line", dir_line, 0, INITIAL}, | 1715 {".line", dir_line, 0, INITIAL}, |
| 1730 {".set", dir_equ, 0, INITIAL} | 1716 {".set", dir_equ, 0, INITIAL} |
| 1731 }; | 1717 }; |
| 1732 | 1718 |
| 1733 static void | 1719 static void |
| 1734 no_delete(void *data) | 1720 no_delete(void *data) |
| 1735 { | 1721 { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1774 if (parser_gas->save_input) | 1760 if (parser_gas->save_input) |
| 1775 yasm_linemap_add_source(parser_gas->linemap, | 1761 yasm_linemap_add_source(parser_gas->linemap, |
| 1776 temp_bc, | 1762 temp_bc, |
| 1777 (char *)parser_gas->save_line[parser_gas->save_last ^ 1]); | 1763 (char *)parser_gas->save_line[parser_gas->save_last ^ 1]); |
| 1778 yasm_linemap_goto_next(parser_gas->linemap); | 1764 yasm_linemap_goto_next(parser_gas->linemap); |
| 1779 parser_gas->dir_line++; /* keep track for .line followed by .file */ | 1765 parser_gas->dir_line++; /* keep track for .line followed by .file */ |
| 1780 } | 1766 } |
| 1781 | 1767 |
| 1782 HAMT_destroy(parser_gas->dirs, no_delete); | 1768 HAMT_destroy(parser_gas->dirs, no_delete); |
| 1783 } | 1769 } |
| OLD | NEW |