1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995-2019 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"
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 typedef struct def_pool_str {
82 struct def_pool_str *next;
86 static def_pool_str *pool_strs = NULL;
88 static char *def_pool_alloc (size_t sz);
89 static char *def_pool_strdup (const char *str);
90 static void def_pool_free (void);
92 static void def_description (const char *);
93 static void def_exports (const char *, const char *, int, int, const char *);
94 static void def_heapsize (int, int);
95 static void def_import (const char *, const char *, const char *, const char *,
97 static void def_image_name (const char *, bfd_vma, int);
98 static void def_section (const char *, int);
99 static void def_section_alt (const char *, const char *);
100 static void def_stacksize (int, int);
101 static void def_version (int, int);
102 static void def_directive (char *);
103 static void def_aligncomm (char *str, int align);
104 static int def_parse (void);
105 static int def_error (const char *);
106 static int def_lex (void);
108 static int lex_forced_token = 0;
109 static const char *lex_parse_string = 0;
110 static const char *lex_parse_string_end = 0;
116 const char *id_const;
122 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
123 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
124 %token PRIVATEU PRIVATEL ALIGNCOMM
125 %token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
127 %token <digits> DIGITS
128 %type <number> NUMBER
129 %type <vma> VMA opt_base
130 %type <digits> opt_digits
131 %type <number> opt_ordinal
132 %type <number> attr attr_list opt_number exp_opt_list exp_opt
133 %type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
134 %type <id> opt_equalequal_name
135 %type <id_const> keyword_as_name
144 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
145 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
146 | DESCRIPTION ID { def_description ($2);}
147 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
148 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
149 | CODE attr_list { def_section ("CODE", $2);}
150 | DATAU attr_list { def_section ("DATA", $2);}
154 | VERSIONK NUMBER { def_version ($2, 0);}
155 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
156 | DIRECTIVE ID { def_directive ($2);}
157 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
168 /* The opt_comma is necessary to support both the usual
169 DEF file syntax as well as .drectve syntax which
170 mandates <expsym>,<expoptlist>. */
171 opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
172 { def_exports ($1, $2, $3, $5, $7); }
175 /* The opt_comma is necessary to support both the usual
176 DEF file syntax as well as .drectve syntax which
177 allows for comma separated opt list. */
178 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
183 | NONAMEL { $$ = 1; }
184 | CONSTANTU { $$ = 2; }
185 | CONSTANTL { $$ = 2; }
188 | PRIVATEU { $$ = 8; }
189 | PRIVATEL { $$ = 8; }
197 ID '=' ID '.' ID '.' ID opt_equalequal_name
198 { def_import ($1, $3, $5, $7, -1, $8); }
199 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
200 { def_import ($1, $3, $5, 0, $7, $8); }
201 | ID '=' ID '.' ID opt_equalequal_name
202 { def_import ($1, $3, 0, $5, -1, $6); }
203 | ID '=' ID '.' NUMBER opt_equalequal_name
204 { def_import ($1, $3, 0, 0, $5, $6); }
205 | ID '.' ID '.' ID opt_equalequal_name
206 { def_import( 0, $1, $3, $5, -1, $6); }
207 | ID '.' ID opt_equalequal_name
208 { def_import ( 0, $1, 0, $3, -1, $4); }
217 ID attr_list { def_section ($1, $2);}
218 | ID ID { def_section_alt ($1, $2);}
222 attr_list opt_comma attr { $$ = $1 | $3; }
230 opt_number: ',' NUMBER { $$=$2;}
242 keyword_as_name: BASE { $$ = "BASE"; }
243 | CODE { $$ = "CODE"; }
244 | CONSTANTU { $$ = "CONSTANT"; }
245 | CONSTANTL { $$ = "constant"; }
246 | DATAU { $$ = "DATA"; }
247 | DATAL { $$ = "data"; }
248 | DESCRIPTION { $$ = "DESCRIPTION"; }
249 | DIRECTIVE { $$ = "DIRECTIVE"; }
250 | EXECUTE { $$ = "EXECUTE"; }
251 | EXPORTS { $$ = "EXPORTS"; }
252 | HEAPSIZE { $$ = "HEAPSIZE"; }
253 | IMPORTS { $$ = "IMPORTS"; }
254 /* Disable LIBRARY keyword as valid symbol-name. This is necessary
255 for libtool, which places this command after EXPORTS command.
256 This behavior is illegal by specification, but sadly required by
257 by compatibility reasons.
258 See PR binutils/13710
259 | LIBRARY { $$ = "LIBRARY"; } */
260 | NAME { $$ = "NAME"; }
261 | NONAMEU { $$ = "NONAME"; }
262 | NONAMEL { $$ = "noname"; }
263 | PRIVATEU { $$ = "PRIVATE"; }
264 | PRIVATEL { $$ = "private"; }
265 | READ { $$ = "READ"; }
266 | SHARED { $$ = "SHARED"; }
267 | STACKSIZE_K { $$ = "STACKSIZE"; }
268 | VERSIONK { $$ = "VERSION"; }
269 | WRITE { $$ = "WRITE"; }
272 opt_name2: ID { $$ = $1; }
273 | '.' keyword_as_name
275 char *name = xmalloc (strlen ($2) + 2);
276 sprintf (name, ".%s", $2);
281 char *name = def_pool_alloc (strlen ($2) + 2);
282 sprintf (name, ".%s", $2);
285 | keyword_as_name '.' opt_name2
287 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
288 sprintf (name, "%s.%s", $1, $3);
293 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
294 sprintf (name, "%s.%s", $1, $3);
299 opt_name: opt_name2 { $$ = $1; }
303 opt_equalequal_name: EQUAL ID { $$ = $2; }
308 '@' NUMBER { $$ = $2;}
313 '=' opt_name2 { $$ = $2; }
317 opt_base: BASE '=' VMA { $$ = $3;}
318 | { $$ = (bfd_vma) -1;}
321 anylang_id: ID { $$ = $1; }
324 char *id = def_pool_alloc (strlen ($2) + 2);
325 sprintf (id, ".%s", $2);
328 | anylang_id '.' opt_digits opt_id
330 char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
331 sprintf (id, "%s.%s%s", $1, $3, $4);
336 opt_digits: DIGITS { $$ = $1; }
340 opt_id: ID { $$ = $1; }
344 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
346 VMA: DIGITS { $$ = (bfd_vma) strtoull ($1, 0, 0); }
350 /*****************************************************************************
352 *****************************************************************************/
354 static FILE *the_file;
355 static const char *def_filename;
356 static int linenumber;
357 static def_file *def;
358 static int saw_newline;
362 struct directive *next;
367 static struct directive *directives = 0;
370 def_file_empty (void)
372 def_file *rv = xmalloc (sizeof (def_file));
373 memset (rv, 0, sizeof (def_file));
375 rv->base_address = (bfd_vma) -1;
376 rv->stack_reserve = rv->stack_commit = -1;
377 rv->heap_reserve = rv->heap_commit = -1;
378 rv->version_major = rv->version_minor = -1;
383 def_file_parse (const char *filename, def_file *add_to)
387 the_file = fopen (filename, "r");
388 def_filename = filename;
401 def = def_file_empty ();
415 while ((d = directives) != NULL)
418 printf ("Adding directive %08x `%s'\n", d->name, d->name);
420 def_file_add_directive (def, d->name, d->len);
421 directives = d->next;
431 def_file_free (def_file *fdef)
439 if (fdef->description)
440 free (fdef->description);
442 if (fdef->section_defs)
444 for (i = 0; i < fdef->num_section_defs; i++)
446 if (fdef->section_defs[i].name)
447 free (fdef->section_defs[i].name);
448 if (fdef->section_defs[i].class)
449 free (fdef->section_defs[i].class);
451 free (fdef->section_defs);
456 for (i = 0; i < fdef->num_exports; i++)
458 if (fdef->exports[i].internal_name
459 && fdef->exports[i].internal_name != fdef->exports[i].name)
460 free (fdef->exports[i].internal_name);
461 if (fdef->exports[i].name)
462 free (fdef->exports[i].name);
463 if (fdef->exports[i].its_name)
464 free (fdef->exports[i].its_name);
466 free (fdef->exports);
471 for (i = 0; i < fdef->num_imports; i++)
473 if (fdef->imports[i].internal_name
474 && fdef->imports[i].internal_name != fdef->imports[i].name)
475 free (fdef->imports[i].internal_name);
476 if (fdef->imports[i].name)
477 free (fdef->imports[i].name);
478 if (fdef->imports[i].its_name)
479 free (fdef->imports[i].its_name);
481 free (fdef->imports);
484 while (fdef->modules)
486 def_file_module *m = fdef->modules;
488 fdef->modules = fdef->modules->next;
492 while (fdef->aligncomms)
494 def_file_aligncomm *c = fdef->aligncomms;
496 fdef->aligncomms = fdef->aligncomms->next;
497 free (c->symbol_name);
504 #ifdef DEF_FILE_PRINT
506 def_file_print (FILE *file, def_file *fdef)
510 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
512 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
513 if (fdef->is_dll != -1)
514 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
515 if (fdef->base_address != (bfd_vma) -1)
517 fprintf (file, " base address: 0x");
518 fprintf_vma (file, fdef->base_address);
519 fprintf (file, "\n");
521 if (fdef->description)
522 fprintf (file, " description: `%s'\n", fdef->description);
523 if (fdef->stack_reserve != -1)
524 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
525 if (fdef->stack_commit != -1)
526 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
527 if (fdef->heap_reserve != -1)
528 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
529 if (fdef->heap_commit != -1)
530 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
532 if (fdef->num_section_defs > 0)
534 fprintf (file, " section defs:\n");
536 for (i = 0; i < fdef->num_section_defs; i++)
538 fprintf (file, " name: `%s', class: `%s', flags:",
539 fdef->section_defs[i].name, fdef->section_defs[i].class);
540 if (fdef->section_defs[i].flag_read)
541 fprintf (file, " R");
542 if (fdef->section_defs[i].flag_write)
543 fprintf (file, " W");
544 if (fdef->section_defs[i].flag_execute)
545 fprintf (file, " X");
546 if (fdef->section_defs[i].flag_shared)
547 fprintf (file, " S");
548 fprintf (file, "\n");
552 if (fdef->num_exports > 0)
554 fprintf (file, " exports:\n");
556 for (i = 0; i < fdef->num_exports; i++)
558 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
559 fdef->exports[i].name, fdef->exports[i].internal_name,
560 fdef->exports[i].ordinal);
561 if (fdef->exports[i].flag_private)
562 fprintf (file, " P");
563 if (fdef->exports[i].flag_constant)
564 fprintf (file, " C");
565 if (fdef->exports[i].flag_noname)
566 fprintf (file, " N");
567 if (fdef->exports[i].flag_data)
568 fprintf (file, " D");
569 fprintf (file, "\n");
573 if (fdef->num_imports > 0)
575 fprintf (file, " imports:\n");
577 for (i = 0; i < fdef->num_imports; i++)
579 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
580 fdef->imports[i].internal_name,
581 fdef->imports[i].module,
582 fdef->imports[i].name,
583 fdef->imports[i].ordinal);
587 if (fdef->version_major != -1)
588 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
590 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
594 /* Helper routine to check for identity of string pointers,
595 which might be NULL. */
598 are_names_equal (const char *s1, const char *s2)
603 return (!s1 ? -1 : 1);
604 return strcmp (s1, s2);
608 cmp_export_elem (const def_file_export *e, const char *ex_name,
609 const char *in_name, const char *its_name,
614 if ((r = are_names_equal (ex_name, e->name)) != 0)
616 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
618 if ((r = are_names_equal (its_name, e->its_name)) != 0)
620 return (ord - e->ordinal);
623 /* Search the position of the identical element, or returns the position
624 of the next higher element. If last valid element is smaller, then MAX
628 find_export_in_list (def_file_export *b, int max,
629 const char *ex_name, const char *in_name,
630 const char *its_name, int ord, int *is_ident)
637 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
645 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
647 else if (!e || max == 2)
657 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
668 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
676 def_file_add_export (def_file *fdef,
677 const char *external_name,
678 const char *internal_name,
680 const char *its_name,
685 int max_exports = ROUND_UP(fdef->num_exports, 32);
687 if (internal_name && !external_name)
688 external_name = internal_name;
689 if (external_name && !internal_name)
690 internal_name = external_name;
692 /* We need to avoid duplicates. */
694 pos = find_export_in_list (fdef->exports, fdef->num_exports,
695 external_name, internal_name,
696 its_name, ordinal, is_dup);
699 return (fdef->exports + pos);
701 if (fdef->num_exports >= max_exports)
703 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
705 fdef->exports = xrealloc (fdef->exports,
706 max_exports * sizeof (def_file_export));
708 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
711 e = fdef->exports + pos;
712 if (pos != fdef->num_exports)
713 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
714 memset (e, 0, sizeof (def_file_export));
715 e->name = xstrdup (external_name);
716 e->internal_name = xstrdup (internal_name);
717 e->its_name = (its_name ? xstrdup (its_name) : NULL);
718 e->ordinal = ordinal;
724 def_get_module (def_file *fdef, const char *name)
728 for (s = fdef->modules; s; s = s->next)
729 if (strcmp (s->name, name) == 0)
735 static def_file_module *
736 def_stash_module (def_file *fdef, const char *name)
740 if ((s = def_get_module (fdef, name)) != NULL)
742 s = xmalloc (sizeof (def_file_module) + strlen (name));
743 s->next = fdef->modules;
746 strcpy (s->name, name);
751 cmp_import_elem (const def_file_import *e, const char *ex_name,
752 const char *in_name, const char *module,
757 if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
759 if ((r = are_names_equal (ex_name, e->name)) != 0)
761 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
763 if (ord != e->ordinal)
764 return (ord < e->ordinal ? -1 : 1);
768 /* Search the position of the identical element, or returns the position
769 of the next higher element. If last valid element is smaller, then MAX
773 find_import_in_list (def_file_import *b, int max,
774 const char *ex_name, const char *in_name,
775 const char *module, int ord, int *is_ident)
782 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
790 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
792 else if (!e || max == 2)
802 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
813 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
821 fill_in_import (def_file_import *i,
823 def_file_module *module,
825 const char *internal_name,
826 const char *its_name)
828 memset (i, 0, sizeof (def_file_import));
830 i->name = xstrdup (name);
832 i->ordinal = ordinal;
834 i->internal_name = xstrdup (internal_name);
836 i->internal_name = i->name;
837 i->its_name = (its_name ? xstrdup (its_name) : NULL);
841 def_file_add_import (def_file *fdef,
845 const char *internal_name,
846 const char *its_name,
851 int max_imports = ROUND_UP (fdef->num_imports, 16);
853 /* We need to avoid here duplicates. */
855 pos = find_import_in_list (fdef->imports, fdef->num_imports,
857 (!internal_name ? name : internal_name),
858 module, ordinal, is_dup);
860 return fdef->imports + pos;
862 if (fdef->num_imports >= max_imports)
864 max_imports = ROUND_UP (fdef->num_imports+1, 16);
867 fdef->imports = xrealloc (fdef->imports,
868 max_imports * sizeof (def_file_import));
870 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
872 i = fdef->imports + pos;
873 if (pos != fdef->num_imports)
874 memmove (i + 1, i, sizeof (def_file_import) * (fdef->num_imports - pos));
876 fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
877 internal_name, its_name);
884 def_file_add_import_from (def_file *fdef,
889 const char *internal_name,
890 const char *its_name ATTRIBUTE_UNUSED)
895 int max_imports = ROUND_UP (fdef->num_imports, 16);
897 /* We need to avoid here duplicates. */
899 pos = find_import_in_list (fdef->imports, fdef->num_imports,
900 name, internal_name ? internal_name : name,
901 module, ordinal, &is_dup);
904 if (fdef->imports && pos != fdef->num_imports)
906 i = fdef->imports + pos;
907 if (i->module && strcmp (i->module->name, module) == 0)
911 if (fdef->num_imports + num_imports - 1 >= max_imports)
913 max_imports = ROUND_UP (fdef->num_imports + num_imports, 16);
916 fdef->imports = xrealloc (fdef->imports,
917 max_imports * sizeof (def_file_import));
919 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
921 i = fdef->imports + pos;
922 if (pos != fdef->num_imports)
923 memmove (i + num_imports, i,
924 sizeof (def_file_import) * (fdef->num_imports - pos));
930 def_file_add_import_at (def_file *fdef,
935 const char *internal_name,
936 const char *its_name)
938 def_file_import *i = fdef->imports + pos;
940 fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
941 internal_name, its_name);
954 { "-heap", HEAPSIZE },
955 { "-stack", STACKSIZE_K },
956 { "-attr", SECTIONS },
957 { "-export", EXPORTS },
958 { "-aligncomm", ALIGNCOMM },
963 def_file_add_directive (def_file *my_def, const char *param, int len)
965 def_file *save_def = def;
966 const char *pend = param + len;
967 char * tend = (char *) param;
975 && (ISSPACE (*param) || *param == '\n' || *param == 0))
981 /* Scan forward until we encounter any of:
982 - the end of the buffer
983 - the start of a new option
984 - a newline separating options
985 - a NUL separating options. */
986 for (tend = (char *) (param + 1);
988 && !(ISSPACE (tend[-1]) && *tend == '-')
989 && *tend != '\n' && *tend != 0);
993 for (i = 0; diropts[i].param; i++)
995 len = strlen (diropts[i].param);
997 if (tend - param >= len
998 && strncmp (param, diropts[i].param, len) == 0
999 && (param[len] == ':' || param[len] == ' '))
1001 lex_parse_string_end = tend;
1002 lex_parse_string = param + len + 1;
1003 lex_forced_token = diropts[i].token;
1011 if (!diropts[i].param)
1019 /* xgettext:c-format */
1020 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
1025 einfo (_("Warning: corrupt .drectve at end of def file\n"));
1029 lex_parse_string = 0;
1037 /* Parser Callbacks. */
1040 def_image_name (const char *name, bfd_vma base, int is_dll)
1042 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
1043 to do here. We retain the output filename specified on command line. */
1046 const char* image_name = lbasename (name);
1048 if (image_name != name)
1049 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
1050 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
1054 /* Append the default suffix, if none specified. */
1055 if (strchr (image_name, '.') == 0)
1057 const char * suffix = is_dll ? ".dll" : ".exe";
1059 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
1060 sprintf (def->name, "%s%s", image_name, suffix);
1063 def->name = xstrdup (image_name);
1066 /* Honor a BASE address statement, even if LIBRARY string is empty. */
1067 def->base_address = base;
1068 def->is_dll = is_dll;
1072 def_description (const char *text)
1074 int len = def->description ? strlen (def->description) : 0;
1076 len += strlen (text) + 1;
1077 if (def->description)
1079 def->description = xrealloc (def->description, len);
1080 strcat (def->description, text);
1084 def->description = xmalloc (len);
1085 strcpy (def->description, text);
1090 def_stacksize (int reserve, int commit)
1092 def->stack_reserve = reserve;
1093 def->stack_commit = commit;
1097 def_heapsize (int reserve, int commit)
1099 def->heap_reserve = reserve;
1100 def->heap_commit = commit;
1104 def_section (const char *name, int attr)
1106 def_file_section *s;
1107 int max_sections = ROUND_UP (def->num_section_defs, 4);
1109 if (def->num_section_defs >= max_sections)
1111 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1113 if (def->section_defs)
1114 def->section_defs = xrealloc (def->section_defs,
1115 max_sections * sizeof (def_file_import));
1117 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1119 s = def->section_defs + def->num_section_defs;
1120 memset (s, 0, sizeof (def_file_section));
1121 s->name = xstrdup (name);
1127 s->flag_execute = 1;
1131 def->num_section_defs++;
1135 def_section_alt (const char *name, const char *attr)
1139 for (; *attr; attr++)
1161 def_section (name, aval);
1165 def_exports (const char *external_name,
1166 const char *internal_name,
1169 const char *its_name)
1171 def_file_export *dfe;
1174 if (!internal_name && external_name)
1175 internal_name = external_name;
1177 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1180 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1183 /* We might check here for flag redefinition and warn. For now we
1184 ignore duplicates silently. */
1189 dfe->flag_noname = 1;
1191 dfe->flag_constant = 1;
1195 dfe->flag_private = 1;
1199 def_import (const char *internal_name,
1204 const char *its_name)
1207 const char *ext = dllext ? dllext : "dll";
1210 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1211 sprintf (buf, "%s.%s", module, ext);
1214 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1220 def_version (int major, int minor)
1222 def->version_major = major;
1223 def->version_minor = minor;
1227 def_directive (char *str)
1229 struct directive *d = xmalloc (sizeof (struct directive));
1231 d->next = directives;
1233 d->name = xstrdup (str);
1234 d->len = strlen (str);
1238 def_aligncomm (char *str, int align)
1240 def_file_aligncomm *c, *p;
1243 c = def->aligncomms;
1246 int e = strcmp (c->symbol_name, str);
1249 /* Not sure if we want to allow here duplicates with
1250 different alignments, but for now we keep them. */
1251 e = (int) c->alignment - align;
1260 c = xmalloc (sizeof (def_file_aligncomm));
1261 c->symbol_name = xstrdup (str);
1262 c->alignment = (unsigned int) align;
1265 c->next = def->aligncomms;
1266 def->aligncomms = c;
1276 def_error (const char *err)
1278 einfo ("%P: %s:%d: %s\n",
1279 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1284 /* Lexical Scanner. */
1289 /* Never freed, but always reused as needed, so no real leak. */
1290 static char *buffer = 0;
1291 static int buflen = 0;
1292 static int bufptr = 0;
1297 if (bufptr == buflen)
1299 buflen += 50; /* overly reasonable, eh? */
1301 buffer = xrealloc (buffer, buflen + 1);
1303 buffer = xmalloc (buflen + 1);
1305 buffer[bufptr++] = c;
1306 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1318 { "CONSTANT", CONSTANTU },
1319 { "constant", CONSTANTL },
1322 { "DESCRIPTION", DESCRIPTION },
1323 { "DIRECTIVE", DIRECTIVE },
1324 { "EXECUTE", EXECUTE },
1325 { "EXPORTS", EXPORTS },
1326 { "HEAPSIZE", HEAPSIZE },
1327 { "IMPORTS", IMPORTS },
1328 { "LIBRARY", LIBRARY },
1330 { "NONAME", NONAMEU },
1331 { "noname", NONAMEL },
1332 { "PRIVATE", PRIVATEU },
1333 { "private", PRIVATEL },
1335 { "SECTIONS", SECTIONS },
1336 { "SEGMENTS", SECTIONS },
1337 { "SHARED", SHARED },
1338 { "STACKSIZE", STACKSIZE_K },
1339 { "VERSION", VERSIONK },
1349 if (lex_parse_string)
1351 if (lex_parse_string >= lex_parse_string_end)
1354 rv = *lex_parse_string++;
1358 rv = fgetc (the_file);
1368 if (lex_parse_string)
1374 return ungetc (c, the_file);
1382 if (lex_forced_token)
1384 i = lex_forced_token;
1385 lex_forced_token = 0;
1387 printf ("lex: forcing token %d\n", i);
1394 /* Trim leading whitespace. */
1395 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1401 printf ("lex: EOF\n");
1406 if (saw_newline && c == ';')
1412 while (c != EOF && c != '\n');
1418 /* Must be something else. */
1424 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1431 yylval.digits = def_pool_strdup (buffer);
1433 printf ("lex: `%s' returns DIGITS\n", buffer);
1438 if (ISALPHA (c) || strchr ("$:-_?@", c))
1447 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1449 else if (ISDIGIT (c)) /* '@' followed by digit. */
1455 printf ("lex: @ returns itself\n");
1459 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1466 if (ISALPHA (q)) /* Check for tokens. */
1468 for (i = 0; tokens[i].name; i++)
1469 if (strcmp (tokens[i].name, buffer) == 0)
1472 printf ("lex: `%s' is a string token\n", buffer);
1474 return tokens[i].token;
1478 printf ("lex: `%s' returns ID\n", buffer);
1480 yylval.id = def_pool_strdup (buffer);
1484 if (c == '\'' || c == '"')
1490 while (c != EOF && c != q)
1495 yylval.id = def_pool_strdup (buffer);
1497 printf ("lex: `%s' returns ID\n", buffer);
1508 printf ("lex: `==' returns EQUAL\n");
1514 printf ("lex: `=' returns itself\n");
1518 if (c == '.' || c == ',')
1521 printf ("lex: `%c' returns itself\n", c);
1532 /*printf ("lex: 0x%02x ignored\n", c); */
1537 def_pool_alloc (size_t sz)
1541 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1542 e->next = pool_strs;
1548 def_pool_strdup (const char *str)
1554 len = strlen (str) + 1;
1555 s = def_pool_alloc (len);
1556 memcpy (s, str, len);
1561 def_pool_free (void)
1564 while ((p = pool_strs) != NULL)
1566 pool_strs = p->next;