* nto-procfs.c (get_regset): Pass correct pointer.
[deliverable/binutils-gdb.git] / ld / deffilep.y
CommitLineData
252b5132
RH
1%{ /* deffilep.y - parser for .def files */
2
3db64b00 3/* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
db09f25b 4 Free Software Foundation, Inc.
252b5132 5
a35bc64f 6 This file is part of GNU Binutils.
252b5132 7
a35bc64f
NC
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
f96b4a7b 10 the Free Software Foundation; either version 3 of the License, or
a35bc64f 11 (at your option) any later version.
252b5132 12
a35bc64f
NC
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
252b5132 17
a35bc64f
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
f96b4a7b
NC
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
252b5132 22
3db64b00 23#include "sysdep.h"
252b5132 24#include "libiberty.h"
3882b010 25#include "safe-ctype.h"
252b5132 26#include "bfd.h"
252b5132
RH
27#include "ld.h"
28#include "ldmisc.h"
29#include "deffile.h"
30
31#define TRACE 0
32
33#define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
34
35/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
36 as well as gratuitiously global symbol names, so we can have multiple
37 yacc generated parsers in ld. Note that these are only the variables
38 produced by yacc. If other parser generators (bison, byacc, etc) produce
39 additional global names that conflict at link time, then those parser
a35bc64f 40 generators need to be fixed instead of adding those names to this list. */
252b5132
RH
41
42#define yymaxdepth def_maxdepth
43#define yyparse def_parse
44#define yylex def_lex
45#define yyerror def_error
46#define yylval def_lval
47#define yychar def_char
48#define yydebug def_debug
49#define yypact def_pact
50#define yyr1 def_r1
51#define yyr2 def_r2
52#define yydef def_def
53#define yychk def_chk
54#define yypgo def_pgo
55#define yyact def_act
56#define yyexca def_exca
57#define yyerrflag def_errflag
58#define yynerrs def_nerrs
59#define yyps def_ps
60#define yypv def_pv
61#define yys def_s
62#define yy_yys def_yys
63#define yystate def_state
64#define yytmp def_tmp
65#define yyv def_v
66#define yy_yyv def_yyv
67#define yyval def_val
68#define yylloc def_lloc
a35bc64f
NC
69#define yyreds def_reds /* With YYDEBUG defined. */
70#define yytoks def_toks /* With YYDEBUG defined. */
252b5132
RH
71#define yylhs def_yylhs
72#define yylen def_yylen
73#define yydefred def_yydefred
74#define yydgoto def_yydgoto
75#define yysindex def_yysindex
76#define yyrindex def_yyrindex
77#define yygindex def_yygindex
78#define yytable def_yytable
79#define yycheck def_yycheck
80
1579bae1
AM
81static void def_description (const char *);
82static void def_exports (const char *, const char *, int, int);
83static void def_heapsize (int, int);
84static void def_import (const char *, const char *, const char *, const char *,
85 int);
a880c748 86static void def_image_name (const char *, int, int);
1579bae1
AM
87static void def_section (const char *, int);
88static void def_section_alt (const char *, const char *);
89static void def_stacksize (int, int);
90static void def_version (int, int);
91static void def_directive (char *);
c1711530 92static void def_aligncomm (char *str, int align);
1579bae1
AM
93static int def_parse (void);
94static int def_error (const char *);
95static int def_lex (void);
252b5132
RH
96
97static int lex_forced_token = 0;
98static const char *lex_parse_string = 0;
99static const char *lex_parse_string_end = 0;
100
101%}
102
103%union {
104 char *id;
105 int number;
106};
107
8e58566f 108%token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
655f76a2 109%token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
c1711530 110%token PRIVATEU PRIVATEL ALIGNCOMM
7c9e78f8 111%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
252b5132
RH
112%token <id> ID
113%token <number> NUMBER
114%type <number> opt_base opt_ordinal
115%type <number> attr attr_list opt_number exp_opt_list exp_opt
053c44e1 116%type <id> opt_name opt_equal_name dot_name
252b5132
RH
117
118%%
119
120start: start command
121 | command
122 ;
123
124command:
a880c748
DS
125 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
126 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
252b5132 127 | DESCRIPTION ID { def_description ($2);}
8e58566f 128 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
252b5132
RH
129 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
130 | CODE attr_list { def_section ("CODE", $2);}
7c9e78f8 131 | DATAU attr_list { def_section ("DATA", $2);}
252b5132
RH
132 | SECTIONS seclist
133 | EXPORTS explist
134 | IMPORTS implist
135 | VERSIONK NUMBER { def_version ($2, 0);}
136 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
137 | DIRECTIVE ID { def_directive ($2);}
c1711530 138 | ALIGNCOMM ID ',' NUMBER { def_aligncomm ($2, $4);}
252b5132
RH
139 ;
140
141
142explist:
143 /* EMPTY */
144 | expline
145 | explist expline
146 ;
147
148expline:
7c9e78f8
DD
149 /* The opt_comma is necessary to support both the usual
150 DEF file syntax as well as .drectve syntax which
151 mandates <expsym>,<expoptlist>. */
053c44e1 152 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
7c9e78f8 153 { def_exports ($1, $2, $3, $5); }
252b5132
RH
154 ;
155exp_opt_list:
7c9e78f8
DD
156 /* The opt_comma is necessary to support both the usual
157 DEF file syntax as well as .drectve syntax which
158 allows for comma separated opt list. */
159 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
252b5132
RH
160 | { $$ = 0; }
161 ;
162exp_opt:
7c9e78f8
DD
163 NONAMEU { $$ = 1; }
164 | NONAMEL { $$ = 1; }
165 | CONSTANTU { $$ = 2; }
166 | CONSTANTL { $$ = 2; }
167 | DATAU { $$ = 4; }
168 | DATAL { $$ = 4; }
169 | PRIVATEU { $$ = 8; }
170 | PRIVATEL { $$ = 8; }
252b5132
RH
171 ;
172implist:
173 implist impline
174 | impline
175 ;
176
177impline:
178 ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
179 | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
180 | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
181 | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
182 | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
183 | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
184;
185
186seclist:
187 seclist secline
188 | secline
189 ;
190
191secline:
192 ID attr_list { def_section ($1, $2);}
193 | ID ID { def_section_alt ($1, $2);}
194 ;
195
196attr_list:
197 attr_list opt_comma attr { $$ = $1 | $3; }
198 | attr { $$ = $1; }
199 ;
200
201opt_comma:
202 ','
203 |
204 ;
205opt_number: ',' NUMBER { $$=$2;}
206 | { $$=-1;}
207 ;
208
209attr:
210 READ { $$ = 1;}
211 | WRITE { $$ = 2;}
212 | EXECUTE { $$=4;}
213 | SHARED { $$=8;}
214 ;
215
216opt_name: ID { $$ = $1; }
5aaace27
NC
217 | ID '.' ID
218 {
1579bae1 219 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
5aaace27
NC
220 sprintf (name, "%s.%s", $1, $3);
221 $$ = name;
222 }
223 | { $$ = ""; }
252b5132
RH
224 ;
225
226opt_ordinal:
227 '@' NUMBER { $$ = $2;}
228 | { $$ = -1;}
229 ;
230
231opt_equal_name:
053c44e1 232 '=' dot_name { $$ = $2; }
252b5132
RH
233 | { $$ = 0; }
234 ;
235
236opt_base: BASE '=' NUMBER { $$ = $3;}
4064c856 237 | { $$ = -1;}
252b5132
RH
238 ;
239
053c44e1
DS
240dot_name: ID { $$ = $1; }
241 | dot_name '.' ID
242 {
1579bae1 243 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
053c44e1
DS
244 sprintf (name, "%s.%s", $1, $3);
245 $$ = name;
246 }
247 ;
252b5132
RH
248
249
250%%
251
252/*****************************************************************************
253 API
254 *****************************************************************************/
255
256static FILE *the_file;
257static const char *def_filename;
258static int linenumber;
259static def_file *def;
260static int saw_newline;
261
262struct directive
263 {
264 struct directive *next;
265 char *name;
266 int len;
267 };
268
269static struct directive *directives = 0;
270
271def_file *
1579bae1 272def_file_empty (void)
252b5132 273{
1579bae1 274 def_file *rv = xmalloc (sizeof (def_file));
252b5132
RH
275 memset (rv, 0, sizeof (def_file));
276 rv->is_dll = -1;
1579bae1 277 rv->base_address = (bfd_vma) -1;
252b5132
RH
278 rv->stack_reserve = rv->stack_commit = -1;
279 rv->heap_reserve = rv->heap_commit = -1;
280 rv->version_major = rv->version_minor = -1;
281 return rv;
282}
283
284def_file *
1579bae1 285def_file_parse (const char *filename, def_file *add_to)
252b5132
RH
286{
287 struct directive *d;
288
289 the_file = fopen (filename, "r");
290 def_filename = filename;
291 linenumber = 1;
292 if (!the_file)
293 {
294 perror (filename);
295 return 0;
296 }
297 if (add_to)
298 {
299 def = add_to;
300 }
301 else
302 {
303 def = def_file_empty ();
304 }
305
306 saw_newline = 1;
307 if (def_parse ())
308 {
309 def_file_free (def);
310 fclose (the_file);
311 return 0;
312 }
313
314 fclose (the_file);
315
316 for (d = directives; d; d = d->next)
317 {
318#if TRACE
319 printf ("Adding directive %08x `%s'\n", d->name, d->name);
320#endif
321 def_file_add_directive (def, d->name, d->len);
322 }
323
324 return def;
325}
326
327void
1579bae1 328def_file_free (def_file *def)
252b5132
RH
329{
330 int i;
a35bc64f 331
252b5132
RH
332 if (!def)
333 return;
334 if (def->name)
335 free (def->name);
336 if (def->description)
337 free (def->description);
338
339 if (def->section_defs)
340 {
341 for (i = 0; i < def->num_section_defs; i++)
342 {
343 if (def->section_defs[i].name)
344 free (def->section_defs[i].name);
345 if (def->section_defs[i].class)
346 free (def->section_defs[i].class);
347 }
348 free (def->section_defs);
349 }
350
351 if (def->exports)
352 {
353 for (i = 0; i < def->num_exports; i++)
354 {
355 if (def->exports[i].internal_name
356 && def->exports[i].internal_name != def->exports[i].name)
357 free (def->exports[i].internal_name);
358 if (def->exports[i].name)
359 free (def->exports[i].name);
360 }
361 free (def->exports);
362 }
363
364 if (def->imports)
365 {
366 for (i = 0; i < def->num_imports; i++)
367 {
368 if (def->imports[i].internal_name
369 && def->imports[i].internal_name != def->imports[i].name)
370 free (def->imports[i].internal_name);
371 if (def->imports[i].name)
372 free (def->imports[i].name);
373 }
374 free (def->imports);
375 }
376
377 while (def->modules)
378 {
379 def_file_module *m = def->modules;
380 def->modules = def->modules->next;
381 free (m);
382 }
383
c1711530
DK
384 while (def->aligncomms)
385 {
386 def_file_aligncomm *c = def->aligncomms;
387 def->aligncomms = def->aligncomms->next;
388 free (c->symbol_name);
389 free (c);
390 }
391
252b5132
RH
392 free (def);
393}
394
395#ifdef DEF_FILE_PRINT
396void
1579bae1 397def_file_print (FILE *file, def_file *def)
252b5132
RH
398{
399 int i;
a35bc64f 400
252b5132
RH
401 fprintf (file, ">>>> def_file at 0x%08x\n", def);
402 if (def->name)
403 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
404 if (def->is_dll != -1)
405 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
1579bae1 406 if (def->base_address != (bfd_vma) -1)
252b5132
RH
407 fprintf (file, " base address: 0x%08x\n", def->base_address);
408 if (def->description)
409 fprintf (file, " description: `%s'\n", def->description);
410 if (def->stack_reserve != -1)
411 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
412 if (def->stack_commit != -1)
413 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
414 if (def->heap_reserve != -1)
415 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
416 if (def->heap_commit != -1)
417 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
418
419 if (def->num_section_defs > 0)
420 {
421 fprintf (file, " section defs:\n");
a35bc64f 422
252b5132
RH
423 for (i = 0; i < def->num_section_defs; i++)
424 {
425 fprintf (file, " name: `%s', class: `%s', flags:",
426 def->section_defs[i].name, def->section_defs[i].class);
427 if (def->section_defs[i].flag_read)
428 fprintf (file, " R");
429 if (def->section_defs[i].flag_write)
430 fprintf (file, " W");
431 if (def->section_defs[i].flag_execute)
432 fprintf (file, " X");
433 if (def->section_defs[i].flag_shared)
434 fprintf (file, " S");
435 fprintf (file, "\n");
436 }
437 }
438
439 if (def->num_exports > 0)
440 {
441 fprintf (file, " exports:\n");
a35bc64f 442
252b5132
RH
443 for (i = 0; i < def->num_exports; i++)
444 {
445 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
446 def->exports[i].name, def->exports[i].internal_name,
447 def->exports[i].ordinal);
448 if (def->exports[i].flag_private)
449 fprintf (file, " P");
450 if (def->exports[i].flag_constant)
451 fprintf (file, " C");
452 if (def->exports[i].flag_noname)
453 fprintf (file, " N");
454 if (def->exports[i].flag_data)
455 fprintf (file, " D");
456 fprintf (file, "\n");
457 }
458 }
459
460 if (def->num_imports > 0)
461 {
462 fprintf (file, " imports:\n");
a35bc64f 463
252b5132
RH
464 for (i = 0; i < def->num_imports; i++)
465 {
466 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
467 def->imports[i].internal_name,
468 def->imports[i].module,
469 def->imports[i].name,
470 def->imports[i].ordinal);
471 }
472 }
a35bc64f 473
252b5132
RH
474 if (def->version_major != -1)
475 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
a35bc64f 476
252b5132
RH
477 fprintf (file, "<<<< def_file at 0x%08x\n", def);
478}
479#endif
480
481def_file_export *
1579bae1
AM
482def_file_add_export (def_file *def,
483 const char *external_name,
484 const char *internal_name,
485 int ordinal)
252b5132
RH
486{
487 def_file_export *e;
488 int max_exports = ROUND_UP(def->num_exports, 32);
a35bc64f 489
252b5132
RH
490 if (def->num_exports >= max_exports)
491 {
a35bc64f 492 max_exports = ROUND_UP(def->num_exports + 1, 32);
252b5132 493 if (def->exports)
1579bae1
AM
494 def->exports = xrealloc (def->exports,
495 max_exports * sizeof (def_file_export));
252b5132 496 else
1579bae1 497 def->exports = xmalloc (max_exports * sizeof (def_file_export));
252b5132
RH
498 }
499 e = def->exports + def->num_exports;
500 memset (e, 0, sizeof (def_file_export));
501 if (internal_name && !external_name)
502 external_name = internal_name;
503 if (external_name && !internal_name)
504 internal_name = external_name;
505 e->name = xstrdup (external_name);
506 e->internal_name = xstrdup (internal_name);
507 e->ordinal = ordinal;
508 def->num_exports++;
509 return e;
510}
511
a35bc64f 512def_file_module *
1579bae1 513def_get_module (def_file *def, const char *name)
a35bc64f
NC
514{
515 def_file_module *s;
516
517 for (s = def->modules; s; s = s->next)
518 if (strcmp (s->name, name) == 0)
519 return s;
520
1579bae1 521 return NULL;
a35bc64f
NC
522}
523
252b5132 524static def_file_module *
1579bae1 525def_stash_module (def_file *def, const char *name)
252b5132
RH
526{
527 def_file_module *s;
a35bc64f 528
1579bae1 529 if ((s = def_get_module (def, name)) != NULL)
252b5132 530 return s;
1579bae1 531 s = xmalloc (sizeof (def_file_module) + strlen (name));
252b5132
RH
532 s->next = def->modules;
533 def->modules = s;
534 s->user_data = 0;
535 strcpy (s->name, name);
536 return s;
537}
538
539def_file_import *
1579bae1
AM
540def_file_add_import (def_file *def,
541 const char *name,
542 const char *module,
543 int ordinal,
544 const char *internal_name)
252b5132
RH
545{
546 def_file_import *i;
1579bae1 547 int max_imports = ROUND_UP (def->num_imports, 16);
a35bc64f 548
252b5132
RH
549 if (def->num_imports >= max_imports)
550 {
1579bae1 551 max_imports = ROUND_UP (def->num_imports+1, 16);
a35bc64f 552
252b5132 553 if (def->imports)
1579bae1
AM
554 def->imports = xrealloc (def->imports,
555 max_imports * sizeof (def_file_import));
252b5132 556 else
1579bae1 557 def->imports = xmalloc (max_imports * sizeof (def_file_import));
252b5132
RH
558 }
559 i = def->imports + def->num_imports;
560 memset (i, 0, sizeof (def_file_import));
561 if (name)
562 i->name = xstrdup (name);
563 if (module)
db09f25b 564 i->module = def_stash_module (def, module);
252b5132
RH
565 i->ordinal = ordinal;
566 if (internal_name)
567 i->internal_name = xstrdup (internal_name);
568 else
569 i->internal_name = i->name;
570 def->num_imports++;
a35bc64f 571
252b5132
RH
572 return i;
573}
574
575struct
576{
577 char *param;
578 int token;
579}
580diropts[] =
581{
582 { "-heap", HEAPSIZE },
8e58566f 583 { "-stack", STACKSIZE_K },
252b5132
RH
584 { "-attr", SECTIONS },
585 { "-export", EXPORTS },
c1711530 586 { "-aligncomm", ALIGNCOMM },
252b5132
RH
587 { 0, 0 }
588};
589
590void
1579bae1 591def_file_add_directive (def_file *my_def, const char *param, int len)
252b5132
RH
592{
593 def_file *save_def = def;
594 const char *pend = param + len;
dc17f155 595 char * tend = (char *) param;
252b5132
RH
596 int i;
597
598 def = my_def;
599
600 while (param < pend)
601 {
1579bae1
AM
602 while (param < pend
603 && (ISSPACE (*param) || *param == '\n' || *param == 0))
252b5132 604 param++;
a35bc64f 605
dc17f155
NC
606 if (param == pend)
607 break;
608
609 /* Scan forward until we encounter any of:
610 - the end of the buffer
611 - the start of a new option
612 - a newline seperating options
613 - a NUL seperating options. */
614 for (tend = (char *) (param + 1);
1579bae1
AM
615 (tend < pend
616 && !(ISSPACE (tend[-1]) && *tend == '-')
617 && *tend != '\n' && *tend != 0);
a35bc64f
NC
618 tend++)
619 ;
252b5132
RH
620
621 for (i = 0; diropts[i].param; i++)
622 {
623 int len = strlen (diropts[i].param);
a35bc64f 624
252b5132
RH
625 if (tend - param >= len
626 && strncmp (param, diropts[i].param, len) == 0
627 && (param[len] == ':' || param[len] == ' '))
628 {
629 lex_parse_string_end = tend;
630 lex_parse_string = param + len + 1;
631 lex_forced_token = diropts[i].token;
632 saw_newline = 0;
dc17f155
NC
633 if (def_parse ())
634 continue;
252b5132
RH
635 break;
636 }
637 }
638
639 if (!diropts[i].param)
dc17f155
NC
640 {
641 char saved;
642
643 saved = * tend;
644 * tend = 0;
645 /* xgettext:c-format */
646 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
647 * tend = saved;
648 }
a35bc64f 649
252b5132
RH
650 lex_parse_string = 0;
651 param = tend;
652 }
653
654 def = save_def;
655}
656
a35bc64f 657/* Parser Callbacks. */
252b5132
RH
658
659static void
a880c748 660def_image_name (const char *name, int base, int is_dll)
252b5132 661{
a2877985
DS
662 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
663 to do here. We retain the output filename specified on command line. */
664 if (*name)
665 {
666 const char* image_name = lbasename (name);
667 if (image_name != name)
668 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
669 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
670 name);
671 if (def->name)
672 free (def->name);
673 /* Append the default suffix, if none specified. */
674 if (strchr (image_name, '.') == 0)
675 {
676 const char * suffix = is_dll ? ".dll" : ".exe";
677
678 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
679 sprintf (def->name, "%s%s", image_name, suffix);
680 }
681 else
682 def->name = xstrdup (image_name);
683 }
684
685 /* Honor a BASE address statement, even if LIBRARY string is empty. */
252b5132 686 def->base_address = base;
a880c748 687 def->is_dll = is_dll;
252b5132
RH
688}
689
690static void
1579bae1 691def_description (const char *text)
252b5132
RH
692{
693 int len = def->description ? strlen (def->description) : 0;
a35bc64f 694
252b5132
RH
695 len += strlen (text) + 1;
696 if (def->description)
697 {
1579bae1 698 def->description = xrealloc (def->description, len);
252b5132
RH
699 strcat (def->description, text);
700 }
701 else
702 {
1579bae1 703 def->description = xmalloc (len);
252b5132
RH
704 strcpy (def->description, text);
705 }
706}
707
708static void
1579bae1 709def_stacksize (int reserve, int commit)
252b5132
RH
710{
711 def->stack_reserve = reserve;
712 def->stack_commit = commit;
713}
714
715static void
1579bae1 716def_heapsize (int reserve, int commit)
252b5132
RH
717{
718 def->heap_reserve = reserve;
719 def->heap_commit = commit;
720}
721
722static void
1579bae1 723def_section (const char *name, int attr)
252b5132
RH
724{
725 def_file_section *s;
1579bae1 726 int max_sections = ROUND_UP (def->num_section_defs, 4);
a35bc64f 727
252b5132
RH
728 if (def->num_section_defs >= max_sections)
729 {
1579bae1 730 max_sections = ROUND_UP (def->num_section_defs+1, 4);
a35bc64f 731
252b5132 732 if (def->section_defs)
1579bae1
AM
733 def->section_defs = xrealloc (def->section_defs,
734 max_sections * sizeof (def_file_import));
252b5132 735 else
1579bae1 736 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
252b5132
RH
737 }
738 s = def->section_defs + def->num_section_defs;
739 memset (s, 0, sizeof (def_file_section));
740 s->name = xstrdup (name);
741 if (attr & 1)
742 s->flag_read = 1;
743 if (attr & 2)
744 s->flag_write = 1;
745 if (attr & 4)
746 s->flag_execute = 1;
747 if (attr & 8)
748 s->flag_shared = 1;
749
750 def->num_section_defs++;
751}
752
753static void
1579bae1 754def_section_alt (const char *name, const char *attr)
252b5132
RH
755{
756 int aval = 0;
a35bc64f 757
252b5132
RH
758 for (; *attr; attr++)
759 {
760 switch (*attr)
761 {
762 case 'R':
763 case 'r':
764 aval |= 1;
765 break;
766 case 'W':
767 case 'w':
768 aval |= 2;
769 break;
770 case 'X':
771 case 'x':
772 aval |= 4;
773 break;
774 case 'S':
775 case 's':
776 aval |= 8;
777 break;
778 }
779 }
780 def_section (name, aval);
781}
782
783static void
1579bae1
AM
784def_exports (const char *external_name,
785 const char *internal_name,
786 int ordinal,
787 int flags)
252b5132
RH
788{
789 def_file_export *dfe;
790
791 if (!internal_name && external_name)
792 internal_name = external_name;
793#if TRACE
794 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
795#endif
796
797 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
798 if (flags & 1)
799 dfe->flag_noname = 1;
800 if (flags & 2)
801 dfe->flag_constant = 1;
802 if (flags & 4)
803 dfe->flag_data = 1;
804 if (flags & 8)
805 dfe->flag_private = 1;
806}
807
808static void
1579bae1
AM
809def_import (const char *internal_name,
810 const char *module,
811 const char *dllext,
812 const char *name,
813 int ordinal)
252b5132
RH
814{
815 char *buf = 0;
053c44e1
DS
816 const char *ext = dllext ? dllext : "dll";
817
1579bae1 818 buf = xmalloc (strlen (module) + strlen (ext) + 2);
053c44e1
DS
819 sprintf (buf, "%s.%s", module, ext);
820 module = buf;
252b5132
RH
821
822 def_file_add_import (def, name, module, ordinal, internal_name);
823 if (buf)
824 free (buf);
825}
826
827static void
1579bae1 828def_version (int major, int minor)
252b5132
RH
829{
830 def->version_major = major;
831 def->version_minor = minor;
832}
833
834static void
1579bae1 835def_directive (char *str)
252b5132 836{
1579bae1 837 struct directive *d = xmalloc (sizeof (struct directive));
a35bc64f 838
252b5132
RH
839 d->next = directives;
840 directives = d;
841 d->name = xstrdup (str);
842 d->len = strlen (str);
843}
844
c1711530
DK
845static void
846def_aligncomm (char *str, int align)
847{
848 def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
849
850 c->symbol_name = xstrdup (str);
851 c->alignment = (unsigned int) align;
852
853 c->next = def->aligncomms;
854 def->aligncomms = c;
855}
856
252b5132 857static int
1579bae1 858def_error (const char *err)
252b5132 859{
1579bae1
AM
860 einfo ("%P: %s:%d: %s\n",
861 def_filename ? def_filename : "<unknown-file>", linenumber, err);
252b5132
RH
862 return 0;
863}
864
865
a35bc64f 866/* Lexical Scanner. */
252b5132
RH
867
868#undef TRACE
869#define TRACE 0
870
a35bc64f 871/* Never freed, but always reused as needed, so no real leak. */
252b5132
RH
872static char *buffer = 0;
873static int buflen = 0;
874static int bufptr = 0;
875
876static void
1579bae1 877put_buf (char c)
252b5132
RH
878{
879 if (bufptr == buflen)
880 {
a35bc64f 881 buflen += 50; /* overly reasonable, eh? */
252b5132 882 if (buffer)
1579bae1 883 buffer = xrealloc (buffer, buflen + 1);
252b5132 884 else
1579bae1 885 buffer = xmalloc (buflen + 1);
252b5132
RH
886 }
887 buffer[bufptr++] = c;
a35bc64f 888 buffer[bufptr] = 0; /* not optimal, but very convenient. */
252b5132
RH
889}
890
891static struct
892{
893 char *name;
894 int token;
895}
896tokens[] =
897{
898 { "BASE", BASE },
899 { "CODE", CODE },
7c9e78f8
DD
900 { "CONSTANT", CONSTANTU },
901 { "constant", CONSTANTL },
902 { "DATA", DATAU },
903 { "data", DATAL },
252b5132
RH
904 { "DESCRIPTION", DESCRIPTION },
905 { "DIRECTIVE", DIRECTIVE },
906 { "EXECUTE", EXECUTE },
907 { "EXPORTS", EXPORTS },
908 { "HEAPSIZE", HEAPSIZE },
909 { "IMPORTS", IMPORTS },
910 { "LIBRARY", LIBRARY },
911 { "NAME", NAME },
7c9e78f8
DD
912 { "NONAME", NONAMEU },
913 { "noname", NONAMEL },
914 { "PRIVATE", PRIVATEU },
915 { "private", PRIVATEL },
252b5132
RH
916 { "READ", READ },
917 { "SECTIONS", SECTIONS },
918 { "SEGMENTS", SECTIONS },
919 { "SHARED", SHARED },
8e58566f 920 { "STACKSIZE", STACKSIZE_K },
252b5132
RH
921 { "VERSION", VERSIONK },
922 { "WRITE", WRITE },
923 { 0, 0 }
924};
925
926static int
1579bae1 927def_getc (void)
252b5132
RH
928{
929 int rv;
a35bc64f 930
252b5132
RH
931 if (lex_parse_string)
932 {
933 if (lex_parse_string >= lex_parse_string_end)
934 rv = EOF;
935 else
936 rv = *lex_parse_string++;
937 }
938 else
939 {
940 rv = fgetc (the_file);
941 }
942 if (rv == '\n')
943 saw_newline = 1;
944 return rv;
945}
946
947static int
1579bae1 948def_ungetc (int c)
252b5132
RH
949{
950 if (lex_parse_string)
951 {
952 lex_parse_string--;
953 return c;
954 }
955 else
956 return ungetc (c, the_file);
957}
958
959static int
1579bae1 960def_lex (void)
252b5132
RH
961{
962 int c, i, q;
963
964 if (lex_forced_token)
965 {
966 i = lex_forced_token;
967 lex_forced_token = 0;
968#if TRACE
969 printf ("lex: forcing token %d\n", i);
970#endif
971 return i;
972 }
973
974 c = def_getc ();
975
a35bc64f 976 /* Trim leading whitespace. */
252b5132
RH
977 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
978 c = def_getc ();
979
980 if (c == EOF)
981 {
982#if TRACE
983 printf ("lex: EOF\n");
984#endif
985 return 0;
986 }
987
988 if (saw_newline && c == ';')
989 {
990 do
991 {
992 c = def_getc ();
993 }
994 while (c != EOF && c != '\n');
995 if (c == '\n')
996 return def_lex ();
997 return 0;
998 }
a35bc64f
NC
999
1000 /* Must be something else. */
252b5132
RH
1001 saw_newline = 0;
1002
3882b010 1003 if (ISDIGIT (c))
252b5132
RH
1004 {
1005 bufptr = 0;
3882b010 1006 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
252b5132
RH
1007 {
1008 put_buf (c);
1009 c = def_getc ();
1010 }
1011 if (c != EOF)
1012 def_ungetc (c);
1013 yylval.number = strtoul (buffer, 0, 0);
1014#if TRACE
1015 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
1016#endif
1017 return NUMBER;
1018 }
1019
c9e38879 1020 if (ISALPHA (c) || strchr ("$:-_?@", c))
252b5132
RH
1021 {
1022 bufptr = 0;
c9e38879
NC
1023 q = c;
1024 put_buf (c);
1025 c = def_getc ();
1026
1027 if (q == '@')
1028 {
1029 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1030 return (q);
1031 else if (ISDIGIT (c)) /* '@' followed by digit. */
1032 {
1033 def_ungetc (c);
1034 return (q);
1035 }
1036#if TRACE
1037 printf ("lex: @ returns itself\n");
1038#endif
1039 }
1040
053c44e1 1041 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
252b5132
RH
1042 {
1043 put_buf (c);
1044 c = def_getc ();
1045 }
1046 if (c != EOF)
1047 def_ungetc (c);
c9e38879
NC
1048 if (ISALPHA (q)) /* Check for tokens. */
1049 {
1050 for (i = 0; tokens[i].name; i++)
1051 if (strcmp (tokens[i].name, buffer) == 0)
1052 {
252b5132 1053#if TRACE
c9e38879 1054 printf ("lex: `%s' is a string token\n", buffer);
252b5132 1055#endif
c9e38879
NC
1056 return tokens[i].token;
1057 }
1058 }
252b5132
RH
1059#if TRACE
1060 printf ("lex: `%s' returns ID\n", buffer);
1061#endif
1062 yylval.id = xstrdup (buffer);
1063 return ID;
1064 }
1065
1066 if (c == '\'' || c == '"')
1067 {
1068 q = c;
1069 c = def_getc ();
1070 bufptr = 0;
a35bc64f 1071
252b5132
RH
1072 while (c != EOF && c != q)
1073 {
1074 put_buf (c);
1075 c = def_getc ();
1076 }
1077 yylval.id = xstrdup (buffer);
1078#if TRACE
1079 printf ("lex: `%s' returns ID\n", buffer);
1080#endif
1081 return ID;
1082 }
1083
c9e38879 1084 if (c == '=' || c == '.' || c == ',')
252b5132
RH
1085 {
1086#if TRACE
1087 printf ("lex: `%c' returns itself\n", c);
1088#endif
1089 return c;
1090 }
1091
1092 if (c == '\n')
1093 {
1094 linenumber++;
1095 saw_newline = 1;
1096 }
1097
1098 /*printf ("lex: 0x%02x ignored\n", c); */
1099 return def_lex ();
1100}
This page took 0.618798 seconds and 4 git commands to generate.