1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995-2018 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
23 #include "libiberty.h"
24 #include "safe-ctype.h"
32 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
34 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
35 as well as gratuitiously global symbol names, so we can have multiple
36 yacc generated parsers in ld. Note that these are only the variables
37 produced by yacc. If other parser generators (bison, byacc, etc) produce
38 additional global names that conflict at link time, then those parser
39 generators need to be fixed instead of adding those names to this list. */
41 #define yymaxdepth def_maxdepth
42 #define yyparse def_parse
44 #define yyerror def_error
45 #define yylval def_lval
46 #define yychar def_char
47 #define yydebug def_debug
48 #define yypact def_pact
55 #define yyexca def_exca
56 #define yyerrflag def_errflag
57 #define yynerrs def_nerrs
61 #define yy_yys def_yys
62 #define yystate def_state
65 #define yy_yyv def_yyv
67 #define yylloc def_lloc
68 #define yyreds def_reds /* With YYDEBUG defined. */
69 #define yytoks def_toks /* With YYDEBUG defined. */
70 #define yylhs def_yylhs
71 #define yylen def_yylen
72 #define yydefred def_yydefred
73 #define yydgoto def_yydgoto
74 #define yysindex def_yysindex
75 #define yyrindex def_yyrindex
76 #define yygindex def_yygindex
77 #define yytable def_yytable
78 #define yycheck def_yycheck
80 typedef struct def_pool_str {
81 struct def_pool_str *next;
85 static def_pool_str *pool_strs = NULL;
87 static char *def_pool_alloc (size_t sz);
88 static char *def_pool_strdup (const char *str);
89 static void def_pool_free (void);
91 static void def_description (const char *);
92 static void def_exports (const char *, const char *, int, int, const char *);
93 static void def_heapsize (int, int);
94 static void def_import (const char *, const char *, const char *, const char *,
96 static void def_image_name (const char *, bfd_vma, int);
97 static void def_section (const char *, int);
98 static void def_section_alt (const char *, const char *);
99 static void def_stacksize (int, int);
100 static void def_version (int, int);
101 static void def_directive (char *);
102 static void def_aligncomm (char *str, int align);
103 static int def_parse (void);
104 static int def_error (const char *);
105 static int def_lex (void);
107 static int lex_forced_token = 0;
108 static const char *lex_parse_string = 0;
109 static const char *lex_parse_string_end = 0;
115 const char *id_const;
121 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
122 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
123 %token PRIVATEU PRIVATEL ALIGNCOMM
124 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
126 %token <digits> DIGITS
127 %type <number> NUMBER
128 %type <vma> VMA opt_base
129 %type <digits> opt_digits
130 %type <number> opt_ordinal
131 %type <number> attr attr_list opt_number exp_opt_list exp_opt
132 %type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
133 %type <id> opt_equalequal_name
134 %type <id_const> keyword_as_name
143 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
144 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
145 | DESCRIPTION ID { def_description ($2);}
146 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
147 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
148 | CODE attr_list { def_section ("CODE", $2);}
149 | DATAU attr_list { def_section ("DATA", $2);}
153 | VERSIONK NUMBER { def_version ($2, 0);}
154 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
155 | DIRECTIVE ID { def_directive ($2);}
156 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
167 /* The opt_comma is necessary to support both the usual
168 DEF file syntax as well as .drectve syntax which
169 mandates <expsym>,<expoptlist>. */
170 opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
171 { def_exports ($1, $2, $3, $5, $7); }
174 /* The opt_comma is necessary to support both the usual
175 DEF file syntax as well as .drectve syntax which
176 allows for comma separated opt list. */
177 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
182 | NONAMEL { $$ = 1; }
183 | CONSTANTU { $$ = 2; }
184 | CONSTANTL { $$ = 2; }
187 | PRIVATEU { $$ = 8; }
188 | PRIVATEL { $$ = 8; }
196 ID '=' ID '.' ID '.' ID opt_equalequal_name
197 { def_import ($1, $3, $5, $7, -1, $8); }
198 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
199 { def_import ($1, $3, $5, 0, $7, $8); }
200 | ID '=' ID '.' ID opt_equalequal_name
201 { def_import ($1, $3, 0, $5, -1, $6); }
202 | ID '=' ID '.' NUMBER opt_equalequal_name
203 { def_import ($1, $3, 0, 0, $5, $6); }
204 | ID '.' ID '.' ID opt_equalequal_name
205 { def_import( 0, $1, $3, $5, -1, $6); }
206 | ID '.' ID opt_equalequal_name
207 { def_import ( 0, $1, 0, $3, -1, $4); }
216 ID attr_list { def_section ($1, $2);}
217 | ID ID { def_section_alt ($1, $2);}
221 attr_list opt_comma attr { $$ = $1 | $3; }
229 opt_number: ',' NUMBER { $$=$2;}
241 keyword_as_name: BASE { $$ = "BASE"; }
242 | CODE { $$ = "CODE"; }
243 | CONSTANTU { $$ = "CONSTANT"; }
244 | CONSTANTL { $$ = "constant"; }
245 | DATAU { $$ = "DATA"; }
246 | DATAL { $$ = "data"; }
247 | DESCRIPTION { $$ = "DESCRIPTION"; }
248 | DIRECTIVE { $$ = "DIRECTIVE"; }
249 | EXECUTE { $$ = "EXECUTE"; }
250 | EXPORTS { $$ = "EXPORTS"; }
251 | HEAPSIZE { $$ = "HEAPSIZE"; }
252 | IMPORTS { $$ = "IMPORTS"; }
253 /* Disable LIBRARY keyword as valid symbol-name. This is necessary
254 for libtool, which places this command after EXPORTS command.
255 This behavior is illegal by specification, but sadly required by
256 by compatibility reasons.
257 See PR binutils/13710
258 | LIBRARY { $$ = "LIBRARY"; } */
259 | NAME { $$ = "NAME"; }
260 | NONAMEU { $$ = "NONAME"; }
261 | NONAMEL { $$ = "noname"; }
262 | PRIVATEU { $$ = "PRIVATE"; }
263 | PRIVATEL { $$ = "private"; }
264 | READ { $$ = "READ"; }
265 | SHARED { $$ = "SHARED"; }
266 | STACKSIZE_K { $$ = "STACKSIZE"; }
267 | VERSIONK { $$ = "VERSION"; }
268 | WRITE { $$ = "WRITE"; }
271 opt_name2: ID { $$ = $1; }
272 | '.' keyword_as_name
274 char *name = xmalloc (strlen ($2) + 2);
275 sprintf (name, ".%s", $2);
280 char *name = def_pool_alloc (strlen ($2) + 2);
281 sprintf (name, ".%s", $2);
284 | keyword_as_name '.' opt_name2
286 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
287 sprintf (name, "%s.%s", $1, $3);
292 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
293 sprintf (name, "%s.%s", $1, $3);
298 opt_name: opt_name2 { $$ = $1; }
302 opt_equalequal_name: EQUAL ID { $$ = $2; }
307 '@' NUMBER { $$ = $2;}
312 '=' opt_name2 { $$ = $2; }
316 opt_base: BASE '=' VMA { $$ = $3;}
317 | { $$ = (bfd_vma) -1;}
320 anylang_id: ID { $$ = $1; }
323 char *id = def_pool_alloc (strlen ($2) + 2);
324 sprintf (id, ".%s", $2);
327 | anylang_id '.' opt_digits opt_id
329 char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
330 sprintf (id, "%s.%s%s", $1, $3, $4);
335 opt_digits: DIGITS { $$ = $1; }
339 opt_id: ID { $$ = $1; }
343 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
345 VMA: DIGITS { $$ = (bfd_vma) strtoull ($1, 0, 0); }
349 /*****************************************************************************
351 *****************************************************************************/
353 static FILE *the_file;
354 static const char *def_filename;
355 static int linenumber;
356 static def_file *def;
357 static int saw_newline;
361 struct directive *next;
366 static struct directive *directives = 0;
369 def_file_empty (void)
371 def_file *rv = xmalloc (sizeof (def_file));
372 memset (rv, 0, sizeof (def_file));
374 rv->base_address = (bfd_vma) -1;
375 rv->stack_reserve = rv->stack_commit = -1;
376 rv->heap_reserve = rv->heap_commit = -1;
377 rv->version_major = rv->version_minor = -1;
382 def_file_parse (const char *filename, def_file *add_to)
386 the_file = fopen (filename, "r");
387 def_filename = filename;
400 def = def_file_empty ();
414 while ((d = directives) != NULL)
417 printf ("Adding directive %08x `%s'\n", d->name, d->name);
419 def_file_add_directive (def, d->name, d->len);
420 directives = d->next;
430 def_file_free (def_file *fdef)
438 if (fdef->description)
439 free (fdef->description);
441 if (fdef->section_defs)
443 for (i = 0; i < fdef->num_section_defs; i++)
445 if (fdef->section_defs[i].name)
446 free (fdef->section_defs[i].name);
447 if (fdef->section_defs[i].class)
448 free (fdef->section_defs[i].class);
450 free (fdef->section_defs);
455 for (i = 0; i < fdef->num_exports; i++)
457 if (fdef->exports[i].internal_name
458 && fdef->exports[i].internal_name != fdef->exports[i].name)
459 free (fdef->exports[i].internal_name);
460 if (fdef->exports[i].name)
461 free (fdef->exports[i].name);
462 if (fdef->exports[i].its_name)
463 free (fdef->exports[i].its_name);
465 free (fdef->exports);
470 for (i = 0; i < fdef->num_imports; i++)
472 if (fdef->imports[i].internal_name
473 && fdef->imports[i].internal_name != fdef->imports[i].name)
474 free (fdef->imports[i].internal_name);
475 if (fdef->imports[i].name)
476 free (fdef->imports[i].name);
477 if (fdef->imports[i].its_name)
478 free (fdef->imports[i].its_name);
480 free (fdef->imports);
483 while (fdef->modules)
485 def_file_module *m = fdef->modules;
487 fdef->modules = fdef->modules->next;
491 while (fdef->aligncomms)
493 def_file_aligncomm *c = fdef->aligncomms;
495 fdef->aligncomms = fdef->aligncomms->next;
496 free (c->symbol_name);
503 #ifdef DEF_FILE_PRINT
505 def_file_print (FILE *file, def_file *fdef)
509 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
511 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
512 if (fdef->is_dll != -1)
513 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
514 if (fdef->base_address != (bfd_vma) -1)
516 fprintf (file, " base address: 0x");
517 fprintf_vma (file, fdef->base_address);
518 fprintf (file, "\n");
520 if (fdef->description)
521 fprintf (file, " description: `%s'\n", fdef->description);
522 if (fdef->stack_reserve != -1)
523 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
524 if (fdef->stack_commit != -1)
525 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
526 if (fdef->heap_reserve != -1)
527 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
528 if (fdef->heap_commit != -1)
529 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
531 if (fdef->num_section_defs > 0)
533 fprintf (file, " section defs:\n");
535 for (i = 0; i < fdef->num_section_defs; i++)
537 fprintf (file, " name: `%s', class: `%s', flags:",
538 fdef->section_defs[i].name, fdef->section_defs[i].class);
539 if (fdef->section_defs[i].flag_read)
540 fprintf (file, " R");
541 if (fdef->section_defs[i].flag_write)
542 fprintf (file, " W");
543 if (fdef->section_defs[i].flag_execute)
544 fprintf (file, " X");
545 if (fdef->section_defs[i].flag_shared)
546 fprintf (file, " S");
547 fprintf (file, "\n");
551 if (fdef->num_exports > 0)
553 fprintf (file, " exports:\n");
555 for (i = 0; i < fdef->num_exports; i++)
557 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
558 fdef->exports[i].name, fdef->exports[i].internal_name,
559 fdef->exports[i].ordinal);
560 if (fdef->exports[i].flag_private)
561 fprintf (file, " P");
562 if (fdef->exports[i].flag_constant)
563 fprintf (file, " C");
564 if (fdef->exports[i].flag_noname)
565 fprintf (file, " N");
566 if (fdef->exports[i].flag_data)
567 fprintf (file, " D");
568 fprintf (file, "\n");
572 if (fdef->num_imports > 0)
574 fprintf (file, " imports:\n");
576 for (i = 0; i < fdef->num_imports; i++)
578 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
579 fdef->imports[i].internal_name,
580 fdef->imports[i].module,
581 fdef->imports[i].name,
582 fdef->imports[i].ordinal);
586 if (fdef->version_major != -1)
587 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
589 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
593 /* Helper routine to check for identity of string pointers,
594 which might be NULL. */
597 are_names_equal (const char *s1, const char *s2)
602 return (!s1 ? -1 : 1);
603 return strcmp (s1, s2);
607 cmp_export_elem (const def_file_export *e, const char *ex_name,
608 const char *in_name, const char *its_name,
613 if ((r = are_names_equal (ex_name, e->name)) != 0)
615 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
617 if ((r = are_names_equal (its_name, e->its_name)) != 0)
619 return (ord - e->ordinal);
622 /* Search the position of the identical element, or returns the position
623 of the next higher element. If last valid element is smaller, then MAX
627 find_export_in_list (def_file_export *b, int max,
628 const char *ex_name, const char *in_name,
629 const char *its_name, int ord, int *is_ident)
636 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
644 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
646 else if (!e || max == 2)
656 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
667 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
675 def_file_add_export (def_file *fdef,
676 const char *external_name,
677 const char *internal_name,
679 const char *its_name,
684 int max_exports = ROUND_UP(fdef->num_exports, 32);
686 if (internal_name && !external_name)
687 external_name = internal_name;
688 if (external_name && !internal_name)
689 internal_name = external_name;
691 /* We need to avoid duplicates. */
693 pos = find_export_in_list (fdef->exports, fdef->num_exports,
694 external_name, internal_name,
695 its_name, ordinal, is_dup);
698 return (fdef->exports + pos);
700 if (fdef->num_exports >= max_exports)
702 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
704 fdef->exports = xrealloc (fdef->exports,
705 max_exports * sizeof (def_file_export));
707 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
710 e = fdef->exports + pos;
711 if (pos != fdef->num_exports)
712 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
713 memset (e, 0, sizeof (def_file_export));
714 e->name = xstrdup (external_name);
715 e->internal_name = xstrdup (internal_name);
716 e->its_name = (its_name ? xstrdup (its_name) : NULL);
717 e->ordinal = ordinal;
723 def_get_module (def_file *fdef, const char *name)
727 for (s = fdef->modules; s; s = s->next)
728 if (strcmp (s->name, name) == 0)
734 static def_file_module *
735 def_stash_module (def_file *fdef, const char *name)
739 if ((s = def_get_module (fdef, name)) != NULL)
741 s = xmalloc (sizeof (def_file_module) + strlen (name));
742 s->next = fdef->modules;
745 strcpy (s->name, name);
750 cmp_import_elem (const def_file_import *e, const char *ex_name,
751 const char *in_name, const char *module,
756 if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
758 if ((r = are_names_equal (ex_name, e->name)) != 0)
760 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
762 if (ord != e->ordinal)
763 return (ord < e->ordinal ? -1 : 1);
767 /* Search the position of the identical element, or returns the position
768 of the next higher element. If last valid element is smaller, then MAX
772 find_import_in_list (def_file_import *b, int max,
773 const char *ex_name, const char *in_name,
774 const char *module, int ord, int *is_ident)
781 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
789 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
791 else if (!e || max == 2)
801 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
812 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
820 fill_in_import (def_file_import *i,
822 def_file_module *module,
824 const char *internal_name,
825 const char *its_name)
827 memset (i, 0, sizeof (def_file_import));
829 i->name = xstrdup (name);
831 i->ordinal = ordinal;
833 i->internal_name = xstrdup (internal_name);
835 i->internal_name = i->name;
836 i->its_name = (its_name ? xstrdup (its_name) : NULL);
840 def_file_add_import (def_file *fdef,
844 const char *internal_name,
845 const char *its_name,
850 int max_imports = ROUND_UP (fdef->num_imports, 16);
852 /* We need to avoid here duplicates. */
854 pos = find_import_in_list (fdef->imports, fdef->num_imports,
856 (!internal_name ? name : internal_name),
857 module, ordinal, is_dup);
859 return fdef->imports + pos;
861 if (fdef->num_imports >= max_imports)
863 max_imports = ROUND_UP (fdef->num_imports+1, 16);
866 fdef->imports = xrealloc (fdef->imports,
867 max_imports * sizeof (def_file_import));
869 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
871 i = fdef->imports + pos;
872 if (pos != fdef->num_imports)
873 memmove (i + 1, i, sizeof (def_file_import) * (fdef->num_imports - pos));
875 fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
876 internal_name, its_name);
883 def_file_add_import_from (def_file *fdef,
888 const char *internal_name,
889 const char *its_name ATTRIBUTE_UNUSED)
894 int max_imports = ROUND_UP (fdef->num_imports, 16);
896 /* We need to avoid here duplicates. */
898 pos = find_import_in_list (fdef->imports, fdef->num_imports,
899 name, internal_name ? internal_name : name,
900 module, ordinal, &is_dup);
903 if (fdef->imports && pos != fdef->num_imports)
905 i = fdef->imports + pos;
906 if (i->module && strcmp (i->module->name, module) == 0)
910 if (fdef->num_imports + num_imports - 1 >= max_imports)
912 max_imports = ROUND_UP (fdef->num_imports + num_imports, 16);
915 fdef->imports = xrealloc (fdef->imports,
916 max_imports * sizeof (def_file_import));
918 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
920 i = fdef->imports + pos;
921 if (pos != fdef->num_imports)
922 memmove (i + num_imports, i,
923 sizeof (def_file_import) * (fdef->num_imports - pos));
929 def_file_add_import_at (def_file *fdef,
934 const char *internal_name,
935 const char *its_name)
937 def_file_import *i = fdef->imports + pos;
939 fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
940 internal_name, its_name);
953 { "-heap", HEAPSIZE },
954 { "-stack", STACKSIZE_K },
955 { "-attr", SECTIONS },
956 { "-export", EXPORTS },
957 { "-aligncomm", ALIGNCOMM },
962 def_file_add_directive (def_file *my_def, const char *param, int len)
964 def_file *save_def = def;
965 const char *pend = param + len;
966 char * tend = (char *) param;
974 && (ISSPACE (*param) || *param == '\n' || *param == 0))
980 /* Scan forward until we encounter any of:
981 - the end of the buffer
982 - the start of a new option
983 - a newline separating options
984 - a NUL separating options. */
985 for (tend = (char *) (param + 1);
987 && !(ISSPACE (tend[-1]) && *tend == '-')
988 && *tend != '\n' && *tend != 0);
992 for (i = 0; diropts[i].param; i++)
994 len = strlen (diropts[i].param);
996 if (tend - param >= len
997 && strncmp (param, diropts[i].param, len) == 0
998 && (param[len] == ':' || param[len] == ' '))
1000 lex_parse_string_end = tend;
1001 lex_parse_string = param + len + 1;
1002 lex_forced_token = diropts[i].token;
1010 if (!diropts[i].param)
1018 /* xgettext:c-format */
1019 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
1024 einfo (_("Warning: corrupt .drectve at end of def file\n"));
1028 lex_parse_string = 0;
1036 /* Parser Callbacks. */
1039 def_image_name (const char *name, bfd_vma base, int is_dll)
1041 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
1042 to do here. We retain the output filename specified on command line. */
1045 const char* image_name = lbasename (name);
1047 if (image_name != name)
1048 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
1049 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
1053 /* Append the default suffix, if none specified. */
1054 if (strchr (image_name, '.') == 0)
1056 const char * suffix = is_dll ? ".dll" : ".exe";
1058 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
1059 sprintf (def->name, "%s%s", image_name, suffix);
1062 def->name = xstrdup (image_name);
1065 /* Honor a BASE address statement, even if LIBRARY string is empty. */
1066 def->base_address = base;
1067 def->is_dll = is_dll;
1071 def_description (const char *text)
1073 int len = def->description ? strlen (def->description) : 0;
1075 len += strlen (text) + 1;
1076 if (def->description)
1078 def->description = xrealloc (def->description, len);
1079 strcat (def->description, text);
1083 def->description = xmalloc (len);
1084 strcpy (def->description, text);
1089 def_stacksize (int reserve, int commit)
1091 def->stack_reserve = reserve;
1092 def->stack_commit = commit;
1096 def_heapsize (int reserve, int commit)
1098 def->heap_reserve = reserve;
1099 def->heap_commit = commit;
1103 def_section (const char *name, int attr)
1105 def_file_section *s;
1106 int max_sections = ROUND_UP (def->num_section_defs, 4);
1108 if (def->num_section_defs >= max_sections)
1110 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1112 if (def->section_defs)
1113 def->section_defs = xrealloc (def->section_defs,
1114 max_sections * sizeof (def_file_import));
1116 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1118 s = def->section_defs + def->num_section_defs;
1119 memset (s, 0, sizeof (def_file_section));
1120 s->name = xstrdup (name);
1126 s->flag_execute = 1;
1130 def->num_section_defs++;
1134 def_section_alt (const char *name, const char *attr)
1138 for (; *attr; attr++)
1160 def_section (name, aval);
1164 def_exports (const char *external_name,
1165 const char *internal_name,
1168 const char *its_name)
1170 def_file_export *dfe;
1173 if (!internal_name && external_name)
1174 internal_name = external_name;
1176 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1179 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1182 /* We might check here for flag redefinition and warn. For now we
1183 ignore duplicates silently. */
1188 dfe->flag_noname = 1;
1190 dfe->flag_constant = 1;
1194 dfe->flag_private = 1;
1198 def_import (const char *internal_name,
1203 const char *its_name)
1206 const char *ext = dllext ? dllext : "dll";
1209 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1210 sprintf (buf, "%s.%s", module, ext);
1213 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1219 def_version (int major, int minor)
1221 def->version_major = major;
1222 def->version_minor = minor;
1226 def_directive (char *str)
1228 struct directive *d = xmalloc (sizeof (struct directive));
1230 d->next = directives;
1232 d->name = xstrdup (str);
1233 d->len = strlen (str);
1237 def_aligncomm (char *str, int align)
1239 def_file_aligncomm *c, *p;
1242 c = def->aligncomms;
1245 int e = strcmp (c->symbol_name, str);
1248 /* Not sure if we want to allow here duplicates with
1249 different alignments, but for now we keep them. */
1250 e = (int) c->alignment - align;
1259 c = xmalloc (sizeof (def_file_aligncomm));
1260 c->symbol_name = xstrdup (str);
1261 c->alignment = (unsigned int) align;
1264 c->next = def->aligncomms;
1265 def->aligncomms = c;
1275 def_error (const char *err)
1277 einfo ("%P: %s:%d: %s\n",
1278 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1283 /* Lexical Scanner. */
1288 /* Never freed, but always reused as needed, so no real leak. */
1289 static char *buffer = 0;
1290 static int buflen = 0;
1291 static int bufptr = 0;
1296 if (bufptr == buflen)
1298 buflen += 50; /* overly reasonable, eh? */
1300 buffer = xrealloc (buffer, buflen + 1);
1302 buffer = xmalloc (buflen + 1);
1304 buffer[bufptr++] = c;
1305 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1317 { "CONSTANT", CONSTANTU },
1318 { "constant", CONSTANTL },
1321 { "DESCRIPTION", DESCRIPTION },
1322 { "DIRECTIVE", DIRECTIVE },
1323 { "EXECUTE", EXECUTE },
1324 { "EXPORTS", EXPORTS },
1325 { "HEAPSIZE", HEAPSIZE },
1326 { "IMPORTS", IMPORTS },
1327 { "LIBRARY", LIBRARY },
1329 { "NONAME", NONAMEU },
1330 { "noname", NONAMEL },
1331 { "PRIVATE", PRIVATEU },
1332 { "private", PRIVATEL },
1334 { "SECTIONS", SECTIONS },
1335 { "SEGMENTS", SECTIONS },
1336 { "SHARED", SHARED },
1337 { "STACKSIZE", STACKSIZE_K },
1338 { "VERSION", VERSIONK },
1348 if (lex_parse_string)
1350 if (lex_parse_string >= lex_parse_string_end)
1353 rv = *lex_parse_string++;
1357 rv = fgetc (the_file);
1367 if (lex_parse_string)
1373 return ungetc (c, the_file);
1381 if (lex_forced_token)
1383 i = lex_forced_token;
1384 lex_forced_token = 0;
1386 printf ("lex: forcing token %d\n", i);
1393 /* Trim leading whitespace. */
1394 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1400 printf ("lex: EOF\n");
1405 if (saw_newline && c == ';')
1411 while (c != EOF && c != '\n');
1417 /* Must be something else. */
1423 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1430 yylval.digits = def_pool_strdup (buffer);
1432 printf ("lex: `%s' returns DIGITS\n", buffer);
1437 if (ISALPHA (c) || strchr ("$:-_?@", c))
1446 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1448 else if (ISDIGIT (c)) /* '@' followed by digit. */
1454 printf ("lex: @ returns itself\n");
1458 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1465 if (ISALPHA (q)) /* Check for tokens. */
1467 for (i = 0; tokens[i].name; i++)
1468 if (strcmp (tokens[i].name, buffer) == 0)
1471 printf ("lex: `%s' is a string token\n", buffer);
1473 return tokens[i].token;
1477 printf ("lex: `%s' returns ID\n", buffer);
1479 yylval.id = def_pool_strdup (buffer);
1483 if (c == '\'' || c == '"')
1489 while (c != EOF && c != q)
1494 yylval.id = def_pool_strdup (buffer);
1496 printf ("lex: `%s' returns ID\n", buffer);
1507 printf ("lex: `==' returns EQUAL\n");
1513 printf ("lex: `=' returns itself\n");
1517 if (c == '.' || c == ',')
1520 printf ("lex: `%c' returns itself\n", c);
1531 /*printf ("lex: 0x%02x ignored\n", c); */
1536 def_pool_alloc (size_t sz)
1540 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1541 e->next = pool_strs;
1547 def_pool_strdup (const char *str)
1553 len = strlen (str) + 1;
1554 s = def_pool_alloc (len);
1555 memcpy (s, str, len);
1560 def_pool_free (void)
1563 while ((p = pool_strs) != NULL)
1565 pool_strs = p->next;