1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007
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 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. */
24 #include "libiberty.h"
25 #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 (const char *);
82 static void def_exports (const char *, const char *, int, int);
83 static void def_heapsize (int, int);
84 static void def_import (const char *, const char *, const char *, const char *,
86 static void def_image_name (const char *, int, int);
87 static void def_section (const char *, int);
88 static void def_section_alt (const char *, const char *);
89 static void def_stacksize (int, int);
90 static void def_version (int, int);
91 static void def_directive (char *);
92 static void def_aligncomm (char *str, int align);
93 static int def_parse (void);
94 static int def_error (const char *);
95 static int def_lex (void);
97 static int lex_forced_token = 0;
98 static const char *lex_parse_string = 0;
99 static const char *lex_parse_string_end = 0;
108 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
109 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
110 %token PRIVATEU PRIVATEL ALIGNCOMM
111 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL 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 dot_name
125 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
126 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
127 | DESCRIPTION ID { def_description ($2);}
128 | STACKSIZE_K 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 | DATAU 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);}
138 | ALIGNCOMM ID ',' NUMBER { def_aligncomm ($2, $4);}
149 /* The opt_comma is necessary to support both the usual
150 DEF file syntax as well as .drectve syntax which
151 mandates <expsym>,<expoptlist>. */
152 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
153 { def_exports ($1, $2, $3, $5); }
156 /* The opt_comma is necessary to support both the usual
157 DEF file syntax as well as .drectve syntax which
158 allows for comma separated opt list. */
159 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
164 | NONAMEL { $$ = 1; }
165 | CONSTANTU { $$ = 2; }
166 | CONSTANTL { $$ = 2; }
169 | PRIVATEU { $$ = 8; }
170 | PRIVATEL { $$ = 8; }
178 ID '=' ID '.' ID '.' ID { def_import ($1, $3, $5, $7, -1); }
179 | ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5, 0, $7); }
180 | ID '=' ID '.' ID { def_import ($1, $3, 0, $5, -1); }
181 | ID '=' ID '.' NUMBER { def_import ($1, $3, 0, 0, $5); }
182 | ID '.' ID '.' ID { def_import ( 0, $1, $3, $5, -1); }
183 | ID '.' ID { def_import ( 0, $1, 0, $3, -1); }
192 ID attr_list { def_section ($1, $2);}
193 | ID ID { def_section_alt ($1, $2);}
197 attr_list opt_comma attr { $$ = $1 | $3; }
205 opt_number: ',' NUMBER { $$=$2;}
216 opt_name: ID { $$ = $1; }
219 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
220 sprintf (name, "%s.%s", $1, $3);
227 '@' NUMBER { $$ = $2;}
232 '=' dot_name { $$ = $2; }
236 opt_base: BASE '=' NUMBER { $$ = $3;}
240 dot_name: ID { $$ = $1; }
243 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
244 sprintf (name, "%s.%s", $1, $3);
252 /*****************************************************************************
254 *****************************************************************************/
256 static FILE *the_file;
257 static const char *def_filename;
258 static int linenumber;
259 static def_file *def;
260 static int saw_newline;
264 struct directive *next;
269 static struct directive *directives = 0;
272 def_file_empty (void)
274 def_file *rv = xmalloc (sizeof (def_file));
275 memset (rv, 0, sizeof (def_file));
277 rv->base_address = (bfd_vma) -1;
278 rv->stack_reserve = rv->stack_commit = -1;
279 rv->heap_reserve = rv->heap_commit = -1;
280 rv->version_major = rv->version_minor = -1;
285 def_file_parse (const char *filename, def_file *add_to)
289 the_file = fopen (filename, "r");
290 def_filename = filename;
303 def = def_file_empty ();
316 for (d = directives; d; d = d->next)
319 printf ("Adding directive %08x `%s'\n", d->name, d->name);
321 def_file_add_directive (def, d->name, d->len);
328 def_file_free (def_file *def)
336 if (def->description)
337 free (def->description);
339 if (def->section_defs)
341 for (i = 0; i < def->num_section_defs; i++)
343 if (def->section_defs[i].name)
344 free (def->section_defs[i].name);
345 if (def->section_defs[i].class)
346 free (def->section_defs[i].class);
348 free (def->section_defs);
353 for (i = 0; i < def->num_exports; i++)
355 if (def->exports[i].internal_name
356 && def->exports[i].internal_name != def->exports[i].name)
357 free (def->exports[i].internal_name);
358 if (def->exports[i].name)
359 free (def->exports[i].name);
366 for (i = 0; i < def->num_imports; i++)
368 if (def->imports[i].internal_name
369 && def->imports[i].internal_name != def->imports[i].name)
370 free (def->imports[i].internal_name);
371 if (def->imports[i].name)
372 free (def->imports[i].name);
379 def_file_module *m = def->modules;
380 def->modules = def->modules->next;
384 while (def->aligncomms)
386 def_file_aligncomm *c = def->aligncomms;
387 def->aligncomms = def->aligncomms->next;
388 free (c->symbol_name);
395 #ifdef DEF_FILE_PRINT
397 def_file_print (FILE *file, def_file *def)
401 fprintf (file, ">>>> def_file at 0x%08x\n", def);
403 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
404 if (def->is_dll != -1)
405 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
406 if (def->base_address != (bfd_vma) -1)
407 fprintf (file, " base address: 0x%08x\n", def->base_address);
408 if (def->description)
409 fprintf (file, " description: `%s'\n", def->description);
410 if (def->stack_reserve != -1)
411 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
412 if (def->stack_commit != -1)
413 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
414 if (def->heap_reserve != -1)
415 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
416 if (def->heap_commit != -1)
417 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
419 if (def->num_section_defs > 0)
421 fprintf (file, " section defs:\n");
423 for (i = 0; i < def->num_section_defs; i++)
425 fprintf (file, " name: `%s', class: `%s', flags:",
426 def->section_defs[i].name, def->section_defs[i].class);
427 if (def->section_defs[i].flag_read)
428 fprintf (file, " R");
429 if (def->section_defs[i].flag_write)
430 fprintf (file, " W");
431 if (def->section_defs[i].flag_execute)
432 fprintf (file, " X");
433 if (def->section_defs[i].flag_shared)
434 fprintf (file, " S");
435 fprintf (file, "\n");
439 if (def->num_exports > 0)
441 fprintf (file, " exports:\n");
443 for (i = 0; i < def->num_exports; i++)
445 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
446 def->exports[i].name, def->exports[i].internal_name,
447 def->exports[i].ordinal);
448 if (def->exports[i].flag_private)
449 fprintf (file, " P");
450 if (def->exports[i].flag_constant)
451 fprintf (file, " C");
452 if (def->exports[i].flag_noname)
453 fprintf (file, " N");
454 if (def->exports[i].flag_data)
455 fprintf (file, " D");
456 fprintf (file, "\n");
460 if (def->num_imports > 0)
462 fprintf (file, " imports:\n");
464 for (i = 0; i < def->num_imports; i++)
466 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
467 def->imports[i].internal_name,
468 def->imports[i].module,
469 def->imports[i].name,
470 def->imports[i].ordinal);
474 if (def->version_major != -1)
475 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
477 fprintf (file, "<<<< def_file at 0x%08x\n", def);
482 def_file_add_export (def_file *def,
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 = xrealloc (def->exports,
495 max_exports * sizeof (def_file_export));
497 def->exports = xmalloc (max_exports * sizeof (def_file_export));
499 e = def->exports + def->num_exports;
500 memset (e, 0, sizeof (def_file_export));
501 if (internal_name && !external_name)
502 external_name = internal_name;
503 if (external_name && !internal_name)
504 internal_name = external_name;
505 e->name = xstrdup (external_name);
506 e->internal_name = xstrdup (internal_name);
507 e->ordinal = ordinal;
513 def_get_module (def_file *def, const char *name)
517 for (s = def->modules; s; s = s->next)
518 if (strcmp (s->name, name) == 0)
524 static def_file_module *
525 def_stash_module (def_file *def, const char *name)
529 if ((s = def_get_module (def, name)) != NULL)
531 s = xmalloc (sizeof (def_file_module) + strlen (name));
532 s->next = def->modules;
535 strcpy (s->name, name);
540 def_file_add_import (def_file *def,
544 const char *internal_name)
547 int max_imports = ROUND_UP (def->num_imports, 16);
549 if (def->num_imports >= max_imports)
551 max_imports = ROUND_UP (def->num_imports+1, 16);
554 def->imports = xrealloc (def->imports,
555 max_imports * sizeof (def_file_import));
557 def->imports = xmalloc (max_imports * sizeof (def_file_import));
559 i = def->imports + def->num_imports;
560 memset (i, 0, sizeof (def_file_import));
562 i->name = xstrdup (name);
564 i->module = def_stash_module (def, module);
565 i->ordinal = ordinal;
567 i->internal_name = xstrdup (internal_name);
569 i->internal_name = i->name;
582 { "-heap", HEAPSIZE },
583 { "-stack", STACKSIZE_K },
584 { "-attr", SECTIONS },
585 { "-export", EXPORTS },
586 { "-aligncomm", ALIGNCOMM },
591 def_file_add_directive (def_file *my_def, const char *param, int len)
593 def_file *save_def = def;
594 const char *pend = param + len;
595 char * tend = (char *) param;
603 && (ISSPACE (*param) || *param == '\n' || *param == 0))
609 /* Scan forward until we encounter any of:
610 - the end of the buffer
611 - the start of a new option
612 - a newline seperating options
613 - a NUL seperating options. */
614 for (tend = (char *) (param + 1);
616 && !(ISSPACE (tend[-1]) && *tend == '-')
617 && *tend != '\n' && *tend != 0);
621 for (i = 0; diropts[i].param; i++)
623 int len = strlen (diropts[i].param);
625 if (tend - param >= len
626 && strncmp (param, diropts[i].param, len) == 0
627 && (param[len] == ':' || param[len] == ' '))
629 lex_parse_string_end = tend;
630 lex_parse_string = param + len + 1;
631 lex_forced_token = diropts[i].token;
639 if (!diropts[i].param)
645 /* xgettext:c-format */
646 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
650 lex_parse_string = 0;
657 /* Parser Callbacks. */
660 def_image_name (const char *name, int base, int is_dll)
662 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
663 to do here. We retain the output filename specified on command line. */
666 const char* image_name = lbasename (name);
667 if (image_name != name)
668 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
669 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
673 /* Append the default suffix, if none specified. */
674 if (strchr (image_name, '.') == 0)
676 const char * suffix = is_dll ? ".dll" : ".exe";
678 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
679 sprintf (def->name, "%s%s", image_name, suffix);
682 def->name = xstrdup (image_name);
685 /* Honor a BASE address statement, even if LIBRARY string is empty. */
686 def->base_address = base;
687 def->is_dll = is_dll;
691 def_description (const char *text)
693 int len = def->description ? strlen (def->description) : 0;
695 len += strlen (text) + 1;
696 if (def->description)
698 def->description = xrealloc (def->description, len);
699 strcat (def->description, text);
703 def->description = xmalloc (len);
704 strcpy (def->description, text);
709 def_stacksize (int reserve, int commit)
711 def->stack_reserve = reserve;
712 def->stack_commit = commit;
716 def_heapsize (int reserve, int commit)
718 def->heap_reserve = reserve;
719 def->heap_commit = commit;
723 def_section (const char *name, int attr)
726 int max_sections = ROUND_UP (def->num_section_defs, 4);
728 if (def->num_section_defs >= max_sections)
730 max_sections = ROUND_UP (def->num_section_defs+1, 4);
732 if (def->section_defs)
733 def->section_defs = xrealloc (def->section_defs,
734 max_sections * sizeof (def_file_import));
736 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
738 s = def->section_defs + def->num_section_defs;
739 memset (s, 0, sizeof (def_file_section));
740 s->name = xstrdup (name);
750 def->num_section_defs++;
754 def_section_alt (const char *name, const char *attr)
758 for (; *attr; attr++)
780 def_section (name, aval);
784 def_exports (const char *external_name,
785 const char *internal_name,
789 def_file_export *dfe;
791 if (!internal_name && external_name)
792 internal_name = external_name;
794 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
797 dfe = def_file_add_export (def, external_name, internal_name, ordinal);
799 dfe->flag_noname = 1;
801 dfe->flag_constant = 1;
805 dfe->flag_private = 1;
809 def_import (const char *internal_name,
816 const char *ext = dllext ? dllext : "dll";
818 buf = xmalloc (strlen (module) + strlen (ext) + 2);
819 sprintf (buf, "%s.%s", module, ext);
822 def_file_add_import (def, name, module, ordinal, internal_name);
828 def_version (int major, int minor)
830 def->version_major = major;
831 def->version_minor = minor;
835 def_directive (char *str)
837 struct directive *d = xmalloc (sizeof (struct directive));
839 d->next = directives;
841 d->name = xstrdup (str);
842 d->len = strlen (str);
846 def_aligncomm (char *str, int align)
848 def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
850 c->symbol_name = xstrdup (str);
851 c->alignment = (unsigned int) align;
853 c->next = def->aligncomms;
858 def_error (const char *err)
860 einfo ("%P: %s:%d: %s\n",
861 def_filename ? def_filename : "<unknown-file>", linenumber, err);
866 /* Lexical Scanner. */
871 /* Never freed, but always reused as needed, so no real leak. */
872 static char *buffer = 0;
873 static int buflen = 0;
874 static int bufptr = 0;
879 if (bufptr == buflen)
881 buflen += 50; /* overly reasonable, eh? */
883 buffer = xrealloc (buffer, buflen + 1);
885 buffer = xmalloc (buflen + 1);
887 buffer[bufptr++] = c;
888 buffer[bufptr] = 0; /* not optimal, but very convenient. */
900 { "CONSTANT", CONSTANTU },
901 { "constant", CONSTANTL },
904 { "DESCRIPTION", DESCRIPTION },
905 { "DIRECTIVE", DIRECTIVE },
906 { "EXECUTE", EXECUTE },
907 { "EXPORTS", EXPORTS },
908 { "HEAPSIZE", HEAPSIZE },
909 { "IMPORTS", IMPORTS },
910 { "LIBRARY", LIBRARY },
912 { "NONAME", NONAMEU },
913 { "noname", NONAMEL },
914 { "PRIVATE", PRIVATEU },
915 { "private", PRIVATEL },
917 { "SECTIONS", SECTIONS },
918 { "SEGMENTS", SECTIONS },
919 { "SHARED", SHARED },
920 { "STACKSIZE", STACKSIZE_K },
921 { "VERSION", VERSIONK },
931 if (lex_parse_string)
933 if (lex_parse_string >= lex_parse_string_end)
936 rv = *lex_parse_string++;
940 rv = fgetc (the_file);
950 if (lex_parse_string)
956 return ungetc (c, the_file);
964 if (lex_forced_token)
966 i = lex_forced_token;
967 lex_forced_token = 0;
969 printf ("lex: forcing token %d\n", i);
976 /* Trim leading whitespace. */
977 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
983 printf ("lex: EOF\n");
988 if (saw_newline && c == ';')
994 while (c != EOF && c != '\n');
1000 /* Must be something else. */
1006 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1013 yylval.number = strtoul (buffer, 0, 0);
1015 printf ("lex: `%s' returns NUMBER %d\n", buffer, yylval.number);
1020 if (ISALPHA (c) || strchr ("$:-_?@", c))
1029 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1031 else if (ISDIGIT (c)) /* '@' followed by digit. */
1037 printf ("lex: @ returns itself\n");
1041 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
1048 if (ISALPHA (q)) /* Check for tokens. */
1050 for (i = 0; tokens[i].name; i++)
1051 if (strcmp (tokens[i].name, buffer) == 0)
1054 printf ("lex: `%s' is a string token\n", buffer);
1056 return tokens[i].token;
1060 printf ("lex: `%s' returns ID\n", buffer);
1062 yylval.id = xstrdup (buffer);
1066 if (c == '\'' || c == '"')
1072 while (c != EOF && c != q)
1077 yylval.id = xstrdup (buffer);
1079 printf ("lex: `%s' returns ID\n", buffer);
1084 if (c == '=' || c == '.' || c == ',')
1087 printf ("lex: `%c' returns itself\n", c);
1098 /*printf ("lex: 0x%02x ignored\n", c); */