1 %option nounput noyywrap 2 3 %{ 4 5 /* Copyright (C) 1991-2024 Free Software Foundation, Inc. 6 Written by Steve Chamberlain of Cygnus Support. 7 8 This file is part of the GNU Binutils. 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 23 MA 02110-1301, USA. */ 24 25 #include "bfd.h" 26 #include "safe-ctype.h" 27 #include "bfdlink.h" 28 #include "ctf-api.h" 29 #include "ld.h" 30 #include "ldmisc.h" 31 #include "ldexp.h" 32 #include "ldlang.h" 33 #include <ldgram.h> 34 #include "ldfile.h" 35 #include "ldlex.h" 36 #include "ldmain.h" 37 #include "libiberty.h" 38 39 /* The type of top-level parser input. 40 yylex and yyparse (indirectly) both check this. */ 41 input_type parser_input; 42 43 /* Line number in the current input file. */ 44 unsigned int lineno; 45 46 /* The string we are currently lexing, or NULL if we are reading a 47 file. */ 48 const char *lex_string = NULL; 49 50 /* Support for flex reading from more than one input file (stream). 51 `include_stack' is flex's input state for each open file; 52 `file_name_stack' is the file names. `lineno_stack' is the current 53 line numbers. 54 55 If `include_stack_ptr' is 0, we haven't started reading anything yet. 56 Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid. */ 57 58 #undef YY_INPUT 59 #define YY_INPUT(buf,result,max_size) result = yy_input (buf, max_size) 60 61 #define MAX_INCLUDE_DEPTH 10 62 static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; 63 static const char *file_name_stack[MAX_INCLUDE_DEPTH]; 64 static unsigned int lineno_stack[MAX_INCLUDE_DEPTH]; 65 static unsigned int sysrooted_stack[MAX_INCLUDE_DEPTH]; 66 static unsigned int include_stack_ptr = 0; 67 static int vers_node_nesting = 0; 68 69 static int yy_input (char *, int); 70 static void comment (void); 71 static void lex_warn_invalid (char *where, char *what); 72 73 /* STATES 74 EXPRESSION in an expression 75 SCRIPT in a script 76 INPUTLIST in a script, a filename-list 77 MRI in an MRI script 78 WILD inside the braces of an output section or overlay, 79 for input section wildcards 80 VERS_START starting a Sun style mapfile 81 VERS_SCRIPT a Sun style mapfile 82 VERS_NODE a node within a Sun style mapfile 83 */ 84 #define RTOKEN(x) { yylval.token = x; return x; } 85 86 %} 87 88 %option nounput 89 90 %a 4000 91 %o 5000 92 93 WILDCHAR [_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]\,\=\?\*\^\!] 94 FILENAMECHAR [_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]\,\=] 95 NOCFILENAMECHAR [_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]] 96 SYMBOLNAMECHAR [_a-zA-Z0-9\/\.\\\$\~] 97 FILENAMECHAR1 [_a-zA-Z\/\.\\\$\~] 98 SYMBOLNAMECHAR1 [_a-zA-Z\.\\\$] 99 WHITE [ \t\n\r]+ 100 101 V_TAG [.$_a-zA-Z][._a-zA-Z0-9]* 102 V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)* 103 104 %s SCRIPT 105 %s INPUTLIST 106 %s EXPRESSION 107 %s MRI 108 %s WILD 109 %s VERS_START 110 %s VERS_SCRIPT 111 %s VERS_NODE 112 %% 113 114 if (parser_input != input_selected) 115 { 116 /* The first token of the input determines the initial parser state. */ 117 input_type t = parser_input; 118 parser_input = input_selected; 119 switch (t) 120 { 121 case input_script: return INPUT_SCRIPT; break; 122 case input_mri_script: return INPUT_MRI_SCRIPT; break; 123 case input_version_script: return INPUT_VERSION_SCRIPT; break; 124 case input_dynamic_list: return INPUT_DYNAMIC_LIST; break; 125 case input_defsym: return INPUT_DEFSYM; break; 126 default: abort (); 127 } 128 } 129 130 <SCRIPT,EXPRESSION,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>"/*" { 131 comment (); } 132 133 <MRI,EXPRESSION>"$"([0-9A-Fa-f])+ { 134 yylval.integer = strtoull (yytext + 1, 0, 16); 135 yylval.bigint.str = NULL; 136 return INT; 137 } 138 139 <MRI,EXPRESSION>([0-9A-Fa-f])+(H|h|X|x|B|b|O|o|D|d) { 140 int ibase ; 141 switch (yytext[yyleng - 1]) { 142 case 'X': 143 case 'x': 144 case 'H': 145 case 'h': 146 ibase = 16; 147 break; 148 case 'O': 149 case 'o': 150 ibase = 8; 151 break; 152 case 'B': 153 case 'b': 154 ibase = 2; 155 break; 156 default: 157 ibase = 10; 158 } 159 yylval.integer = strtoull (yytext, 0, ibase); 160 yylval.bigint.str = NULL; 161 return INT; 162 } 163 <SCRIPT,MRI,EXPRESSION>((("$"|0[xX])([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? { 164 char *s = yytext; 165 int ibase = 0; 166 167 if (*s == '$') 168 { 169 ++s; 170 ibase = 16; 171 } 172 yylval.integer = strtoull (s, 0, ibase); 173 yylval.bigint.str = NULL; 174 if (yytext[yyleng - 1] == 'M' 175 || yytext[yyleng - 1] == 'm') 176 { 177 yylval.integer *= 1024 * 1024; 178 } 179 else if (yytext[yyleng - 1] == 'K' 180 || yytext[yyleng - 1]=='k') 181 { 182 yylval.integer *= 1024; 183 } 184 else if (yytext[0] == '0' 185 && (yytext[1] == 'x' 186 || yytext[1] == 'X')) 187 { 188 yylval.bigint.str = xstrdup (yytext + 2); 189 } 190 return INT; 191 } 192 193 /* Some tokens that only appear in expressions must be enabled for 194 states other than EXPRESSION, since parser lookahead means they 195 must be recognised before the parser switches the lexer out of 196 SCRIPT or WILD state into EXPRESSION state. 197 198 This sort of thing happens for example with NAME in ldgram.y 199 "section" rule, which is immediately followed by ldlex_expression. 200 However, if you follow the grammar from "sec_or_group_p1" you see 201 "assignment" appearing in "statement_anywhere". Now, 202 "assignment" also has NAME as its first token, just like 203 "section". So the parser can't know whether it is in the 204 "section" or the "assignment" rule until it has scanned the next 205 token to find an assignment operator. Thus the next token after 206 NAME in the "section" rule may be lexed before the lexer is 207 switched to EXPRESSION state, and there are quite a number of 208 optional components. The first token in all those components 209 must be able to be lexed in SCRIPT state, as well as the 210 assignment operators. In fact, due to "opt_exp_with_type", 211 anything that can appear on the left hand side of "exp" might 212 need to be lexed in SCRIPT state. 213 214 MRI mode tends to cover everything in MRI scripts. 215 */ 216 <MRI,WILD>"]" { RTOKEN(']'); } 217 <MRI,WILD>"[" { RTOKEN('['); } 218 <SCRIPT,EXPRESSION,MRI,WILD>"<<=" { RTOKEN(LSHIFTEQ); } 219 <SCRIPT,EXPRESSION,MRI,WILD>">>=" { RTOKEN(RSHIFTEQ); } 220 <EXPRESSION,MRI>"||" { RTOKEN(OROR); } 221 <EXPRESSION,MRI>"==" { RTOKEN(EQ); } 222 <EXPRESSION,MRI>"!=" { RTOKEN(NE); } 223 <EXPRESSION,MRI>">=" { RTOKEN(GE); } 224 <EXPRESSION,MRI>"<=" { RTOKEN(LE); } 225 <EXPRESSION,MRI>"<<" { RTOKEN(LSHIFT); } 226 <EXPRESSION,MRI>">>" { RTOKEN(RSHIFT); } 227 <SCRIPT,EXPRESSION,MRI,WILD>"+=" { RTOKEN(PLUSEQ); } 228 <SCRIPT,EXPRESSION,MRI,WILD>"-=" { RTOKEN(MINUSEQ); } 229 <SCRIPT,EXPRESSION,MRI,WILD>"*=" { RTOKEN(MULTEQ); } 230 <SCRIPT,EXPRESSION,MRI,WILD>"/=" { RTOKEN(DIVEQ); } 231 <SCRIPT,EXPRESSION,MRI,WILD>"&=" { RTOKEN(ANDEQ); } 232 <SCRIPT,EXPRESSION,MRI,WILD>"|=" { RTOKEN(OREQ); } 233 <SCRIPT,EXPRESSION,MRI,WILD>"^=" { RTOKEN(XOREQ); } 234 <EXPRESSION,MRI>"&&" { RTOKEN(ANDAND); } 235 <SCRIPT,EXPRESSION,MRI>">" { RTOKEN('>'); } 236 <SCRIPT,EXPRESSION,MRI,INPUTLIST>"," { RTOKEN(','); } 237 <EXPRESSION,MRI,WILD>"&" { RTOKEN('&'); } 238 <EXPRESSION,MRI>"|" { RTOKEN('|'); } 239 <SCRIPT,EXPRESSION,MRI>"~" { RTOKEN('~'); } 240 <SCRIPT,EXPRESSION,MRI>"!" { RTOKEN('!'); } 241 <EXPRESSION,MRI>"?" { RTOKEN('?'); } 242 <EXPRESSION,MRI>"*" { RTOKEN('*'); } 243 <SCRIPT,EXPRESSION,MRI>"+" { RTOKEN('+'); } 244 <SCRIPT,EXPRESSION,MRI>"-" { RTOKEN('-'); } 245 <EXPRESSION,MRI>"/" { RTOKEN('/'); } 246 <EXPRESSION,MRI>"%" { RTOKEN('%'); } 247 <EXPRESSION,MRI>"<" { RTOKEN('<'); } 248 <EXPRESSION,MRI>"^" { RTOKEN('^'); } 249 <SCRIPT,EXPRESSION,MRI,WILD>"=" { RTOKEN('='); } 250 <SCRIPT,EXPRESSION,MRI,WILD>"}" { RTOKEN('}'); } 251 <SCRIPT,EXPRESSION,MRI,WILD>"{" { RTOKEN('{'); } 252 <SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>")" { RTOKEN(')'); } 253 <SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>"(" { RTOKEN('('); } 254 <SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); } 255 <SCRIPT,EXPRESSION,MRI,WILD>";" { RTOKEN(';'); } 256 <SCRIPT>"MEMORY" { RTOKEN(MEMORY); } 257 <SCRIPT>"REGION_ALIAS" { RTOKEN(REGION_ALIAS); } 258 <SCRIPT>"LD_FEATURE" { RTOKEN(LD_FEATURE); } 259 <SCRIPT,EXPRESSION>"ORIGIN" { RTOKEN(ORIGIN); } 260 <SCRIPT>"VERSION" { RTOKEN(VERSIONK); } 261 <SCRIPT,EXPRESSION>"BLOCK" { RTOKEN(BLOCK); } 262 <SCRIPT,EXPRESSION>"BIND" { RTOKEN(BIND); } 263 <SCRIPT,EXPRESSION>"LENGTH" { RTOKEN(LENGTH); } 264 <SCRIPT,EXPRESSION>"ALIGN" { RTOKEN(ALIGN_K); } 265 <SCRIPT,EXPRESSION>"DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN); } 266 <SCRIPT,EXPRESSION>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END); } 267 <SCRIPT,EXPRESSION>"DATA_SEGMENT_END" { RTOKEN(DATA_SEGMENT_END); } 268 <SCRIPT,EXPRESSION>"ADDR" { RTOKEN(ADDR); } 269 <SCRIPT,EXPRESSION>"LOADADDR" { RTOKEN(LOADADDR); } 270 <SCRIPT,EXPRESSION>"ALIGNOF" { RTOKEN(ALIGNOF); } 271 <SCRIPT,EXPRESSION>"ABSOLUTE" { RTOKEN(ABSOLUTE); } 272 <SCRIPT,EXPRESSION>"MAX" { RTOKEN(MAX_K); } 273 <SCRIPT,EXPRESSION>"MIN" { RTOKEN(MIN_K); } 274 <SCRIPT,EXPRESSION>"LOG2CEIL" { RTOKEN(LOG2CEIL); } 275 <SCRIPT,EXPRESSION,WILD>"ASSERT" { RTOKEN(ASSERT_K); } 276 <SCRIPT>"ENTRY" { RTOKEN(ENTRY); } 277 <SCRIPT,MRI>"EXTERN" { RTOKEN(EXTERN); } 278 <SCRIPT,EXPRESSION>"NEXT" { RTOKEN(NEXT); } 279 <SCRIPT,EXPRESSION>"SIZEOF_HEADERS" { RTOKEN(SIZEOF_HEADERS); } 280 <SCRIPT,EXPRESSION>"SEGMENT_START" { RTOKEN(SEGMENT_START); } 281 <SCRIPT>"MAP" { RTOKEN(MAP); } 282 <SCRIPT,EXPRESSION>"SIZEOF" { RTOKEN(SIZEOF); } 283 <SCRIPT>"TARGET" { RTOKEN(TARGET_K); } 284 <SCRIPT>"SEARCH_DIR" { RTOKEN(SEARCH_DIR); } 285 <SCRIPT>"OUTPUT" { RTOKEN(OUTPUT); } 286 <SCRIPT>"INPUT" { RTOKEN(INPUT); } 287 <SCRIPT>"GROUP" { RTOKEN(GROUP); } 288 <INPUTLIST>"AS_NEEDED" { RTOKEN(AS_NEEDED); } 289 <SCRIPT,EXPRESSION>"DEFINED" { RTOKEN(DEFINED); } 290 <WILD>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS); } 291 <WILD>"CONSTRUCTORS" { RTOKEN(CONSTRUCTORS); } 292 <SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION); } 293 <SCRIPT>"FORCE_GROUP_ALLOCATION" { RTOKEN(FORCE_GROUP_ALLOCATION); } 294 <SCRIPT>"INHIBIT_COMMON_ALLOCATION" { RTOKEN(INHIBIT_COMMON_ALLOCATION); } 295 <SCRIPT>"SECTIONS" { RTOKEN(SECTIONS); } 296 <SCRIPT>"INSERT" { RTOKEN(INSERT_K); } 297 <SCRIPT>"AFTER" { RTOKEN(AFTER); } 298 <SCRIPT>"BEFORE" { RTOKEN(BEFORE); } 299 <WILD>"FILL" { RTOKEN(FILL); } 300 <SCRIPT>"STARTUP" { RTOKEN(STARTUP); } 301 <SCRIPT>"OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT); } 302 <SCRIPT>"OUTPUT_ARCH" { RTOKEN(OUTPUT_ARCH); } 303 <SCRIPT>"HLL" { RTOKEN(HLL); } 304 <SCRIPT>"SYSLIB" { RTOKEN(SYSLIB); } 305 <SCRIPT>"FLOAT" { RTOKEN(FLOAT); } 306 <WILD>"QUAD" { RTOKEN(QUAD); } 307 <WILD>"SQUAD" { RTOKEN(SQUAD); } 308 <WILD>"LONG" { RTOKEN(LONG); } 309 <WILD>"SHORT" { RTOKEN(SHORT); } 310 <WILD>"BYTE" { RTOKEN(BYTE); } 311 <WILD>"ASCIZ" { RTOKEN(ASCIZ); } 312 <WILD>"LINKER_VERSION" { RTOKEN(LINKER_VERSION); } 313 <SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT); } 314 <SCRIPT,EXPRESSION>"NOCROSSREFS" { RTOKEN(NOCROSSREFS); } 315 <SCRIPT,EXPRESSION>"NOCROSSREFS_TO" { RTOKEN(NOCROSSREFS_TO); } 316 <SCRIPT,EXPRESSION>"OVERLAY" { RTOKEN(OVERLAY); } 317 <WILD>"SORT_BY_NAME" { RTOKEN(SORT_BY_NAME); } 318 <WILD>"SORT_BY_ALIGNMENT" { RTOKEN(SORT_BY_ALIGNMENT); } 319 <WILD>"SORT" { RTOKEN(SORT_BY_NAME); } 320 <WILD>"SORT_BY_INIT_PRIORITY" { RTOKEN(SORT_BY_INIT_PRIORITY); } 321 <WILD>"SORT_NONE" { RTOKEN(SORT_NONE); } 322 <WILD>"REVERSE" { RTOKEN(REVERSE); } 323 <EXPRESSION>"NOLOAD" { RTOKEN(NOLOAD); } 324 <EXPRESSION>"READONLY" { RTOKEN(READONLY); } 325 <EXPRESSION>"DSECT" { RTOKEN(DSECT); } 326 <EXPRESSION>"COPY" { RTOKEN(COPY); } 327 <EXPRESSION>"INFO" { RTOKEN(INFO); } 328 <EXPRESSION>"TYPE" { RTOKEN(TYPE); } 329 <SCRIPT,EXPRESSION>"ONLY_IF_RO" { RTOKEN(ONLY_IF_RO); } 330 <SCRIPT,EXPRESSION>"ONLY_IF_RW" { RTOKEN(ONLY_IF_RW); } 331 <SCRIPT,EXPRESSION>"SPECIAL" { RTOKEN(SPECIAL); } 332 <SCRIPT>"o" { RTOKEN(ORIGIN); } 333 <SCRIPT>"org" { RTOKEN(ORIGIN); } 334 <SCRIPT>"l" { RTOKEN(LENGTH); } 335 <SCRIPT>"len" { RTOKEN(LENGTH); } 336 <WILD>"INPUT_SECTION_FLAGS" { RTOKEN(INPUT_SECTION_FLAGS); } 337 <SCRIPT,EXPRESSION,WILD,MRI>"INCLUDE" { RTOKEN(INCLUDE);} 338 <SCRIPT>"PHDRS" { RTOKEN(PHDRS); } 339 <SCRIPT,EXPRESSION,WILD>"AT" { RTOKEN(AT);} 340 <SCRIPT,EXPRESSION>"ALIGN_WITH_INPUT" { RTOKEN(ALIGN_WITH_INPUT);} 341 <SCRIPT,EXPRESSION>"SUBALIGN" { RTOKEN(SUBALIGN);} 342 <SCRIPT,EXPRESSION,WILD>"HIDDEN" { RTOKEN(HIDDEN); } 343 <SCRIPT,EXPRESSION,WILD>"PROVIDE" { RTOKEN(PROVIDE); } 344 <SCRIPT,EXPRESSION,WILD>"PROVIDE_HIDDEN" { RTOKEN(PROVIDE_HIDDEN); } 345 <WILD>"KEEP" { RTOKEN(KEEP); } 346 <WILD>"EXCLUDE_FILE" { RTOKEN(EXCLUDE_FILE); } 347 <SCRIPT,EXPRESSION>"CONSTANT" { RTOKEN(CONSTANT);} 348 349 <MRI>"#".*\n? { ++ lineno; } 350 <MRI>"\n" { ++ lineno; RTOKEN(NEWLINE); } 351 <MRI>"*".* { /* Mri comment line */ } 352 <MRI>";".* { /* Mri comment line */ } 353 <MRI>"END" { RTOKEN(ENDWORD); } 354 <MRI>"ABSOLUTE" { RTOKEN(ABSOLUTE); } 355 <MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);} 356 <MRI>"ALIGN" { RTOKEN(ALIGN_K);} 357 <MRI>"CHIP" { RTOKEN(CHIP); } 358 <MRI>"BASE" { RTOKEN(BASE); } 359 <MRI>"ALIAS" { RTOKEN(ALIAS); } 360 <MRI>"TRUNCATE" { RTOKEN(TRUNCATE); } 361 <MRI>"LOAD" { RTOKEN(LOAD); } 362 <MRI>"PUBLIC" { RTOKEN(PUBLIC); } 363 <MRI>"ORDER" { RTOKEN(ORDER); } 364 <MRI>"NAME" { RTOKEN(NAMEWORD); } 365 <MRI>"FORMAT" { RTOKEN(FORMAT); } 366 <MRI>"CASE" { RTOKEN(CASE); } 367 <MRI>"START" { RTOKEN(START); } 368 <MRI>"LIST".* { RTOKEN(LIST); /* LIST and ignore to end of line */ } 369 <MRI>"SECT" { RTOKEN(SECT); } 370 <MRI>"end" { RTOKEN(ENDWORD); } 371 <MRI>"absolute" { RTOKEN(ABSOLUTE); } 372 <MRI>"alignmod" { RTOKEN(ALIGNMOD);} 373 <MRI>"align" { RTOKEN(ALIGN_K);} 374 <MRI>"chip" { RTOKEN(CHIP); } 375 <MRI>"base" { RTOKEN(BASE); } 376 <MRI>"alias" { RTOKEN(ALIAS); } 377 <MRI>"truncate" { RTOKEN(TRUNCATE); } 378 <MRI>"load" { RTOKEN(LOAD); } 379 <MRI>"public" { RTOKEN(PUBLIC); } 380 <MRI>"order" { RTOKEN(ORDER); } 381 <MRI>"name" { RTOKEN(NAMEWORD); } 382 <MRI>"format" { RTOKEN(FORMAT); } 383 <MRI>"case" { RTOKEN(CASE); } 384 <MRI>"extern" { RTOKEN(EXTERN); } 385 <MRI>"start" { RTOKEN(START); } 386 <MRI>"list".* { RTOKEN(LIST); /* LIST and ignore to end of line */ } 387 <MRI>"sect" { RTOKEN(SECT); } 388 389 <MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}* { 390 /* Filename without commas, needed to parse mri stuff */ 391 yylval.name = xstrdup (yytext); 392 return NAME; 393 } 394 395 396 <SCRIPT,INPUTLIST>{FILENAMECHAR1}{FILENAMECHAR}* { 397 yylval.name = xstrdup (yytext); 398 return NAME; 399 } 400 <INPUTLIST>"="{FILENAMECHAR1}{FILENAMECHAR}* { 401 /* Filename to be prefixed by --sysroot or when non-sysrooted, nothing. */ 402 yylval.name = xstrdup (yytext); 403 return NAME; 404 } 405 <INPUTLIST>"-l"{FILENAMECHAR}+ { 406 yylval.name = xstrdup (yytext + 2); 407 return LNAME; 408 } 409 <EXPRESSION>{SYMBOLNAMECHAR1}{SYMBOLNAMECHAR}* { 410 yylval.name = xstrdup (yytext); 411 return NAME; 412 } 413 /* The following rule is to prevent a fill expression on the output 414 section before /DISCARD/ interpreting the '/' as a divide. */ 415 <EXPRESSION>"/DISCARD/" { 416 yylval.name = xstrdup (yytext); 417 return NAME; 418 } 419 <WILD>{WILDCHAR}* { 420 /* Annoyingly, this pattern can match comments, and we have 421 longest match issues to consider. So if the first two 422 characters are a comment opening, put the input back and 423 try again. */ 424 if (yytext[0] == '/' && yytext[1] == '*') 425 { 426 yyless (2); 427 comment (); 428 } 429 else 430 { 431 yylval.name = xstrdup (yytext); 432 return NAME; 433 } 434 } 435 436 <SCRIPT,EXPRESSION,WILD,VERS_NODE,INPUTLIST>"\""[^\"]*"\"" { 437 /* No matter the state, quotes give what's inside. */ 438 yylval.name = xmemdup (yytext + 1, yyleng - 2, yyleng - 1); 439 return NAME; 440 } 441 442 <SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>"\n" { 443 lineno++; } 444 <MRI,SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>[ \t\r]+ { 445 /* Eat up whitespace */ } 446 <SCRIPT,EXPRESSION,WILD,VERS_START,VERS_NODE,VERS_SCRIPT>#.* { 447 /* Eat up comments */ } 448 449 <VERS_NODE,VERS_SCRIPT>[:,;] { return *yytext; } 450 451 <VERS_NODE>global { RTOKEN(GLOBAL); } 452 453 <VERS_NODE>local { RTOKEN(LOCAL); } 454 455 <VERS_NODE>extern { RTOKEN(EXTERN); } 456 457 <VERS_NODE>{V_IDENTIFIER} { yylval.name = xstrdup (yytext); 458 return VERS_IDENTIFIER; } 459 460 <VERS_SCRIPT>{V_TAG} { yylval.name = xstrdup (yytext); 461 return VERS_TAG; } 462 463 <VERS_START>"{" { BEGIN(VERS_SCRIPT); return *yytext; } 464 465 <VERS_SCRIPT>"{" { BEGIN(VERS_NODE); 466 vers_node_nesting = 0; 467 return *yytext; 468 } 469 <VERS_SCRIPT>"}" { return *yytext; } 470 <VERS_NODE>"{" { vers_node_nesting++; return *yytext; } 471 <VERS_NODE>"}" { if (--vers_node_nesting < 0) 472 BEGIN(VERS_SCRIPT); 473 return *yytext; 474 } 475 476 <<EOF>> { 477 include_stack_ptr--; 478 if (include_stack_ptr == 0) 479 { 480 lineno = 0; 481 yyterminate (); 482 } 483 else 484 yy_switch_to_buffer (include_stack[include_stack_ptr]); 485 486 lineno = lineno_stack[include_stack_ptr]; 487 input_flags.sysrooted = sysrooted_stack[include_stack_ptr]; 488 489 return END; 490 } 491 492 <SCRIPT,WILD,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>. lex_warn_invalid (_(" in script"), yytext); 493 <EXPRESSION>. lex_warn_invalid (_(" in expression"), yytext); 494 495 %% 496 497 498 /* Switch flex to reading script file NAME, open on FILE, 499 saving the current input info on the include stack. */ 500 501 void 502 lex_push_file (FILE *file, const char *name, unsigned int sysrooted) 503 { 504 if (include_stack_ptr >= MAX_INCLUDE_DEPTH) 505 { 506 einfo (_("%F:includes nested too deeply\n")); 507 } 508 file_name_stack[include_stack_ptr] = name; 509 lineno_stack[include_stack_ptr] = lineno; 510 sysrooted_stack[include_stack_ptr] = input_flags.sysrooted; 511 include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; 512 513 include_stack_ptr++; 514 lineno = 1; 515 input_flags.sysrooted = sysrooted; 516 yyin = file; 517 yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE)); 518 } 519 520 /* Return a newly created flex input buffer containing STRING, 521 which is SIZE bytes long. */ 522 523 static YY_BUFFER_STATE 524 yy_create_string_buffer (const char *string, size_t size) 525 { 526 YY_BUFFER_STATE b; 527 528 b = xmalloc (sizeof (struct yy_buffer_state)); 529 b->yy_input_file = 0; 530 b->yy_buf_size = size; 531 532 /* yy_ch_buf has to be 2 characters longer than the size given because 533 we need to put in 2 end-of-buffer characters. */ 534 b->yy_ch_buf = xmalloc ((size_t) b->yy_buf_size + 3); 535 536 b->yy_ch_buf[0] = '\n'; 537 strcpy (b->yy_ch_buf+1, string); 538 b->yy_ch_buf[size+1] = YY_END_OF_BUFFER_CHAR; 539 b->yy_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR; 540 b->yy_n_chars = size+1; 541 b->yy_buf_pos = &b->yy_ch_buf[1]; 542 543 b->yy_is_our_buffer = 1; 544 b->yy_is_interactive = 0; 545 b->yy_at_bol = 1; 546 b->yy_fill_buffer = 0; 547 548 /* flex 2.4.7 changed the interface. FIXME: We should not be using 549 a flex internal interface in the first place! */ 550 #ifdef YY_BUFFER_NEW 551 b->yy_buffer_status = YY_BUFFER_NEW; 552 #else 553 b->yy_eof_status = EOF_NOT_SEEN; 554 #endif 555 556 return b; 557 } 558 559 /* Switch flex to reading from STRING, saving the current input info 560 on the include stack. */ 561 562 void 563 lex_redirect (const char *string, const char *fake_filename, unsigned int count) 564 { 565 YY_BUFFER_STATE tmp; 566 567 yy_init = 0; 568 if (include_stack_ptr >= MAX_INCLUDE_DEPTH) 569 { 570 einfo (_("%F: macros nested too deeply\n")); 571 } 572 file_name_stack[include_stack_ptr] = fake_filename; 573 lineno_stack[include_stack_ptr] = lineno; 574 include_stack[include_stack_ptr] = YY_CURRENT_BUFFER; 575 include_stack_ptr++; 576 lineno = count; 577 tmp = yy_create_string_buffer (string, strlen (string)); 578 yy_switch_to_buffer (tmp); 579 } 580 581 /* Functions to switch to a different flex start condition, 582 saving the current start condition on `state_stack'. */ 583 584 static int state_stack[MAX_INCLUDE_DEPTH * 2]; 585 static int *state_stack_p = state_stack; 586 587 void 588 ldlex_script (void) 589 { 590 *(state_stack_p)++ = yy_start; 591 BEGIN (SCRIPT); 592 } 593 594 void 595 ldlex_inputlist (void) 596 { 597 *(state_stack_p)++ = yy_start; 598 BEGIN (INPUTLIST); 599 } 600 601 void 602 ldlex_mri_script (void) 603 { 604 *(state_stack_p)++ = yy_start; 605 BEGIN (MRI); 606 } 607 608 void 609 ldlex_version_script (void) 610 { 611 *(state_stack_p)++ = yy_start; 612 BEGIN (VERS_START); 613 } 614 615 void 616 ldlex_version_file (void) 617 { 618 *(state_stack_p)++ = yy_start; 619 BEGIN (VERS_SCRIPT); 620 } 621 622 void 623 ldlex_expression (void) 624 { 625 *(state_stack_p)++ = yy_start; 626 BEGIN (EXPRESSION); 627 } 628 629 void 630 ldlex_wild (void) 631 { 632 *(state_stack_p)++ = yy_start; 633 BEGIN (WILD); 634 } 635 636 void 637 ldlex_popstate (void) 638 { 639 yy_start = *(--state_stack_p); 640 } 641 642 /* In cases where the parser needs to look ahead and the context 643 changes from expression to script or vice-versa, throw away a 644 NAME. What constitutes a NAME depends on context. */ 645 646 void 647 ldlex_backup (void) 648 { 649 yyless (0); 650 } 651 652 /* Return the current file name, or the previous file if no file is 653 current. */ 654 655 const char* 656 ldlex_filename (void) 657 { 658 return file_name_stack[include_stack_ptr - (include_stack_ptr != 0)]; 659 } 660 661 662 /* Place up to MAX_SIZE characters in BUF and return 663 either the number of characters read, or 0 to indicate EOF. */ 664 665 static int 666 yy_input (char *buf, int max_size) 667 { 668 int result = 0; 669 if (YY_CURRENT_BUFFER != NULL && YY_CURRENT_BUFFER->yy_input_file) 670 { 671 if (yyin) 672 { 673 result = fread (buf, 1, max_size, yyin); 674 if (result < max_size && ferror (yyin)) 675 einfo (_("%F%P: read in flex scanner failed\n")); 676 } 677 } 678 return result; 679 } 680 681 /* Eat the rest of a C-style comment. */ 682 683 static void 684 comment (void) 685 { 686 int c; 687 688 while (1) 689 { 690 c = input(); 691 while (c != '*' && c != 0) 692 { 693 if (c == '\n') 694 lineno++; 695 c = input(); 696 } 697 698 if (c == '*') 699 { 700 c = input(); 701 while (c == '*') 702 c = input(); 703 if (c == '/') 704 break; /* found the end */ 705 } 706 707 if (c == '\n') 708 lineno++; 709 710 if (c == 0) 711 { 712 einfo (_("%F%P: EOF in comment\n")); 713 break; 714 } 715 } 716 } 717 718 /* Warn the user about a garbage character WHAT in the input 719 in context WHERE. */ 720 721 static void 722 lex_warn_invalid (char *where, char *what) 723 { 724 char buf[5]; 725 726 /* If we have found an input file whose format we do not recognize, 727 and we are therefore treating it as a linker script, and we find 728 an invalid character, then most likely this is a real object file 729 of some different format. Treat it as such. */ 730 if (ldfile_assumed_script) 731 { 732 bfd_set_error (bfd_error_file_not_recognized); 733 einfo (_("%F%s: file not recognized: %E\n"), ldlex_filename ()); 734 } 735 736 if (! ISPRINT (*what)) 737 { 738 sprintf (buf, "\\%03o", *(unsigned char *) what); 739 what = buf; 740 } 741 742 einfo (_("%P:%pS: ignoring invalid character `%s'%s\n"), NULL, what, where); 743 } 744