133965Sjdp%{
233965Sjdp
389857Sobrien/* Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
4218822Sdim   2000, 2001, 2002, 2003, 2004, 2005, 2007
5218822Sdim   Free Software Foundation, Inc.
633965Sjdp
7218822Sdim   This file is part of GLD, the Gnu Linker.
833965Sjdp
9218822Sdim   GLD is free software; you can redistribute it and/or modify
10218822Sdim   it under the terms of the GNU General Public License as published by
11218822Sdim   the Free Software Foundation; either version 2, or (at your option)
12218822Sdim   any later version.
1333965Sjdp
14218822Sdim   GLD is distributed in the hope that it will be useful,
15218822Sdim   but WITHOUT ANY WARRANTY; without even the implied warranty of
16218822Sdim   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17218822Sdim   GNU General Public License for more details.
1833965Sjdp
19218822Sdim   You should have received a copy of the GNU General Public License
20218822Sdim   along with GLD; see the file COPYING.  If not, write to the Free
21218822Sdim   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
22218822Sdim   02110-1301, USA.  */
2333965Sjdp
2433965Sjdp/*
2533965SjdpThis was written by steve chamberlain
2633965Sjdp                    sac@cygnus.com
2733965Sjdp*/
2833965Sjdp
29218822Sdim#include "sysdep.h"
3033965Sjdp#include "bfd.h"
3189857Sobrien#include "safe-ctype.h"
32104834Sobrien#include "bfdlink.h"
3333965Sjdp#include "ld.h"
3433965Sjdp#include "ldmisc.h"
3533965Sjdp#include "ldexp.h"
3633965Sjdp#include "ldlang.h"
37107492Sobrien#include <ldgram.h>
3833965Sjdp#include "ldfile.h"
3933965Sjdp#include "ldlex.h"
4033965Sjdp#include "ldmain.h"
4178828Sobrien#include "libiberty.h"
4233965Sjdp
4333965Sjdp/* The type of top-level parser input.
4433965Sjdp   yylex and yyparse (indirectly) both check this.  */
4533965Sjdpinput_type parser_input;
4633965Sjdp
4733965Sjdp/* Line number in the current input file.
4833965Sjdp   (FIXME Actually, it doesn't appear to get reset for each file?)  */
4933965Sjdpunsigned int lineno = 1;
5033965Sjdp
5133965Sjdp/* The string we are currently lexing, or NULL if we are reading a
5233965Sjdp   file.  */
5333965Sjdpconst char *lex_string = NULL;
5433965Sjdp
5533965Sjdp/* Support for flex reading from more than one input file (stream).
5633965Sjdp   `include_stack' is flex's input state for each open file;
5733965Sjdp   `file_name_stack' is the file names.  `lineno_stack' is the current
5833965Sjdp   line numbers.
5933965Sjdp
6033965Sjdp   If `include_stack_ptr' is 0, we haven't started reading anything yet.
6133965Sjdp   Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid.  */
6233965Sjdp
6333965Sjdp#undef YY_INPUT
64130561Sobrien#define YY_INPUT(buf,result,max_size) yy_input (buf, &result, max_size)
6533965Sjdp
6633965Sjdp#define MAX_INCLUDE_DEPTH 10
6733965Sjdpstatic YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
6833965Sjdpstatic const char *file_name_stack[MAX_INCLUDE_DEPTH];
6933965Sjdpstatic unsigned int lineno_stack[MAX_INCLUDE_DEPTH];
7033965Sjdpstatic unsigned int include_stack_ptr = 0;
7160484Sobrienstatic int vers_node_nesting = 0;
7233965Sjdp
73252181Smariusstatic void yy_input (char *, yy_size_t *, yy_size_t);
74130561Sobrienstatic void comment (void);
75130561Sobrienstatic void lex_warn_invalid (char *where, char *what);
7633965Sjdp
77130561Sobrien/* STATES
7833965Sjdp	EXPRESSION	definitely in an expression
7933965Sjdp	SCRIPT		definitely in a script
8033965Sjdp	BOTH		either EXPRESSION or SCRIPT
8133965Sjdp	DEFSYMEXP	in an argument to -defsym
8233965Sjdp        MRI             in an MRI script
8333965Sjdp	VERS_START	starting a Sun style mapfile
8433965Sjdp	VERS_SCRIPT	a Sun style mapfile
8533965Sjdp	VERS_NODE	a node within a Sun style mapfile
8633965Sjdp*/
8733965Sjdp#define RTOKEN(x)  {  yylval.token = x; return x; }
8833965Sjdp
8933965Sjdp/* Some versions of flex want this.  */
9033965Sjdp#ifndef yywrap
91130561Sobrienint yywrap (void) { return 1; }
9233965Sjdp#endif
9333965Sjdp%}
9433965Sjdp
95252181Smarius%option nounput
96252181Smarius
9733965Sjdp%a 4000
9833965Sjdp%o 5000
9933965Sjdp
10033965SjdpCMDFILENAMECHAR   [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\-\~]
10133965SjdpCMDFILENAMECHAR1  [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\~]
10233965SjdpFILENAMECHAR1	[_a-zA-Z\/\.\\\$\_\~]
10333965SjdpSYMBOLCHARN     [_a-zA-Z\/\.\\\$\_\~0-9]
10433965SjdpFILENAMECHAR	[_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~]
10533965SjdpWILDCHAR	[_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~\?\*]
106130561SobrienWHITE		[ \t\n\r]+
10733965Sjdp
10833965SjdpNOCFILENAMECHAR	[_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
10933965Sjdp
11033965SjdpV_TAG [.$_a-zA-Z][._a-zA-Z0-9]*
111130561SobrienV_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([*?.$_a-zA-Z0-9\[\]\-\!\^\\]|::)*
11233965Sjdp
11333965Sjdp%s SCRIPT
11433965Sjdp%s EXPRESSION
11533965Sjdp%s BOTH
11633965Sjdp%s DEFSYMEXP
11733965Sjdp%s MRI
11833965Sjdp%s VERS_START
11933965Sjdp%s VERS_SCRIPT
12033965Sjdp%s VERS_NODE
12133965Sjdp%%
12233965Sjdp
12333965Sjdp  if (parser_input != input_selected)
12433965Sjdp    {
12533965Sjdp      /* The first token of the input determines the initial parser state.  */
12633965Sjdp      input_type t = parser_input;
12733965Sjdp      parser_input = input_selected;
12833965Sjdp      switch (t)
12933965Sjdp	{
13033965Sjdp	case input_script: return INPUT_SCRIPT; break;
13133965Sjdp	case input_mri_script: return INPUT_MRI_SCRIPT; break;
13233965Sjdp	case input_version_script: return INPUT_VERSION_SCRIPT; break;
133218822Sdim	case input_dynamic_list: return INPUT_DYNAMIC_LIST; break;
13433965Sjdp	case input_defsym: return INPUT_DEFSYM; break;
13533965Sjdp	default: abort ();
13633965Sjdp	}
13733965Sjdp    }
13833965Sjdp
139130561Sobrien<BOTH,SCRIPT,EXPRESSION,VERS_START,VERS_NODE,VERS_SCRIPT>"/*"	{ comment (); }
14033965Sjdp
14133965Sjdp
14233965Sjdp<DEFSYMEXP>"-"                  { RTOKEN('-');}
14333965Sjdp<DEFSYMEXP>"+"                  { RTOKEN('+');}
144130561Sobrien<DEFSYMEXP>{FILENAMECHAR1}{SYMBOLCHARN}*   { yylval.name = xstrdup (yytext); return NAME; }
14533965Sjdp<DEFSYMEXP>"="                  { RTOKEN('='); }
14633965Sjdp
14733965Sjdp<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
148130561Sobrien  				yylval.integer = bfd_scan_vma (yytext + 1, 0, 16);
149130561Sobrien				yylval.bigint.str = NULL;
15033965Sjdp				return INT;
15133965Sjdp			}
15233965Sjdp
15333965Sjdp<MRI,EXPRESSION>([0-9A-Fa-f])+(H|h|X|x|B|b|O|o|D|d) {
15433965Sjdp				   int ibase ;
155130561Sobrien				   switch (yytext[yyleng - 1]) {
156130561Sobrien				    case 'X':
15733965Sjdp				    case 'x':
15833965Sjdp				    case 'H':
15933965Sjdp				    case 'h':
16033965Sjdp				     ibase = 16;
16133965Sjdp				     break;
16233965Sjdp				    case 'O':
16333965Sjdp				    case 'o':
16433965Sjdp				     ibase = 8;
16533965Sjdp				     break;
16633965Sjdp				    case 'B':
16733965Sjdp				    case 'b':
16833965Sjdp				     ibase = 2;
16933965Sjdp				     break;
17033965Sjdp				    default:
17133965Sjdp				     ibase = 10;
17233965Sjdp				   }
17333965Sjdp				   yylval.integer = bfd_scan_vma (yytext, 0,
17433965Sjdp								  ibase);
175130561Sobrien				   yylval.bigint.str = NULL;
17633965Sjdp				   return INT;
17733965Sjdp				 }
178104834Sobrien<SCRIPT,DEFSYMEXP,MRI,BOTH,EXPRESSION>((("$"|0[xX])([0-9A-Fa-f])+)|(([0-9])+))(M|K|m|k)? {
17938889Sjdp				  char *s = yytext;
180104834Sobrien				  int ibase = 0;
18138889Sjdp
18238889Sjdp				  if (*s == '$')
183104834Sobrien				    {
184104834Sobrien				      ++s;
185104834Sobrien				      ibase = 16;
186104834Sobrien				    }
187104834Sobrien				  yylval.integer = bfd_scan_vma (s, 0, ibase);
188130561Sobrien				  yylval.bigint.str = NULL;
189130561Sobrien				  if (yytext[yyleng - 1] == 'M'
190130561Sobrien				      || yytext[yyleng - 1] == 'm')
191104834Sobrien				    {
192104834Sobrien				      yylval.integer *= 1024 * 1024;
193104834Sobrien				    }
194130561Sobrien				  else if (yytext[yyleng - 1] == 'K'
195130561Sobrien				      || yytext[yyleng - 1]=='k')
196104834Sobrien				    {
197104834Sobrien				      yylval.integer *= 1024;
198104834Sobrien				    }
199104834Sobrien				  else if (yytext[0] == '0'
200104834Sobrien					   && (yytext[1] == 'x'
201104834Sobrien					       || yytext[1] == 'X'))
202104834Sobrien				    {
203104834Sobrien				      yylval.bigint.str = xstrdup (yytext + 2);
204104834Sobrien				    }
20533965Sjdp				  return INT;
20633965Sjdp				}
20733965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"]"		{ RTOKEN(']');}
20833965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"["		{ RTOKEN('[');}
20933965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"<<="	{ RTOKEN(LSHIFTEQ);}
21033965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>">>="	{ RTOKEN(RSHIFTEQ);}
21133965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"||"	{ RTOKEN(OROR);}
21233965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"=="	{ RTOKEN(EQ);}
21333965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"!="	{ RTOKEN(NE);}
21433965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>">="	{ RTOKEN(GE);}
21533965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"<="	{ RTOKEN(LE);}
21633965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"<<"	{ RTOKEN(LSHIFT);}
21733965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>">>"	{ RTOKEN(RSHIFT);}
21833965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"+="	{ RTOKEN(PLUSEQ);}
21933965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"-="	{ RTOKEN(MINUSEQ);}
22033965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"*="	{ RTOKEN(MULTEQ);}
22133965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"/="	{ RTOKEN(DIVEQ);}
22233965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"&="	{ RTOKEN(ANDEQ);}
22333965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"|="	{ RTOKEN(OREQ);}
22433965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"&&"	{ RTOKEN(ANDAND);}
22533965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>">"		{ RTOKEN('>');}
22633965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>","		{ RTOKEN(',');}
22733965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"&"		{ RTOKEN('&');}
22833965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"|"		{ RTOKEN('|');}
22933965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"~"		{ RTOKEN('~');}
23033965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"!"		{ RTOKEN('!');}
23133965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"?"		{ RTOKEN('?');}
23233965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"*"		{ RTOKEN('*');}
23333965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"+"		{ RTOKEN('+');}
23433965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"-"		{ RTOKEN('-');}
23533965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"/"		{ RTOKEN('/');}
23633965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"%"		{ RTOKEN('%');}
23733965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>"<"		{ RTOKEN('<');}
238218822Sdim<BOTH,SCRIPT,EXPRESSION,MRI>"="         { RTOKEN('=');}
239218822Sdim<BOTH,SCRIPT,EXPRESSION,MRI>"}"		{ RTOKEN('}') ; }
240218822Sdim<BOTH,SCRIPT,EXPRESSION,MRI>"{"		{ RTOKEN('{'); }
241218822Sdim<BOTH,SCRIPT,EXPRESSION,MRI>")"		{ RTOKEN(')');}
242218822Sdim<BOTH,SCRIPT,EXPRESSION,MRI>"("		{ RTOKEN('(');}
24333965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>":"		{ RTOKEN(':'); }
24433965Sjdp<BOTH,SCRIPT,EXPRESSION,MRI>";"		{ RTOKEN(';');}
245218822Sdim<BOTH,SCRIPT>"MEMORY"			{ RTOKEN(MEMORY);}
246218822Sdim<BOTH,SCRIPT,EXPRESSION>"ORIGIN"	{ RTOKEN(ORIGIN);}
247218822Sdim<BOTH,SCRIPT>"VERSION"			{ RTOKEN(VERSIONK);}
24833965Sjdp<EXPRESSION,BOTH,SCRIPT>"BLOCK"		{ RTOKEN(BLOCK);}
24933965Sjdp<EXPRESSION,BOTH,SCRIPT>"BIND"		{ RTOKEN(BIND);}
250218822Sdim<BOTH,SCRIPT,EXPRESSION>"LENGTH"	{ RTOKEN(LENGTH);}
251218822Sdim<EXPRESSION,BOTH,SCRIPT>"ALIGN"		{ RTOKEN(ALIGN_K);}
252104834Sobrien<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_ALIGN"	{ RTOKEN(DATA_SEGMENT_ALIGN);}
253218822Sdim<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_RELRO_END"	{ RTOKEN(DATA_SEGMENT_RELRO_END);}
254104834Sobrien<EXPRESSION,BOTH,SCRIPT>"DATA_SEGMENT_END"	{ RTOKEN(DATA_SEGMENT_END);}
255218822Sdim<EXPRESSION,BOTH,SCRIPT>"ADDR"		{ RTOKEN(ADDR);}
256218822Sdim<EXPRESSION,BOTH,SCRIPT>"LOADADDR"	{ RTOKEN(LOADADDR);}
257218822Sdim<EXPRESSION,BOTH,SCRIPT>"ALIGNOF"	{ RTOKEN(ALIGNOF); }
25860484Sobrien<EXPRESSION,BOTH>"MAX"			{ RTOKEN(MAX_K); }
25960484Sobrien<EXPRESSION,BOTH>"MIN"			{ RTOKEN(MIN_K); }
260218822Sdim<EXPRESSION,BOTH,SCRIPT>"ASSERT"	{ RTOKEN(ASSERT_K); }
26133965Sjdp<BOTH,SCRIPT>"ENTRY"			{ RTOKEN(ENTRY);}
26260484Sobrien<BOTH,SCRIPT,MRI>"EXTERN"		{ RTOKEN(EXTERN);}
263218822Sdim<EXPRESSION,BOTH,SCRIPT>"NEXT"		{ RTOKEN(NEXT);}
26433965Sjdp<EXPRESSION,BOTH,SCRIPT>"sizeof_headers"	{ RTOKEN(SIZEOF_HEADERS);}
26533965Sjdp<EXPRESSION,BOTH,SCRIPT>"SIZEOF_HEADERS"	{ RTOKEN(SIZEOF_HEADERS);}
266218822Sdim<EXPRESSION,BOTH,SCRIPT>"SEGMENT_START" { RTOKEN(SEGMENT_START);}
26733965Sjdp<BOTH,SCRIPT>"MAP"			{ RTOKEN(MAP);}
268218822Sdim<EXPRESSION,BOTH,SCRIPT>"SIZEOF"	{ RTOKEN(SIZEOF);}
269218822Sdim<BOTH,SCRIPT>"TARGET"			{ RTOKEN(TARGET_K);}
27033965Sjdp<BOTH,SCRIPT>"SEARCH_DIR"		{ RTOKEN(SEARCH_DIR);}
271218822Sdim<BOTH,SCRIPT>"OUTPUT"			{ RTOKEN(OUTPUT);}
27233965Sjdp<BOTH,SCRIPT>"INPUT"			{ RTOKEN(INPUT);}
27333965Sjdp<EXPRESSION,BOTH,SCRIPT>"GROUP"		{ RTOKEN(GROUP);}
274218822Sdim<EXPRESSION,BOTH,SCRIPT>"AS_NEEDED"	{ RTOKEN(AS_NEEDED);}
275218822Sdim<EXPRESSION,BOTH,SCRIPT>"DEFINED"	{ RTOKEN(DEFINED);}
27633965Sjdp<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS"	{ RTOKEN(CREATE_OBJECT_SYMBOLS);}
27733965Sjdp<BOTH,SCRIPT>"CONSTRUCTORS"		{ RTOKEN( CONSTRUCTORS);}
278218822Sdim<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION"	{ RTOKEN(FORCE_COMMON_ALLOCATION);}
27989857Sobrien<BOTH,SCRIPT>"INHIBIT_COMMON_ALLOCATION" { RTOKEN(INHIBIT_COMMON_ALLOCATION);}
280218822Sdim<BOTH,SCRIPT>"SECTIONS"			{ RTOKEN(SECTIONS);}
28133965Sjdp<BOTH,SCRIPT>"FILL"			{ RTOKEN(FILL);}
282218822Sdim<BOTH,SCRIPT>"STARTUP"			{ RTOKEN(STARTUP);}
28333965Sjdp<BOTH,SCRIPT>"OUTPUT_FORMAT"		{ RTOKEN(OUTPUT_FORMAT);}
28433965Sjdp<BOTH,SCRIPT>"OUTPUT_ARCH"		{ RTOKEN( OUTPUT_ARCH);}
28533965Sjdp<BOTH,SCRIPT>"HLL"			{ RTOKEN(HLL);}
286218822Sdim<BOTH,SCRIPT>"SYSLIB"			{ RTOKEN(SYSLIB);}
28733965Sjdp<BOTH,SCRIPT>"FLOAT"			{ RTOKEN(FLOAT);}
28833965Sjdp<BOTH,SCRIPT>"QUAD"			{ RTOKEN( QUAD);}
28938889Sjdp<BOTH,SCRIPT>"SQUAD"			{ RTOKEN( SQUAD);}
29033965Sjdp<BOTH,SCRIPT>"LONG"			{ RTOKEN( LONG);}
29133965Sjdp<BOTH,SCRIPT>"SHORT"			{ RTOKEN( SHORT);}
29233965Sjdp<BOTH,SCRIPT>"BYTE"			{ RTOKEN( BYTE);}
293218822Sdim<BOTH,SCRIPT>"NOFLOAT"			{ RTOKEN(NOFLOAT);}
29433965Sjdp<EXPRESSION,BOTH,SCRIPT>"NOCROSSREFS"	{ RTOKEN(NOCROSSREFS);}
29533965Sjdp<BOTH,SCRIPT>"OVERLAY"			{ RTOKEN(OVERLAY); }
296218822Sdim<BOTH,SCRIPT>"SORT_BY_NAME"		{ RTOKEN(SORT_BY_NAME); }
297218822Sdim<BOTH,SCRIPT>"SORT_BY_ALIGNMENT"	{ RTOKEN(SORT_BY_ALIGNMENT); }
298218822Sdim<BOTH,SCRIPT>"SORT"			{ RTOKEN(SORT_BY_NAME); }
29933965Sjdp<EXPRESSION,BOTH,SCRIPT>"NOLOAD"	{ RTOKEN(NOLOAD);}
30033965Sjdp<EXPRESSION,BOTH,SCRIPT>"DSECT"		{ RTOKEN(DSECT);}
30133965Sjdp<EXPRESSION,BOTH,SCRIPT>"COPY"		{ RTOKEN(COPY);}
30233965Sjdp<EXPRESSION,BOTH,SCRIPT>"INFO"		{ RTOKEN(INFO);}
30333965Sjdp<EXPRESSION,BOTH,SCRIPT>"OVERLAY"	{ RTOKEN(OVERLAY);}
304218822Sdim<EXPRESSION,BOTH,SCRIPT>"ONLY_IF_RO"	{ RTOKEN(ONLY_IF_RO); }
305218822Sdim<EXPRESSION,BOTH,SCRIPT>"ONLY_IF_RW"	{ RTOKEN(ONLY_IF_RW); }
306218822Sdim<EXPRESSION,BOTH,SCRIPT>"SPECIAL"	{ RTOKEN(SPECIAL); }
30733965Sjdp<BOTH,SCRIPT>"o"			{ RTOKEN(ORIGIN);}
30833965Sjdp<BOTH,SCRIPT>"org"			{ RTOKEN(ORIGIN);}
30933965Sjdp<BOTH,SCRIPT>"l"			{ RTOKEN( LENGTH);}
31033965Sjdp<BOTH,SCRIPT>"len"			{ RTOKEN( LENGTH);}
31133965Sjdp<BOTH,SCRIPT>"INCLUDE"			{ RTOKEN(INCLUDE);}
31233965Sjdp<BOTH,SCRIPT>"PHDRS"			{ RTOKEN (PHDRS); }
313218822Sdim<EXPRESSION,BOTH,SCRIPT>"AT"		{ RTOKEN(AT);}
314218822Sdim<EXPRESSION,BOTH,SCRIPT>"SUBALIGN"	{ RTOKEN(SUBALIGN);}
315218822Sdim<EXPRESSION,BOTH,SCRIPT>"PROVIDE"	{ RTOKEN(PROVIDE); }
316218822Sdim<EXPRESSION,BOTH,SCRIPT>"PROVIDE_HIDDEN" { RTOKEN(PROVIDE_HIDDEN); }
31760484Sobrien<EXPRESSION,BOTH,SCRIPT>"KEEP"		{ RTOKEN(KEEP); }
318218822Sdim<EXPRESSION,BOTH,SCRIPT>"EXCLUDE_FILE"  { RTOKEN(EXCLUDE_FILE); }
319218822Sdim<EXPRESSION,BOTH,SCRIPT>"CONSTANT"	{ RTOKEN(CONSTANT);}
32038889Sjdp<MRI>"#".*\n?			{ ++ lineno; }
32133965Sjdp<MRI>"\n"	                { ++ lineno;  RTOKEN(NEWLINE); }
32233965Sjdp<MRI>"*".*			{ /* Mri comment line */ }
32333965Sjdp<MRI>";".*			{ /* Mri comment line */ }
32433965Sjdp<MRI>"END"                      { RTOKEN(ENDWORD); }
325218822Sdim<MRI>"ALIGNMOD"			{ RTOKEN(ALIGNMOD);}
326218822Sdim<MRI>"ALIGN"			{ RTOKEN(ALIGN_K);}
32733965Sjdp<MRI>"CHIP"                     { RTOKEN(CHIP); }
32833965Sjdp<MRI>"BASE"                     { RTOKEN(BASE); }
329218822Sdim<MRI>"ALIAS"                    { RTOKEN(ALIAS); }
330218822Sdim<MRI>"TRUNCATE"                 { RTOKEN(TRUNCATE); }
33133965Sjdp<MRI>"LOAD"                     { RTOKEN(LOAD); }
33233965Sjdp<MRI>"PUBLIC"                   { RTOKEN(PUBLIC); }
33333965Sjdp<MRI>"ORDER"                    { RTOKEN(ORDER); }
33433965Sjdp<MRI>"NAME"                     { RTOKEN(NAMEWORD); }
33533965Sjdp<MRI>"FORMAT"                   { RTOKEN(FORMAT); }
33633965Sjdp<MRI>"CASE"                     { RTOKEN(CASE); }
33733965Sjdp<MRI>"START"                    { RTOKEN(START); }
33833965Sjdp<MRI>"LIST".*                   { RTOKEN(LIST); /* LIST and ignore to end of line */ }
33933965Sjdp<MRI>"SECT"			{ RTOKEN(SECT); }
34033965Sjdp<EXPRESSION,BOTH,SCRIPT,MRI>"ABSOLUTE"			{ RTOKEN(ABSOLUTE); }
34133965Sjdp<MRI>"end"                      { RTOKEN(ENDWORD); }
342218822Sdim<MRI>"alignmod"			{ RTOKEN(ALIGNMOD);}
343218822Sdim<MRI>"align"			{ RTOKEN(ALIGN_K);}
34433965Sjdp<MRI>"chip"                     { RTOKEN(CHIP); }
34533965Sjdp<MRI>"base"                     { RTOKEN(BASE); }
346218822Sdim<MRI>"alias"                    { RTOKEN(ALIAS); }
347218822Sdim<MRI>"truncate"                 { RTOKEN(TRUNCATE); }
34833965Sjdp<MRI>"load"                     { RTOKEN(LOAD); }
34933965Sjdp<MRI>"public"                   { RTOKEN(PUBLIC); }
35033965Sjdp<MRI>"order"                    { RTOKEN(ORDER); }
35133965Sjdp<MRI>"name"                     { RTOKEN(NAMEWORD); }
35233965Sjdp<MRI>"format"                   { RTOKEN(FORMAT); }
35333965Sjdp<MRI>"case"                     { RTOKEN(CASE); }
35433965Sjdp<MRI>"extern"                   { RTOKEN(EXTERN); }
35533965Sjdp<MRI>"start"                    { RTOKEN(START); }
35633965Sjdp<MRI>"list".*                   { RTOKEN(LIST); /* LIST and ignore to end of line */ }
35733965Sjdp<MRI>"sect"			{ RTOKEN(SECT); }
35833965Sjdp<EXPRESSION,BOTH,SCRIPT,MRI>"absolute"			{ RTOKEN(ABSOLUTE); }
35933965Sjdp
36033965Sjdp<MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}*	{
36133965Sjdp/* Filename without commas, needed to parse mri stuff */
362130561Sobrien				 yylval.name = xstrdup (yytext);
36333965Sjdp				  return NAME;
36433965Sjdp				}
36533965Sjdp
36633965Sjdp
367218822Sdim<BOTH>{FILENAMECHAR1}{FILENAMECHAR}*	{
368130561Sobrien				 yylval.name = xstrdup (yytext);
36933965Sjdp				  return NAME;
37033965Sjdp				}
371218822Sdim<BOTH>"-l"{FILENAMECHAR}+ {
37278828Sobrien				  yylval.name = xstrdup (yytext + 2);
37333965Sjdp				  return LNAME;
37433965Sjdp				}
375218822Sdim<EXPRESSION>{FILENAMECHAR1}{NOCFILENAMECHAR}*	{
376218822Sdim				 yylval.name = xstrdup (yytext);
377218822Sdim				  return NAME;
378218822Sdim				}
379218822Sdim<EXPRESSION>"-l"{NOCFILENAMECHAR}+ {
380218822Sdim				  yylval.name = xstrdup (yytext + 2);
381218822Sdim				  return LNAME;
382218822Sdim				}
38338889Sjdp<SCRIPT>{WILDCHAR}* {
38438889Sjdp		/* Annoyingly, this pattern can match comments, and we have
38538889Sjdp		   longest match issues to consider.  So if the first two
38638889Sjdp		   characters are a comment opening, put the input back and
38738889Sjdp		   try again.  */
38838889Sjdp		if (yytext[0] == '/' && yytext[1] == '*')
38938889Sjdp		  {
390130561Sobrien		    yyless (2);
39138889Sjdp		    comment ();
39238889Sjdp		  }
39338889Sjdp		else
39438889Sjdp		  {
395130561Sobrien		    yylval.name = xstrdup (yytext);
39638889Sjdp		    return NAME;
39738889Sjdp		  }
39838889Sjdp	}
39933965Sjdp
40060484Sobrien<EXPRESSION,BOTH,SCRIPT,VERS_NODE>"\""[^\"]*"\"" {
40133965Sjdp					/* No matter the state, quotes
40233965Sjdp					   give what's inside */
403130561Sobrien					yylval.name = xstrdup (yytext + 1);
404130561Sobrien					yylval.name[yyleng - 2] = 0;
40533965Sjdp					return NAME;
40633965Sjdp				}
40733965Sjdp<BOTH,SCRIPT,EXPRESSION>"\n"		{ lineno++;}
40838889Sjdp<MRI,BOTH,SCRIPT,EXPRESSION>[ \t\r]+	{ }
40933965Sjdp
41033965Sjdp<VERS_NODE,VERS_SCRIPT>[:,;]	{ return *yytext; }
41133965Sjdp
41233965Sjdp<VERS_NODE>global		{ RTOKEN(GLOBAL); }
41333965Sjdp
41433965Sjdp<VERS_NODE>local		{ RTOKEN(LOCAL); }
41533965Sjdp
41660484Sobrien<VERS_NODE>extern		{ RTOKEN(EXTERN); }
41760484Sobrien
41878828Sobrien<VERS_NODE>{V_IDENTIFIER}	{ yylval.name = xstrdup (yytext);
41933965Sjdp				  return VERS_IDENTIFIER; }
42033965Sjdp
42178828Sobrien<VERS_SCRIPT>{V_TAG}		{ yylval.name = xstrdup (yytext);
42233965Sjdp				  return VERS_TAG; }
42333965Sjdp
42433965Sjdp<VERS_START>"{"			{ BEGIN(VERS_SCRIPT); return *yytext; }
42533965Sjdp
426130561Sobrien<VERS_SCRIPT>"{"		{ BEGIN(VERS_NODE);
42760484Sobrien				  vers_node_nesting = 0;
42860484Sobrien				  return *yytext;
42960484Sobrien				}
43060484Sobrien<VERS_SCRIPT>"}"		{ return *yytext; }
43160484Sobrien<VERS_NODE>"{"			{ vers_node_nesting++; return *yytext; }
43260484Sobrien<VERS_NODE>"}"			{ if (--vers_node_nesting < 0)
43360484Sobrien				    BEGIN(VERS_SCRIPT);
43460484Sobrien				  return *yytext;
43560484Sobrien				}
43633965Sjdp
43738889Sjdp<VERS_START,VERS_NODE,VERS_SCRIPT>[\n]		{ lineno++; }
43833965Sjdp
43933965Sjdp<VERS_START,VERS_NODE,VERS_SCRIPT>#.*		{ /* Eat up comments */ }
44033965Sjdp
44138889Sjdp<VERS_START,VERS_NODE,VERS_SCRIPT>[ \t\r]+   	{ /* Eat up whitespace */ }
44233965Sjdp
44333965Sjdp<<EOF>> {
44433965Sjdp  include_stack_ptr--;
445130561Sobrien
446130561Sobrien  if (include_stack_ptr == 0)
44733965Sjdp  {
448130561Sobrien    yyterminate ();
44933965Sjdp  }
450130561Sobrien  else
45133965Sjdp  {
452130561Sobrien    yy_switch_to_buffer (include_stack[include_stack_ptr]);
45389857Sobrien  }
45433965Sjdp
45533965Sjdp  ldfile_input_filename = file_name_stack[include_stack_ptr - 1];
45689857Sobrien  lineno = lineno_stack[include_stack_ptr];
45733965Sjdp
45833965Sjdp  return END;
45933965Sjdp}
46033965Sjdp
461130561Sobrien<SCRIPT,MRI,VERS_START,VERS_SCRIPT,VERS_NODE>.	lex_warn_invalid (" in script", yytext);
462130561Sobrien<EXPRESSION,DEFSYMEXP,BOTH>.	lex_warn_invalid (" in expression", yytext);
463130561Sobrien
46433965Sjdp%%
46533965Sjdp
46633965Sjdp
46733965Sjdp/* Switch flex to reading script file NAME, open on FILE,
46833965Sjdp   saving the current input info on the include stack.  */
46933965Sjdp
47033965Sjdpvoid
471130561Sobrienlex_push_file (FILE *file, const char *name)
47233965Sjdp{
473130561Sobrien  if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
47433965Sjdp    {
475130561Sobrien      einfo ("%F:includes nested too deeply\n");
47633965Sjdp    }
47733965Sjdp  file_name_stack[include_stack_ptr] = name;
47889857Sobrien  lineno_stack[include_stack_ptr] = lineno;
47933965Sjdp  include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
48033965Sjdp
48133965Sjdp  include_stack_ptr++;
48289857Sobrien  lineno = 1;
48333965Sjdp  yyin = file;
484130561Sobrien  yy_switch_to_buffer (yy_create_buffer (yyin, YY_BUF_SIZE));
48533965Sjdp}
48633965Sjdp
48733965Sjdp/* Return a newly created flex input buffer containing STRING,
48833965Sjdp   which is SIZE bytes long.  */
48933965Sjdp
490130561Sobrienstatic YY_BUFFER_STATE
491130561Sobrienyy_create_string_buffer (const char *string, size_t size)
49233965Sjdp{
49333965Sjdp  YY_BUFFER_STATE b;
49433965Sjdp
49533965Sjdp  /* Calls to m-alloc get turned by sed into xm-alloc.  */
496130561Sobrien  b = malloc (sizeof (struct yy_buffer_state));
49733965Sjdp  b->yy_input_file = 0;
49833965Sjdp  b->yy_buf_size = size;
49933965Sjdp
50033965Sjdp  /* yy_ch_buf has to be 2 characters longer than the size given because
50133965Sjdp     we need to put in 2 end-of-buffer characters.  */
502130561Sobrien  b->yy_ch_buf = malloc ((unsigned) (b->yy_buf_size + 3));
50333965Sjdp
50433965Sjdp  b->yy_ch_buf[0] = '\n';
50533965Sjdp  strcpy (b->yy_ch_buf+1, string);
50633965Sjdp  b->yy_ch_buf[size+1] = YY_END_OF_BUFFER_CHAR;
50733965Sjdp  b->yy_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR;
50833965Sjdp  b->yy_n_chars = size+1;
50933965Sjdp  b->yy_buf_pos = &b->yy_ch_buf[1];
51033965Sjdp
51168765Sobrien  b->yy_is_our_buffer = 1;
51268765Sobrien  b->yy_is_interactive = 0;
51368765Sobrien  b->yy_at_bol = 1;
51468765Sobrien  b->yy_fill_buffer = 0;
51568765Sobrien
51633965Sjdp  /* flex 2.4.7 changed the interface.  FIXME: We should not be using
51733965Sjdp     a flex internal interface in the first place!  */
51833965Sjdp#ifdef YY_BUFFER_NEW
51933965Sjdp  b->yy_buffer_status = YY_BUFFER_NEW;
52033965Sjdp#else
52133965Sjdp  b->yy_eof_status = EOF_NOT_SEEN;
52233965Sjdp#endif
52333965Sjdp
52433965Sjdp  return b;
52533965Sjdp}
52633965Sjdp
52733965Sjdp/* Switch flex to reading from STRING, saving the current input info
52833965Sjdp   on the include stack.  */
52933965Sjdp
53033965Sjdpvoid
531130561Sobrienlex_redirect (const char *string)
53233965Sjdp{
53333965Sjdp  YY_BUFFER_STATE tmp;
53433965Sjdp
53533965Sjdp  yy_init = 0;
536130561Sobrien  if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
53733965Sjdp    {
53833965Sjdp      einfo("%F: macros nested too deeply\n");
53933965Sjdp    }
54033965Sjdp  file_name_stack[include_stack_ptr] = "redirect";
54189857Sobrien  lineno_stack[include_stack_ptr] = lineno;
54233965Sjdp  include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
54333965Sjdp  include_stack_ptr++;
54489857Sobrien  lineno = 1;
54533965Sjdp  tmp = yy_create_string_buffer (string, strlen (string));
54633965Sjdp  yy_switch_to_buffer (tmp);
54733965Sjdp}
54833965Sjdp
54933965Sjdp/* Functions to switch to a different flex start condition,
55033965Sjdp   saving the current start condition on `state_stack'.  */
55133965Sjdp
55233965Sjdpstatic int state_stack[MAX_INCLUDE_DEPTH * 2];
55333965Sjdpstatic int *state_stack_p = state_stack;
55433965Sjdp
55533965Sjdpvoid
556130561Sobrienldlex_script (void)
55733965Sjdp{
55833965Sjdp  *(state_stack_p)++ = yy_start;
55933965Sjdp  BEGIN (SCRIPT);
56033965Sjdp}
56133965Sjdp
56233965Sjdpvoid
563130561Sobrienldlex_mri_script (void)
56433965Sjdp{
56533965Sjdp  *(state_stack_p)++ = yy_start;
56633965Sjdp  BEGIN (MRI);
56733965Sjdp}
56833965Sjdp
56933965Sjdpvoid
570130561Sobrienldlex_version_script (void)
57133965Sjdp{
57233965Sjdp  *(state_stack_p)++ = yy_start;
57333965Sjdp  BEGIN (VERS_START);
57433965Sjdp}
57533965Sjdp
57633965Sjdpvoid
577130561Sobrienldlex_version_file (void)
57833965Sjdp{
57933965Sjdp  *(state_stack_p)++ = yy_start;
58033965Sjdp  BEGIN (VERS_SCRIPT);
58133965Sjdp}
58233965Sjdp
58333965Sjdpvoid
584130561Sobrienldlex_defsym (void)
58533965Sjdp{
58633965Sjdp  *(state_stack_p)++ = yy_start;
58733965Sjdp  BEGIN (DEFSYMEXP);
58833965Sjdp}
589130561Sobrien
59033965Sjdpvoid
591130561Sobrienldlex_expression (void)
59233965Sjdp{
59333965Sjdp  *(state_stack_p)++ = yy_start;
59433965Sjdp  BEGIN (EXPRESSION);
59533965Sjdp}
59633965Sjdp
59733965Sjdpvoid
598130561Sobrienldlex_both (void)
59933965Sjdp{
60033965Sjdp  *(state_stack_p)++ = yy_start;
60133965Sjdp  BEGIN (BOTH);
60233965Sjdp}
60333965Sjdp
60433965Sjdpvoid
605130561Sobrienldlex_popstate (void)
60633965Sjdp{
60733965Sjdp  yy_start = *(--state_stack_p);
60833965Sjdp}
60933965Sjdp
61033965Sjdp
61133965Sjdp/* Place up to MAX_SIZE characters in BUF and return in *RESULT
61233965Sjdp   either the number of characters read, or 0 to indicate EOF.  */
61333965Sjdp
61433965Sjdpstatic void
615252181Smariusyy_input (char *buf, yy_size_t *result, yy_size_t max_size)
61633965Sjdp{
617130561Sobrien  *result = 0;
618130561Sobrien  if (YY_CURRENT_BUFFER->yy_input_file)
61933965Sjdp    {
62033965Sjdp      if (yyin)
62133965Sjdp	{
622130561Sobrien	  *result = fread (buf, 1, max_size, yyin);
623130561Sobrien	  if (*result < max_size && ferror (yyin))
62438889Sjdp	    einfo ("%F%P: read in flex scanner failed\n");
62533965Sjdp	}
62633965Sjdp    }
62733965Sjdp}
62833965Sjdp
62933965Sjdp/* Eat the rest of a C-style comment.  */
63033965Sjdp
63133965Sjdpstatic void
632130561Sobriencomment (void)
63333965Sjdp{
63433965Sjdp  int c;
63533965Sjdp
63633965Sjdp  while (1)
63733965Sjdp  {
63833965Sjdp    c = input();
639130561Sobrien    while (c != '*' && c != EOF)
64033965Sjdp    {
64138889Sjdp      if (c == '\n')
64233965Sjdp	lineno++;
64333965Sjdp      c = input();
64433965Sjdp    }
64533965Sjdp
64633965Sjdp    if (c == '*')
64733965Sjdp    {
64833965Sjdp      c = input();
64933965Sjdp      while (c == '*')
65033965Sjdp       c = input();
65133965Sjdp      if (c == '/')
65233965Sjdp       break;			/* found the end */
65333965Sjdp    }
65433965Sjdp
65538889Sjdp    if (c == '\n')
65633965Sjdp      lineno++;
65733965Sjdp
65833965Sjdp    if (c == EOF)
65933965Sjdp    {
66033965Sjdp      einfo( "%F%P: EOF in comment\n");
66133965Sjdp      break;
66233965Sjdp    }
66333965Sjdp  }
66433965Sjdp}
66533965Sjdp
66633965Sjdp/* Warn the user about a garbage character WHAT in the input
66733965Sjdp   in context WHERE.  */
66833965Sjdp
66933965Sjdpstatic void
670130561Sobrienlex_warn_invalid (char *where, char *what)
67133965Sjdp{
67233965Sjdp  char buf[5];
67333965Sjdp
67433965Sjdp  /* If we have found an input file whose format we do not recognize,
67533965Sjdp     and we are therefore treating it as a linker script, and we find
67633965Sjdp     an invalid character, then most likely this is a real object file
67733965Sjdp     of some different format.  Treat it as such.  */
67833965Sjdp  if (ldfile_assumed_script)
67933965Sjdp    {
68033965Sjdp      bfd_set_error (bfd_error_file_not_recognized);
68133965Sjdp      einfo ("%F%s: file not recognized: %E\n", ldfile_input_filename);
68233965Sjdp    }
68333965Sjdp
68489857Sobrien  if (! ISPRINT (*what))
68533965Sjdp    {
68633965Sjdp      sprintf (buf, "\\%03o", (unsigned int) *what);
68733965Sjdp      what = buf;
68833965Sjdp    }
68933965Sjdp
69033965Sjdp  einfo ("%P:%S: ignoring invalid character `%s'%s\n", what, where);
69133965Sjdp}
692