]> Git Repo - binutils.git/blame - ld/ldlex.l
Added the sizeof_headers keyword.
[binutils.git] / ld / ldlex.l
CommitLineData
2fa0b342
DHW
1%{
2/* Copyright (C) 1991 Free Software Foundation, Inc.
3
4This file is part of GLD, the Gnu Linker.
5
6GLD is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GLD is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GLD; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/*
21 * $Id$
7ca04d28 22
2fa0b342
DHW
23 *
24*/
25
26
27
28/*SUPPRESS 529*/
29/*SUPPRESS 26*/
30/*SUPPRESS 29*/
1418c83b 31#define LEXDEBUG 0
2fa0b342
DHW
32#include "sysdep.h"
33#include "bfd.h"
34
35#include <ctype.h>
36#include "ldlex.h"
37
38#include "ld.h"
39#include "ldexp.h"
40#include "ldgram.tab.h"
41#include "ldmisc.h"
42
43#undef input
44#undef unput
45#define input lex_input
46#define unput lex_unput
47int debug;
7ca04d28 48
1d45ccb3 49
a37cc0c0 50static boolean ldgram_in_defsym;
1d45ccb3 51static boolean ldgram_had_equals;
1418c83b 52extern boolean ldgram_in_script;
2fa0b342
DHW
53static char *command_line;
54
55extern int fgetc();
56extern int yyparse();
57
58typedef struct {
59 char *name;
60int value;
61} keyword_type;
62#define RTOKEN(x) { yylval.token = x; return x; }
63keyword_type keywords[] =
64{
1d45ccb3 65"/", '/',
2fa0b342
DHW
66"MEMORY",MEMORY,
67"ORIGIN",ORIGIN,
68"BLOCK",BLOCK,
69"LENGTH",LENGTH,
70"ALIGN",ALIGN_K,
71"SUBSECTION_ALIGN",SUBSECTION_ALIGN,
72"ADDR",ADDR,
73"ENTRY",ENTRY,
1418c83b
SC
74"SCRIPT", SCRIPT,
75"ENDSCRIPT", ENDSCRIPT,
2fa0b342 76"NEXT",NEXT,
65c552e3
SC
77"sizeof_headers",SIZEOF_HEADERS,
78"SIZEOF_HEADERS",SIZEOF_HEADERS,
2fa0b342
DHW
79"MAP",MAP,
80"SIZEOF",SIZEOF,
81"TARGET",TARGET_K,
82"SEARCH_DIR",SEARCH_DIR,
83"OUTPUT",OUTPUT,
84"INPUT",INPUT,
85"DEFINED",DEFINED,
86"CREATE_OBJECT_SYMBOLS",CREATE_OBJECT_SYMBOLS,
fd846434 87"FORCE_COMMON_ALLOCATION",FORCE_COMMON_ALLOCATION,
2fa0b342
DHW
88"SECTIONS",SECTIONS,
89"FILL",FILL,
90"STARTUP",STARTUP,
fd846434 91"OUTPUT_FORMAT",OUTPUT_FORMAT,
a37cc0c0 92"OUTPUT_ARCH", OUTPUT_ARCH,
2fa0b342
DHW
93"HLL",HLL,
94"SYSLIB",SYSLIB,
95"FLOAT",FLOAT,
96"LONG", LONG,
97"SHORT", SHORT,
98"BYTE", BYTE,
99"NOFLOAT",NOFLOAT,
100"o",ORIGIN,
101"org",ORIGIN,
102"l", LENGTH,
103"len", LENGTH,
1040,0};
105unsigned int lineno;
106extern boolean hex_mode;
107FILE *ldlex_input_stack;
108static unsigned int have_pushback;
1d45ccb3 109
2fa0b342
DHW
110#define NPUSHBACK 10
111int pushback[NPUSHBACK];
112int thischar;
113extern char *ldfile_input_filename;
1418c83b 114int donehash = 0;
2fa0b342
DHW
115int
116lex_input()
117{
2fa0b342 118 if (have_pushback > 0)
1418c83b
SC
119 {
120 have_pushback --;
121 return thischar = pushback[have_pushback];
122 }
2fa0b342
DHW
123 if (ldlex_input_stack) {
124 thischar = fgetc(ldlex_input_stack);
125
126 if (thischar == EOF) {
127 fclose(ldlex_input_stack);
128 ldlex_input_stack = (FILE *)NULL;
129 ldfile_input_filename = (char *)NULL;
1418c83b 130 /* First char after script eof is a @ so that we can tell the grammer
a37cc0c0 131 that we've left */
1418c83b 132 thischar = '@';
2fa0b342
DHW
133
134 }
135 }
136 else if (command_line && *command_line) {
137 thischar = *(command_line++);
138 }
1418c83b
SC
139 else {
140 thischar = 0;
141 }
2fa0b342 142 if(thischar == '\t') thischar = ' ';
7ca04d28 143 if (thischar == '\n') { thischar = ' '; lineno++; }
2fa0b342
DHW
144 return thischar ;
145}
146
147void
148lex_unput(c)
149int c;
150{
151 if (have_pushback > NPUSHBACK) {
152 info("%F%P Too many pushbacks\n");
153 }
154
155 pushback[have_pushback] = c;
156 have_pushback ++;
157}
158
159
160 int
161yywrap()
162 { return 1; }
163/*VARARGS*/
164
165void
166allprint(x)
167int x;
168{
169fprintf(yyout,"%d",x);
170}
171
172void
173sprint(x)
174char *x;
175{
176fprintf(yyout,"%s",x);
177}
178
179int thischar;
180
181void parse_line(arg)
182char *arg;
183{
184 command_line = arg;
185 have_pushback = 0;
186 yyparse();
187}
188
189
190
191void
192parse_args(ac, av)
193int ac;
194char **av;
195{
196 char *p;
197 int i;
198 size_t size = 0;
199 char *dst;
200 debug = 1;
201 for (i= 1; i < ac; i++) {
202 size += strlen(av[i]) + 2;
203 }
204 dst = p = (char *)ldmalloc(size + 2);
205/* Put a space arount each option */
206
207
208 for (i =1; i < ac; i++) {
209
210 unsigned int s = strlen(av[i]);
211 *dst++ = ' ';
212 memcpy(dst, av[i], s);
213 dst[s] = ' ';
214 dst += s + 1;
215 }
216 *dst = 0;
217 parse_line(p);
218
219 free(p);
220
221
222}
223
1d45ccb3
SC
224static long
225DEFUN(number,(default_if_zero,base),
226 int default_if_zero AND
227 int base)
2fa0b342 228{
1418c83b 229 unsigned long l = 0;
1d45ccb3
SC
230 int ch = yytext[0];
231 if (ch == 0) {
232 base = default_if_zero;
233 }
234 while (1) {
235 switch (ch) {
236 case 'x':
237 base = 16;
238 break;
239 case 'k':
240 case 'K':
2fa0b342 241 l =l * 1024;
1d45ccb3
SC
242 break;
243 case 'm':
244 case 'M':
2fa0b342 245 l =l * 1024 * 1024;
1d45ccb3
SC
246 break;
247 case '0': case '1': case '2': case '3': case '4':
248 case '5': case '6': case '7': case '8': case '9':
249 l = l * base + ch - '0';
250 break;
251 case 'a': case 'b': case 'c' : case 'd' : case 'e': case 'f':
252 l =l *base + ch - 'a' + 10;
253 break;
254 case 'A': case 'B': case 'C' : case 'D' : case 'E': case 'F':
255 l =l *base + ch - 'A' + 10;
256 break;
257 default:
258 unput(ch);
259 yylval.integer = l;
260 return INT;
2fa0b342 261 }
1d45ccb3 262ch = input();
2fa0b342 263 }
2fa0b342
DHW
264}
265%}
266
267%a 4000
268%o 5000
1418c83b 269FILENAMECHAR [a-zA-Z0-9\/\.\-\_\+\=]
2fa0b342 270FILENAME {FILENAMECHAR}+
1d45ccb3 271WHITE [ \t]+
2fa0b342
DHW
272
273%%
2fa0b342 274
a37cc0c0
SC
275"@" { return '}'; }
276"\ -defsym\ " { ldgram_in_defsym = true; return OPTION_defsym; }
1418c83b
SC
277"\ -noinhibit_exec\ " { return OPTION_noinhibit_exec; }
278"\ -format\ " { return OPTION_format; }
279"\ -n\ " { return OPTION_n; }
280"\ -r\ " { return OPTION_r; }
a37cc0c0 281"\ -i\ " { return OPTION_r; }
1418c83b
SC
282"\ -Ur\ " { return OPTION_Ur; }
283"\ -o\ " { return OPTION_o; }
284"\ -g\ " { return OPTION_g; }
285"\ -e\ " { return OPTION_e; }
286"\ -b\ " { return OPTION_b; }
287"\ -dc\ " { return OPTION_dc; }
288"\ -dp\ " { return OPTION_dp; }
289"\ -d\ " { return OPTION_d; }
290"\ -v\ " { return OPTION_v; }
291"\ -M\ " { return OPTION_M; }
292"\ -t\ " { return OPTION_t; }
293"\ -X\ " { return OPTION_X; }
294"\ -x\ " { return OPTION_x; }
295"\ -c\ " { return OPTION_c; }
296"\ -R\ " { return OPTION_R; }
297"\ -u\ " { return OPTION_u; }
298"\ -s\ " { return OPTION_s; }
299"\ -S\ " { return OPTION_S; }
a37cc0c0 300"\ -B{FILENAME}\ " { /* Ignored */ }
2fa0b342
DHW
301"\ -l"{FILENAME} {
302 yylval.name = buystring(yytext+3);
303 return OPTION_l;
304 }
305
306"\ -L"{FILENAME} {
307 yylval.name = buystring(yytext+3);
308 return OPTION_L;
309 }
1418c83b 310"\ -Ttext\ " {
2fa0b342
DHW
311 yylval.name = ".text";
312 return OPTION_Texp;
313 }
1418c83b 314"\ -Tdata\ " {
2fa0b342
DHW
315 yylval.name = ".data";
316 return OPTION_Texp;
317 }
1418c83b 318"\ -Tbss\ " {
2fa0b342
DHW
319 yylval.name = ".bss";
320 return OPTION_Texp;
321 }
322
323"\ -T"{FILENAME} {
324 yylval.name = buystring(yytext+3);
325 return OPTION_Tfile;
326 }
1418c83b 327"\ -T\ " {
2fa0b342
DHW
328 return OPTION_T;
329 }
330
7ca04d28
SC
331"\ -F"{FILENAME} {
332 return OPTION_F;
333 }
1418c83b 334"\ -F\ " {
7ca04d28
SC
335 return OPTION_F;
336 }
337
2fa0b342
DHW
338"\ -A"{FILENAME} {
339 yylval.name = buystring(yytext+3);
340 return OPTION_Aarch;
341 }
1d45ccb3 342
a37cc0c0
SC
343" " {
344 if (ldgram_had_equals == true) {
345 ldgram_in_defsym = false;
346 ldgram_had_equals = false;
347 }
348 }
2fa0b342
DHW
349"<<=" { RTOKEN(LSHIFTEQ);}
350">>=" { RTOKEN(RSHIFTEQ);}
351"||" { RTOKEN(OROR);}
352"==" { RTOKEN(EQ);}
353"!=" { RTOKEN(NE);}
354">=" { RTOKEN(GE);}
355"<=" { RTOKEN(LE);}
356"<<" { RTOKEN(LSHIFT);}
357">>" { RTOKEN(RSHIFT);}
358"+=" { RTOKEN(PLUSEQ);}
359"-=" { RTOKEN(MINUSEQ);}
360"*=" { RTOKEN(MULTEQ);}
361"/=" { RTOKEN(DIVEQ);}
362"&=" { RTOKEN(ANDEQ);}
363"|=" { RTOKEN(OREQ);}
2fa0b342
DHW
364"&&" { RTOKEN(ANDAND);}
365">" { RTOKEN('>');}
366"," { RTOKEN(',');}
367"&" { RTOKEN('&');}
368"|" { RTOKEN('|');}
369"~" { RTOKEN('~');}
370"!" { RTOKEN('!');}
371"?" { RTOKEN('?');}
372"*" { RTOKEN('*');}
373"%" { RTOKEN('%');}
374"<" { RTOKEN('<');}
2fa0b342
DHW
375">" { RTOKEN('>');}
376"}" { RTOKEN('}') ; }
377"{" { RTOKEN('{'); }
378")" { RTOKEN(')');}
379"(" { RTOKEN('(');}
380"]" { RTOKEN(']');}
381"[" { RTOKEN('[');}
382":" { RTOKEN(':'); }
fd846434 383";" { RTOKEN('\;');}
2fa0b342 384"-" { RTOKEN('-');}
1418c83b 385
2fa0b342
DHW
386
387
388"/*" {
389 while (1) {
390 int ch;
391 ch = input();
392 while (ch != '*') {
2fa0b342
DHW
393 ch = input();
394 }
395
396
397
398 if (input() == '/') {
399 break;
400 }
401 unput(yytext[yyleng-1]);
402 }
403}
404
405"\""[^\"]*"\"" {
406
407 yylval.name = buystring(yytext+1);
408 yylval.name[yyleng-2] = 0; /* Fry final quote */
409 return NAME;
410}
2fa0b342 411
7ca04d28 412{FILENAMECHAR} {
2fa0b342 413
7ca04d28 414 boolean loop = false;
7ca04d28 415 int ch;
2fa0b342 416 keyword_type *k;
1418c83b 417
1d45ccb3
SC
418 /* If we're in hex mode (only after a -T) then all we can see are numbers
419 hex digit we see will be a number. */
420
421 if (hex_mode) {
422 return number(16, 16);
1418c83b
SC
423 }
424
1d45ccb3
SC
425 /* If we're in a defsym then all things starting with a digit are in
426 hex */
427
428 if (isdigit(yytext[0]) && ldgram_in_defsym) {
429 return number(16,16);
430 }
431
432
433 /* Otherwise if we're in a script we will parse the numbers
434 normally */
435
436 if (ldgram_in_script == true && isdigit(yytext[0])) {
437 return number(8,10);
1418c83b
SC
438 }
439
1d45ccb3
SC
440 /* Anywhere not in a script or defsym, an opertor is part of a
441 filename, except / and, which is an operator when on its own */
442 if (ldgram_in_script == true|| ldgram_in_defsym == true) {
1418c83b 443
1d45ccb3
SC
444 switch (yytext[0]) {
445 case '*': RTOKEN('*');
1418c83b 446
1d45ccb3
SC
447 case '=': {
448 ldgram_had_equals = true;
449 RTOKEN('=');
450 }
451 break;
452 case '/': {
453 if (ldgram_in_defsym) RTOKEN('/');
454 }
455 break;
7ca04d28
SC
456 case '+': RTOKEN('+');
457 case '-': RTOKEN('-');
1d45ccb3
SC
458 case '!': RTOKEN('!');
459 case '~': RTOKEN('~');
7ca04d28 460 }
2fa0b342 461 }
2fa0b342 462
1d45ccb3
SC
463
464/* Otherwise this must be a file or a symbol name, and it will continue to be a
465 filename until we get to something strange. In scripts operator looking
466 things are taken to be operators, except /, which will be left
467 */
7ca04d28
SC
468 ch = input();
469 while (true)
470 {
1d45ccb3
SC
471 if (ldgram_in_defsym == true) {
472 switch (ch) {
473 case '*':
474 case '=':
475 case '+':
476 case '/':
477 case '-':
478 case '!':
479 case '~':
480 goto quit;
481 }
482
ac004870 483 }
a37cc0c0
SC
484 if(ldgram_in_script == true) {
485 switch (ch) {
486 case '*':
487 case '=':
488 case '+':
489 case '-':
490 case '!':
491 case '~':
492 goto quit;
493 }
494 }
495
1d45ccb3
SC
496 if (isalpha(ch) || isdigit(ch) || ch == '.' || ch == '_' ||
497 ch == '/' || ch == '.' || ch == '+' || ch == '-' || ch =='=') {
7ca04d28
SC
498 yytext[yyleng++] = ch;
499 }
500 else
501 break;
502 ch = input();
503 }
1d45ccb3 504 quit:;
2fa0b342
DHW
505 yytext[yyleng] = 0;
506 unput(ch);
2fa0b342 507
1d45ccb3 508 for(k = keywords; k ->name != (char *)NULL; k++) {
2fa0b342
DHW
509 if (strcmp(k->name, yytext)==0) {
510 yylval.token = k->value;
511 return k->value;
512 }
513 }
514 yylval.name = buystring(yytext);
515 return NAME;
516}
517
518
519
520
521
522%%
This page took 0.087076 seconds and 4 git commands to generate.