From 8e1bd2ba044400e28b3219ba13d05d594825ceea Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Thu, 3 Nov 2005 05:29:42 +0000 Subject: [PATCH] Handle instruction and prefix identifiers properly when used in other places in GAS input. Do this by adding a tokenizer state that turns off insn and prefix generation when inside an instruction or directive, AND adding a special case for labels. * gas-parser.h (state): Add INSTDIR. * gas-token.re: Switch state back to INITIAL on ';' or newline; set state when entering instruction or directive, add special case for labels. * gas-bison.y: Remove non-working attempt at translating INSN and PREFIX into string token; add special case for LABEL identifiers (generated from special case for labels in tokenizer). svn path=/trunk/yasm/; revision=1309 --- modules/parsers/gas/gas-bison.y | 20 +- modules/parsers/gas/gas-parser.h | 3 +- modules/parsers/gas/gas-token.re | 143 ++++--- modules/parsers/gas/tests/Makefile.inc | 3 + modules/parsers/gas/tests/gas-instlabel.asm | 3 + .../parsers/gas/tests/gas-instlabel.errwarn | 0 modules/parsers/gas/tests/gas-instlabel.hex | 376 ++++++++++++++++++ 7 files changed, 476 insertions(+), 72 deletions(-) create mode 100644 modules/parsers/gas/tests/gas-instlabel.asm create mode 100644 modules/parsers/gas/tests/gas-instlabel.errwarn create mode 100644 modules/parsers/gas/tests/gas-instlabel.hex diff --git a/modules/parsers/gas/gas-bison.y b/modules/parsers/gas/gas-bison.y index 81cec4ee..442983c6 100644 --- a/modules/parsers/gas/gas-bison.y +++ b/modules/parsers/gas/gas-bison.y @@ -102,7 +102,7 @@ static void gas_parser_directive %token RESERVE_SPACE %token INSN PREFIX REG REGGROUP SEGREG TARGETMOD %token LEFT_OP RIGHT_OP -%token ID DIR_ID +%token ID DIR_ID LABEL %token LINE %token DIR_2BYTE DIR_4BYTE DIR_ALIGN DIR_ASCII DIR_ASCIZ DIR_BALIGN %token DIR_BSS DIR_BYTE DIR_COMM DIR_DATA DIR_DOUBLE DIR_ENDR DIR_EXTERN @@ -169,6 +169,14 @@ lineexp: instr $$ = $3; define_label(parser_gas, $1, 0); } + | LABEL { + $$ = (yasm_bytecode *)NULL; + define_label(parser_gas, $1, 0); + } + | LABEL instr { + $$ = $2; + define_label(parser_gas, $1, 0); + } /* Line directive */ | DIR_LINE INTNUM { $$ = (yasm_bytecode *)NULL; @@ -716,16 +724,6 @@ expr_id: label_id | DIR_DATA { $$ = yasm__xstrdup(".data"); } | DIR_TEXT { $$ = yasm__xstrdup(".text"); } | DIR_BSS { $$ = yasm__xstrdup(".bss"); } - | INSN { - /* Used as an identifier, grab token to make it one! */ - $$ = yasm__xstrndup(parser_gas->s.tok, - (size_t)(parser_gas->s.cur - parser_gas->s.tok)); - } - | PREFIX { - /* Used as an identifier, grab token to make it one! */ - $$ = yasm__xstrndup(parser_gas->s.tok, - (size_t)(parser_gas->s.cur - parser_gas->s.tok)); - } ; label_id: ID | DIR_ID; diff --git a/modules/parsers/gas/gas-parser.h b/modules/parsers/gas/gas-parser.h index d17ee34a..df9421f2 100644 --- a/modules/parsers/gas/gas-parser.h +++ b/modules/parsers/gas/gas-parser.h @@ -88,7 +88,8 @@ typedef struct yasm_parser_gas { Scanner s; enum { INITIAL, - SECTION_DIRECTIVE + SECTION_DIRECTIVE, + INSTDIR } state; int code_section; diff --git a/modules/parsers/gas/gas-token.re b/modules/parsers/gas/gas-token.re index e284232f..67bcb6bf 100644 --- a/modules/parsers/gas/gas-token.re +++ b/modules/parsers/gas/gas-token.re @@ -334,60 +334,64 @@ scan: ">>" { RETURN(RIGHT_OP); } "<" { RETURN(LEFT_OP); } ">" { RETURN(RIGHT_OP); } - [-+|^!*&/~$():;@=,] { RETURN(s->tok[0]); } + [-+|^!*&/~$():@=,] { RETURN(s->tok[0]); } + ";" { + parser_gas->state = INITIAL; + RETURN(s->tok[0]); + } /* arch-independent directives */ - '.2byte' { RETURN(DIR_2BYTE); } - '.4byte' { RETURN(DIR_4BYTE); } - '.8byte' { RETURN(DIR_QUAD); } - '.align' { RETURN(DIR_ALIGN); } - '.ascii' { RETURN(DIR_ASCII); } - '.asciz' { RETURN(DIR_ASCIZ); } - '.balign' { RETURN(DIR_BALIGN); } - '.bss' { RETURN(DIR_BSS); } - '.byte' { RETURN(DIR_BYTE); } - '.comm' { RETURN(DIR_COMM); } - '.data' { RETURN(DIR_DATA); } - '.double' { RETURN(DIR_DOUBLE); } - '.endr' { RETURN(DIR_ENDR); } - '.equ' { RETURN(DIR_EQU); } - '.extern' { RETURN(DIR_EXTERN); } - '.file' { RETURN(DIR_FILE); } - '.float' { RETURN(DIR_FLOAT); } - '.global' { RETURN(DIR_GLOBAL); } - '.globl' { RETURN(DIR_GLOBAL); } - '.hword' { RETURN(DIR_SHORT); } - '.ident' { RETURN(DIR_IDENT); } - '.int' { RETURN(DIR_INT); } - '.lcomm' { RETURN(DIR_LCOMM); } - '.line' { RETURN(DIR_LINE); } - '.loc' { RETURN(DIR_LOC); } - '.long' { RETURN(DIR_INT); } - '.octa' { RETURN(DIR_OCTA); } - '.org' { RETURN(DIR_ORG); } - '.p2align' { RETURN(DIR_P2ALIGN); } - '.rept' { RETURN(DIR_REPT); } + '.2byte' { parser_gas->state = INSTDIR; RETURN(DIR_2BYTE); } + '.4byte' { parser_gas->state = INSTDIR; RETURN(DIR_4BYTE); } + '.8byte' { parser_gas->state = INSTDIR; RETURN(DIR_QUAD); } + '.align' { parser_gas->state = INSTDIR; RETURN(DIR_ALIGN); } + '.ascii' { parser_gas->state = INSTDIR; RETURN(DIR_ASCII); } + '.asciz' { parser_gas->state = INSTDIR; RETURN(DIR_ASCIZ); } + '.balign' { parser_gas->state = INSTDIR; RETURN(DIR_BALIGN); } + '.bss' { parser_gas->state = INSTDIR; RETURN(DIR_BSS); } + '.byte' { parser_gas->state = INSTDIR; RETURN(DIR_BYTE); } + '.comm' { parser_gas->state = INSTDIR; RETURN(DIR_COMM); } + '.data' { parser_gas->state = INSTDIR; RETURN(DIR_DATA); } + '.double' { parser_gas->state = INSTDIR; RETURN(DIR_DOUBLE); } + '.endr' { parser_gas->state = INSTDIR; RETURN(DIR_ENDR); } + '.equ' { parser_gas->state = INSTDIR; RETURN(DIR_EQU); } + '.extern' { parser_gas->state = INSTDIR; RETURN(DIR_EXTERN); } + '.file' { parser_gas->state = INSTDIR; RETURN(DIR_FILE); } + '.float' { parser_gas->state = INSTDIR; RETURN(DIR_FLOAT); } + '.global' { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); } + '.globl' { parser_gas->state = INSTDIR; RETURN(DIR_GLOBAL); } + '.hword' { parser_gas->state = INSTDIR; RETURN(DIR_SHORT); } + '.ident' { parser_gas->state = INSTDIR; RETURN(DIR_IDENT); } + '.int' { parser_gas->state = INSTDIR; RETURN(DIR_INT); } + '.lcomm' { parser_gas->state = INSTDIR; RETURN(DIR_LCOMM); } + '.line' { parser_gas->state = INSTDIR; RETURN(DIR_LINE); } + '.loc' { parser_gas->state = INSTDIR; RETURN(DIR_LOC); } + '.long' { parser_gas->state = INSTDIR; RETURN(DIR_INT); } + '.octa' { parser_gas->state = INSTDIR; RETURN(DIR_OCTA); } + '.org' { parser_gas->state = INSTDIR; RETURN(DIR_ORG); } + '.p2align' { parser_gas->state = INSTDIR; RETURN(DIR_P2ALIGN); } + '.rept' { parser_gas->state = INSTDIR; RETURN(DIR_REPT); } '.section' { parser_gas->state = SECTION_DIRECTIVE; RETURN(DIR_SECTION); } - '.set' { RETURN(DIR_EQU); } - '.short' { RETURN(DIR_SHORT); } - '.single' { RETURN(DIR_FLOAT); } - '.size' { RETURN(DIR_SIZE); } - '.skip' { RETURN(DIR_SKIP); } - '.sleb128' { RETURN(DIR_SLEB128); } - '.space' { RETURN(DIR_SKIP); } - '.string' { RETURN(DIR_ASCIZ); } - '.text' { RETURN(DIR_TEXT); } - '.tfloat' { RETURN(DIR_TFLOAT); } - '.type' { RETURN(DIR_TYPE); } - '.quad' { RETURN(DIR_QUAD); } - '.uleb128' { RETURN(DIR_ULEB128); } - '.value' { RETURN(DIR_VALUE); } - '.weak' { RETURN(DIR_WEAK); } - '.word' { RETURN(DIR_WORD); } - '.zero' { RETURN(DIR_ZERO); } + '.set' { parser_gas->state = INSTDIR; RETURN(DIR_EQU); } + '.short' { parser_gas->state = INSTDIR; RETURN(DIR_SHORT); } + '.single' { parser_gas->state = INSTDIR; RETURN(DIR_FLOAT); } + '.size' { parser_gas->state = INSTDIR; RETURN(DIR_SIZE); } + '.skip' { parser_gas->state = INSTDIR; RETURN(DIR_SKIP); } + '.sleb128' { parser_gas->state = INSTDIR; RETURN(DIR_SLEB128); } + '.space' { parser_gas->state = INSTDIR; RETURN(DIR_SKIP); } + '.string' { parser_gas->state = INSTDIR; RETURN(DIR_ASCIZ); } + '.text' { parser_gas->state = INSTDIR; RETURN(DIR_TEXT); } + '.tfloat' { parser_gas->state = INSTDIR; RETURN(DIR_TFLOAT); } + '.type' { parser_gas->state = INSTDIR; RETURN(DIR_TYPE); } + '.quad' { parser_gas->state = INSTDIR; RETURN(DIR_QUAD); } + '.uleb128' { parser_gas->state = INSTDIR; RETURN(DIR_ULEB128); } + '.value' { parser_gas->state = INSTDIR; RETURN(DIR_VALUE); } + '.weak' { parser_gas->state = INSTDIR; RETURN(DIR_WEAK); } + '.word' { parser_gas->state = INSTDIR; RETURN(DIR_WORD); } + '.zero' { parser_gas->state = INSTDIR; RETURN(DIR_ZERO); } /* label or maybe directive */ [.][a-zA-Z0-9_$.]* { @@ -432,22 +436,41 @@ scan: RETURN(REG); } + /* label */ + [a-zA-Z][a-zA-Z0-9_$.]* ws* ':' { + /* strip off colon and any whitespace */ + count = TOKLEN-1; + while (s->tok[count] == ' ' || s->tok[count] == '\t' + || s->tok[count] == '\r') + count--; + /* Just an identifier, return as such. */ + lvalp->str_val = yasm__xstrndup(s->tok, count); + RETURN(LABEL); + } + /* identifier that may be an instruction, etc. */ [a-zA-Z][a-zA-Z0-9_$.]* { - savech = s->tok[TOKLEN]; - s->tok[TOKLEN] = '\0'; - if (yasm_arch_parse_check_insn(parser_gas->arch, lvalp->arch_data, - s->tok, cur_line)) { - s->tok[TOKLEN] = savech; - RETURN(INSN); - } - if (yasm_arch_parse_check_prefix(parser_gas->arch, - lvalp->arch_data, s->tok, - cur_line)) { + /* Can only be an instruction/prefix when not inside an + * instruction or directive. + */ + if (parser_gas->state != INSTDIR) { + savech = s->tok[TOKLEN]; + s->tok[TOKLEN] = '\0'; + if (yasm_arch_parse_check_insn(parser_gas->arch, + lvalp->arch_data, s->tok, + cur_line)) { + s->tok[TOKLEN] = savech; + parser_gas->state = INSTDIR; + RETURN(INSN); + } + if (yasm_arch_parse_check_prefix(parser_gas->arch, + lvalp->arch_data, s->tok, + cur_line)) { + s->tok[TOKLEN] = savech; + RETURN(PREFIX); + } s->tok[TOKLEN] = savech; - RETURN(PREFIX); } - s->tok[TOKLEN] = savech; /* Just an identifier, return as such. */ lvalp->str_val = yasm__xstrndup(s->tok, TOKLEN); RETURN(ID); diff --git a/modules/parsers/gas/tests/Makefile.inc b/modules/parsers/gas/tests/Makefile.inc index 7134b34a..e357c98b 100644 --- a/modules/parsers/gas/tests/Makefile.inc +++ b/modules/parsers/gas/tests/Makefile.inc @@ -12,6 +12,9 @@ EXTRA_DIST += modules/parsers/gas/tests/datavis.hex EXTRA_DIST += modules/parsers/gas/tests/datavis2.asm EXTRA_DIST += modules/parsers/gas/tests/datavis2.errwarn EXTRA_DIST += modules/parsers/gas/tests/datavis2.hex +EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.asm +EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.errwarn +EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.hex EXTRA_DIST += modules/parsers/gas/tests/gas-semi.asm EXTRA_DIST += modules/parsers/gas/tests/gas-semi.errwarn EXTRA_DIST += modules/parsers/gas/tests/gas-semi.hex diff --git a/modules/parsers/gas/tests/gas-instlabel.asm b/modules/parsers/gas/tests/gas-instlabel.asm new file mode 100644 index 00000000..44c47482 --- /dev/null +++ b/modules/parsers/gas/tests/gas-instlabel.asm @@ -0,0 +1,3 @@ + .globl SUB + .type SUB, @function +SUB: diff --git a/modules/parsers/gas/tests/gas-instlabel.errwarn b/modules/parsers/gas/tests/gas-instlabel.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/parsers/gas/tests/gas-instlabel.hex b/modules/parsers/gas/tests/gas-instlabel.hex new file mode 100644 index 00000000..cba25918 --- /dev/null +++ b/modules/parsers/gas/tests/gas-instlabel.hex @@ -0,0 +1,376 @@ +7f +45 +4c +46 +01 +01 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +03 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +b0 +00 +00 +00 +00 +00 +00 +00 +34 +00 +00 +00 +00 +00 +28 +00 +05 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +2e +74 +65 +78 +74 +00 +2e +73 +74 +72 +74 +61 +62 +00 +2e +73 +79 +6d +74 +61 +62 +00 +2e +73 +68 +73 +74 +72 +74 +61 +62 +00 +00 +00 +00 +00 +2d +00 +53 +55 +42 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +00 +f1 +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +04 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +12 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +17 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +21 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +64 +00 +00 +00 +07 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +0f +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +6c +00 +00 +00 +40 +00 +00 +00 +02 +00 +00 +00 +03 +00 +00 +00 +04 +00 +00 +00 +10 +00 +00 +00 +01 +00 +00 +00 +01 +00 +00 +00 +06 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00 -- 2.40.0