1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 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, const char *);
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;
109 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
110 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
111 %token PRIVATEU PRIVATEL ALIGNCOMM
112 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
114 %token <digits> DIGITS
115 %type <number> NUMBER
116 %type <digits> opt_digits
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 anylang_id opt_id
120 %type <id> opt_equalequal_name
129 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
130 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
131 | DESCRIPTION ID { def_description ($2);}
132 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
133 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
134 | CODE attr_list { def_section ("CODE", $2);}
135 | DATAU attr_list { def_section ("DATA", $2);}
139 | VERSIONK NUMBER { def_version ($2, 0);}
140 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
141 | DIRECTIVE ID { def_directive ($2);}
142 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
153 /* The opt_comma is necessary to support both the usual
154 DEF file syntax as well as .drectve syntax which
155 mandates <expsym>,<expoptlist>. */
156 dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
157 { def_exports ($1, $2, $3, $5, $7); }
160 /* The opt_comma is necessary to support both the usual
161 DEF file syntax as well as .drectve syntax which
162 allows for comma separated opt list. */
163 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
168 | NONAMEL { $$ = 1; }
169 | CONSTANTU { $$ = 2; }
170 | CONSTANTL { $$ = 2; }
173 | PRIVATEU { $$ = 8; }
174 | PRIVATEL { $$ = 8; }
182 ID '=' ID '.' ID '.' ID opt_equalequal_name
183 { def_import ($1, $3, $5, $7, -1, $8); }
184 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
185 { def_import ($1, $3, $5, 0, $7, $8); }
186 | ID '=' ID '.' ID opt_equalequal_name
187 { def_import ($1, $3, 0, $5, -1, $6); }
188 | ID '=' ID '.' NUMBER opt_equalequal_name
189 { def_import ($1, $3, 0, 0, $5, $6); }
190 | ID '.' ID '.' ID opt_equalequal_name
191 { def_import( 0, $1, $3, $5, -1, $6); }
192 | ID '.' ID opt_equalequal_name
193 { def_import ( 0, $1, 0, $3, -1, $4); }
202 ID attr_list { def_section ($1, $2);}
203 | ID ID { def_section_alt ($1, $2);}
207 attr_list opt_comma attr { $$ = $1 | $3; }
215 opt_number: ',' NUMBER { $$=$2;}
226 opt_name: ID { $$ = $1; }
229 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
230 sprintf (name, "%s.%s", $1, $3);
236 opt_equalequal_name: EQUAL ID { $$ = $2; }
241 '@' NUMBER { $$ = $2;}
246 '=' dot_name { $$ = $2; }
250 opt_base: BASE '=' NUMBER { $$ = $3;}
254 dot_name: ID { $$ = $1; }
257 char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
258 sprintf (name, "%s.%s", $1, $3);
263 anylang_id: ID { $$ = $1; }
264 | anylang_id '.' opt_digits opt_id
266 char *id = xmalloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
267 sprintf (id, "%s.%s%s", $1, $3, $4);
272 opt_digits: DIGITS { $$ = $1; }
276 opt_id: ID { $$ = $1; }
280 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
284 /*****************************************************************************
286 *****************************************************************************/
288 static FILE *the_file;
289 static const char *def_filename;
290 static int linenumber;
291 static def_file *def;
292 static int saw_newline;
296 struct directive *next;
301 static struct directive *directives = 0;
304 def_file_empty (void)
306 def_file *rv = xmalloc (sizeof (def_file));
307 memset (rv, 0, sizeof (def_file));
309 rv->base_address = (bfd_vma) -1;
310 rv->stack_reserve = rv->stack_commit = -1;
311 rv->heap_reserve = rv->heap_commit = -1;
312 rv->version_major = rv->version_minor = -1;
317 def_file_parse (const char *filename, def_file *add_to)
321 the_file = fopen (filename, "r");
322 def_filename = filename;
335 def = def_file_empty ();
348 for (d = directives; d; d = d->next)
351 printf ("Adding directive %08x `%s'\n", d->name, d->name);
353 def_file_add_directive (def, d->name, d->len);
360 def_file_free (def_file *def)
368 if (def->description)
369 free (def->description);
371 if (def->section_defs)
373 for (i = 0; i < def->num_section_defs; i++)
375 if (def->section_defs[i].name)
376 free (def->section_defs[i].name);
377 if (def->section_defs[i].class)
378 free (def->section_defs[i].class);
380 free (def->section_defs);
385 for (i = 0; i < def->num_exports; i++)
387 if (def->exports[i].internal_name
388 && def->exports[i].internal_name != def->exports[i].name)
389 free (def->exports[i].internal_name);
390 if (def->exports[i].name)
391 free (def->exports[i].name);
392 if (def->exports[i].its_name)
393 free (def->exports[i].its_name);
400 for (i = 0; i < def->num_imports; i++)
402 if (def->imports[i].internal_name
403 && def->imports[i].internal_name != def->imports[i].name)
404 free (def->imports[i].internal_name);
405 if (def->imports[i].name)
406 free (def->imports[i].name);
407 if (def->imports[i].its_name)
408 free (def->imports[i].its_name);
415 def_file_module *m = def->modules;
416 def->modules = def->modules->next;
420 while (def->aligncomms)
422 def_file_aligncomm *c = def->aligncomms;
423 def->aligncomms = def->aligncomms->next;
424 free (c->symbol_name);
431 #ifdef DEF_FILE_PRINT
433 def_file_print (FILE *file, def_file *def)
437 fprintf (file, ">>>> def_file at 0x%08x\n", def);
439 fprintf (file, " name: %s\n", def->name ? def->name : "(unspecified)");
440 if (def->is_dll != -1)
441 fprintf (file, " is dll: %s\n", def->is_dll ? "yes" : "no");
442 if (def->base_address != (bfd_vma) -1)
443 fprintf (file, " base address: 0x%08x\n", def->base_address);
444 if (def->description)
445 fprintf (file, " description: `%s'\n", def->description);
446 if (def->stack_reserve != -1)
447 fprintf (file, " stack reserve: 0x%08x\n", def->stack_reserve);
448 if (def->stack_commit != -1)
449 fprintf (file, " stack commit: 0x%08x\n", def->stack_commit);
450 if (def->heap_reserve != -1)
451 fprintf (file, " heap reserve: 0x%08x\n", def->heap_reserve);
452 if (def->heap_commit != -1)
453 fprintf (file, " heap commit: 0x%08x\n", def->heap_commit);
455 if (def->num_section_defs > 0)
457 fprintf (file, " section defs:\n");
459 for (i = 0; i < def->num_section_defs; i++)
461 fprintf (file, " name: `%s', class: `%s', flags:",
462 def->section_defs[i].name, def->section_defs[i].class);
463 if (def->section_defs[i].flag_read)
464 fprintf (file, " R");
465 if (def->section_defs[i].flag_write)
466 fprintf (file, " W");
467 if (def->section_defs[i].flag_execute)
468 fprintf (file, " X");
469 if (def->section_defs[i].flag_shared)
470 fprintf (file, " S");
471 fprintf (file, "\n");
475 if (def->num_exports > 0)
477 fprintf (file, " exports:\n");
479 for (i = 0; i < def->num_exports; i++)
481 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
482 def->exports[i].name, def->exports[i].internal_name,
483 def->exports[i].ordinal);
484 if (def->exports[i].flag_private)
485 fprintf (file, " P");
486 if (def->exports[i].flag_constant)
487 fprintf (file, " C");
488 if (def->exports[i].flag_noname)
489 fprintf (file, " N");
490 if (def->exports[i].flag_data)
491 fprintf (file, " D");
492 fprintf (file, "\n");
496 if (def->num_imports > 0)
498 fprintf (file, " imports:\n");
500 for (i = 0; i < def->num_imports; i++)
502 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
503 def->imports[i].internal_name,
504 def->imports[i].module,
505 def->imports[i].name,
506 def->imports[i].ordinal);
510 if (def->version_major != -1)
511 fprintf (file, " version: %d.%d\n", def->version_major, def->version_minor);
513 fprintf (file, "<<<< def_file at 0x%08x\n", def);
518 def_file_add_export (def_file *def,
519 const char *external_name,
520 const char *internal_name,
522 const char *its_name)
525 int max_exports = ROUND_UP(def->num_exports, 32);
527 if (def->num_exports >= max_exports)
529 max_exports = ROUND_UP(def->num_exports + 1, 32);
531 def->exports = xrealloc (def->exports,
532 max_exports * sizeof (def_file_export));
534 def->exports = xmalloc (max_exports * sizeof (def_file_export));
536 e = def->exports + def->num_exports;
537 memset (e, 0, sizeof (def_file_export));
538 if (internal_name && !external_name)
539 external_name = internal_name;
540 if (external_name && !internal_name)
541 internal_name = external_name;
542 e->name = xstrdup (external_name);
543 e->internal_name = xstrdup (internal_name);
544 e->its_name = (its_name ? xstrdup (its_name) : NULL);
545 e->ordinal = ordinal;
551 def_get_module (def_file *def, const char *name)
555 for (s = def->modules; s; s = s->next)
556 if (strcmp (s->name, name) == 0)
562 static def_file_module *
563 def_stash_module (def_file *def, const char *name)
567 if ((s = def_get_module (def, name)) != NULL)
569 s = xmalloc (sizeof (def_file_module) + strlen (name));
570 s->next = def->modules;
573 strcpy (s->name, name);
578 def_file_add_import (def_file *def,
582 const char *internal_name,
583 const char *its_name)
586 int max_imports = ROUND_UP (def->num_imports, 16);
588 if (def->num_imports >= max_imports)
590 max_imports = ROUND_UP (def->num_imports+1, 16);
593 def->imports = xrealloc (def->imports,
594 max_imports * sizeof (def_file_import));
596 def->imports = xmalloc (max_imports * sizeof (def_file_import));
598 i = def->imports + def->num_imports;
599 memset (i, 0, sizeof (def_file_import));
601 i->name = xstrdup (name);
603 i->module = def_stash_module (def, module);
604 i->ordinal = ordinal;
606 i->internal_name = xstrdup (internal_name);
608 i->internal_name = i->name;
609 i->its_name = (its_name ? xstrdup (its_name) : NULL);
622 { "-heap", HEAPSIZE },
623 { "-stack", STACKSIZE_K },
624 { "-attr", SECTIONS },
625 { "-export", EXPORTS },
626 { "-aligncomm", ALIGNCOMM },
631 def_file_add_directive (def_file *my_def, const char *param, int len)
633 def_file *save_def = def;
634 const char *pend = param + len;
635 char * tend = (char *) param;
643 && (ISSPACE (*param) || *param == '\n' || *param == 0))
649 /* Scan forward until we encounter any of:
650 - the end of the buffer
651 - the start of a new option
652 - a newline seperating options
653 - a NUL seperating options. */
654 for (tend = (char *) (param + 1);
656 && !(ISSPACE (tend[-1]) && *tend == '-')
657 && *tend != '\n' && *tend != 0);
661 for (i = 0; diropts[i].param; i++)
663 int len = strlen (diropts[i].param);
665 if (tend - param >= len
666 && strncmp (param, diropts[i].param, len) == 0
667 && (param[len] == ':' || param[len] == ' '))
669 lex_parse_string_end = tend;
670 lex_parse_string = param + len + 1;
671 lex_forced_token = diropts[i].token;
679 if (!diropts[i].param)
685 /* xgettext:c-format */
686 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
690 lex_parse_string = 0;
697 /* Parser Callbacks. */
700 def_image_name (const char *name, int base, int is_dll)
702 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
703 to do here. We retain the output filename specified on command line. */
706 const char* image_name = lbasename (name);
707 if (image_name != name)
708 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
709 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
713 /* Append the default suffix, if none specified. */
714 if (strchr (image_name, '.') == 0)
716 const char * suffix = is_dll ? ".dll" : ".exe";
718 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
719 sprintf (def->name, "%s%s", image_name, suffix);
722 def->name = xstrdup (image_name);
725 /* Honor a BASE address statement, even if LIBRARY string is empty. */
726 def->base_address = base;
727 def->is_dll = is_dll;
731 def_description (const char *text)
733 int len = def->description ? strlen (def->description) : 0;
735 len += strlen (text) + 1;
736 if (def->description)
738 def->description = xrealloc (def->description, len);
739 strcat (def->description, text);
743 def->description = xmalloc (len);
744 strcpy (def->description, text);
749 def_stacksize (int reserve, int commit)
751 def->stack_reserve = reserve;
752 def->stack_commit = commit;
756 def_heapsize (int reserve, int commit)
758 def->heap_reserve = reserve;
759 def->heap_commit = commit;
763 def_section (const char *name, int attr)
766 int max_sections = ROUND_UP (def->num_section_defs, 4);
768 if (def->num_section_defs >= max_sections)
770 max_sections = ROUND_UP (def->num_section_defs+1, 4);
772 if (def->section_defs)
773 def->section_defs = xrealloc (def->section_defs,
774 max_sections * sizeof (def_file_import));
776 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
778 s = def->section_defs + def->num_section_defs;
779 memset (s, 0, sizeof (def_file_section));
780 s->name = xstrdup (name);
790 def->num_section_defs++;
794 def_section_alt (const char *name, const char *attr)
798 for (; *attr; attr++)
820 def_section (name, aval);
824 def_exports (const char *external_name,
825 const char *internal_name,
828 const char *its_name)
830 def_file_export *dfe;
832 if (!internal_name && external_name)
833 internal_name = external_name;
835 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
838 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
841 dfe->flag_noname = 1;
843 dfe->flag_constant = 1;
847 dfe->flag_private = 1;
851 def_import (const char *internal_name,
856 const char *its_name)
859 const char *ext = dllext ? dllext : "dll";
861 buf = xmalloc (strlen (module) + strlen (ext) + 2);
862 sprintf (buf, "%s.%s", module, ext);
865 def_file_add_import (def, name, module, ordinal, internal_name, its_name);
871 def_version (int major, int minor)
873 def->version_major = major;
874 def->version_minor = minor;
878 def_directive (char *str)
880 struct directive *d = xmalloc (sizeof (struct directive));
882 d->next = directives;
884 d->name = xstrdup (str);
885 d->len = strlen (str);
889 def_aligncomm (char *str, int align)
891 def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
893 c->symbol_name = xstrdup (str);
894 c->alignment = (unsigned int) align;
896 c->next = def->aligncomms;
901 def_error (const char *err)
903 einfo ("%P: %s:%d: %s\n",
904 def_filename ? def_filename : "<unknown-file>", linenumber, err);
909 /* Lexical Scanner. */
914 /* Never freed, but always reused as needed, so no real leak. */
915 static char *buffer = 0;
916 static int buflen = 0;
917 static int bufptr = 0;
922 if (bufptr == buflen)
924 buflen += 50; /* overly reasonable, eh? */
926 buffer = xrealloc (buffer, buflen + 1);
928 buffer = xmalloc (buflen + 1);
930 buffer[bufptr++] = c;
931 buffer[bufptr] = 0; /* not optimal, but very convenient. */
943 { "CONSTANT", CONSTANTU },
944 { "constant", CONSTANTL },
947 { "DESCRIPTION", DESCRIPTION },
948 { "DIRECTIVE", DIRECTIVE },
949 { "EXECUTE", EXECUTE },
950 { "EXPORTS", EXPORTS },
951 { "HEAPSIZE", HEAPSIZE },
952 { "IMPORTS", IMPORTS },
953 { "LIBRARY", LIBRARY },
955 { "NONAME", NONAMEU },
956 { "noname", NONAMEL },
957 { "PRIVATE", PRIVATEU },
958 { "private", PRIVATEL },
960 { "SECTIONS", SECTIONS },
961 { "SEGMENTS", SECTIONS },
962 { "SHARED", SHARED },
963 { "STACKSIZE", STACKSIZE_K },
964 { "VERSION", VERSIONK },
974 if (lex_parse_string)
976 if (lex_parse_string >= lex_parse_string_end)
979 rv = *lex_parse_string++;
983 rv = fgetc (the_file);
993 if (lex_parse_string)
999 return ungetc (c, the_file);
1007 if (lex_forced_token)
1009 i = lex_forced_token;
1010 lex_forced_token = 0;
1012 printf ("lex: forcing token %d\n", i);
1019 /* Trim leading whitespace. */
1020 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1026 printf ("lex: EOF\n");
1031 if (saw_newline && c == ';')
1037 while (c != EOF && c != '\n');
1043 /* Must be something else. */
1049 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1056 yylval.digits = xstrdup (buffer);
1058 printf ("lex: `%s' returns DIGITS\n", buffer);
1063 if (ISALPHA (c) || strchr ("$:-_?@", c))
1072 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1074 else if (ISDIGIT (c)) /* '@' followed by digit. */
1080 printf ("lex: @ returns itself\n");
1084 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1091 if (ISALPHA (q)) /* Check for tokens. */
1093 for (i = 0; tokens[i].name; i++)
1094 if (strcmp (tokens[i].name, buffer) == 0)
1097 printf ("lex: `%s' is a string token\n", buffer);
1099 return tokens[i].token;
1103 printf ("lex: `%s' returns ID\n", buffer);
1105 yylval.id = xstrdup (buffer);
1109 if (c == '\'' || c == '"')
1115 while (c != EOF && c != q)
1120 yylval.id = xstrdup (buffer);
1122 printf ("lex: `%s' returns ID\n", buffer);
1133 printf ("lex: `==' returns EQUAL\n");
1139 printf ("lex: `=' returns itself\n");
1143 if (c == '.' || c == ',')
1146 printf ("lex: `%c' returns itself\n", c);
1157 /*printf ("lex: 0x%02x ignored\n", c); */