%{
-/* Copyright (C) 1991 Free Software Foundation, Inc.
+
+/* Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/*
- * $Id$
- *
- * $Log$
- * Revision 1.1 1991/03/21 21:28:50 gumby
- * Initial revision
- *
- * Revision 1.3 1991/03/16 22:27:24 rich
- * fish
- *
- * Revision 1.2 1991/03/15 18:45:55 rich
- * foo
- *
- * Revision 1.1 1991/03/13 00:48:27 chrisb
- * Initial revision
- *
- * Revision 1.6 1991/03/10 09:31:32 rich
- * Modified Files:
- * Makefile config.h ld-emul.c ld-emul.h ld-gld.c ld-gld960.c
- * ld-lnk960.c ld.h lddigest.c ldexp.c ldexp.h ldfile.c ldfile.h
- * ldgram.y ldinfo.h ldlang.c ldlang.h ldlex.h ldlex.l ldmain.c
- * ldmain.h ldmisc.c ldmisc.h ldsym.c ldsym.h ldversion.c
- * ldversion.h ldwarn.h ldwrite.c ldwrite.h y.tab.h
- *
- * As of this round of changes, ld now builds on all hosts of (Intel960)
- * interest and copy passes my copy test on big endian hosts again.
- *
- * Revision 1.5 1991/03/09 03:25:49 sac
- * Can now parse the -Ur flag
- *
- * Revision 1.4 1991/03/06 02:26:04 sac
- * Added support for constructor sections.
- * Remove parsing ambiguity.
- * Lint
- *
- * Revision 1.3 1991/02/22 17:15:14 sac
- * Added RCS keywords and copyrights
- *
+This was written by steve chamberlain
+ sac@cygnus.com
*/
-
-/*SUPPRESS 529*/
-/*SUPPRESS 26*/
-/*SUPPRESS 29*/
-#define LEXDEBUG
-#include "sysdep.h"
-#include "bfd.h"
-
+#include <ansidecl.h>
+#include <stdio.h>
#include <ctype.h>
-#include "ldlex.h"
+#ifdef MPW
+/* Prevent enum redefinition problems. */
+#define TRUE_FALSE_ALREADY_DEFINED
+#endif /* MPW */
+
+#include "bfd.h"
+#include "sysdep.h"
#include "ld.h"
-#include "ldexp.h"
-#include "ldgram.tab.h"
+#include "ldgram.h"
#include "ldmisc.h"
+#include "ldexp.h"
+#include "ldlang.h"
+#include "ldfile.h"
+#include "ldlex.h"
+#include "ldmain.h"
-#undef input
-#undef unput
-#define input lex_input
-#define unput lex_unput
-int debug;
-extern boolean ldgram_want_filename;
-extern boolean ldgram_mustbe_filename;
-extern boolean ldgram_mustbe_symbolname;
-static char *command_line;
-
-extern int fgetc();
-extern int yyparse();
-
-typedef struct {
- char *name;
-int value;
-} keyword_type;
-#define RTOKEN(x) { yylval.token = x; return x; }
-keyword_type keywords[] =
-{
-"MEMORY",MEMORY,
-"ORIGIN",ORIGIN,
-"BLOCK",BLOCK,
-"LENGTH",LENGTH,
-"ALIGN",ALIGN_K,
-"SUBSECTION_ALIGN",SUBSECTION_ALIGN,
-"ADDR",ADDR,
-"ENTRY",ENTRY,
-"NEXT",NEXT,
-"MAP",MAP,
-"SIZEOF",SIZEOF,
-"TARGET",TARGET_K,
-"SEARCH_DIR",SEARCH_DIR,
-"OUTPUT",OUTPUT,
-"INPUT",INPUT,
-"DEFINED",DEFINED,
-"CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
-"SECTIONS",SECTIONS,
-"FILL",FILL,
-"STARTUP",STARTUP,
-"HLL",HLL,
-"SYSLIB",SYSLIB,
-"FLOAT",FLOAT,
-"LONG", LONG,
-"SHORT", SHORT,
-"BYTE", BYTE,
-"NOFLOAT",NOFLOAT,
-"o",ORIGIN,
-"org",ORIGIN,
-"l", LENGTH,
-"len", LENGTH,
-0,0};
-unsigned int lineno;
-extern boolean hex_mode;
-FILE *ldlex_input_stack;
-static unsigned int have_pushback;
-#define NPUSHBACK 10
-int pushback[NPUSHBACK];
-int thischar;
-extern char *ldfile_input_filename;
-
-int
-lex_input()
-{
- /*
- When we know that the next token must be a filename we force the
- input routine to return a '#' character, which will cause the special
- filname regexp to match the following chars even if they don't look
- much like a filename to any sane person.
- */
- if (ldgram_mustbe_filename) {
- ldgram_mustbe_filename = false;
- return '#';
- }
+/* The type of top-level parser input.
+ yylex and yyparse (indirectly) both check this. */
+input_type parser_input;
- if (have_pushback > 0)
- {
- have_pushback --;
- return thischar = pushback[have_pushback];
- }
- if (ldlex_input_stack) {
- thischar = fgetc(ldlex_input_stack);
+/* Radix to use for bfd_scan_vma -- 0 (default to base 10) or 16. */
+int hex_mode;
- if (thischar == EOF) {
- fclose(ldlex_input_stack);
- ldlex_input_stack = (FILE *)NULL;
- ldfile_input_filename = (char *)NULL;
- thischar = lex_input();
+/* Line number in the current input file.
+ (FIXME Actually, it doesn't appear to get reset for each file?) */
+unsigned int lineno = 1;
- }
- }
- else if (command_line && *command_line) {
- thischar = *(command_line++);
- }
- else thischar = 0;
- if(thischar == '\t') thischar = ' ';
- return thischar ;
-}
+/* The string we are currently lexing, or NULL if we are reading a
+ file. */
+const char *lex_string = NULL;
-void
-lex_unput(c)
-int c;
-{
- if (have_pushback > NPUSHBACK) {
- info("%F%P Too many pushbacks\n");
- }
+/* Support for flex reading from more than one input file (stream).
+ `include_stack' is flex's input state for each open file;
+ `file_name_stack' is the file names. `lineno_stack' is the current
+ line numbers.
- pushback[have_pushback] = c;
- have_pushback ++;
-}
+ If `include_stack_ptr' is 0, we haven't started reading anything yet.
+ Otherwise, stack elements 0 through `include_stack_ptr - 1' are valid. */
+#undef YY_INPUT
+#define YY_INPUT(buf,result,max_size) yy_input(buf, &result, max_size)
- int
-yywrap()
- { return 1; }
-/*VARARGS*/
+#define MAX_INCLUDE_DEPTH 10
+static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
+static const char *file_name_stack[MAX_INCLUDE_DEPTH];
+static unsigned int lineno_stack[MAX_INCLUDE_DEPTH];
+static unsigned int include_stack_ptr = 0;
-void
-allprint(x)
-int x;
-{
-fprintf(yyout,"%d",x);
-}
+static YY_BUFFER_STATE yy_create_string_buffer PARAMS ((const char *string,
+ size_t size));
+static void yy_input PARAMS ((char *, int *result, int max_size));
-void
-sprint(x)
-char *x;
-{
-fprintf(yyout,"%s",x);
-}
+static void comment PARAMS ((void));
+static void lex_warn_invalid PARAMS ((char *where, char *what));
-int thischar;
+/* STATES
+ EXPRESSION definitely in an expression
+ SCRIPT definitely in a script
+ BOTH either EXPRESSION or SCRIPT
+ DEFSYMEXP in an argument to -defsym
+ MRI in an MRI script
+*/
+#define RTOKEN(x) { yylval.token = x; return x; }
-void parse_line(arg)
-char *arg;
-{
- command_line = arg;
- have_pushback = 0;
- yyparse();
-}
+/* Some versions of flex want this. */
+#ifndef yywrap
+int yywrap () { return 1; }
+#endif
+%}
+%a 4000
+%o 5000
+CMDFILENAMECHAR [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\-\~]
+CMDFILENAMECHAR1 [_a-zA-Z0-9\/\.\\_\+\$\:\[\]\\\,\=\&\!\<\>\~]
+FILENAMECHAR1 [_a-zA-Z\/\.\\\$\_\~]
+SYMBOLCHARN [_a-zA-Z\/\.\\0-9]
+FILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~]
+WILDCHAR [_a-zA-Z0-9\/\.\-\_\+\=\$\:\[\]\\\,\~\?\*]
+WHITE [ \t\n\r]+
-void
-parse_args(ac, av)
-int ac;
-char **av;
-{
- char *p;
- int i;
- size_t size = 0;
- char *dst;
- debug = 1;
- for (i= 1; i < ac; i++) {
- size += strlen(av[i]) + 2;
- }
- dst = p = (char *)ldmalloc(size + 2);
-/* Put a space arount each option */
+NOCFILENAMECHAR [_a-zA-Z0-9\/\.\-\_\+\$\:\[\]\\\~]
- for (i =1; i < ac; i++) {
+%s SCRIPT
+%s EXPRESSION
+%s BOTH
+%s DEFSYMEXP
+%s MRI
+%%
- unsigned int s = strlen(av[i]);
- *dst++ = ' ';
- memcpy(dst, av[i], s);
- dst[s] = ' ';
- dst += s + 1;
- }
- *dst = 0;
- parse_line(p);
+ if (parser_input != input_selected)
+ {
+ /* The first token of the input determines the initial parser state. */
+ input_type t = parser_input;
+ parser_input = input_selected;
+ switch (t)
+ {
+ case input_script: return INPUT_SCRIPT; break;
+ case input_mri_script: return INPUT_MRI_SCRIPT; break;
+ case input_defsym: return INPUT_DEFSYM; break;
+ default: abort ();
+ }
+ }
- free(p);
+<BOTH,SCRIPT,EXPRESSION>"/*" { comment(); }
+
+
+<DEFSYMEXP>"-" { RTOKEN('-');}
+<DEFSYMEXP>"+" { RTOKEN('+');}
+<DEFSYMEXP>{FILENAMECHAR1}{SYMBOLCHARN}* { yylval.name = buystring(yytext); return NAME; }
+<DEFSYMEXP>"=" { RTOKEN('='); }
+
+<MRI,EXPRESSION>"$"([0-9A-Fa-f])+ {
+ yylval.integer = bfd_scan_vma (yytext+1, 0,16);
+ return INT;
+ }
+
+<MRI,EXPRESSION>([0-9A-Fa-f])+(H|h|X|x|B|b|O|o|D|d) {
+ int ibase ;
+ switch (yytext[yyleng-1]) {
+ case 'X':
+ case 'x':
+ case 'H':
+ case 'h':
+ ibase = 16;
+ break;
+ case 'O':
+ case 'o':
+ ibase = 8;
+ break;
+ case 'B':
+ case 'b':
+ ibase = 2;
+ break;
+ default:
+ ibase = 10;
+ }
+ yylval.integer = bfd_scan_vma (yytext, 0,
+ ibase);
+ return INT;
+ }
+<SCRIPT,DEFSYMEXP,MRI,BOTH,EXPRESSION>"$"?"0x"?([0-9A-Fa-f])+(M|K|m|k)? {
+ yylval.integer = bfd_scan_vma (yytext, 0,
+ hex_mode);
+ if (yytext[yyleng-1]=='M'
+ || yytext[yyleng-1] == 'm') {
+ yylval.integer *= 1024*1024;
+ }
+ if (yytext[yyleng-1]=='K'
+ || yytext[yyleng-1]=='k') {
+ yylval.integer *= 1024;
+ }
+ return INT;
+ }
+<BOTH,SCRIPT,EXPRESSION,MRI>"]" { RTOKEN(']');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"[" { RTOKEN('[');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"<<=" { RTOKEN(LSHIFTEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>">>=" { RTOKEN(RSHIFTEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"||" { RTOKEN(OROR);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"==" { RTOKEN(EQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"!=" { RTOKEN(NE);}
+<BOTH,SCRIPT,EXPRESSION,MRI>">=" { RTOKEN(GE);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"<=" { RTOKEN(LE);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"<<" { RTOKEN(LSHIFT);}
+<BOTH,SCRIPT,EXPRESSION,MRI>">>" { RTOKEN(RSHIFT);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"+=" { RTOKEN(PLUSEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"-=" { RTOKEN(MINUSEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"*=" { RTOKEN(MULTEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"/=" { RTOKEN(DIVEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"&=" { RTOKEN(ANDEQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"|=" { RTOKEN(OREQ);}
+<BOTH,SCRIPT,EXPRESSION,MRI>"&&" { RTOKEN(ANDAND);}
+<BOTH,SCRIPT,EXPRESSION,MRI>">" { RTOKEN('>');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"," { RTOKEN(',');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"&" { RTOKEN('&');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"|" { RTOKEN('|');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"~" { RTOKEN('~');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"!" { RTOKEN('!');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"?" { RTOKEN('?');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"*" { RTOKEN('*');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"+" { RTOKEN('+');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"-" { RTOKEN('-');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"/" { RTOKEN('/');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"%" { RTOKEN('%');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"<" { RTOKEN('<');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"=" { RTOKEN('=');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"}" { RTOKEN('}') ; }
+<BOTH,SCRIPT,EXPRESSION,MRI>"{" { RTOKEN('{'); }
+<BOTH,SCRIPT,EXPRESSION,MRI>")" { RTOKEN(')');}
+<BOTH,SCRIPT,EXPRESSION,MRI>"(" { RTOKEN('(');}
+<BOTH,SCRIPT,EXPRESSION,MRI>":" { RTOKEN(':'); }
+<BOTH,SCRIPT,EXPRESSION,MRI>";" { RTOKEN(';');}
+<BOTH,SCRIPT>"MEMORY" { RTOKEN(MEMORY);}
+<BOTH,SCRIPT>"ORIGIN" { RTOKEN(ORIGIN);}
+<EXPRESSION,BOTH,SCRIPT>"BLOCK" { RTOKEN(BLOCK);}
+<EXPRESSION,BOTH,SCRIPT>"BIND" { RTOKEN(BIND);}
+<BOTH,SCRIPT>"LENGTH" { RTOKEN(LENGTH);}
+<EXPRESSION,BOTH,SCRIPT>"ALIGN" { RTOKEN(ALIGN_K);}
+<EXPRESSION,BOTH,SCRIPT>"ADDR" { RTOKEN(ADDR);}
+<EXPRESSION,BOTH,SCRIPT>"LOADADDR" { RTOKEN(LOADADDR);}
+<BOTH,SCRIPT>"ENTRY" { RTOKEN(ENTRY);}
+<EXPRESSION,BOTH,SCRIPT>"NEXT" { RTOKEN(NEXT);}
+<EXPRESSION,BOTH,SCRIPT>"sizeof_headers" { RTOKEN(SIZEOF_HEADERS);}
+<EXPRESSION,BOTH,SCRIPT>"SIZEOF_HEADERS" { RTOKEN(SIZEOF_HEADERS);}
+<BOTH,SCRIPT>"MAP" { RTOKEN(MAP);}
+<EXPRESSION,BOTH,SCRIPT>"SIZEOF" { RTOKEN(SIZEOF);}
+<BOTH,SCRIPT>"TARGET" { RTOKEN(TARGET_K);}
+<BOTH,SCRIPT>"SEARCH_DIR" { RTOKEN(SEARCH_DIR);}
+<BOTH,SCRIPT>"OUTPUT" { RTOKEN(OUTPUT);}
+<BOTH,SCRIPT>"INPUT" { RTOKEN(INPUT);}
+<EXPRESSION,BOTH,SCRIPT>"GROUP" { RTOKEN(GROUP);}
+<EXPRESSION,BOTH,SCRIPT>"DEFINED" { RTOKEN(DEFINED);}
+<BOTH,SCRIPT>"CREATE_OBJECT_SYMBOLS" { RTOKEN(CREATE_OBJECT_SYMBOLS);}
+<BOTH,SCRIPT>"CONSTRUCTORS" { RTOKEN( CONSTRUCTORS);}
+<BOTH,SCRIPT>"FORCE_COMMON_ALLOCATION" { RTOKEN(FORCE_COMMON_ALLOCATION);}
+<BOTH,SCRIPT>"SECTIONS" { RTOKEN(SECTIONS);}
+<BOTH,SCRIPT>"FILL" { RTOKEN(FILL);}
+<BOTH,SCRIPT>"STARTUP" { RTOKEN(STARTUP);}
+<BOTH,SCRIPT>"OUTPUT_FORMAT" { RTOKEN(OUTPUT_FORMAT);}
+<BOTH,SCRIPT>"OUTPUT_ARCH" { RTOKEN( OUTPUT_ARCH);}
+<BOTH,SCRIPT>"HLL" { RTOKEN(HLL);}
+<BOTH,SCRIPT>"SYSLIB" { RTOKEN(SYSLIB);}
+<BOTH,SCRIPT>"FLOAT" { RTOKEN(FLOAT);}
+<BOTH,SCRIPT>"QUAD" { RTOKEN( QUAD);}
+<BOTH,SCRIPT>"LONG" { RTOKEN( LONG);}
+<BOTH,SCRIPT>"SHORT" { RTOKEN( SHORT);}
+<BOTH,SCRIPT>"BYTE" { RTOKEN( BYTE);}
+<BOTH,SCRIPT>"NOFLOAT" { RTOKEN(NOFLOAT);}
+<BOTH,SCRIPT>"NOCROSSREFS" { RTOKEN(NOCROSSREFS);}
+<EXPRESSION,BOTH,SCRIPT>"NOLOAD" { RTOKEN(NOLOAD);}
+<EXPRESSION,BOTH,SCRIPT>"DSECT" { RTOKEN(DSECT);}
+<EXPRESSION,BOTH,SCRIPT>"COPY" { RTOKEN(COPY);}
+<EXPRESSION,BOTH,SCRIPT>"INFO" { RTOKEN(INFO);}
+<EXPRESSION,BOTH,SCRIPT>"OVERLAY" { RTOKEN(OVERLAY);}
+<BOTH,SCRIPT>"o" { RTOKEN(ORIGIN);}
+<BOTH,SCRIPT>"org" { RTOKEN(ORIGIN);}
+<BOTH,SCRIPT>"l" { RTOKEN( LENGTH);}
+<BOTH,SCRIPT>"len" { RTOKEN( LENGTH);}
+<BOTH,SCRIPT>"INCLUDE" { RTOKEN(INCLUDE);}
+<BOTH,SCRIPT>"PHDRS" { RTOKEN (PHDRS); }
+<EXPRESSION,BOTH,SCRIPT>"AT" { RTOKEN(AT);}
+<EXPRESSION,BOTH,SCRIPT>"PROVIDE" { RTOKEN(PROVIDE); }
+<MRI>"#".*\n?\r? { ++ lineno; }
+<MRI>"\n" { ++ lineno; RTOKEN(NEWLINE); }
+<MRI>"\r" { ++ lineno; RTOKEN(NEWLINE); }
+<MRI>"*".* { /* Mri comment line */ }
+<MRI>";".* { /* Mri comment line */ }
+<MRI>"END" { RTOKEN(ENDWORD); }
+<MRI>"ALIGNMOD" { RTOKEN(ALIGNMOD);}
+<MRI>"ALIGN" { RTOKEN(ALIGN_K);}
+<MRI>"CHIP" { RTOKEN(CHIP); }
+<MRI>"BASE" { RTOKEN(BASE); }
+<MRI>"ALIAS" { RTOKEN(ALIAS); }
+<MRI>"TRUNCATE" { RTOKEN(TRUNCATE); }
+<MRI>"LOAD" { RTOKEN(LOAD); }
+<MRI>"PUBLIC" { RTOKEN(PUBLIC); }
+<MRI>"ORDER" { RTOKEN(ORDER); }
+<MRI>"NAME" { RTOKEN(NAMEWORD); }
+<MRI>"FORMAT" { RTOKEN(FORMAT); }
+<MRI>"CASE" { RTOKEN(CASE); }
+<MRI>"EXTERN" { RTOKEN(EXTERN); }
+<MRI>"START" { RTOKEN(START); }
+<MRI>"LIST".* { RTOKEN(LIST); /* LIST and ignore to end of line */ }
+<MRI>"SECT" { RTOKEN(SECT); }
+<EXPRESSION,BOTH,SCRIPT,MRI>"ABSOLUTE" { RTOKEN(ABSOLUTE); }
+<MRI>"end" { RTOKEN(ENDWORD); }
+<MRI>"alignmod" { RTOKEN(ALIGNMOD);}
+<MRI>"align" { RTOKEN(ALIGN_K);}
+<MRI>"chip" { RTOKEN(CHIP); }
+<MRI>"base" { RTOKEN(BASE); }
+<MRI>"alias" { RTOKEN(ALIAS); }
+<MRI>"truncate" { RTOKEN(TRUNCATE); }
+<MRI>"load" { RTOKEN(LOAD); }
+<MRI>"public" { RTOKEN(PUBLIC); }
+<MRI>"order" { RTOKEN(ORDER); }
+<MRI>"name" { RTOKEN(NAMEWORD); }
+<MRI>"format" { RTOKEN(FORMAT); }
+<MRI>"case" { RTOKEN(CASE); }
+<MRI>"extern" { RTOKEN(EXTERN); }
+<MRI>"start" { RTOKEN(START); }
+<MRI>"list".* { RTOKEN(LIST); /* LIST and ignore to end of line */ }
+<MRI>"sect" { RTOKEN(SECT); }
+<EXPRESSION,BOTH,SCRIPT,MRI>"absolute" { RTOKEN(ABSOLUTE); }
+
+<MRI>{FILENAMECHAR1}{NOCFILENAMECHAR}* {
+/* Filename without commas, needed to parse mri stuff */
+ yylval.name = buystring(yytext);
+ return NAME;
+ }
+
+
+<BOTH,EXPRESSION>{FILENAMECHAR1}{FILENAMECHAR}* {
+ yylval.name = buystring(yytext);
+ return NAME;
+ }
+<BOTH,EXPRESSION>"-l"{FILENAMECHAR}+ {
+ yylval.name = buystring (yytext + 2);
+ return LNAME;
+ }
+<SCRIPT>{WILDCHAR}* { yylval.name = buystring(yytext); return NAME; }
+
+<EXPRESSION,BOTH,SCRIPT>"\""[^\"]*"\"" {
+ /* No matter the state, quotes
+ give what's inside */
+ yylval.name = buystring(yytext+1);
+ yylval.name[yyleng-2] = 0;
+ return NAME;
+ }
+<BOTH,SCRIPT,EXPRESSION>"\n" { lineno++;}
+<BOTH,SCRIPT,EXPRESSION>"\r" { lineno++;}
+<MRI,BOTH,SCRIPT,EXPRESSION>[ \t]
+
+<<EOF>> {
+ include_stack_ptr--;
+
+ if (include_stack_ptr == 0)
+ {
+ yyterminate();
+ }
+ else
+ {
+ yy_switch_to_buffer(include_stack[include_stack_ptr]);
+ }
+ BEGIN(SCRIPT);
+ ldfile_input_filename = file_name_stack[include_stack_ptr - 1];
+ lineno = lineno_stack[include_stack_ptr - 1];
+ return END;
}
-long number(text, base)
-char *text;
-int base;
+<SCRIPT,MRI>. lex_warn_invalid(" in script", yytext);
+<EXPRESSION,DEFSYMEXP,BOTH>. lex_warn_invalid(" in expression", yytext);
+
+%%
+\f
+
+/* Switch flex to reading script file NAME, open on FILE,
+ saving the current input info on the include stack. */
+
+void
+lex_push_file (file, name)
+ FILE *file;
+ const char *name;
{
-unsigned long l = 0;
- char *p;
- for (p = text; *p != 0; p++) {
- if (*p == 'K') {
- l =l * 1024;
- }
- else if(*p== 'M') {
- l =l * 1024 * 1024;
- }
- else {
- l =l * base;
- if (isdigit(*p)) {
- l += *p - '0';
- }
- else if (islower(*p)) {
- l += *p - 'a' + 10;
- }
- else {
- l += *p - 'A' + 10;
- }
+ if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
+ {
+ einfo("%F:includes nested too deeply\n");
}
- }
- return l;
+ file_name_stack[include_stack_ptr] = name;
+ lineno_stack[include_stack_ptr] = 1;
+ include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
+
+ include_stack_ptr++;
+ yyin = file;
+ yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
+ BEGIN (SCRIPT);
}
-%}
-%a 4000
-%o 5000
-FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+]
-FILENAME {FILENAMECHAR}+
+/* Return a newly created flex input buffer containing STRING,
+ which is SIZE bytes long. */
+static YY_BUFFER_STATE
+yy_create_string_buffer (string, size)
+ CONST char *string;
+ size_t size;
+{
+ YY_BUFFER_STATE b;
+
+ /* Calls to m-alloc get turned by sed into xm-alloc. */
+ b = (YY_BUFFER_STATE) malloc (sizeof (struct yy_buffer_state));
+ b->yy_input_file = 0;
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ we need to put in 2 end-of-buffer characters. */
+ b->yy_ch_buf = (char *) malloc ((unsigned) (b->yy_buf_size + 3));
+
+ b->yy_ch_buf[0] = '\n';
+ strcpy (b->yy_ch_buf+1, string);
+ b->yy_ch_buf[size+1] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[size+2] = YY_END_OF_BUFFER_CHAR;
+ b->yy_n_chars = size+1;
+ b->yy_buf_pos = &b->yy_ch_buf[1];
+
+ /* flex 2.4.7 changed the interface. FIXME: We should not be using
+ a flex internal interface in the first place! */
+#ifdef YY_BUFFER_NEW
+ b->yy_buffer_status = YY_BUFFER_NEW;
+#else
+ b->yy_eof_status = EOF_NOT_SEEN;
+#endif
+
+ return b;
+}
-WHITE [ \t]+
+/* Switch flex to reading from STRING, saving the current input info
+ on the include stack. */
-%%
-"\n" { lineno++; }
-
-
-"\ -defsym" { return OPTION_defsym; }
-"\ -noinhibit_exec" { return OPTION_noinhibit_exec; }
-"\ -format" { return OPTION_format; }
-"\ -n" { return OPTION_n; }
-"\ -r" { return OPTION_r; }
-"\ -Ur" { return OPTION_Ur; }
-"\ -o" { return OPTION_o; }
-"\ -g" { return OPTION_g; }
-"\ -e" { return OPTION_e; }
-"\ -b" { return OPTION_b; }
-"\ -dc" { return OPTION_dc; }
-"\ -dp" { return OPTION_dp; }
-"\ -d" { return OPTION_d; }
-"\ -v" { return OPTION_v; }
-"\ -M" { return OPTION_M; }
-"\ -t" { return OPTION_t; }
-"\ -X" { return OPTION_X; }
-"\ -x" { return OPTION_x; }
-"\ -c" { return OPTION_c; }
-"\ -s" { return OPTION_s; }
-"\ -S" { return OPTION_S; }
-"\ -l"{FILENAME} {
- yylval.name = buystring(yytext+3);
- return OPTION_l;
- }
+void
+lex_redirect (string)
+ CONST char *string;
+{
+ YY_BUFFER_STATE tmp;
-"\ -L"{FILENAME} {
- yylval.name = buystring(yytext+3);
- return OPTION_L;
- }
-"\ -Ttext" {
- yylval.name = ".text";
- return OPTION_Texp;
- }
-"\ -Tdata" {
- yylval.name = ".data";
- return OPTION_Texp;
- }
-"\ -Tbss" {
- yylval.name = ".bss";
- return OPTION_Texp;
- }
-
-"\ -T"{FILENAME} {
- yylval.name = buystring(yytext+3);
- return OPTION_Tfile;
- }
-"\ -T" {
- return OPTION_T;
- }
-
-"\ -A"{FILENAME} {
- yylval.name = buystring(yytext+3);
- return OPTION_Aarch;
- }
-" " { }
-"<<=" { RTOKEN(LSHIFTEQ);}
-">>=" { RTOKEN(RSHIFTEQ);}
-"||" { RTOKEN(OROR);}
-"==" { RTOKEN(EQ);}
-"!=" { RTOKEN(NE);}
-">=" { RTOKEN(GE);}
-"<=" { RTOKEN(LE);}
-"<<" { RTOKEN(LSHIFT);}
-">>" { RTOKEN(RSHIFT);}
-"+=" { RTOKEN(PLUSEQ);}
-"-=" { RTOKEN(MINUSEQ);}
-"*=" { RTOKEN(MULTEQ);}
-"/=" { RTOKEN(DIVEQ);}
-"&=" { RTOKEN(ANDEQ);}
-"|=" { RTOKEN(OREQ);}
-
-"&&" { RTOKEN(ANDAND);}
-">" { RTOKEN('>');}
-"," { RTOKEN(',');}
-"&" { RTOKEN('&');}
-"|" { RTOKEN('|');}
-"~" { RTOKEN('~');}
-"!" { RTOKEN('!');}
-"?" { RTOKEN('?');}
-"*" { RTOKEN('*');}
-"%" { RTOKEN('%');}
-"<" { RTOKEN('<');}
-"+" { RTOKEN('+');}
-">" { RTOKEN('>');}
-"}" { RTOKEN('}') ; }
-"{" { RTOKEN('{'); }
-")" { RTOKEN(')');}
-"(" { RTOKEN('(');}
-"]" { RTOKEN(']');}
-"[" { RTOKEN('[');}
-":" { RTOKEN(':'); }
-";" { RTOKEN(';');}
-"-" { RTOKEN('-');}
-"=" { RTOKEN('=');}
-
-
-"/*" {
- while (1) {
- int ch;
- ch = input();
- while (ch != '*') {
- if (ch == '\n') {lineno++; }
- ch = input();
+ yy_init = 0;
+ if (include_stack_ptr >= MAX_INCLUDE_DEPTH)
+ {
+ einfo("%F: macros nested too deeply\n");
}
+ file_name_stack[include_stack_ptr] = "redirect";
+ lineno_stack[include_stack_ptr] = 0;
+ include_stack[include_stack_ptr] = YY_CURRENT_BUFFER;
+ include_stack_ptr++;
+ tmp = yy_create_string_buffer (string, strlen (string));
+ yy_switch_to_buffer (tmp);
+ BEGIN (SCRIPT);
+}
+\f
+/* Functions to switch to a different flex start condition,
+ saving the current start condition on `state_stack'. */
+static int state_stack[MAX_INCLUDE_DEPTH * 2];
+static int *state_stack_p = state_stack;
-
- if (input() == '/') {
- break;
- }
- unput(yytext[yyleng-1]);
- }
+void
+ldlex_script ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (SCRIPT);
}
-"\""[^\"]*"\"" {
-
- yylval.name = buystring(yytext+1);
- yylval.name[yyleng-2] = 0; /* Fry final quote */
- return NAME;
+void
+ldlex_mri_script ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (MRI);
}
-[0][0-7KM]* {
- yylval.integer = number(yytext+1, 8);
- return INT;
+void
+ldlex_defsym ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (DEFSYMEXP);
+}
+
+void
+ldlex_expression ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (EXPRESSION);
}
-[0-9]+[KM]? {
- if (hex_mode == true) {
- yylval.integer = number(yytext, 16);
- }
- else {
- yylval.integer = number(yytext, 10);
- }
- return INT;
+void
+ldlex_both ()
+{
+ *(state_stack_p)++ = yy_start;
+ BEGIN (BOTH);
}
-0[Xx][0-9a-fA-FKM]+ {
-
- yylval.integer = number(yytext+2,16);
- return INT;
+void
+ldlex_popstate ()
+{
+ yy_start = *(--state_stack_p);
}
+\f
+
+/* Place up to MAX_SIZE characters in BUF and return in *RESULT
+ either the number of characters read, or 0 to indicate EOF. */
-"\#"{WHITE}*{FILENAMECHAR}+ {
- char *p = yytext+1;
- while(*p ==' ' || *p == '\t') p++;
- yylval.name = buystring(p);
- return NAME;
+static void
+yy_input (buf, result, max_size)
+ char *buf;
+ int *result;
+ int max_size;
+{
+ *result = 0;
+ if (yy_current_buffer->yy_input_file)
+ {
+ if (yyin)
+ {
+ *result = read (fileno (yyin), (char *) buf, max_size);
+ if (*result < 0)
+ einfo ("%F%P: read in flex scanner failed");
+ }
+ }
}
+/* Eat the rest of a C-style comment. */
-{FILENAMECHAR} {
+static void
+comment ()
+{
+ int c;
-int ch;
- keyword_type *k;
- if (yytext[0] == '/' && ldgram_mustbe_symbolname)
- { RTOKEN('/');}
- ch = input();
- while (true) {
- if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_') {
- yytext[yyleng++] = ch;
- }
- else if (ch == '-' && ldgram_want_filename == true) {
- yytext[yyleng++] = ch;
- }
- else if (ch == '+' && ldgram_want_filename == true) {
- yytext[yyleng++] = ch;
+ while (1)
+ {
+ c = input();
+ while (c != '*' && c != EOF)
+ {
+ if (c == '\n' || c == '\r')
+ lineno++;
+ c = input();
}
- else if (ch == '/' && ldgram_want_filename == true) {
- yytext[yyleng++] = ch;
+ if (c == '*')
+ {
+ c = input();
+ while (c == '*')
+ c = input();
+ if (c == '/')
+ break; /* found the end */
}
- else break;
- ch = input();
- }
-
- yytext[yyleng] = 0;
- unput(ch);
-
- for(k = keywords; k ->name != (char *)NULL; k++) {
+ if (c == '\n' || c == '\r')
+ lineno++;
- if (strcmp(k->name, yytext)==0) {
- yylval.token = k->value;
- return k->value;
+ if (c == EOF)
+ {
+ einfo( "%F%P: EOF in comment\n");
+ break;
}
}
- yylval.name = buystring(yytext);
- return NAME;
}
+/* Warn the user about a garbage character WHAT in the input
+ in context WHERE. */
+static void
+lex_warn_invalid (where, what)
+ char *where, *what;
+{
+ char buf[5];
+ /* If we have found an input file whose format we do not recognize,
+ and we are therefore treating it as a linker script, and we find
+ an invalid character, then most likely this is a real object file
+ of some different format. Treat it as such. */
+ if (ldfile_assumed_script)
+ {
+ bfd_set_error (bfd_error_file_not_recognized);
+ einfo ("%F%s: file not recognized: %E\n", ldfile_input_filename);
+ }
+ if (! isprint ((unsigned char) *what))
+ {
+ sprintf (buf, "\\%03o", (unsigned int) *what);
+ what = buf;
+ }
-%%
+ einfo ("%P:%S: ignoring invalid character `%s'%s\n", what, where);
+}