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