2.41 Release sources
[binutils-gdb.git] / ld / ldlex.l
blob1a6be1b6af23e4cff6fbfd906bfc2c393f2fc6f5
1 %option nounput noyywrap
3 %{
5 /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
6    Written by Steve Chamberlain of Cygnus Support.
8    This file is part of the GNU Binutils.
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.
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.
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.  */
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"
39 /* The type of top-level parser input.
40    yylex and yyparse (indirectly) both check this.  */
41 input_type parser_input;
43 /* Line number in the current input file.  */
44 unsigned int lineno;
46 /* The string we are currently lexing, or NULL if we are reading a
47    file.  */
48 const char *lex_string = NULL;
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.
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.  */
58 #undef YY_INPUT
59 #define YY_INPUT(buf,result,max_size) result = yy_input (buf, max_size)
61 #ifndef YY_NO_UNPUT
62 #define YY_NO_UNPUT
63 #endif
65 #define MAX_INCLUDE_DEPTH 10
66 static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
67 static const char *file_name_stack[MAX_INCLUDE_DEPTH];
68 static unsigned int lineno_stack[MAX_INCLUDE_DEPTH];
69 static unsigned int sysrooted_stack[MAX_INCLUDE_DEPTH];
70 static unsigned int include_stack_ptr = 0;
71 static int vers_node_nesting = 0;
73 static int yy_input (char *, int);
74 static void comment (void);
75 static void lex_warn_invalid (char *where, char *what);
77 /* STATES
78         EXPRESSION      in an expression
79         SCRIPT          in a script
80         INPUTLIST       in a script, a filename-list
81         MRI             in an MRI script
82         WILD            inside the braces of an output section or overlay,
83                         for input section wildcards
84         VERS_START      starting a Sun style mapfile
85         VERS_SCRIPT     a Sun style mapfile
86         VERS_NODE       a node within a Sun style mapfile
88 #define RTOKEN(x)  {  yylval.token = x; return x; }
92 %a 4000
93 %o 5000
95 WILDCHAR        [_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]\,\=\?\*\^\!]
96 FILENAMECHAR    [_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]\,\=]
97 NOCFILENAMECHAR [_a-zA-Z0-9\/\.\\\$\~\-\+\:\[\]]
98 SYMBOLNAMECHAR  [_a-zA-Z0-9\/\.\\\$\~]
99 FILENAMECHAR1   [_a-zA-Z\/\.\\\$\~]
100 SYMBOLNAMECHAR1 [_a-zA-Z\.\\\$]
101 WHITE           [ \t\n\r]+
103 V_TAG [.$_a-zA-Z][._a-zA-Z0-9]*
104 V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
106 %s SCRIPT
107 %s INPUTLIST
108 %s EXPRESSION
109 %s MRI
110 %s WILD
111 %s VERS_START
112 %s VERS_SCRIPT
113 %s VERS_NODE
116   if (parser_input != input_selected)
117     {
118       /* The first token of the input determines the initial parser state.  */
119       input_type t = parser_input;
120       parser_input = input_selected;
121       switch (t)
122         {
123         case input_script: return INPUT_SCRIPT; break;
124         case input_mri_script: return INPUT_MRI_SCRIPT; break;
125         case input_version_script: return INPUT_VERSION_SCRIPT; break;
126         case input_dynamic_list: return INPUT_DYNAMIC_LIST; break;
127         case input_defsym: return INPUT_DEFSYM; break;
128         default: abort ();
129         }
130     }
132 <SCRIPT,EXPRESSION,VERS_START,VERS_NODE,VERS_SCRIPT,INPUTLIST>"/*" {
133                                 comment (); }
135 <MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
136                                 yylval.integer = bfd_scan_vma (yytext + 1, 0, 16);
137                                 yylval.bigint.str = NULL;
138                                 return INT;
139                         }
141 <MRI,EXPRESSION>([0-9A-Fa-f])+(H|h|X|x|B|b|O|o|D|d) {
142                                    int ibase ;
143                                    switch (yytext[yyleng - 1]) {
144                                     case 'X':
145                                     case 'x':
146                                     case 'H':
147                                     case 'h':
148                                      ibase = 16;
149                                      break;
150                                     case 'O':
151                                     case 'o':
152                                      ibase = 8;
153                                      break;
154                                     case 'B':
155                                     case 'b':
156                                      ibase = 2;
157                                      break;
158                                     default:
159                                      ibase = 10;
160                                    }
161                                    yylval.integer = bfd_scan_vma (yytext, 0,
162                                                                   ibase);
163                                    yylval.bigint.str = NULL;
164                                    return INT;
165                                  }
166 <SCRIPT,MRI,EXPRESSION>((("$"|0[xX])([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? {
167                                   char *s = yytext;
168                                   int ibase = 0;
170                                   if (*s == '$')
171                                     {
172                                       ++s;
173                                       ibase = 16;
174                                     }
175                                   yylval.integer = bfd_scan_vma (s, 0, ibase);
176                                   yylval.bigint.str = NULL;
177                                   if (yytext[yyleng - 1] == 'M'
178                                       || yytext[yyleng - 1] == 'm')
179                                     {
180                                       yylval.integer *= 1024 * 1024;
181                                     }
182                                   else if (yytext[yyleng - 1] == 'K'
183                                       || yytext[yyleng - 1]=='k')
184                                     {
185                                       yylval.integer *= 1024;
186                                     }
187                                   else if (yytext[0] == '0'
188                                            && (yytext[1] == 'x'
189                                                || yytext[1] == 'X'))
190                                     {
191                                       yylval.bigint.str = xstrdup (yytext + 2);
192                                     }
193                                   return INT;
194                                 }
196   /* Some tokens that only appear in expressions must be enabled for
197      states other than EXPRESSION, since parser lookahead means they
198      must be recognised before the parser switches the lexer out of
199      SCRIPT or WILD state into EXPRESSION state.
201      This sort of thing happens for example with NAME in ldgram.y
202      "section" rule, which is immediately followed by ldlex_expression.
203      However, if you follow the grammar from "sec_or_group_p1" you see
204      "assignment" appearing in "statement_anywhere".  Now,
205      "assignment" also has NAME as its first token, just like
206      "section".  So the parser can't know whether it is in the
207      "section" or the "assignment" rule until it has scanned the next
208      token to find an assignment operator.  Thus the next token after
209      NAME in the "section" rule may be lexed before the lexer is
210      switched to EXPRESSION state, and there are quite a number of
211      optional components.  The first token in all those components
212      must be able to be lexed in SCRIPT state, as well as the
213      assignment operators.  In fact, due to "opt_exp_with_type",
214      anything that can appear on the left hand side of "exp" might
215      need to be lexed in SCRIPT state.
217      MRI mode tends to cover everything in MRI scripts.
218   */
219 <MRI,WILD>"]"                           { RTOKEN(']'); }
220 <MRI,WILD>"["                           { RTOKEN('['); }
221 <SCRIPT,EXPRESSION,MRI,WILD>"<<="       { RTOKEN(LSHIFTEQ); }
222 <SCRIPT,EXPRESSION,MRI,WILD>">>="       { RTOKEN(RSHIFTEQ); }
223 <EXPRESSION,MRI>"||"                    { RTOKEN(OROR); }
224 <EXPRESSION,MRI>"=="                    { RTOKEN(EQ); }
225 <EXPRESSION,MRI>"!="                    { RTOKEN(NE); }
226 <EXPRESSION,MRI>">="                    { RTOKEN(GE); }
227 <EXPRESSION,MRI>"<="                    { RTOKEN(LE); }
228 <EXPRESSION,MRI>"<<"                    { RTOKEN(LSHIFT); }
229 <EXPRESSION,MRI>">>"                    { RTOKEN(RSHIFT); }
230 <SCRIPT,EXPRESSION,MRI,WILD>"+="        { RTOKEN(PLUSEQ); }
231 <SCRIPT,EXPRESSION,MRI,WILD>"-="        { RTOKEN(MINUSEQ); }
232 <SCRIPT,EXPRESSION,MRI,WILD>"*="        { RTOKEN(MULTEQ); }
233 <SCRIPT,EXPRESSION,MRI,WILD>"/="        { RTOKEN(DIVEQ); }
234 <SCRIPT,EXPRESSION,MRI,WILD>"&="        { RTOKEN(ANDEQ); }
235 <SCRIPT,EXPRESSION,MRI,WILD>"|="        { RTOKEN(OREQ); }
236 <EXPRESSION,MRI>"&&"                    { RTOKEN(ANDAND); }
237 <SCRIPT,EXPRESSION,MRI>">"              { RTOKEN('>'); }
238 <SCRIPT,EXPRESSION,MRI,INPUTLIST>","    { RTOKEN(','); }
239 <EXPRESSION,MRI,WILD>"&"                { RTOKEN('&'); }
240 <EXPRESSION,MRI>"|"                     { RTOKEN('|'); }
241 <SCRIPT,EXPRESSION,MRI>"~"              { RTOKEN('~'); }
242 <SCRIPT,EXPRESSION,MRI>"!"              { RTOKEN('!'); }
243 <EXPRESSION,MRI>"?"                     { RTOKEN('?'); }
244 <EXPRESSION,MRI>"*"                     { RTOKEN('*'); }
245 <SCRIPT,EXPRESSION,MRI>"+"              { RTOKEN('+'); }
246 <SCRIPT,EXPRESSION,MRI>"-"              { RTOKEN('-'); }
247 <EXPRESSION,MRI>"/"                     { RTOKEN('/'); }
248 <EXPRESSION,MRI>"%"                     { RTOKEN('%'); }
249 <EXPRESSION,MRI>"<"                     { RTOKEN('<'); }
250 <SCRIPT,EXPRESSION,MRI,WILD>"="         { RTOKEN('='); }
251 <SCRIPT,EXPRESSION,MRI,WILD>"}"         { RTOKEN('}'); }
252 <SCRIPT,EXPRESSION,MRI,WILD>"{"         { RTOKEN('{'); }
253 <SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>")" { RTOKEN(')'); }
254 <SCRIPT,EXPRESSION,MRI,WILD,INPUTLIST>"(" { RTOKEN('('); }
255 <SCRIPT,EXPRESSION,MRI>":"              { RTOKEN(':'); }
256 <SCRIPT,EXPRESSION,MRI,WILD>";"         { RTOKEN(';'); }
257 <SCRIPT>"MEMORY"                        { RTOKEN(MEMORY); }
258 <SCRIPT>"REGION_ALIAS"                  { RTOKEN(REGION_ALIAS); }
259 <SCRIPT>"LD_FEATURE"                    { RTOKEN(LD_FEATURE); }
260 <SCRIPT,EXPRESSION>"ORIGIN"             { RTOKEN(ORIGIN); }
261 <SCRIPT>"VERSION"                       { RTOKEN(VERSIONK); }
262 <SCRIPT,EXPRESSION>"BLOCK"              { RTOKEN(BLOCK); }
263 <SCRIPT,EXPRESSION>"BIND"               { RTOKEN(BIND); }
264 <SCRIPT,EXPRESSION>"LENGTH"             { RTOKEN(LENGTH); }
265 <SCRIPT,EXPRESSION>"ALIGN"              { RTOKEN(ALIGN_K); }
266 <SCRIPT,EXPRESSION>"DATA_SEGMENT_ALIGN" { RTOKEN(DATA_SEGMENT_ALIGN); }
267 <SCRIPT,EXPRESSION>"DATA_SEGMENT_RELRO_END" { RTOKEN(DATA_SEGMENT_RELRO_END); }
268 <SCRIPT,EXPRESSION>"DATA_SEGMENT_END"   { RTOKEN(DATA_SEGMENT_END); }
269 <SCRIPT,EXPRESSION>"ADDR"               { RTOKEN(ADDR); }
270 <SCRIPT,EXPRESSION>"LOADADDR"           { RTOKEN(LOADADDR); }
271 <SCRIPT,EXPRESSION>"ALIGNOF"            { RTOKEN(ALIGNOF); }
272 <SCRIPT,EXPRESSION>"ABSOLUTE"           { RTOKEN(ABSOLUTE); }
273 <SCRIPT,EXPRESSION>"MAX"                { RTOKEN(MAX_K); }
274 <SCRIPT,EXPRESSION>"MIN"                { RTOKEN(MIN_K); }
275 <SCRIPT,EXPRESSION>"LOG2CEIL"           { RTOKEN(LOG2CEIL); }
276 <SCRIPT,EXPRESSION,WILD>"ASSERT"        { RTOKEN(ASSERT_K); }
277 <SCRIPT>"ENTRY"                         { RTOKEN(ENTRY); }
278 <SCRIPT,MRI>"EXTERN"                    { RTOKEN(EXTERN); }
279 <SCRIPT,EXPRESSION>"NEXT"               { RTOKEN(NEXT); }
280 <SCRIPT,EXPRESSION>"SIZEOF_HEADERS"     { RTOKEN(SIZEOF_HEADERS); }
281 <SCRIPT,EXPRESSION>"SEGMENT_START"      { RTOKEN(SEGMENT_START); }
282 <SCRIPT>"MAP"                           { RTOKEN(MAP); }
283 <SCRIPT,EXPRESSION>"SIZEOF"             { RTOKEN(SIZEOF); }
284 <SCRIPT>"TARGET"                        { RTOKEN(TARGET_K); }
285 <SCRIPT>"SEARCH_DIR"                    { RTOKEN(SEARCH_DIR); }
286 <SCRIPT>"OUTPUT"                        { RTOKEN(OUTPUT); }
287 <SCRIPT>"INPUT"                         { RTOKEN(INPUT); }
288 <SCRIPT>"GROUP"                         { RTOKEN(GROUP); }
289 <INPUTLIST>"AS_NEEDED"                  { RTOKEN(AS_NEEDED); }
290 <SCRIPT,EXPRESSION>"DEFINED"            { RTOKEN(DEFINED); }
291 <WILD>"CREATE_OBJECT_SYMBOLS"           { RTOKEN(CREATE_OBJECT_SYMBOLS); }
292 <WILD>"CONSTRUCTORS"                    { RTOKEN(CONSTRUCTORS); }
293 <SCRIPT>"FORCE_COMMON_ALLOCATION"       { RTOKEN(FORCE_COMMON_ALLOCATION); }
294 <SCRIPT>"FORCE_GROUP_ALLOCATION"        { RTOKEN(FORCE_GROUP_ALLOCATION); }
295 <SCRIPT>"INHIBIT_COMMON_ALLOCATION"     { RTOKEN(INHIBIT_COMMON_ALLOCATION); }
296 <SCRIPT>"SECTIONS"                      { RTOKEN(SECTIONS); }
297 <SCRIPT>"INSERT"                        { RTOKEN(INSERT_K); }
298 <SCRIPT>"AFTER"                         { RTOKEN(AFTER); }
299 <SCRIPT>"BEFORE"                        { RTOKEN(BEFORE); }
300 <WILD>"FILL"                            { RTOKEN(FILL); }
301 <SCRIPT>"STARTUP"                       { RTOKEN(STARTUP); }
302 <SCRIPT>"OUTPUT_FORMAT"                 { RTOKEN(OUTPUT_FORMAT); }
303 <SCRIPT>"OUTPUT_ARCH"                   { RTOKEN(OUTPUT_ARCH); }
304 <SCRIPT>"HLL"                           { RTOKEN(HLL); }
305 <SCRIPT>"SYSLIB"                        { RTOKEN(SYSLIB); }
306 <SCRIPT>"FLOAT"                         { RTOKEN(FLOAT); }
307 <WILD>"QUAD"                            { RTOKEN(QUAD); }
308 <WILD>"SQUAD"                           { RTOKEN(SQUAD); }
309 <WILD>"LONG"                            { RTOKEN(LONG); }
310 <WILD>"SHORT"                           { RTOKEN(SHORT); }
311 <WILD>"BYTE"                            { RTOKEN(BYTE); }
312 <WILD>"ASCIZ"                           { RTOKEN(ASCIZ); }
313 <WILD>"LINKER_VERSION"                  { RTOKEN(LINKER_VERSION); }
314 <SCRIPT>"NOFLOAT"                       { RTOKEN(NOFLOAT); }
315 <SCRIPT,EXPRESSION>"NOCROSSREFS"        { RTOKEN(NOCROSSREFS); }
316 <SCRIPT,EXPRESSION>"NOCROSSREFS_TO"     { RTOKEN(NOCROSSREFS_TO); }
317 <SCRIPT,EXPRESSION>"OVERLAY"            { RTOKEN(OVERLAY); }
318 <WILD>"SORT_BY_NAME"                    { RTOKEN(SORT_BY_NAME); }
319 <WILD>"SORT_BY_ALIGNMENT"               { RTOKEN(SORT_BY_ALIGNMENT); }
320 <WILD>"SORT"                            { RTOKEN(SORT_BY_NAME); }
321 <WILD>"SORT_BY_INIT_PRIORITY"           { RTOKEN(SORT_BY_INIT_PRIORITY); }
322 <WILD>"SORT_NONE"                       { RTOKEN(SORT_NONE); }
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);}
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); }
389 <MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}*  {
390 /* Filename without commas, needed to parse mri stuff */
391                                   yylval.name = xstrdup (yytext);
392                                   return NAME;
393                                 }
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         }
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         }
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 */ }
449 <VERS_NODE,VERS_SCRIPT>[:,;]    { return *yytext; }
451 <VERS_NODE>global               { RTOKEN(GLOBAL); }
453 <VERS_NODE>local                { RTOKEN(LOCAL); }
455 <VERS_NODE>extern               { RTOKEN(EXTERN); }
457 <VERS_NODE>{V_IDENTIFIER}       { yylval.name = xstrdup (yytext);
458                                   return VERS_IDENTIFIER; }
460 <VERS_SCRIPT>{V_TAG}            { yylval.name = xstrdup (yytext);
461                                   return VERS_TAG; }
463 <VERS_START>"{"                 { BEGIN(VERS_SCRIPT); return *yytext; }
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                                 }
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]);
486   lineno = lineno_stack[include_stack_ptr];
487   input_flags.sysrooted = sysrooted_stack[include_stack_ptr];
489   return END;
492 <SCRIPT,WILD,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>.     lex_warn_invalid (_(" in script"), yytext);
493 <EXPRESSION>.   lex_warn_invalid (_(" in expression"), yytext);
498 /* Switch flex to reading script file NAME, open on FILE,
499    saving the current input info on the include stack.  */
501 void
502 lex_push_file (FILE *file, const char *name, unsigned int sysrooted)
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;
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));
520 /* Return a newly created flex input buffer containing STRING,
521    which is SIZE bytes long.  */
523 static YY_BUFFER_STATE
524 yy_create_string_buffer (const char *string, size_t size)
526   YY_BUFFER_STATE b;
528   b = xmalloc (sizeof (struct yy_buffer_state));
529   b->yy_input_file = 0;
530   b->yy_buf_size = size;
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);
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];
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;
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
556   return b;
559 /* Switch flex to reading from STRING, saving the current input info
560    on the include stack.  */
562 void
563 lex_redirect (const char *string, const char *fake_filename, unsigned int count)
565   YY_BUFFER_STATE tmp;
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);
581 /* Functions to switch to a different flex start condition,
582    saving the current start condition on `state_stack'.  */
584 static int state_stack[MAX_INCLUDE_DEPTH * 2];
585 static int *state_stack_p = state_stack;
587 void
588 ldlex_script (void)
590   *(state_stack_p)++ = yy_start;
591   BEGIN (SCRIPT);
594 void
595 ldlex_inputlist (void)
597   *(state_stack_p)++ = yy_start;
598   BEGIN (INPUTLIST);
601 void
602 ldlex_mri_script (void)
604   *(state_stack_p)++ = yy_start;
605   BEGIN (MRI);
608 void
609 ldlex_version_script (void)
611   *(state_stack_p)++ = yy_start;
612   BEGIN (VERS_START);
615 void
616 ldlex_version_file (void)
618   *(state_stack_p)++ = yy_start;
619   BEGIN (VERS_SCRIPT);
622 void
623 ldlex_expression (void)
625   *(state_stack_p)++ = yy_start;
626   BEGIN (EXPRESSION);
629 void
630 ldlex_wild (void)
632   *(state_stack_p)++ = yy_start;
633   BEGIN (WILD);
636 void
637 ldlex_popstate (void)
639   yy_start = *(--state_stack_p);
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.  */
646 void
647 ldlex_backup (void)
649   yyless (0);
652 /* Return the current file name, or the previous file if no file is
653    current.  */
655 const char*
656 ldlex_filename (void)
658   return file_name_stack[include_stack_ptr - (include_stack_ptr != 0)];
662 /* Place up to MAX_SIZE characters in BUF and return
663    either the number of characters read, or 0 to indicate EOF.  */
665 static int
666 yy_input (char *buf, int max_size)
668   int result = 0;
669   if (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;
681 /* Eat the rest of a C-style comment.  */
683 static void
684 comment (void)
686   int c;
688   while (1)
689     {
690       c = input();
691       while (c != '*' && c != 0)
692         {
693           if (c == '\n')
694             lineno++;
695           c = input();
696         }
698       if (c == '*')
699         {
700           c = input();
701           while (c == '*')
702             c = input();
703           if (c == '/')
704             break;                      /* found the end */
705         }
707       if (c == '\n')
708         lineno++;
710       if (c == 0)
711         {
712           einfo (_("%F%P: EOF in comment\n"));
713           break;
714         }
715     }
718 /* Warn the user about a garbage character WHAT in the input
719    in context WHERE.  */
721 static void
722 lex_warn_invalid (char *where, char *what)
724   char buf[5];
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     }
736   if (! ISPRINT (*what))
737     {
738       sprintf (buf, "\\%03o", *(unsigned char *) what);
739       what = buf;
740     }
742   einfo (_("%P:%pS: ignoring invalid character `%s'%s\n"), NULL, what, where);