1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995, 1997, 1998, 1999 Free Software Foundation, Inc.
5 This file is part of GNU Binutils.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "libiberty.h"
32 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
34 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
35 as well as gratuitiously global symbol names, so we can have multiple
36 yacc generated parsers in ld. Note that these are only the variables
37 produced by yacc. If other parser generators (bison, byacc, etc) produce
38 additional global names that conflict at link time, then those parser
39 generators need to be fixed instead of adding those names to this list. */
41 #define yymaxdepth def_maxdepth
42 #define yyparse def_parse
44 #define yyerror def_error
45 #define yylval def_lval
46 #define yychar def_char
47 #define yydebug def_debug
48 #define yypact def_pact
55 #define yyexca def_exca
56 #define yyerrflag def_errflag
57 #define yynerrs def_nerrs
61 #define yy_yys def_yys
62 #define yystate def_state
65 #define yy_yyv def_yyv
67 #define yylloc def_lloc
68 #define yyreds def_reds /* With YYDEBUG defined */
69 #define yytoks def_toks /* With YYDEBUG defined */
70 #define yylhs def_yylhs
71 #define yylen def_yylen
72 #define yydefred def_yydefred
73 #define yydgoto def_yydgoto
74 #define yysindex def_yysindex
75 #define yyrindex def_yyrindex
76 #define yygindex def_yygindex
77 #define yytable def_yytable
78 #define yycheck def_yycheck
80 static int def_lex ();
82 static void def_description PARAMS ((const char *));
83 static void def_exports PARAMS ((const char *, const char *, int, int));
84 static void def_heapsize PARAMS ((int, int));
85 static void def_import
86 PARAMS ((const char *, const char *, const char *, const char *, int));
87 static void def_library PARAMS ((const char *, int));
88 static void def_name PARAMS ((const char *, int));
89 static void def_section PARAMS ((const char *, int));
90 static void def_section_alt PARAMS ((const char *, const char *));
91 static void def_stacksize PARAMS ((int, int));
92 static void def_version PARAMS ((int, int));
93 static void def_directive PARAMS ((char *));
94 static int def_parse PARAMS ((void));
95 static int def_error PARAMS ((const char *));
96 static int def_lex PARAMS ((void));
98 static int lex_forced_token = 0;
99 static const char *lex_parse_string = 0;
100 static const char *lex_parse_string_end = 0;
109 %token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATA
110 %token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANT, PRIVATE
111 %token READ WRITE EXECUTE SHARED NONAME DIRECTIVE
113 %token <number> NUMBER
114 %type <number> opt_base opt_ordinal
115 %type <number> attr attr_list opt_number exp_opt_list exp_opt
116 %type <id> opt_name opt_equal_name
125 NAME opt_name opt_base { def_name ($2, $3); }
126 | LIBRARY opt_name opt_base { def_library ($2, $3); }
127 | DESCRIPTION ID { def_description ($2);}
128 | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
129 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
130 | CODE attr_list { def_section ("CODE", $2);}
131 | DATA attr_list { def_section ("DATA", $2);}
135 | VERSIONK NUMBER { def_version ($2, 0);}
136 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
137 | DIRECTIVE ID { def_directive ($2);}
148 ID opt_equal_name opt_ordinal exp_opt_list
149 { def_exports ($1, $2, $3, $4); }
152 exp_opt exp_opt_list { $$ = $1 | $2; }
157 | CONSTANT { $$ = 2; }
159 | PRIVATE { $$ = 8; }
167 ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
168 | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
169 | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
170 | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
171 | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
172 | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
181 ID attr_list { def_section ($1, $2);}
182 | ID ID { def_section_alt ($1, $2);}
186 attr_list opt_comma attr { $$ = $1 | $3; }
194 opt_number: ',' NUMBER { $$=$2;}
205 opt_name: ID { $$ = $1; }
210 '@' NUMBER { $$ = $2;}
219 opt_base: BASE '=' NUMBER { $$ = $3;}
227 /*****************************************************************************
229 *****************************************************************************/
231 static FILE *the_file;
232 static const char *def_filename;
233 static int linenumber;
234 static def_file *def;
235 static int saw_newline;
239 struct directive *next;
244 static struct directive *directives = 0;
249 def_file *rv = (def_file *) xmalloc (sizeof (def_file));
250 memset (rv, 0, sizeof (def_file));
252 rv->base_address = (bfd_vma) (-1);
253 rv->stack_reserve = rv->stack_commit = -1;
254 rv->heap_reserve = rv->heap_commit = -1;
255 rv->version_major = rv->version_minor = -1;
260 def_file_parse (filename, add_to)
261 const char *filename;
266 the_file = fopen (filename, "r");
267 def_filename = filename;
280 def = def_file_empty ();
293 for (d = directives; d; d = d->next)
296 printf ("Adding directive %08x `%s'\n", d->name, d->name);
298 def_file_add_directive (def, d->name, d->len);
313 if (def->description)
314 free (def->description);
316 if (def->section_defs)
318 for (i = 0; i < def->num_section_defs; i++)
320 if (def->section_defs[i].name)
321 free (def->section_defs[i].name);
322 if (def->section_defs[i].class)
323 free (def->section_defs[i].class);
325 free (def->section_defs);
330 for (i = 0; i < def->num_exports; i++)
332 if (def->exports[i].internal_name
333 && def->exports[i].internal_name != def->exports[i].name)
334 free (def->exports[i].internal_name);
335 if (def->exports[i].name)
336 free (def->exports[i].name);
343 for (i = 0; i < def->num_imports; i++)
345 if (def->imports[i].internal_name
346 && def->imports[i].internal_name != def->imports[i].name)
347 free (def->imports[i].internal_name);
348 if (def->imports[i].name)
349 free (def->imports[i].name);
356 def_file_module *m = def->modules;
357 def->modules = def->modules->next;
364 #ifdef DEF_FILE_PRINT
366 def_file_print (file, def)
371 fprintf (file, ">>>> def_file at 0x%08x\n", def);
373 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
374 if (def->is_dll != -1)
375 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
376 if (def->base_address != (bfd_vma) (-1))
377 fprintf (file, " base address: 0x%08x\n", def->base_address);
378 if (def->description)
379 fprintf (file, " description: `%s'\n", def->description);
380 if (def->stack_reserve != -1)
381 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
382 if (def->stack_commit != -1)
383 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
384 if (def->heap_reserve != -1)
385 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
386 if (def->heap_commit != -1)
387 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
389 if (def->num_section_defs > 0)
391 fprintf (file, " section defs:\n");
392 for (i = 0; i < def->num_section_defs; i++)
394 fprintf (file, " name: `%s', class: `%s', flags:",
395 def->section_defs[i].name, def->section_defs[i].class);
396 if (def->section_defs[i].flag_read)
397 fprintf (file, " R");
398 if (def->section_defs[i].flag_write)
399 fprintf (file, " W");
400 if (def->section_defs[i].flag_execute)
401 fprintf (file, " X");
402 if (def->section_defs[i].flag_shared)
403 fprintf (file, " S");
404 fprintf (file, "\n");
408 if (def->num_exports > 0)
410 fprintf (file, " exports:\n");
411 for (i = 0; i < def->num_exports; i++)
413 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
414 def->exports[i].name, def->exports[i].internal_name,
415 def->exports[i].ordinal);
416 if (def->exports[i].flag_private)
417 fprintf (file, " P");
418 if (def->exports[i].flag_constant)
419 fprintf (file, " C");
420 if (def->exports[i].flag_noname)
421 fprintf (file, " N");
422 if (def->exports[i].flag_data)
423 fprintf (file, " D");
424 fprintf (file, "\n");
428 if (def->num_imports > 0)
430 fprintf (file, " imports:\n");
431 for (i = 0; i < def->num_imports; i++)
433 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
434 def->imports[i].internal_name,
435 def->imports[i].module,
436 def->imports[i].name,
437 def->imports[i].ordinal);
440 if (def->version_major != -1)
441 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
442 fprintf (file, "<<<< def_file at 0x%08x\n", def);
447 def_file_add_export (def, external_name, internal_name, ordinal)
449 const char *external_name;
450 const char *internal_name;
454 int max_exports = ROUND_UP(def->num_exports, 32);
455 if (def->num_exports >= max_exports)
457 max_exports = ROUND_UP(def->num_exports+1, 32);
459 def->exports = (def_file_export *) xrealloc (def->exports, max_exports * sizeof (def_file_export));
461 def->exports = (def_file_export *) xmalloc (max_exports * sizeof (def_file_export));
463 e = def->exports + def->num_exports;
464 memset (e, 0, sizeof (def_file_export));
465 if (internal_name && !external_name)
466 external_name = internal_name;
467 if (external_name && !internal_name)
468 internal_name = external_name;
469 e->name = xstrdup (external_name);
470 e->internal_name = xstrdup (internal_name);
471 e->ordinal = ordinal;
476 static def_file_module *
477 def_stash_module (def, name)
482 for (s=def->modules; s; s=s->next)
483 if (strcmp (s->name, name) == 0)
485 s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name));
486 s->next = def->modules;
489 strcpy (s->name, name);
494 def_file_add_import (def, name, module, ordinal, internal_name)
499 const char *internal_name;
502 int max_imports = ROUND_UP(def->num_imports, 16);
503 if (def->num_imports >= max_imports)
505 max_imports = ROUND_UP(def->num_imports+1, 16);
507 def->imports = (def_file_import *) xrealloc (def->imports, max_imports * sizeof (def_file_import));
509 def->imports = (def_file_import *) xmalloc (max_imports * sizeof (def_file_import));
511 i = def->imports + def->num_imports;
512 memset (i, 0, sizeof (def_file_import));
514 i->name = xstrdup (name);
516 i->module = def_stash_module(def, module);
517 i->ordinal = ordinal;
519 i->internal_name = xstrdup (internal_name);
521 i->internal_name = i->name;
533 { "-heap", HEAPSIZE },
534 { "-stack", STACKSIZE },
535 { "-attr", SECTIONS },
536 { "-export", EXPORTS },
541 def_file_add_directive (my_def, param, len)
546 def_file *save_def = def;
547 const char *pend = param + len;
548 const char *tend = param;
555 while (param < pend && isspace (*param))
557 for (tend = param + 1;
558 tend < pend && !(isspace (tend[-1]) && *tend == '-');
561 for (i = 0; diropts[i].param; i++)
563 int len = strlen (diropts[i].param);
564 if (tend - param >= len
565 && strncmp (param, diropts[i].param, len) == 0
566 && (param[len] == ':' || param[len] == ' '))
568 lex_parse_string_end = tend;
569 lex_parse_string = param + len + 1;
570 lex_forced_token = diropts[i].token;
577 if (!diropts[i].param)
579 /* xgettext:c-format */
580 einfo (_("Warning: .drectve `%.*s' unrecognized\n"),
581 tend - param, param);
583 lex_parse_string = 0;
590 /*****************************************************************************
592 *****************************************************************************/
595 def_name (name, base)
601 def->name = xstrdup (name);
602 def->base_address = base;
607 def_library (name, base)
613 def->name = xstrdup (name);
614 def->base_address = base;
619 def_description (text)
622 int len = def->description ? strlen (def->description) : 0;
623 len += strlen (text) + 1;
624 if (def->description)
626 def->description = (char *) xrealloc (def->description, len);
627 strcat (def->description, text);
631 def->description = (char *) xmalloc (len);
632 strcpy (def->description, text);
637 def_stacksize (reserve, commit)
641 def->stack_reserve = reserve;
642 def->stack_commit = commit;
646 def_heapsize (reserve, commit)
650 def->heap_reserve = reserve;
651 def->heap_commit = commit;
655 def_section (name, attr)
660 int max_sections = ROUND_UP(def->num_section_defs, 4);
661 if (def->num_section_defs >= max_sections)
663 max_sections = ROUND_UP(def->num_section_defs+1, 4);
664 if (def->section_defs)
665 def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import));
667 def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import));
669 s = def->section_defs + def->num_section_defs;
670 memset (s, 0, sizeof (def_file_section));
671 s->name = xstrdup (name);
681 def->num_section_defs++;
685 def_section_alt (name, attr)
690 for (; *attr; attr++)
712 def_section (name, aval);
716 def_exports (external_name, internal_name, ordinal, flags)
717 const char *external_name;
718 const char *internal_name;
722 def_file_export *dfe;
724 if (!internal_name && external_name)
725 internal_name = external_name;
727 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
730 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
732 dfe->flag_noname = 1;
734 dfe->flag_constant = 1;
738 dfe->flag_private = 1;
742 def_import (internal_name, module, dllext, name, ordinal)
743 const char *internal_name;
753 buf = (char *) xmalloc (strlen (module) + strlen (dllext) + 2);
754 sprintf (buf, "%s.%s", module, dllext);
758 def_file_add_import (def, name, module, ordinal, internal_name);
764 def_version (major, minor)
768 def->version_major = major;
769 def->version_minor = minor;
776 struct directive *d = (struct directive *) xmalloc (sizeof (struct directive));
777 d->next = directives;
779 d->name = xstrdup (str);
780 d->len = strlen (str);
787 einfo ("%P: %s:%d: %s\n", def_filename, linenumber, err);
793 /*****************************************************************************
795 *****************************************************************************/
800 /* Never freed, but always reused as needed, so no real leak */
801 static char *buffer = 0;
802 static int buflen = 0;
803 static int bufptr = 0;
809 if (bufptr == buflen)
811 buflen += 50; /* overly reasonable, eh? */
813 buffer = (char *) xrealloc (buffer, buflen + 1);
815 buffer = (char *) xmalloc (buflen + 1);
817 buffer[bufptr++] = c;
818 buffer[bufptr] = 0; /* not optimal, but very convenient */
830 { "CONSTANT", CONSTANT },
832 { "DESCRIPTION", DESCRIPTION },
833 { "DIRECTIVE", DIRECTIVE },
834 { "EXECUTE", EXECUTE },
835 { "EXPORTS", EXPORTS },
836 { "HEAPSIZE", HEAPSIZE },
837 { "IMPORTS", IMPORTS },
838 { "LIBRARY", LIBRARY },
840 { "NONAME", NONAME },
841 { "PRIVATE", PRIVATE },
843 { "SECTIONS", SECTIONS },
844 { "SEGMENTS", SECTIONS },
845 { "SHARED", SHARED },
846 { "STACKSIZE", STACKSIZE },
847 { "VERSION", VERSIONK },
856 if (lex_parse_string)
858 if (lex_parse_string >= lex_parse_string_end)
861 rv = *lex_parse_string++;
865 rv = fgetc (the_file);
876 if (lex_parse_string)
882 return ungetc (c, the_file);
890 if (lex_forced_token)
892 i = lex_forced_token;
893 lex_forced_token = 0;
895 printf ("lex: forcing token %d\n", i);
902 /* trim leading whitespace */
903 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
909 printf ("lex: EOF\n");
914 if (saw_newline && c == ';')
920 while (c != EOF && c != '\n');
925 /* must be something else */
931 while (c != EOF && (isxdigit (c) || (c == 'x')))
938 yylval.number = strtoul (buffer, 0, 0);
940 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
945 if (isalpha (c) || strchr ("$:-_?", c))
948 while (c != EOF && (isalnum (c) || strchr ("$:-_?/@", c)))
955 for (i = 0; tokens[i].name; i++)
956 if (strcmp (tokens[i].name, buffer) == 0)
959 printf ("lex: `%s' is a string token\n", buffer);
961 return tokens[i].token;
964 printf ("lex: `%s' returns ID\n", buffer);
966 yylval.id = xstrdup (buffer);
970 if (c == '\'' || c == '"')
975 while (c != EOF && c != q)
980 yylval.id = xstrdup (buffer);
982 printf ("lex: `%s' returns ID\n", buffer);
987 if (c == '=' || c == '.' || c == '@' || c == ',')
990 printf ("lex: `%c' returns itself\n", c);
1001 /*printf ("lex: 0x%02x ignored\n", c); */