1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995, 1997, 1998 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"
30 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
31 as well as gratuitiously global symbol names, so we can have multiple
32 yacc generated parsers in ld. Note that these are only the variables
33 produced by yacc. If other parser generators (bison, byacc, etc) produce
34 additional global names that conflict at link time, then those parser
35 generators need to be fixed instead of adding those names to this list. */
37 #define yymaxdepth def_maxdepth
38 #define yyparse def_parse
40 #define yyerror def_error
41 #define yylval def_lval
42 #define yychar def_char
43 #define yydebug def_debug
44 #define yypact def_pact
51 #define yyexca def_exca
52 #define yyerrflag def_errflag
53 #define yynerrs def_nerrs
57 #define yy_yys def_yys
58 #define yystate def_state
61 #define yy_yyv def_yyv
63 #define yylloc def_lloc
64 #define yyreds def_reds /* With YYDEBUG defined */
65 #define yytoks def_toks /* With YYDEBUG defined */
66 #define yylhs def_yylhs
67 #define yylen def_yylen
68 #define yydefred def_yydefred
69 #define yydgoto def_yydgoto
70 #define yysindex def_yysindex
71 #define yyrindex def_yyrindex
72 #define yygindex def_yygindex
73 #define yytable def_yytable
74 #define yycheck def_yycheck
76 static int def_lex ();
78 static void def_description PARAMS ((const char *));
79 static void def_exports PARAMS ((const char *, const char *, int, int));
80 static void def_heapsize PARAMS ((int, int));
81 static void def_import
82 PARAMS ((const char *, const char *, const char *, const char *, int));
83 static void def_library PARAMS ((const char *, int));
84 static void def_name PARAMS ((const char *, int));
85 static void def_section PARAMS ((const char *, int));
86 static void def_section_alt PARAMS ((const char *, const char *));
87 static void def_stacksize PARAMS ((int, int));
88 static void def_version PARAMS ((int, int));
89 static void def_directive PARAMS ((char *));
90 static int def_parse PARAMS ((void));
91 static int def_error PARAMS ((const char *));
93 static int def_lex PARAMS ((void));
95 static int lex_forced_token = 0;
96 static const char *lex_parse_string = 0;
97 static const char *lex_parse_string_end = 0;
106 %token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATA
107 %token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANT, PRIVATE
108 %token READ WRITE EXECUTE SHARED NONAME DIRECTIVE
110 %token <number> NUMBER
111 %type <number> opt_base opt_ordinal
112 %type <number> attr attr_list opt_number exp_opt_list exp_opt
113 %type <id> opt_name opt_equal_name
122 NAME opt_name opt_base { def_name ($2, $3); }
123 | LIBRARY opt_name opt_base { def_library ($2, $3); }
124 | DESCRIPTION ID { def_description ($2);}
125 | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
126 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
127 | CODE attr_list { def_section ("CODE", $2);}
128 | DATA attr_list { def_section ("DATA", $2);}
132 | VERSIONK NUMBER { def_version ($2, 0);}
133 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
134 | DIRECTIVE ID { def_directive ($2);}
145 ID opt_equal_name opt_ordinal exp_opt_list
146 { def_exports ($1, $2, $3, $4); }
149 exp_opt exp_opt_list { $$ = $1 | $2; }
154 | CONSTANT { $$ = 2; }
156 | PRIVATE { $$ = 8; }
164 ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
165 | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
166 | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
167 | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
168 | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
169 | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
178 ID attr_list { def_section ($1, $2);}
179 | ID ID { def_section_alt ($1, $2);}
183 attr_list opt_comma attr { $$ = $1 | $3; }
191 opt_number: ',' NUMBER { $$=$2;}
202 opt_name: ID { $$ = $1; }
207 '@' NUMBER { $$ = $2;}
216 opt_base: BASE '=' NUMBER { $$ = $3;}
224 /*****************************************************************************
226 *****************************************************************************/
228 static FILE *the_file;
229 static const char *def_filename;
230 static int linenumber;
231 static def_file *def;
232 static int max_exports, max_imports, max_sections;
233 static int saw_newline;
237 struct directive *next;
242 static struct directive *directives = 0;
247 def_file *rv = (def_file *) xmalloc (sizeof (def_file));
248 memset (rv, 0, sizeof (def_file));
249 max_exports = max_imports = max_sections = 0;
251 rv->base_address = (bfd_vma) (-1);
252 rv->stack_reserve = rv->stack_commit = -1;
253 rv->heap_reserve = rv->heap_commit = -1;
254 rv->version_major = rv->version_minor = -1;
259 def_file_parse (filename, add_to)
260 const char *filename;
265 the_file = fopen (filename, "r");
266 def_filename = filename;
276 max_exports = def->num_exports;
277 max_imports = def->num_imports;
278 max_sections = def->num_section_defs;
282 def = def_file_empty ();
295 for (d = directives; d; d = d->next)
298 printf ("Adding directive `%s'\n", d->name);
300 def_file_add_directive (def, d->name, d->len);
315 if (def->description)
316 free (def->description);
318 if (def->section_defs)
320 for (i = 0; i < def->num_section_defs; i++)
322 if (def->section_defs[i].name)
323 free (def->section_defs[i].name);
324 if (def->section_defs[i].class)
325 free (def->section_defs[i].class);
327 free (def->section_defs);
332 for (i = 0; i < def->num_exports; i++)
334 if (def->exports[i].internal_name
335 && def->exports[i].internal_name != def->exports[i].name)
336 free (def->exports[i].internal_name);
337 if (def->exports[i].name)
338 free (def->exports[i].name);
345 for (i = 0; i < def->num_imports; i++)
347 if (def->imports[i].internal_name
348 && def->imports[i].internal_name != def->imports[i].name)
349 free (def->imports[i].internal_name);
350 if (def->imports[i].name)
351 free (def->imports[i].name);
352 if (def->imports[i].module)
353 free (def->imports[i].module);
361 #ifdef DEF_FILE_PRINT
363 def_file_print (file, def)
368 fprintf (file, ">>>> def_file at 0x%08x\n", def);
370 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
371 if (def->is_dll != -1)
372 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
373 if (def->base_address != (bfd_vma) (-1))
374 fprintf (file, " base address: 0x%08x\n", def->base_address);
375 if (def->description)
376 fprintf (file, " description: `%s'\n", def->description);
377 if (def->stack_reserve != -1)
378 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
379 if (def->stack_commit != -1)
380 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
381 if (def->heap_reserve != -1)
382 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
383 if (def->heap_commit != -1)
384 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
386 if (def->num_section_defs > 0)
388 fprintf (file, " section defs:\n");
389 for (i = 0; i < def->num_section_defs; i++)
391 fprintf (file, " name: `%s', class: `%s', flags:",
392 def->section_defs[i].name, def->section_defs[i].class);
393 if (def->section_defs[i].flag_read)
394 fprintf (file, " R");
395 if (def->section_defs[i].flag_write)
396 fprintf (file, " W");
397 if (def->section_defs[i].flag_execute)
398 fprintf (file, " X");
399 if (def->section_defs[i].flag_shared)
400 fprintf (file, " S");
401 fprintf (file, "\n");
405 if (def->num_exports > 0)
407 fprintf (file, " exports:\n");
408 for (i = 0; i < def->num_exports; i++)
410 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
411 def->exports[i].name, def->exports[i].internal_name,
412 def->exports[i].ordinal);
413 if (def->exports[i].flag_private)
414 fprintf (file, " P");
415 if (def->exports[i].flag_constant)
416 fprintf (file, " C");
417 if (def->exports[i].flag_noname)
418 fprintf (file, " N");
419 if (def->exports[i].flag_data)
420 fprintf (file, " D");
421 fprintf (file, "\n");
425 if (def->num_imports > 0)
427 fprintf (file, " imports:\n");
428 for (i = 0; i < def->num_imports; i++)
430 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
431 def->imports[i].internal_name,
432 def->imports[i].module,
433 def->imports[i].name,
434 def->imports[i].ordinal);
437 if (def->version_major != -1)
438 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
439 fprintf (file, "<<<< def_file at 0x%08x\n", def);
444 def_file_add_export (def, external_name, internal_name, ordinal)
446 const char *external_name;
447 const char *internal_name;
451 if (def->num_exports >= max_exports)
453 max_exports = def->num_exports + 50;
455 def->exports = (def_file_export *) xrealloc (def->exports, max_exports * sizeof (def_file_export));
457 def->exports = (def_file_export *) xmalloc (max_exports * sizeof (def_file_export));
459 e = def->exports + def->num_exports;
460 memset (e, 0, sizeof (def_file_export));
461 if (internal_name && !external_name)
462 external_name = internal_name;
463 if (external_name && !internal_name)
464 internal_name = external_name;
465 e->name = xstrdup (external_name);
466 e->internal_name = xstrdup (internal_name);
467 e->ordinal = ordinal;
473 def_file_add_import (def, name, module, ordinal, internal_name)
478 const char *internal_name;
481 if (def->num_imports >= max_imports)
483 max_imports = def->num_imports + 50;
485 def->imports = (def_file_import *) xrealloc (def->imports, max_imports * sizeof (def_file_import));
487 def->imports = (def_file_import *) xmalloc (max_imports * sizeof (def_file_import));
489 i = def->imports + def->num_imports;
490 memset (i, 0, sizeof (def_file_import));
492 i->name = xstrdup (name);
494 i->module = xstrdup (module);
495 i->ordinal = ordinal;
497 i->internal_name = xstrdup (internal_name);
499 i->internal_name = i->name;
511 { "-heap", HEAPSIZE },
512 { "-stack", STACKSIZE },
513 { "-attr", SECTIONS },
514 { "-export", EXPORTS },
519 def_file_add_directive (my_def, param, len)
524 def_file *save_def = def;
525 const char *pend = param + len;
526 const char *tend = param;
527 unsigned int sh_reserve, sh_commit;
534 while (param < pend && isspace (*param))
536 for (tend = param + 1;
537 tend < pend && !(isspace (tend[-1]) && *tend == '-');
540 for (i = 0; diropts[i].param; i++)
542 int len = strlen (diropts[i].param);
543 if (tend - param >= len
544 && strncmp (param, diropts[i].param, len) == 0
545 && (param[len] == ':' || param[len] == ' '))
547 lex_parse_string_end = tend;
548 lex_parse_string = param + len + 1;
549 lex_forced_token = diropts[i].token;
556 if (!diropts[i].param)
558 /* xgettext:c-format */
559 einfo (_("Warning: .drectve `%.*s' unrecognized\n"),
560 tend - param, param);
562 lex_parse_string = 0;
569 /*****************************************************************************
571 *****************************************************************************/
574 def_name (name, base)
580 def->name = xstrdup (name);
581 def->base_address = base;
586 def_library (name, base)
592 def->name = xstrdup (name);
593 def->base_address = base;
598 def_description (text)
601 int len = def->description ? strlen (def->description) : 0;
602 len += strlen (text) + 1;
603 if (def->description)
605 def->description = (char *) xrealloc (def->description, len);
606 strcat (def->description, text);
610 def->description = (char *) xmalloc (len);
611 strcpy (def->description, text);
616 def_stacksize (reserve, commit)
620 def->stack_reserve = reserve;
621 def->stack_commit = commit;
625 def_heapsize (reserve, commit)
629 def->heap_reserve = reserve;
630 def->heap_commit = commit;
634 def_section (name, attr)
639 if (def->num_section_defs >= max_sections)
641 max_sections = def->num_section_defs + 50;
642 if (def->section_defs)
643 def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import));
645 def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import));
647 s = def->section_defs + def->num_section_defs;
648 memset (s, 0, sizeof (def_file_section));
649 s->name = xstrdup (name);
659 def->num_section_defs++;
663 def_section_alt (name, attr)
668 for (; *attr; attr++)
690 def_section (name, aval);
694 def_exports (external_name, internal_name, ordinal, flags)
695 const char *external_name;
696 const char *internal_name;
700 def_file_export *dfe;
702 if (!internal_name && external_name)
703 internal_name = external_name;
705 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
708 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
710 dfe->flag_noname = 1;
712 dfe->flag_constant = 1;
716 dfe->flag_private = 1;
720 def_import (internal_name, module, dllext, name, ordinal)
721 const char *internal_name;
731 buf = (char *) xmalloc (strlen (module) + strlen (dllext) + 2);
732 sprintf (buf, "%s.%s", module, dllext);
736 def_file_add_import (def, name, module, ordinal, internal_name);
742 def_version (major, minor)
746 def->version_major = major;
747 def->version_minor = minor;
754 struct directive *d = (struct directive *) xmalloc (sizeof (struct directive));
755 d->next = directives;
757 d->name = xstrdup (str);
758 d->len = strlen (str);
765 einfo ("%P: %s:%d: %s\n", def_filename, linenumber, err);
771 /*****************************************************************************
773 *****************************************************************************/
778 /* Never freed, but always reused as needed, so no real leak */
779 static char *buffer = 0;
780 static int buflen = 0;
781 static int bufptr = 0;
787 if (bufptr == buflen)
789 buflen += 50; /* overly reasonable, eh? */
791 buffer = (char *) xrealloc (buffer, buflen + 1);
793 buffer = (char *) xmalloc (buflen + 1);
795 buffer[bufptr++] = c;
796 buffer[bufptr] = 0; /* not optimal, but very convenient */
808 { "CONSTANT", CONSTANT },
810 { "DESCRIPTION", DESCRIPTION },
811 { "DIRECTIVE", DIRECTIVE },
812 { "EXECUTE", EXECUTE },
813 { "EXPORTS", EXPORTS },
814 { "HEAPSIZE", HEAPSIZE },
815 { "IMPORTS", IMPORTS },
816 { "LIBRARY", LIBRARY },
818 { "NONAME", NONAME },
819 { "PRIVATE", PRIVATE },
821 { "SECTIONS", SECTIONS },
822 { "SEGMENTS", SECTIONS },
823 { "SHARED", SHARED },
824 { "STACKSIZE", STACKSIZE },
825 { "VERSION", VERSIONK },
834 if (lex_parse_string)
836 if (lex_parse_string >= lex_parse_string_end)
839 rv = *lex_parse_string++;
843 rv = fgetc (the_file);
854 if (lex_parse_string)
857 return ungetc (c, the_file);
865 if (lex_forced_token)
867 i = lex_forced_token;
868 lex_forced_token = 0;
870 printf ("lex: forcing token %d\n", i);
877 /* trim leading whitespace */
878 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
884 printf ("lex: EOF\n");
889 if (saw_newline && c == ';')
895 while (c != EOF && c != '\n');
900 /* must be something else */
906 while (c != EOF && isxdigit (c) || (c == 'x'))
913 yylval.number = strtoul (buffer, 0, 0);
915 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
920 if (isalpha (c) || strchr ("$:-_?", c))
923 while (c != EOF && isalnum (c) || strchr ("$:-_?/@", c))
930 for (i = 0; tokens[i].name; i++)
931 if (strcmp (tokens[i].name, buffer) == 0)
934 printf ("lex: `%s' is a string token\n", buffer);
936 return tokens[i].token;
939 printf ("lex: `%s' returns ID\n", buffer);
941 yylval.id = xstrdup (buffer);
945 if (c == '\'' || c == '"')
950 while (c != EOF && c != q)
955 yylval.id = xstrdup (buffer);
957 printf ("lex: `%s' returns ID\n", buffer);
962 if (c == '=' || c == '.' || c == '@' || c == ',')
965 printf ("lex: `%c' returns itself\n", c);
976 /*printf ("lex: 0x%02x ignored\n", c); */