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