* binutils-all/dw2-decodedline.S: Always have whitespace before
[binutils.git] / ld / deffilep.y
blobf66ca2d37f3bb3d70d0c672d2b1e8f8788842780
1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
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.
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.
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. */
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"
31 #define TRACE 0
33 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
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. */
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
81 typedef struct def_pool_str {
82 struct def_pool_str *next;
83 char data[1];
84 } def_pool_str;
86 static def_pool_str *pool_strs = NULL;
88 static char *def_pool_alloc (size_t sz);
89 static char *def_pool_strdup (const char *str);
90 static void def_pool_free (void);
92 static void def_description (const char *);
93 static void def_exports (const char *, const char *, int, int, const char *);
94 static void def_heapsize (int, int);
95 static void def_import (const char *, const char *, const char *, const char *,
96 int, const char *);
97 static void def_image_name (const char *, int, int);
98 static void def_section (const char *, int);
99 static void def_section_alt (const char *, const char *);
100 static void def_stacksize (int, int);
101 static void def_version (int, int);
102 static void def_directive (char *);
103 static void def_aligncomm (char *str, int align);
104 static int def_parse (void);
105 static int def_error (const char *);
106 static int def_lex (void);
108 static int lex_forced_token = 0;
109 static const char *lex_parse_string = 0;
110 static const char *lex_parse_string_end = 0;
114 %union {
115 char *id;
116 const char *id_const;
117 int number;
118 char *digits;
121 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
122 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
123 %token PRIVATEU PRIVATEL ALIGNCOMM
124 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
125 %token <id> ID
126 %token <digits> DIGITS
127 %type <number> NUMBER
128 %type <digits> opt_digits
129 %type <number> opt_base opt_ordinal
130 %type <number> attr attr_list opt_number exp_opt_list exp_opt
131 %type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
132 %type <id> opt_equalequal_name
133 %type <id_const> keyword_as_name
137 start: start command
138 | command
141 command:
142 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
143 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
144 | DESCRIPTION ID { def_description ($2);}
145 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
146 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
147 | CODE attr_list { def_section ("CODE", $2);}
148 | DATAU attr_list { def_section ("DATA", $2);}
149 | SECTIONS seclist
150 | EXPORTS explist
151 | IMPORTS implist
152 | VERSIONK NUMBER { def_version ($2, 0);}
153 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
154 | DIRECTIVE ID { def_directive ($2);}
155 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
159 explist:
160 /* EMPTY */
161 | expline
162 | explist expline
165 expline:
166 /* The opt_comma is necessary to support both the usual
167 DEF file syntax as well as .drectve syntax which
168 mandates <expsym>,<expoptlist>. */
169 opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
170 { def_exports ($1, $2, $3, $5, $7); }
172 exp_opt_list:
173 /* The opt_comma is necessary to support both the usual
174 DEF file syntax as well as .drectve syntax which
175 allows for comma separated opt list. */
176 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
177 | { $$ = 0; }
179 exp_opt:
180 NONAMEU { $$ = 1; }
181 | NONAMEL { $$ = 1; }
182 | CONSTANTU { $$ = 2; }
183 | CONSTANTL { $$ = 2; }
184 | DATAU { $$ = 4; }
185 | DATAL { $$ = 4; }
186 | PRIVATEU { $$ = 8; }
187 | PRIVATEL { $$ = 8; }
189 implist:
190 implist impline
191 | impline
194 impline:
195 ID '=' ID '.' ID '.' ID opt_equalequal_name
196 { def_import ($1, $3, $5, $7, -1, $8); }
197 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
198 { def_import ($1, $3, $5, 0, $7, $8); }
199 | ID '=' ID '.' ID opt_equalequal_name
200 { def_import ($1, $3, 0, $5, -1, $6); }
201 | ID '=' ID '.' NUMBER opt_equalequal_name
202 { def_import ($1, $3, 0, 0, $5, $6); }
203 | ID '.' ID '.' ID opt_equalequal_name
204 { def_import( 0, $1, $3, $5, -1, $6); }
205 | ID '.' ID opt_equalequal_name
206 { def_import ( 0, $1, 0, $3, -1, $4); }
209 seclist:
210 seclist secline
211 | secline
214 secline:
215 ID attr_list { def_section ($1, $2);}
216 | ID ID { def_section_alt ($1, $2);}
219 attr_list:
220 attr_list opt_comma attr { $$ = $1 | $3; }
221 | attr { $$ = $1; }
224 opt_comma:
228 opt_number: ',' NUMBER { $$=$2;}
229 | { $$=-1;}
232 attr:
233 READ { $$ = 1;}
234 | WRITE { $$ = 2;}
235 | EXECUTE { $$=4;}
236 | SHARED { $$=8;}
240 keyword_as_name: BASE { $$ = "BASE"; }
241 | CODE { $$ = "CODE"; }
242 | CONSTANTU { $$ = "CONSTANT"; }
243 | CONSTANTL { $$ = "constant"; }
244 | DATAU { $$ = "DATA"; }
245 | DATAL { $$ = "data"; }
246 | DESCRIPTION { $$ = "DESCRIPTION"; }
247 | DIRECTIVE { $$ = "DIRECTIVE"; }
248 | EXECUTE { $$ = "EXECUTE"; }
249 | EXPORTS { $$ = "EXPORTS"; }
250 | HEAPSIZE { $$ = "HEAPSIZE"; }
251 | IMPORTS { $$ = "IMPORTS"; }
252 | LIBRARY { $$ = "LIBRARY"; }
253 | NAME { $$ = "NAME"; }
254 | NONAMEU { $$ = "NONAME"; }
255 | NONAMEL { $$ = "noname"; }
256 | PRIVATEU { $$ = "PRIVATE"; }
257 | PRIVATEL { $$ = "private"; }
258 | READ { $$ = "READ"; }
259 | SHARED { $$ = "SHARED"; }
260 | STACKSIZE_K { $$ = "STACKSIZE"; }
261 | VERSIONK { $$ = "VERSION"; }
262 | WRITE { $$ = "WRITE"; }
265 opt_name2: ID { $$ = $1; }
266 | '.' keyword_as_name
268 char *name = xmalloc (strlen ($2) + 2);
269 sprintf (name, ".%s", $2);
270 $$ = name;
272 | '.' opt_name2
274 char *name = def_pool_alloc (strlen ($2) + 2);
275 sprintf (name, ".%s", $2);
276 $$ = name;
278 | keyword_as_name '.' opt_name2
280 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
281 sprintf (name, "%s.%s", $1, $3);
282 $$ = name;
284 | ID '.' opt_name2
286 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
287 sprintf (name, "%s.%s", $1, $3);
288 $$ = name;
292 opt_name: opt_name2 { $$ = $1; }
293 | { $$ = ""; }
296 opt_equalequal_name: EQUAL ID { $$ = $2; }
297 | { $$ = 0; }
300 opt_ordinal:
301 '@' NUMBER { $$ = $2;}
302 | { $$ = -1;}
305 opt_equal_name:
306 '=' opt_name2 { $$ = $2; }
307 | { $$ = 0; }
310 opt_base: BASE '=' NUMBER { $$ = $3;}
311 | { $$ = -1;}
314 anylang_id: ID { $$ = $1; }
315 | '.' ID
317 char *id = def_pool_alloc (strlen ($2) + 2);
318 sprintf (id, ".%s", $2);
319 $$ = id;
321 | anylang_id '.' opt_digits opt_id
323 char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
324 sprintf (id, "%s.%s%s", $1, $3, $4);
325 $$ = id;
329 opt_digits: DIGITS { $$ = $1; }
330 | { $$ = ""; }
333 opt_id: ID { $$ = $1; }
334 | { $$ = ""; }
337 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
341 /*****************************************************************************
343 *****************************************************************************/
345 static FILE *the_file;
346 static const char *def_filename;
347 static int linenumber;
348 static def_file *def;
349 static int saw_newline;
351 struct directive
353 struct directive *next;
354 char *name;
355 int len;
358 static struct directive *directives = 0;
360 def_file *
361 def_file_empty (void)
363 def_file *rv = xmalloc (sizeof (def_file));
364 memset (rv, 0, sizeof (def_file));
365 rv->is_dll = -1;
366 rv->base_address = (bfd_vma) -1;
367 rv->stack_reserve = rv->stack_commit = -1;
368 rv->heap_reserve = rv->heap_commit = -1;
369 rv->version_major = rv->version_minor = -1;
370 return rv;
373 def_file *
374 def_file_parse (const char *filename, def_file *add_to)
376 struct directive *d;
378 the_file = fopen (filename, "r");
379 def_filename = filename;
380 linenumber = 1;
381 if (!the_file)
383 perror (filename);
384 return 0;
386 if (add_to)
388 def = add_to;
390 else
392 def = def_file_empty ();
395 saw_newline = 1;
396 if (def_parse ())
398 def_file_free (def);
399 fclose (the_file);
400 def_pool_free ();
401 return 0;
404 fclose (the_file);
406 while ((d = directives) != NULL)
408 #if TRACE
409 printf ("Adding directive %08x `%s'\n", d->name, d->name);
410 #endif
411 def_file_add_directive (def, d->name, d->len);
412 directives = d->next;
413 free (d->name);
414 free (d);
416 def_pool_free ();
418 return def;
421 void
422 def_file_free (def_file *fdef)
424 int i;
426 if (!fdef)
427 return;
428 if (fdef->name)
429 free (fdef->name);
430 if (fdef->description)
431 free (fdef->description);
433 if (fdef->section_defs)
435 for (i = 0; i < fdef->num_section_defs; i++)
437 if (fdef->section_defs[i].name)
438 free (fdef->section_defs[i].name);
439 if (fdef->section_defs[i].class)
440 free (fdef->section_defs[i].class);
442 free (fdef->section_defs);
445 if (fdef->exports)
447 for (i = 0; i < fdef->num_exports; i++)
449 if (fdef->exports[i].internal_name
450 && fdef->exports[i].internal_name != fdef->exports[i].name)
451 free (fdef->exports[i].internal_name);
452 if (fdef->exports[i].name)
453 free (fdef->exports[i].name);
454 if (fdef->exports[i].its_name)
455 free (fdef->exports[i].its_name);
457 free (fdef->exports);
460 if (fdef->imports)
462 for (i = 0; i < fdef->num_imports; i++)
464 if (fdef->imports[i].internal_name
465 && fdef->imports[i].internal_name != fdef->imports[i].name)
466 free (fdef->imports[i].internal_name);
467 if (fdef->imports[i].name)
468 free (fdef->imports[i].name);
469 if (fdef->imports[i].its_name)
470 free (fdef->imports[i].its_name);
472 free (fdef->imports);
475 while (fdef->modules)
477 def_file_module *m = fdef->modules;
479 fdef->modules = fdef->modules->next;
480 free (m);
483 while (fdef->aligncomms)
485 def_file_aligncomm *c = fdef->aligncomms;
487 fdef->aligncomms = fdef->aligncomms->next;
488 free (c->symbol_name);
489 free (c);
492 free (fdef);
495 #ifdef DEF_FILE_PRINT
496 void
497 def_file_print (FILE *file, def_file *fdef)
499 int i;
501 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
502 if (fdef->name)
503 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
504 if (fdef->is_dll != -1)
505 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
506 if (fdef->base_address != (bfd_vma) -1)
507 fprintf (file, " base address: 0x%08x\n", fdef->base_address);
508 if (fdef->description)
509 fprintf (file, " description: `%s'\n", fdef->description);
510 if (fdef->stack_reserve != -1)
511 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
512 if (fdef->stack_commit != -1)
513 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
514 if (fdef->heap_reserve != -1)
515 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
516 if (fdef->heap_commit != -1)
517 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
519 if (fdef->num_section_defs > 0)
521 fprintf (file, " section defs:\n");
523 for (i = 0; i < fdef->num_section_defs; i++)
525 fprintf (file, " name: `%s', class: `%s', flags:",
526 fdef->section_defs[i].name, fdef->section_defs[i].class);
527 if (fdef->section_defs[i].flag_read)
528 fprintf (file, " R");
529 if (fdef->section_defs[i].flag_write)
530 fprintf (file, " W");
531 if (fdef->section_defs[i].flag_execute)
532 fprintf (file, " X");
533 if (fdef->section_defs[i].flag_shared)
534 fprintf (file, " S");
535 fprintf (file, "\n");
539 if (fdef->num_exports > 0)
541 fprintf (file, " exports:\n");
543 for (i = 0; i < fdef->num_exports; i++)
545 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
546 fdef->exports[i].name, fdef->exports[i].internal_name,
547 fdef->exports[i].ordinal);
548 if (fdef->exports[i].flag_private)
549 fprintf (file, " P");
550 if (fdef->exports[i].flag_constant)
551 fprintf (file, " C");
552 if (fdef->exports[i].flag_noname)
553 fprintf (file, " N");
554 if (fdef->exports[i].flag_data)
555 fprintf (file, " D");
556 fprintf (file, "\n");
560 if (fdef->num_imports > 0)
562 fprintf (file, " imports:\n");
564 for (i = 0; i < fdef->num_imports; i++)
566 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
567 fdef->imports[i].internal_name,
568 fdef->imports[i].module,
569 fdef->imports[i].name,
570 fdef->imports[i].ordinal);
574 if (fdef->version_major != -1)
575 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
577 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
579 #endif
581 /* Helper routine to check for identity of string pointers,
582 which might be NULL. */
584 static int
585 are_names_equal (const char *s1, const char *s2)
587 if (!s1 && !s2)
588 return 0;
589 if (!s1 || !s2)
590 return (!s1 ? -1 : 1);
591 return strcmp (s1, s2);
594 static int
595 cmp_export_elem (const def_file_export *e, const char *ex_name,
596 const char *in_name, const char *its_name,
597 int ord)
599 int r;
601 if ((r = are_names_equal (ex_name, e->name)) != 0)
602 return r;
603 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
604 return r;
605 if ((r = are_names_equal (its_name, e->its_name)) != 0)
606 return r;
607 return (ord - e->ordinal);
610 /* Search the position of the identical element, or returns the position
611 of the next higher element. If last valid element is smaller, then MAX
612 is returned. */
614 static int
615 find_export_in_list (def_file_export *b, int max,
616 const char *ex_name, const char *in_name,
617 const char *its_name, int ord, int *is_ident)
619 int e, l, r, p;
621 *is_ident = 0;
622 if (!max)
623 return 0;
624 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
626 if (!e)
627 *is_ident = 1;
628 return 0;
630 if (max == 1)
631 return 1;
632 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
633 return max;
634 else if (!e || max == 2)
636 if (!e)
637 *is_ident = 1;
638 return max - 1;
640 l = 0; r = max - 1;
641 while (l < r)
643 p = (l + r) / 2;
644 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
645 if (!e)
647 *is_ident = 1;
648 return p;
650 else if (e < 0)
651 r = p - 1;
652 else if (e > 0)
653 l = p + 1;
655 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
656 ++l;
657 else if (!e)
658 *is_ident = 1;
659 return l;
662 def_file_export *
663 def_file_add_export (def_file *fdef,
664 const char *external_name,
665 const char *internal_name,
666 int ordinal,
667 const char *its_name,
668 int *is_dup)
670 def_file_export *e;
671 int pos;
672 int max_exports = ROUND_UP(fdef->num_exports, 32);
674 if (internal_name && !external_name)
675 external_name = internal_name;
676 if (external_name && !internal_name)
677 internal_name = external_name;
679 /* We need to avoid duplicates. */
680 *is_dup = 0;
681 pos = find_export_in_list (fdef->exports, fdef->num_exports,
682 external_name, internal_name,
683 its_name, ordinal, is_dup);
685 if (*is_dup != 0)
686 return (fdef->exports + pos);
688 if (fdef->num_exports >= max_exports)
690 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
691 if (fdef->exports)
692 fdef->exports = xrealloc (fdef->exports,
693 max_exports * sizeof (def_file_export));
694 else
695 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
698 e = fdef->exports + pos;
699 if (pos != fdef->num_exports)
700 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
701 memset (e, 0, sizeof (def_file_export));
702 e->name = xstrdup (external_name);
703 e->internal_name = xstrdup (internal_name);
704 e->its_name = (its_name ? xstrdup (its_name) : NULL);
705 e->ordinal = ordinal;
706 fdef->num_exports++;
707 return e;
710 def_file_module *
711 def_get_module (def_file *fdef, const char *name)
713 def_file_module *s;
715 for (s = fdef->modules; s; s = s->next)
716 if (strcmp (s->name, name) == 0)
717 return s;
719 return NULL;
722 static def_file_module *
723 def_stash_module (def_file *fdef, const char *name)
725 def_file_module *s;
727 if ((s = def_get_module (fdef, name)) != NULL)
728 return s;
729 s = xmalloc (sizeof (def_file_module) + strlen (name));
730 s->next = fdef->modules;
731 fdef->modules = s;
732 s->user_data = 0;
733 strcpy (s->name, name);
734 return s;
737 static int
738 cmp_import_elem (const def_file_import *e, const char *ex_name,
739 const char *in_name, const char *module,
740 int ord)
742 int r;
744 if ((r = are_names_equal (ex_name, e->name)) != 0)
745 return r;
746 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
747 return r;
748 if (ord != e->ordinal)
749 return (ord < e->ordinal ? -1 : 1);
750 return are_names_equal (module, (e->module ? e->module->name : NULL));
753 /* Search the position of the identical element, or returns the position
754 of the next higher element. If last valid element is smaller, then MAX
755 is returned. */
757 static int
758 find_import_in_list (def_file_import *b, int max,
759 const char *ex_name, const char *in_name,
760 const char *module, int ord, int *is_ident)
762 int e, l, r, p;
764 *is_ident = 0;
765 if (!max)
766 return 0;
767 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
769 if (!e)
770 *is_ident = 1;
771 return 0;
773 if (max == 1)
774 return 1;
775 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
776 return max;
777 else if (!e || max == 2)
779 if (!e)
780 *is_ident = 1;
781 return max - 1;
783 l = 0; r = max - 1;
784 while (l < r)
786 p = (l + r) / 2;
787 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
788 if (!e)
790 *is_ident = 1;
791 return p;
793 else if (e < 0)
794 r = p - 1;
795 else if (e > 0)
796 l = p + 1;
798 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
799 ++l;
800 else if (!e)
801 *is_ident = 1;
802 return l;
805 def_file_import *
806 def_file_add_import (def_file *fdef,
807 const char *name,
808 const char *module,
809 int ordinal,
810 const char *internal_name,
811 const char *its_name,
812 int *is_dup)
814 def_file_import *i;
815 int pos;
816 int max_imports = ROUND_UP (fdef->num_imports, 16);
818 /* We need to avoid here duplicates. */
819 *is_dup = 0;
820 pos = find_import_in_list (fdef->imports, fdef->num_imports,
821 name,
822 (!internal_name ? name : internal_name),
823 module, ordinal, is_dup);
824 if (*is_dup != 0)
825 return fdef->imports + pos;
827 if (fdef->num_imports >= max_imports)
829 max_imports = ROUND_UP (fdef->num_imports+1, 16);
831 if (fdef->imports)
832 fdef->imports = xrealloc (fdef->imports,
833 max_imports * sizeof (def_file_import));
834 else
835 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
837 i = fdef->imports + pos;
838 if (pos != fdef->num_imports)
839 memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
840 memset (i, 0, sizeof (def_file_import));
841 if (name)
842 i->name = xstrdup (name);
843 if (module)
844 i->module = def_stash_module (fdef, module);
845 i->ordinal = ordinal;
846 if (internal_name)
847 i->internal_name = xstrdup (internal_name);
848 else
849 i->internal_name = i->name;
850 i->its_name = (its_name ? xstrdup (its_name) : NULL);
851 fdef->num_imports++;
853 return i;
856 struct
858 char *param;
859 int token;
861 diropts[] =
863 { "-heap", HEAPSIZE },
864 { "-stack", STACKSIZE_K },
865 { "-attr", SECTIONS },
866 { "-export", EXPORTS },
867 { "-aligncomm", ALIGNCOMM },
868 { 0, 0 }
871 void
872 def_file_add_directive (def_file *my_def, const char *param, int len)
874 def_file *save_def = def;
875 const char *pend = param + len;
876 char * tend = (char *) param;
877 int i;
879 def = my_def;
881 while (param < pend)
883 while (param < pend
884 && (ISSPACE (*param) || *param == '\n' || *param == 0))
885 param++;
887 if (param == pend)
888 break;
890 /* Scan forward until we encounter any of:
891 - the end of the buffer
892 - the start of a new option
893 - a newline seperating options
894 - a NUL seperating options. */
895 for (tend = (char *) (param + 1);
896 (tend < pend
897 && !(ISSPACE (tend[-1]) && *tend == '-')
898 && *tend != '\n' && *tend != 0);
899 tend++)
902 for (i = 0; diropts[i].param; i++)
904 len = strlen (diropts[i].param);
906 if (tend - param >= len
907 && strncmp (param, diropts[i].param, len) == 0
908 && (param[len] == ':' || param[len] == ' '))
910 lex_parse_string_end = tend;
911 lex_parse_string = param + len + 1;
912 lex_forced_token = diropts[i].token;
913 saw_newline = 0;
914 if (def_parse ())
915 continue;
916 break;
920 if (!diropts[i].param)
922 char saved;
924 saved = * tend;
925 * tend = 0;
926 /* xgettext:c-format */
927 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
928 * tend = saved;
931 lex_parse_string = 0;
932 param = tend;
935 def = save_def;
936 def_pool_free ();
939 /* Parser Callbacks. */
941 static void
942 def_image_name (const char *name, int base, int is_dll)
944 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
945 to do here. We retain the output filename specified on command line. */
946 if (*name)
948 const char* image_name = lbasename (name);
950 if (image_name != name)
951 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
952 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
953 name);
954 if (def->name)
955 free (def->name);
956 /* Append the default suffix, if none specified. */
957 if (strchr (image_name, '.') == 0)
959 const char * suffix = is_dll ? ".dll" : ".exe";
961 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
962 sprintf (def->name, "%s%s", image_name, suffix);
964 else
965 def->name = xstrdup (image_name);
968 /* Honor a BASE address statement, even if LIBRARY string is empty. */
969 def->base_address = base;
970 def->is_dll = is_dll;
973 static void
974 def_description (const char *text)
976 int len = def->description ? strlen (def->description) : 0;
978 len += strlen (text) + 1;
979 if (def->description)
981 def->description = xrealloc (def->description, len);
982 strcat (def->description, text);
984 else
986 def->description = xmalloc (len);
987 strcpy (def->description, text);
991 static void
992 def_stacksize (int reserve, int commit)
994 def->stack_reserve = reserve;
995 def->stack_commit = commit;
998 static void
999 def_heapsize (int reserve, int commit)
1001 def->heap_reserve = reserve;
1002 def->heap_commit = commit;
1005 static void
1006 def_section (const char *name, int attr)
1008 def_file_section *s;
1009 int max_sections = ROUND_UP (def->num_section_defs, 4);
1011 if (def->num_section_defs >= max_sections)
1013 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1015 if (def->section_defs)
1016 def->section_defs = xrealloc (def->section_defs,
1017 max_sections * sizeof (def_file_import));
1018 else
1019 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1021 s = def->section_defs + def->num_section_defs;
1022 memset (s, 0, sizeof (def_file_section));
1023 s->name = xstrdup (name);
1024 if (attr & 1)
1025 s->flag_read = 1;
1026 if (attr & 2)
1027 s->flag_write = 1;
1028 if (attr & 4)
1029 s->flag_execute = 1;
1030 if (attr & 8)
1031 s->flag_shared = 1;
1033 def->num_section_defs++;
1036 static void
1037 def_section_alt (const char *name, const char *attr)
1039 int aval = 0;
1041 for (; *attr; attr++)
1043 switch (*attr)
1045 case 'R':
1046 case 'r':
1047 aval |= 1;
1048 break;
1049 case 'W':
1050 case 'w':
1051 aval |= 2;
1052 break;
1053 case 'X':
1054 case 'x':
1055 aval |= 4;
1056 break;
1057 case 'S':
1058 case 's':
1059 aval |= 8;
1060 break;
1063 def_section (name, aval);
1066 static void
1067 def_exports (const char *external_name,
1068 const char *internal_name,
1069 int ordinal,
1070 int flags,
1071 const char *its_name)
1073 def_file_export *dfe;
1074 int is_dup = 0;
1076 if (!internal_name && external_name)
1077 internal_name = external_name;
1078 #if TRACE
1079 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1080 #endif
1082 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1083 its_name, &is_dup);
1085 /* We might check here for flag redefinition and warn. For now we
1086 ignore duplicates silently. */
1087 if (is_dup)
1088 return;
1090 if (flags & 1)
1091 dfe->flag_noname = 1;
1092 if (flags & 2)
1093 dfe->flag_constant = 1;
1094 if (flags & 4)
1095 dfe->flag_data = 1;
1096 if (flags & 8)
1097 dfe->flag_private = 1;
1100 static void
1101 def_import (const char *internal_name,
1102 const char *module,
1103 const char *dllext,
1104 const char *name,
1105 int ordinal,
1106 const char *its_name)
1108 char *buf = 0;
1109 const char *ext = dllext ? dllext : "dll";
1110 int is_dup = 0;
1112 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1113 sprintf (buf, "%s.%s", module, ext);
1114 module = buf;
1116 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1117 &is_dup);
1118 free (buf);
1121 static void
1122 def_version (int major, int minor)
1124 def->version_major = major;
1125 def->version_minor = minor;
1128 static void
1129 def_directive (char *str)
1131 struct directive *d = xmalloc (sizeof (struct directive));
1133 d->next = directives;
1134 directives = d;
1135 d->name = xstrdup (str);
1136 d->len = strlen (str);
1139 static void
1140 def_aligncomm (char *str, int align)
1142 def_file_aligncomm *c, *p;
1144 p = NULL;
1145 c = def->aligncomms;
1146 while (c != NULL)
1148 int e = strcmp (c->symbol_name, str);
1149 if (!e)
1151 /* Not sure if we want to allow here duplicates with
1152 different alignments, but for now we keep them. */
1153 e = (int) c->alignment - align;
1154 if (!e)
1155 return;
1157 if (e > 0)
1158 break;
1159 c = (p = c)->next;
1162 c = xmalloc (sizeof (def_file_aligncomm));
1163 c->symbol_name = xstrdup (str);
1164 c->alignment = (unsigned int) align;
1165 if (!p)
1167 c->next = def->aligncomms;
1168 def->aligncomms = c;
1170 else
1172 c->next = p->next;
1173 p->next = c;
1177 static int
1178 def_error (const char *err)
1180 einfo ("%P: %s:%d: %s\n",
1181 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1182 return 0;
1186 /* Lexical Scanner. */
1188 #undef TRACE
1189 #define TRACE 0
1191 /* Never freed, but always reused as needed, so no real leak. */
1192 static char *buffer = 0;
1193 static int buflen = 0;
1194 static int bufptr = 0;
1196 static void
1197 put_buf (char c)
1199 if (bufptr == buflen)
1201 buflen += 50; /* overly reasonable, eh? */
1202 if (buffer)
1203 buffer = xrealloc (buffer, buflen + 1);
1204 else
1205 buffer = xmalloc (buflen + 1);
1207 buffer[bufptr++] = c;
1208 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1211 static struct
1213 char *name;
1214 int token;
1216 tokens[] =
1218 { "BASE", BASE },
1219 { "CODE", CODE },
1220 { "CONSTANT", CONSTANTU },
1221 { "constant", CONSTANTL },
1222 { "DATA", DATAU },
1223 { "data", DATAL },
1224 { "DESCRIPTION", DESCRIPTION },
1225 { "DIRECTIVE", DIRECTIVE },
1226 { "EXECUTE", EXECUTE },
1227 { "EXPORTS", EXPORTS },
1228 { "HEAPSIZE", HEAPSIZE },
1229 { "IMPORTS", IMPORTS },
1230 { "LIBRARY", LIBRARY },
1231 { "NAME", NAME },
1232 { "NONAME", NONAMEU },
1233 { "noname", NONAMEL },
1234 { "PRIVATE", PRIVATEU },
1235 { "private", PRIVATEL },
1236 { "READ", READ },
1237 { "SECTIONS", SECTIONS },
1238 { "SEGMENTS", SECTIONS },
1239 { "SHARED", SHARED },
1240 { "STACKSIZE", STACKSIZE_K },
1241 { "VERSION", VERSIONK },
1242 { "WRITE", WRITE },
1243 { 0, 0 }
1246 static int
1247 def_getc (void)
1249 int rv;
1251 if (lex_parse_string)
1253 if (lex_parse_string >= lex_parse_string_end)
1254 rv = EOF;
1255 else
1256 rv = *lex_parse_string++;
1258 else
1260 rv = fgetc (the_file);
1262 if (rv == '\n')
1263 saw_newline = 1;
1264 return rv;
1267 static int
1268 def_ungetc (int c)
1270 if (lex_parse_string)
1272 lex_parse_string--;
1273 return c;
1275 else
1276 return ungetc (c, the_file);
1279 static int
1280 def_lex (void)
1282 int c, i, q;
1284 if (lex_forced_token)
1286 i = lex_forced_token;
1287 lex_forced_token = 0;
1288 #if TRACE
1289 printf ("lex: forcing token %d\n", i);
1290 #endif
1291 return i;
1294 c = def_getc ();
1296 /* Trim leading whitespace. */
1297 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1298 c = def_getc ();
1300 if (c == EOF)
1302 #if TRACE
1303 printf ("lex: EOF\n");
1304 #endif
1305 return 0;
1308 if (saw_newline && c == ';')
1312 c = def_getc ();
1314 while (c != EOF && c != '\n');
1315 if (c == '\n')
1316 return def_lex ();
1317 return 0;
1320 /* Must be something else. */
1321 saw_newline = 0;
1323 if (ISDIGIT (c))
1325 bufptr = 0;
1326 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1328 put_buf (c);
1329 c = def_getc ();
1331 if (c != EOF)
1332 def_ungetc (c);
1333 yylval.digits = def_pool_strdup (buffer);
1334 #if TRACE
1335 printf ("lex: `%s' returns DIGITS\n", buffer);
1336 #endif
1337 return DIGITS;
1340 if (ISALPHA (c) || strchr ("$:-_?@", c))
1342 bufptr = 0;
1343 q = c;
1344 put_buf (c);
1345 c = def_getc ();
1347 if (q == '@')
1349 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1350 return (q);
1351 else if (ISDIGIT (c)) /* '@' followed by digit. */
1353 def_ungetc (c);
1354 return (q);
1356 #if TRACE
1357 printf ("lex: @ returns itself\n");
1358 #endif
1361 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1363 put_buf (c);
1364 c = def_getc ();
1366 if (c != EOF)
1367 def_ungetc (c);
1368 if (ISALPHA (q)) /* Check for tokens. */
1370 for (i = 0; tokens[i].name; i++)
1371 if (strcmp (tokens[i].name, buffer) == 0)
1373 #if TRACE
1374 printf ("lex: `%s' is a string token\n", buffer);
1375 #endif
1376 return tokens[i].token;
1379 #if TRACE
1380 printf ("lex: `%s' returns ID\n", buffer);
1381 #endif
1382 yylval.id = def_pool_strdup (buffer);
1383 return ID;
1386 if (c == '\'' || c == '"')
1388 q = c;
1389 c = def_getc ();
1390 bufptr = 0;
1392 while (c != EOF && c != q)
1394 put_buf (c);
1395 c = def_getc ();
1397 yylval.id = def_pool_strdup (buffer);
1398 #if TRACE
1399 printf ("lex: `%s' returns ID\n", buffer);
1400 #endif
1401 return ID;
1404 if ( c == '=')
1406 c = def_getc ();
1407 if (c == '=')
1409 #if TRACE
1410 printf ("lex: `==' returns EQUAL\n");
1411 #endif
1412 return EQUAL;
1414 def_ungetc (c);
1415 #if TRACE
1416 printf ("lex: `=' returns itself\n");
1417 #endif
1418 return '=';
1420 if (c == '.' || c == ',')
1422 #if TRACE
1423 printf ("lex: `%c' returns itself\n", c);
1424 #endif
1425 return c;
1428 if (c == '\n')
1430 linenumber++;
1431 saw_newline = 1;
1434 /*printf ("lex: 0x%02x ignored\n", c); */
1435 return def_lex ();
1438 static char *
1439 def_pool_alloc (size_t sz)
1441 def_pool_str *e;
1443 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1444 e->next = pool_strs;
1445 pool_strs = e;
1446 return e->data;
1449 static char *
1450 def_pool_strdup (const char *str)
1452 char *s;
1453 size_t len;
1454 if (!str)
1455 return NULL;
1456 len = strlen (str) + 1;
1457 s = def_pool_alloc (len);
1458 memcpy (s, str, len);
1459 return s;
1462 static void
1463 def_pool_free (void)
1465 def_pool_str *p;
1466 while ((p = pool_strs) != NULL)
1468 pool_strs = p->next;
1469 free (p);