1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 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 2 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "libiberty.h"
24 #include "safe-ctype.h"
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
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
56 #define yyexca def_exca
57 #define yyerrflag def_errflag
58 #define yynerrs def_nerrs
62 #define yy_yys def_yys
63 #define yystate def_state
66 #define yy_yyv def_yyv
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 static void def_description PARAMS ((const char *));
82 static void def_exports PARAMS ((const char *, const char *, int, int));
83 static void def_heapsize PARAMS ((int, int));
84 static void def_import PARAMS ((const char *, const char *, const char *, const char *, int));
85 static void def_library PARAMS ((const char *, int));
86 static def_file_module *def_stash_module PARAMS ((def_file *, const char *));
87 static void def_name PARAMS ((const char *, int));
88 static void def_section PARAMS ((const char *, int));
89 static void def_section_alt PARAMS ((const char *, const char *));
90 static void def_stacksize PARAMS ((int, int));
91 static void def_version PARAMS ((int, int));
92 static void def_directive PARAMS ((char *));
93 static int def_parse PARAMS ((void));
94 static int def_error PARAMS ((const char *));
95 static void put_buf PARAMS ((char));
96 static int def_getc PARAMS ((void));
97 static int def_ungetc PARAMS ((int));
98 static int def_lex PARAMS ((void));
100 static int lex_forced_token = 0;
101 static const char *lex_parse_string = 0;
102 static const char *lex_parse_string_end = 0;
111 %token NAME, LIBRARY, DESCRIPTION, STACKSIZE, HEAPSIZE, CODE, DATAU, DATAL
112 %token SECTIONS, EXPORTS, IMPORTS, VERSIONK, BASE, CONSTANTU, CONSTANTL
113 %token PRIVATEU, PRIVATEL
114 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
116 %token <number> NUMBER
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
128 NAME opt_name opt_base { def_name ($2, $3); }
129 | LIBRARY opt_name opt_base { def_library ($2, $3); }
130 | DESCRIPTION ID { def_description ($2);}
131 | STACKSIZE NUMBER opt_number { def_stacksize ($2, $3);}
132 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
133 | CODE attr_list { def_section ("CODE", $2);}
134 | DATAU attr_list { def_section ("DATA", $2);}
138 | VERSIONK NUMBER { def_version ($2, 0);}
139 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
140 | DIRECTIVE ID { def_directive ($2);}
151 /* The opt_comma is necessary to support both the usual
152 DEF file syntax as well as .drectve syntax which
153 mandates <expsym>,<expoptlist>. */
154 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
155 { def_exports ($1, $2, $3, $5); }
158 /* The opt_comma is necessary to support both the usual
159 DEF file syntax as well as .drectve syntax which
160 allows for comma separated opt list. */
161 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
166 | NONAMEL { $$ = 1; }
167 | CONSTANTU { $$ = 2; }
168 | CONSTANTL { $$ = 2; }
171 | PRIVATEU { $$ = 8; }
172 | PRIVATEL { $$ = 8; }
180 ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
181 | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
182 | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
183 | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
184 | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
185 | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
194 ID attr_list { def_section ($1, $2);}
195 | ID ID { def_section_alt ($1, $2);}
199 attr_list opt_comma attr { $$ = $1 | $3; }
207 opt_number: ',' NUMBER { $$=$2;}
218 opt_name: ID { $$ = $1; }
221 char * name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
222 sprintf (name, "%s.%s", $1, $3);
229 '@' NUMBER { $$ = $2;}
234 '=' dot_name { $$ = $2; }
238 opt_base: BASE '=' NUMBER { $$ = $3;}
242 dot_name: ID { $$ = $1; }
245 char * name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
246 sprintf (name, "%s.%s", $1, $3);
254 /*****************************************************************************
256 *****************************************************************************/
258 static FILE *the_file;
259 static const char *def_filename;
260 static int linenumber;
261 static def_file *def;
262 static int saw_newline;
266 struct directive *next;
271 static struct directive *directives = 0;
276 def_file *rv = (def_file *) xmalloc (sizeof (def_file));
277 memset (rv, 0, sizeof (def_file));
279 rv->base_address = (bfd_vma) (-1);
280 rv->stack_reserve = rv->stack_commit = -1;
281 rv->heap_reserve = rv->heap_commit = -1;
282 rv->version_major = rv->version_minor = -1;
287 def_file_parse (filename, add_to)
288 const char *filename;
293 the_file = fopen (filename, "r");
294 def_filename = filename;
307 def = def_file_empty ();
320 for (d = directives; d; d = d->next)
323 printf ("Adding directive %08x `%s'\n", d->name, d->name);
325 def_file_add_directive (def, d->name, d->len);
341 if (def->description)
342 free (def->description);
344 if (def->section_defs)
346 for (i = 0; i < def->num_section_defs; i++)
348 if (def->section_defs[i].name)
349 free (def->section_defs[i].name);
350 if (def->section_defs[i].class)
351 free (def->section_defs[i].class);
353 free (def->section_defs);
358 for (i = 0; i < def->num_exports; i++)
360 if (def->exports[i].internal_name
361 && def->exports[i].internal_name != def->exports[i].name)
362 free (def->exports[i].internal_name);
363 if (def->exports[i].name)
364 free (def->exports[i].name);
371 for (i = 0; i < def->num_imports; i++)
373 if (def->imports[i].internal_name
374 && def->imports[i].internal_name != def->imports[i].name)
375 free (def->imports[i].internal_name);
376 if (def->imports[i].name)
377 free (def->imports[i].name);
384 def_file_module *m = def->modules;
385 def->modules = def->modules->next;
392 #ifdef DEF_FILE_PRINT
394 def_file_print (file, def)
400 fprintf (file, ">>>> def_file at 0x%08x\n", def);
402 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
403 if (def->is_dll != -1)
404 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
405 if (def->base_address != (bfd_vma) (-1))
406 fprintf (file, " base address: 0x%08x\n", def->base_address);
407 if (def->description)
408 fprintf (file, " description: `%s'\n", def->description);
409 if (def->stack_reserve != -1)
410 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
411 if (def->stack_commit != -1)
412 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
413 if (def->heap_reserve != -1)
414 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
415 if (def->heap_commit != -1)
416 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
418 if (def->num_section_defs > 0)
420 fprintf (file, " section defs:\n");
422 for (i = 0; i < def->num_section_defs; i++)
424 fprintf (file, " name: `%s', class: `%s', flags:",
425 def->section_defs[i].name, def->section_defs[i].class);
426 if (def->section_defs[i].flag_read)
427 fprintf (file, " R");
428 if (def->section_defs[i].flag_write)
429 fprintf (file, " W");
430 if (def->section_defs[i].flag_execute)
431 fprintf (file, " X");
432 if (def->section_defs[i].flag_shared)
433 fprintf (file, " S");
434 fprintf (file, "\n");
438 if (def->num_exports > 0)
440 fprintf (file, " exports:\n");
442 for (i = 0; i < def->num_exports; i++)
444 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
445 def->exports[i].name, def->exports[i].internal_name,
446 def->exports[i].ordinal);
447 if (def->exports[i].flag_private)
448 fprintf (file, " P");
449 if (def->exports[i].flag_constant)
450 fprintf (file, " C");
451 if (def->exports[i].flag_noname)
452 fprintf (file, " N");
453 if (def->exports[i].flag_data)
454 fprintf (file, " D");
455 fprintf (file, "\n");
459 if (def->num_imports > 0)
461 fprintf (file, " imports:\n");
463 for (i = 0; i < def->num_imports; i++)
465 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
466 def->imports[i].internal_name,
467 def->imports[i].module,
468 def->imports[i].name,
469 def->imports[i].ordinal);
473 if (def->version_major != -1)
474 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
476 fprintf (file, "<<<< def_file at 0x%08x\n", def);
481 def_file_add_export (def, external_name, internal_name, ordinal)
483 const char *external_name;
484 const char *internal_name;
488 int max_exports = ROUND_UP(def->num_exports, 32);
490 if (def->num_exports >= max_exports)
492 max_exports = ROUND_UP(def->num_exports + 1, 32);
494 def->exports = (def_file_export *)
495 xrealloc (def->exports, max_exports * sizeof (def_file_export));
497 def->exports = (def_file_export *)
498 xmalloc (max_exports * sizeof (def_file_export));
500 e = def->exports + def->num_exports;
501 memset (e, 0, sizeof (def_file_export));
502 if (internal_name && !external_name)
503 external_name = internal_name;
504 if (external_name && !internal_name)
505 internal_name = external_name;
506 e->name = xstrdup (external_name);
507 e->internal_name = xstrdup (internal_name);
508 e->ordinal = ordinal;
514 def_get_module (def, name)
520 for (s = def->modules; s; s = s->next)
521 if (strcmp (s->name, name) == 0)
524 return (def_file_module *) 0;
527 static def_file_module *
528 def_stash_module (def, name)
534 if ((s = def_get_module (def, name)) != (def_file_module *) 0)
536 s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name));
537 s->next = def->modules;
540 strcpy (s->name, name);
545 def_file_add_import (def, name, module, ordinal, internal_name)
550 const char *internal_name;
553 int max_imports = ROUND_UP(def->num_imports, 16);
555 if (def->num_imports >= max_imports)
557 max_imports = ROUND_UP(def->num_imports+1, 16);
560 def->imports = (def_file_import *)
561 xrealloc (def->imports, max_imports * sizeof (def_file_import));
563 def->imports = (def_file_import *)
564 xmalloc (max_imports * sizeof (def_file_import));
566 i = def->imports + def->num_imports;
567 memset (i, 0, sizeof (def_file_import));
569 i->name = xstrdup (name);
571 i->module = def_stash_module (def, module);
572 i->ordinal = ordinal;
574 i->internal_name = xstrdup (internal_name);
576 i->internal_name = i->name;
589 { "-heap", HEAPSIZE },
590 { "-stack", STACKSIZE },
591 { "-attr", SECTIONS },
592 { "-export", EXPORTS },
597 def_file_add_directive (my_def, param, len)
602 def_file *save_def = def;
603 const char *pend = param + len;
604 char * tend = (char *) param;
611 while (param < pend && (ISSPACE (*param) || * param == '\n' || * param == 0))
617 /* Scan forward until we encounter any of:
618 - the end of the buffer
619 - the start of a new option
620 - a newline seperating options
621 - a NUL seperating options. */
622 for (tend = (char *) (param + 1);
623 tend < pend && !(ISSPACE (tend[-1]) && *tend == '-') && (*tend != '\n') && (*tend != 0);
627 for (i = 0; diropts[i].param; i++)
629 int len = strlen (diropts[i].param);
631 if (tend - param >= len
632 && strncmp (param, diropts[i].param, len) == 0
633 && (param[len] == ':' || param[len] == ' '))
635 lex_parse_string_end = tend;
636 lex_parse_string = param + len + 1;
637 lex_forced_token = diropts[i].token;
645 if (!diropts[i].param)
651 /* xgettext:c-format */
652 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
656 lex_parse_string = 0;
663 /* Parser Callbacks. */
666 def_name (name, base)
672 def->name = xstrdup (name);
673 def->base_address = base;
678 def_library (name, base)
684 def->name = xstrdup (name);
685 def->base_address = base;
690 def_description (text)
693 int len = def->description ? strlen (def->description) : 0;
695 len += strlen (text) + 1;
696 if (def->description)
698 def->description = (char *) xrealloc (def->description, len);
699 strcat (def->description, text);
703 def->description = (char *) xmalloc (len);
704 strcpy (def->description, text);
709 def_stacksize (reserve, commit)
713 def->stack_reserve = reserve;
714 def->stack_commit = commit;
718 def_heapsize (reserve, commit)
722 def->heap_reserve = reserve;
723 def->heap_commit = commit;
727 def_section (name, attr)
732 int max_sections = ROUND_UP(def->num_section_defs, 4);
734 if (def->num_section_defs >= max_sections)
736 max_sections = ROUND_UP(def->num_section_defs+1, 4);
738 if (def->section_defs)
739 def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import));
741 def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import));
743 s = def->section_defs + def->num_section_defs;
744 memset (s, 0, sizeof (def_file_section));
745 s->name = xstrdup (name);
755 def->num_section_defs++;
759 def_section_alt (name, attr)
765 for (; *attr; attr++)
787 def_section (name, aval);
791 def_exports (external_name, internal_name, ordinal, flags)
792 const char *external_name;
793 const char *internal_name;
797 def_file_export *dfe;
799 if (!internal_name && external_name)
800 internal_name = external_name;
802 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
805 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
807 dfe->flag_noname = 1;
809 dfe->flag_constant = 1;
813 dfe->flag_private = 1;
817 def_import (internal_name, module, dllext, name, ordinal)
818 const char *internal_name;
825 const char *ext = dllext ? dllext : "dll";
827 buf = (char *) xmalloc (strlen (module) + strlen (ext) + 2);
828 sprintf (buf, "%s.%s", module, ext);
831 def_file_add_import (def, name, module, ordinal, internal_name);
837 def_version (major, minor)
841 def->version_major = major;
842 def->version_minor = minor;
849 struct directive *d = (struct directive *) xmalloc (sizeof (struct directive));
851 d->next = directives;
853 d->name = xstrdup (str);
854 d->len = strlen (str);
861 einfo ("%P: %s:%d: %s\n", def_filename ? def_filename : "<unknown-file>", linenumber, err);
867 /* Lexical Scanner. */
872 /* Never freed, but always reused as needed, so no real leak. */
873 static char *buffer = 0;
874 static int buflen = 0;
875 static int bufptr = 0;
881 if (bufptr == buflen)
883 buflen += 50; /* overly reasonable, eh? */
885 buffer = (char *) xrealloc (buffer, buflen + 1);
887 buffer = (char *) xmalloc (buflen + 1);
889 buffer[bufptr++] = c;
890 buffer[bufptr] = 0; /* not optimal, but very convenient. */
902 { "CONSTANT", CONSTANTU },
903 { "constant", CONSTANTL },
906 { "DESCRIPTION", DESCRIPTION },
907 { "DIRECTIVE", DIRECTIVE },
908 { "EXECUTE", EXECUTE },
909 { "EXPORTS", EXPORTS },
910 { "HEAPSIZE", HEAPSIZE },
911 { "IMPORTS", IMPORTS },
912 { "LIBRARY", LIBRARY },
914 { "NONAME", NONAMEU },
915 { "noname", NONAMEL },
916 { "PRIVATE", PRIVATEU },
917 { "private", PRIVATEL },
919 { "SECTIONS", SECTIONS },
920 { "SEGMENTS", SECTIONS },
921 { "SHARED", SHARED },
922 { "STACKSIZE", STACKSIZE },
923 { "VERSION", VERSIONK },
933 if (lex_parse_string)
935 if (lex_parse_string >= lex_parse_string_end)
938 rv = *lex_parse_string++;
942 rv = fgetc (the_file);
953 if (lex_parse_string)
959 return ungetc (c, the_file);
967 if (lex_forced_token)
969 i = lex_forced_token;
970 lex_forced_token = 0;
972 printf ("lex: forcing token %d\n", i);
979 /* Trim leading whitespace. */
980 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
986 printf ("lex: EOF\n");
991 if (saw_newline && c == ';')
997 while (c != EOF && c != '\n');
1003 /* Must be something else. */
1009 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1016 yylval.number = strtoul (buffer, 0, 0);
1018 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
1023 if (ISALPHA (c) || strchr ("$:-_?@", c))
1032 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1034 else if (ISDIGIT (c)) /* '@' followed by digit. */
1040 printf ("lex: @ returns itself\n");
1044 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
1051 if (ISALPHA (q)) /* Check for tokens. */
1053 for (i = 0; tokens[i].name; i++)
1054 if (strcmp (tokens[i].name, buffer) == 0)
1057 printf ("lex: `%s' is a string token\n", buffer);
1059 return tokens[i].token;
1063 printf ("lex: `%s' returns ID\n", buffer);
1065 yylval.id = xstrdup (buffer);
1069 if (c == '\'' || c == '"')
1075 while (c != EOF && c != q)
1080 yylval.id = xstrdup (buffer);
1082 printf ("lex: `%s' returns ID\n", buffer);
1087 if (c == '=' || c == '.' || c == ',')
1090 printf ("lex: `%c' returns itself\n", c);
1101 /*printf ("lex: 0x%02x ignored\n", c); */