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