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
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 ID 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;}
238 opt_base: BASE '=' NUMBER { $$ = $3;}
246 /*****************************************************************************
248 *****************************************************************************/
250 static FILE *the_file;
251 static const char *def_filename;
252 static int linenumber;
253 static def_file *def;
254 static int saw_newline;
258 struct directive *next;
263 static struct directive *directives = 0;
268 def_file *rv = (def_file *) xmalloc (sizeof (def_file));
269 memset (rv, 0, sizeof (def_file));
271 rv->base_address = (bfd_vma) (-1);
272 rv->stack_reserve = rv->stack_commit = -1;
273 rv->heap_reserve = rv->heap_commit = -1;
274 rv->version_major = rv->version_minor = -1;
279 def_file_parse (filename, add_to)
280 const char *filename;
285 the_file = fopen (filename, "r");
286 def_filename = filename;
299 def = def_file_empty ();
312 for (d = directives; d; d = d->next)
315 printf ("Adding directive %08x `%s'\n", d->name, d->name);
317 def_file_add_directive (def, d->name, d->len);
333 if (def->description)
334 free (def->description);
336 if (def->section_defs)
338 for (i = 0; i < def->num_section_defs; i++)
340 if (def->section_defs[i].name)
341 free (def->section_defs[i].name);
342 if (def->section_defs[i].class)
343 free (def->section_defs[i].class);
345 free (def->section_defs);
350 for (i = 0; i < def->num_exports; i++)
352 if (def->exports[i].internal_name
353 && def->exports[i].internal_name != def->exports[i].name)
354 free (def->exports[i].internal_name);
355 if (def->exports[i].name)
356 free (def->exports[i].name);
363 for (i = 0; i < def->num_imports; i++)
365 if (def->imports[i].internal_name
366 && def->imports[i].internal_name != def->imports[i].name)
367 free (def->imports[i].internal_name);
368 if (def->imports[i].name)
369 free (def->imports[i].name);
376 def_file_module *m = def->modules;
377 def->modules = def->modules->next;
384 #ifdef DEF_FILE_PRINT
386 def_file_print (file, def)
392 fprintf (file, ">>>> def_file at 0x%08x\n", def);
394 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
395 if (def->is_dll != -1)
396 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
397 if (def->base_address != (bfd_vma) (-1))
398 fprintf (file, " base address: 0x%08x\n", def->base_address);
399 if (def->description)
400 fprintf (file, " description: `%s'\n", def->description);
401 if (def->stack_reserve != -1)
402 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
403 if (def->stack_commit != -1)
404 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
405 if (def->heap_reserve != -1)
406 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
407 if (def->heap_commit != -1)
408 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
410 if (def->num_section_defs > 0)
412 fprintf (file, " section defs:\n");
414 for (i = 0; i < def->num_section_defs; i++)
416 fprintf (file, " name: `%s', class: `%s', flags:",
417 def->section_defs[i].name, def->section_defs[i].class);
418 if (def->section_defs[i].flag_read)
419 fprintf (file, " R");
420 if (def->section_defs[i].flag_write)
421 fprintf (file, " W");
422 if (def->section_defs[i].flag_execute)
423 fprintf (file, " X");
424 if (def->section_defs[i].flag_shared)
425 fprintf (file, " S");
426 fprintf (file, "\n");
430 if (def->num_exports > 0)
432 fprintf (file, " exports:\n");
434 for (i = 0; i < def->num_exports; i++)
436 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
437 def->exports[i].name, def->exports[i].internal_name,
438 def->exports[i].ordinal);
439 if (def->exports[i].flag_private)
440 fprintf (file, " P");
441 if (def->exports[i].flag_constant)
442 fprintf (file, " C");
443 if (def->exports[i].flag_noname)
444 fprintf (file, " N");
445 if (def->exports[i].flag_data)
446 fprintf (file, " D");
447 fprintf (file, "\n");
451 if (def->num_imports > 0)
453 fprintf (file, " imports:\n");
455 for (i = 0; i < def->num_imports; i++)
457 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
458 def->imports[i].internal_name,
459 def->imports[i].module,
460 def->imports[i].name,
461 def->imports[i].ordinal);
465 if (def->version_major != -1)
466 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
468 fprintf (file, "<<<< def_file at 0x%08x\n", def);
473 def_file_add_export (def, external_name, internal_name, ordinal)
475 const char *external_name;
476 const char *internal_name;
480 int max_exports = ROUND_UP(def->num_exports, 32);
482 if (def->num_exports >= max_exports)
484 max_exports = ROUND_UP(def->num_exports + 1, 32);
486 def->exports = (def_file_export *)
487 xrealloc (def->exports, max_exports * sizeof (def_file_export));
489 def->exports = (def_file_export *)
490 xmalloc (max_exports * sizeof (def_file_export));
492 e = def->exports + def->num_exports;
493 memset (e, 0, sizeof (def_file_export));
494 if (internal_name && !external_name)
495 external_name = internal_name;
496 if (external_name && !internal_name)
497 internal_name = external_name;
498 e->name = xstrdup (external_name);
499 e->internal_name = xstrdup (internal_name);
500 e->ordinal = ordinal;
506 def_get_module (def, name)
512 for (s = def->modules; s; s = s->next)
513 if (strcmp (s->name, name) == 0)
516 return (def_file_module *) 0;
519 static def_file_module *
520 def_stash_module (def, name)
526 if ((s = def_get_module (def, name)) != (def_file_module *) 0)
528 s = (def_file_module *) xmalloc (sizeof (def_file_module) + strlen (name));
529 s->next = def->modules;
532 strcpy (s->name, name);
537 def_file_add_import (def, name, module, ordinal, internal_name)
542 const char *internal_name;
545 int max_imports = ROUND_UP(def->num_imports, 16);
547 if (def->num_imports >= max_imports)
549 max_imports = ROUND_UP(def->num_imports+1, 16);
552 def->imports = (def_file_import *)
553 xrealloc (def->imports, max_imports * sizeof (def_file_import));
555 def->imports = (def_file_import *)
556 xmalloc (max_imports * sizeof (def_file_import));
558 i = def->imports + def->num_imports;
559 memset (i, 0, sizeof (def_file_import));
561 i->name = xstrdup (name);
563 i->module = def_stash_module (def, module);
564 i->ordinal = ordinal;
566 i->internal_name = xstrdup (internal_name);
568 i->internal_name = i->name;
581 { "-heap", HEAPSIZE },
582 { "-stack", STACKSIZE },
583 { "-attr", SECTIONS },
584 { "-export", EXPORTS },
589 def_file_add_directive (my_def, param, len)
594 def_file *save_def = def;
595 const char *pend = param + len;
596 const char *tend = param;
603 while (param < pend && ISSPACE (*param))
606 for (tend = param + 1;
607 tend < pend && !(ISSPACE (tend[-1]) && *tend == '-');
611 for (i = 0; diropts[i].param; i++)
613 int len = strlen (diropts[i].param);
615 if (tend - param >= len
616 && strncmp (param, diropts[i].param, len) == 0
617 && (param[len] == ':' || param[len] == ' '))
619 lex_parse_string_end = tend;
620 lex_parse_string = param + len + 1;
621 lex_forced_token = diropts[i].token;
628 if (!diropts[i].param)
629 /* xgettext:c-format */
630 einfo (_("Warning: .drectve `%.*s' unrecognized\n"),
631 tend - param, param);
633 lex_parse_string = 0;
640 /* Parser Callbacks. */
643 def_name (name, base)
649 def->name = xstrdup (name);
650 def->base_address = base;
655 def_library (name, base)
661 def->name = xstrdup (name);
662 def->base_address = base;
667 def_description (text)
670 int len = def->description ? strlen (def->description) : 0;
672 len += strlen (text) + 1;
673 if (def->description)
675 def->description = (char *) xrealloc (def->description, len);
676 strcat (def->description, text);
680 def->description = (char *) xmalloc (len);
681 strcpy (def->description, text);
686 def_stacksize (reserve, commit)
690 def->stack_reserve = reserve;
691 def->stack_commit = commit;
695 def_heapsize (reserve, commit)
699 def->heap_reserve = reserve;
700 def->heap_commit = commit;
704 def_section (name, attr)
709 int max_sections = ROUND_UP(def->num_section_defs, 4);
711 if (def->num_section_defs >= max_sections)
713 max_sections = ROUND_UP(def->num_section_defs+1, 4);
715 if (def->section_defs)
716 def->section_defs = (def_file_section *) xrealloc (def->section_defs, max_sections * sizeof (def_file_import));
718 def->section_defs = (def_file_section *) xmalloc (max_sections * sizeof (def_file_import));
720 s = def->section_defs + def->num_section_defs;
721 memset (s, 0, sizeof (def_file_section));
722 s->name = xstrdup (name);
732 def->num_section_defs++;
736 def_section_alt (name, attr)
742 for (; *attr; attr++)
764 def_section (name, aval);
768 def_exports (external_name, internal_name, ordinal, flags)
769 const char *external_name;
770 const char *internal_name;
774 def_file_export *dfe;
776 if (!internal_name && external_name)
777 internal_name = external_name;
779 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
782 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
784 dfe->flag_noname = 1;
786 dfe->flag_constant = 1;
790 dfe->flag_private = 1;
794 def_import (internal_name, module, dllext, name, ordinal)
795 const char *internal_name;
805 buf = (char *) xmalloc (strlen (module) + strlen (dllext) + 2);
806 sprintf (buf, "%s.%s", module, dllext);
810 def_file_add_import (def, name, module, ordinal, internal_name);
816 def_version (major, minor)
820 def->version_major = major;
821 def->version_minor = minor;
828 struct directive *d = (struct directive *) xmalloc (sizeof (struct directive));
830 d->next = directives;
832 d->name = xstrdup (str);
833 d->len = strlen (str);
840 einfo ("%P: %s:%d: %s\n", def_filename, linenumber, err);
846 /* Lexical Scanner. */
851 /* Never freed, but always reused as needed, so no real leak. */
852 static char *buffer = 0;
853 static int buflen = 0;
854 static int bufptr = 0;
860 if (bufptr == buflen)
862 buflen += 50; /* overly reasonable, eh? */
864 buffer = (char *) xrealloc (buffer, buflen + 1);
866 buffer = (char *) xmalloc (buflen + 1);
868 buffer[bufptr++] = c;
869 buffer[bufptr] = 0; /* not optimal, but very convenient. */
881 { "CONSTANT", CONSTANTU },
882 { "constant", CONSTANTL },
885 { "DESCRIPTION", DESCRIPTION },
886 { "DIRECTIVE", DIRECTIVE },
887 { "EXECUTE", EXECUTE },
888 { "EXPORTS", EXPORTS },
889 { "HEAPSIZE", HEAPSIZE },
890 { "IMPORTS", IMPORTS },
891 { "LIBRARY", LIBRARY },
893 { "NONAME", NONAMEU },
894 { "noname", NONAMEL },
895 { "PRIVATE", PRIVATEU },
896 { "private", PRIVATEL },
898 { "SECTIONS", SECTIONS },
899 { "SEGMENTS", SECTIONS },
900 { "SHARED", SHARED },
901 { "STACKSIZE", STACKSIZE },
902 { "VERSION", VERSIONK },
912 if (lex_parse_string)
914 if (lex_parse_string >= lex_parse_string_end)
917 rv = *lex_parse_string++;
921 rv = fgetc (the_file);
932 if (lex_parse_string)
938 return ungetc (c, the_file);
946 if (lex_forced_token)
948 i = lex_forced_token;
949 lex_forced_token = 0;
951 printf ("lex: forcing token %d\n", i);
958 /* Trim leading whitespace. */
959 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
965 printf ("lex: EOF\n");
970 if (saw_newline && c == ';')
976 while (c != EOF && c != '\n');
982 /* Must be something else. */
988 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
995 yylval.number = strtoul (buffer, 0, 0);
997 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
1002 if (ISALPHA (c) || strchr ("$:-_?@", c))
1011 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1013 else if (ISDIGIT (c)) /* '@' followed by digit. */
1019 printf ("lex: @ returns itself\n");
1023 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
1030 if (ISALPHA (q)) /* Check for tokens. */
1032 for (i = 0; tokens[i].name; i++)
1033 if (strcmp (tokens[i].name, buffer) == 0)
1036 printf ("lex: `%s' is a string token\n", buffer);
1038 return tokens[i].token;
1042 printf ("lex: `%s' returns ID\n", buffer);
1044 yylval.id = xstrdup (buffer);
1048 if (c == '\'' || c == '"')
1054 while (c != EOF && c != q)
1059 yylval.id = xstrdup (buffer);
1061 printf ("lex: `%s' returns ID\n", buffer);
1066 if (c == '=' || c == '.' || c == ',')
1069 printf ("lex: `%c' returns itself\n", c);
1080 /*printf ("lex: 0x%02x ignored\n", c); */