1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995-2022 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 void def_exclude_symbols (char *str);
105 static int def_parse (void);
106 static void def_error (const char *);
107 static int def_lex (void);
109 static int lex_forced_token = 0;
110 static const char *lex_parse_string = 0;
111 static const char *lex_parse_string_end = 0;
117 const char *id_const;
123 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
124 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
125 %token PRIVATEU PRIVATEL ALIGNCOMM EXCLUDE_SYMBOLS
126 %token READ WRITE EXECUTE SHARED_K NONAMEU NONAMEL DIRECTIVE EQUAL
128 %token <digits> DIGITS
129 %type <number> NUMBER
130 %type <vma> VMA opt_base
131 %type <digits> opt_digits
132 %type <number> opt_ordinal
133 %type <number> attr attr_list opt_number exp_opt_list exp_opt
134 %type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
135 %type <id> opt_equalequal_name symbol_list
136 %type <id_const> keyword_as_name
145 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
146 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
147 | DESCRIPTION ID { def_description ($2);}
148 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
149 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
150 | CODE attr_list { def_section ("CODE", $2);}
151 | DATAU attr_list { def_section ("DATA", $2);}
155 | VERSIONK NUMBER { def_version ($2, 0);}
156 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
157 | DIRECTIVE ID { def_directive ($2);}
158 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
159 | EXCLUDE_SYMBOLS symbol_list
170 /* The opt_comma is necessary to support both the usual
171 DEF file syntax as well as .drectve syntax which
172 mandates <expsym>,<expoptlist>. */
173 opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
174 { def_exports ($1, $2, $3, $5, $7); }
177 /* The opt_comma is necessary to support both the usual
178 DEF file syntax as well as .drectve syntax which
179 allows for comma separated opt list. */
180 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
185 | NONAMEL { $$ = 1; }
186 | CONSTANTU { $$ = 2; }
187 | CONSTANTL { $$ = 2; }
190 | PRIVATEU { $$ = 8; }
191 | PRIVATEL { $$ = 8; }
199 ID '=' ID '.' ID '.' ID opt_equalequal_name
200 { def_import ($1, $3, $5, $7, -1, $8); }
201 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
202 { def_import ($1, $3, $5, 0, $7, $8); }
203 | ID '=' ID '.' ID opt_equalequal_name
204 { def_import ($1, $3, 0, $5, -1, $6); }
205 | ID '=' ID '.' NUMBER opt_equalequal_name
206 { def_import ($1, $3, 0, 0, $5, $6); }
207 | ID '.' ID '.' ID opt_equalequal_name
208 { def_import( 0, $1, $3, $5, -1, $6); }
209 | ID '.' ID opt_equalequal_name
210 { def_import ( 0, $1, 0, $3, -1, $4); }
219 ID attr_list { def_section ($1, $2);}
220 | ID ID { def_section_alt ($1, $2);}
224 attr_list opt_comma attr { $$ = $1 | $3; }
232 opt_number: ',' NUMBER { $$=$2;}
244 keyword_as_name: BASE { $$ = "BASE"; }
245 | CODE { $$ = "CODE"; }
246 | CONSTANTU { $$ = "CONSTANT"; }
247 | CONSTANTL { $$ = "constant"; }
248 | DATAU { $$ = "DATA"; }
249 | DATAL { $$ = "data"; }
250 | DESCRIPTION { $$ = "DESCRIPTION"; }
251 | DIRECTIVE { $$ = "DIRECTIVE"; }
252 | EXCLUDE_SYMBOLS { $$ = "EXCLUDE_SYMBOLS"; }
253 | EXECUTE { $$ = "EXECUTE"; }
254 | EXPORTS { $$ = "EXPORTS"; }
255 | HEAPSIZE { $$ = "HEAPSIZE"; }
256 | IMPORTS { $$ = "IMPORTS"; }
257 /* Disable LIBRARY keyword as valid symbol-name. This is necessary
258 for libtool, which places this command after EXPORTS command.
259 This behavior is illegal by specification, but sadly required by
260 by compatibility reasons.
261 See PR binutils/13710
262 | LIBRARY { $$ = "LIBRARY"; } */
263 | NAME { $$ = "NAME"; }
264 | NONAMEU { $$ = "NONAME"; }
265 | NONAMEL { $$ = "noname"; }
266 | PRIVATEU { $$ = "PRIVATE"; }
267 | PRIVATEL { $$ = "private"; }
268 | READ { $$ = "READ"; }
269 | SHARED_K { $$ = "SHARED"; }
270 | STACKSIZE_K { $$ = "STACKSIZE"; }
271 | VERSIONK { $$ = "VERSION"; }
272 | WRITE { $$ = "WRITE"; }
275 opt_name2: ID { $$ = $1; }
276 | '.' keyword_as_name
278 char *name = xmalloc (strlen ($2) + 2);
279 sprintf (name, ".%s", $2);
284 char *name = def_pool_alloc (strlen ($2) + 2);
285 sprintf (name, ".%s", $2);
288 | keyword_as_name '.' opt_name2
290 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
291 sprintf (name, "%s.%s", $1, $3);
296 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
297 sprintf (name, "%s.%s", $1, $3);
302 opt_name: opt_name2 { $$ = $1; }
306 opt_equalequal_name: EQUAL ID { $$ = $2; }
311 '@' NUMBER { $$ = $2;}
316 '=' opt_name2 { $$ = $2; }
320 opt_base: BASE '=' VMA { $$ = $3;}
321 | { $$ = (bfd_vma) -1;}
324 anylang_id: ID { $$ = $1; }
327 char *id = def_pool_alloc (strlen ($2) + 2);
328 sprintf (id, ".%s", $2);
331 | anylang_id '.' opt_digits opt_id
333 char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
334 sprintf (id, "%s.%s%s", $1, $3, $4);
340 anylang_id { def_exclude_symbols ($1); }
341 | symbol_list anylang_id { def_exclude_symbols ($2); }
342 | symbol_list ',' anylang_id { def_exclude_symbols ($3); }
345 opt_digits: DIGITS { $$ = $1; }
349 opt_id: ID { $$ = $1; }
353 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
355 VMA: DIGITS { $$ = (bfd_vma) strtoull ($1, 0, 0); }
359 /*****************************************************************************
361 *****************************************************************************/
363 static FILE *the_file;
364 static const char *def_filename;
365 static int linenumber;
366 static def_file *def;
367 static int saw_newline;
371 struct directive *next;
376 static struct directive *directives = 0;
379 def_file_empty (void)
381 def_file *rv = xmalloc (sizeof (def_file));
382 memset (rv, 0, sizeof (def_file));
384 rv->base_address = (bfd_vma) -1;
385 rv->stack_reserve = rv->stack_commit = -1;
386 rv->heap_reserve = rv->heap_commit = -1;
387 rv->version_major = rv->version_minor = -1;
392 def_file_parse (const char *filename, def_file *add_to)
396 the_file = fopen (filename, "r");
397 def_filename = filename;
410 def = def_file_empty ();
424 while ((d = directives) != NULL)
427 printf ("Adding directive %08x `%s'\n", d->name, d->name);
429 def_file_add_directive (def, d->name, d->len);
430 directives = d->next;
440 def_file_free (def_file *fdef)
447 free (fdef->description);
449 if (fdef->section_defs)
451 for (i = 0; i < fdef->num_section_defs; i++)
453 free (fdef->section_defs[i].name);
454 free (fdef->section_defs[i].class);
456 free (fdef->section_defs);
461 for (i = 0; i < fdef->num_exports; i++)
463 if (fdef->exports[i].internal_name != fdef->exports[i].name)
464 free (fdef->exports[i].internal_name);
465 free (fdef->exports[i].name);
466 free (fdef->exports[i].its_name);
468 free (fdef->exports);
473 for (i = 0; i < fdef->num_imports; i++)
475 if (fdef->imports[i].internal_name != fdef->imports[i].name)
476 free (fdef->imports[i].internal_name);
477 free (fdef->imports[i].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);
500 while (fdef->exclude_symbols)
502 def_file_exclude_symbol *e = fdef->exclude_symbols;
504 fdef->exclude_symbols = fdef->exclude_symbols->next;
505 free (e->symbol_name);
512 #ifdef DEF_FILE_PRINT
514 def_file_print (FILE *file, def_file *fdef)
518 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
520 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
521 if (fdef->is_dll != -1)
522 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
523 if (fdef->base_address != (bfd_vma) -1)
524 fprintf (file, " base address: 0x%" PRIx64 "\n",
525 (uint64_t) fdef->base_address);
526 if (fdef->description)
527 fprintf (file, " description: `%s'\n", fdef->description);
528 if (fdef->stack_reserve != -1)
529 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
530 if (fdef->stack_commit != -1)
531 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
532 if (fdef->heap_reserve != -1)
533 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
534 if (fdef->heap_commit != -1)
535 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
537 if (fdef->num_section_defs > 0)
539 fprintf (file, " section defs:\n");
541 for (i = 0; i < fdef->num_section_defs; i++)
543 fprintf (file, " name: `%s', class: `%s', flags:",
544 fdef->section_defs[i].name, fdef->section_defs[i].class);
545 if (fdef->section_defs[i].flag_read)
546 fprintf (file, " R");
547 if (fdef->section_defs[i].flag_write)
548 fprintf (file, " W");
549 if (fdef->section_defs[i].flag_execute)
550 fprintf (file, " X");
551 if (fdef->section_defs[i].flag_shared)
552 fprintf (file, " S");
553 fprintf (file, "\n");
557 if (fdef->num_exports > 0)
559 fprintf (file, " exports:\n");
561 for (i = 0; i < fdef->num_exports; i++)
563 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
564 fdef->exports[i].name, fdef->exports[i].internal_name,
565 fdef->exports[i].ordinal);
566 if (fdef->exports[i].flag_private)
567 fprintf (file, " P");
568 if (fdef->exports[i].flag_constant)
569 fprintf (file, " C");
570 if (fdef->exports[i].flag_noname)
571 fprintf (file, " N");
572 if (fdef->exports[i].flag_data)
573 fprintf (file, " D");
574 fprintf (file, "\n");
578 if (fdef->num_imports > 0)
580 fprintf (file, " imports:\n");
582 for (i = 0; i < fdef->num_imports; i++)
584 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
585 fdef->imports[i].internal_name,
586 fdef->imports[i].module,
587 fdef->imports[i].name,
588 fdef->imports[i].ordinal);
592 if (fdef->version_major != -1)
593 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
595 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
599 /* Helper routine to check for identity of string pointers,
600 which might be NULL. */
603 are_names_equal (const char *s1, const char *s2)
608 return (!s1 ? -1 : 1);
609 return strcmp (s1, s2);
613 cmp_export_elem (const def_file_export *e, const char *ex_name,
614 const char *in_name, const char *its_name,
619 if ((r = are_names_equal (ex_name, e->name)) != 0)
621 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
623 if ((r = are_names_equal (its_name, e->its_name)) != 0)
625 return (ord - e->ordinal);
628 /* Search the position of the identical element, or returns the position
629 of the next higher element. If last valid element is smaller, then MAX
633 find_export_in_list (def_file_export *b, int max,
634 const char *ex_name, const char *in_name,
635 const char *its_name, int ord, int *is_ident)
642 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
650 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
652 else if (!e || max == 2)
662 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
673 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
681 def_file_add_export (def_file *fdef,
682 const char *external_name,
683 const char *internal_name,
685 const char *its_name,
690 int max_exports = ROUND_UP(fdef->num_exports, 32);
692 if (internal_name && !external_name)
693 external_name = internal_name;
694 if (external_name && !internal_name)
695 internal_name = external_name;
697 /* We need to avoid duplicates. */
699 pos = find_export_in_list (fdef->exports, fdef->num_exports,
700 external_name, internal_name,
701 its_name, ordinal, is_dup);
704 return (fdef->exports + pos);
706 if (fdef->num_exports >= max_exports)
708 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
710 fdef->exports = xrealloc (fdef->exports,
711 max_exports * sizeof (def_file_export));
713 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
716 e = fdef->exports + pos;
717 if (pos != fdef->num_exports)
718 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
719 memset (e, 0, sizeof (def_file_export));
720 e->name = xstrdup (external_name);
721 e->internal_name = xstrdup (internal_name);
722 e->its_name = (its_name ? xstrdup (its_name) : NULL);
723 e->ordinal = ordinal;
729 def_get_module (def_file *fdef, const char *name)
733 for (s = fdef->modules; s; s = s->next)
734 if (strcmp (s->name, name) == 0)
740 static def_file_module *
741 def_stash_module (def_file *fdef, const char *name)
745 if ((s = def_get_module (fdef, name)) != NULL)
747 s = xmalloc (sizeof (def_file_module) + strlen (name));
748 s->next = fdef->modules;
751 strcpy (s->name, name);
756 cmp_import_elem (const def_file_import *e, const char *ex_name,
757 const char *in_name, const char *module,
762 if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
764 if ((r = are_names_equal (ex_name, e->name)) != 0)
766 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
768 if (ord != e->ordinal)
769 return (ord < e->ordinal ? -1 : 1);
773 /* Search the position of the identical element, or returns the position
774 of the next higher element. If last valid element is smaller, then MAX
778 find_import_in_list (def_file_import *b, int max,
779 const char *ex_name, const char *in_name,
780 const char *module, int ord, int *is_ident)
787 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
795 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
797 else if (!e || max == 2)
807 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
818 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
826 fill_in_import (def_file_import *i,
828 def_file_module *module,
830 const char *internal_name,
831 const char *its_name)
833 memset (i, 0, sizeof (def_file_import));
835 i->name = xstrdup (name);
837 i->ordinal = ordinal;
839 i->internal_name = xstrdup (internal_name);
841 i->internal_name = i->name;
842 i->its_name = (its_name ? xstrdup (its_name) : NULL);
846 def_file_add_import (def_file *fdef,
850 const char *internal_name,
851 const char *its_name,
856 int max_imports = ROUND_UP (fdef->num_imports, 16);
858 /* We need to avoid here duplicates. */
860 pos = find_import_in_list (fdef->imports, fdef->num_imports,
862 (!internal_name ? name : internal_name),
863 module, ordinal, is_dup);
865 return fdef->imports + pos;
867 if (fdef->num_imports >= max_imports)
869 max_imports = ROUND_UP (fdef->num_imports+1, 16);
872 fdef->imports = xrealloc (fdef->imports,
873 max_imports * sizeof (def_file_import));
875 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
877 i = fdef->imports + pos;
878 if (pos != fdef->num_imports)
879 memmove (i + 1, i, sizeof (def_file_import) * (fdef->num_imports - pos));
881 fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
882 internal_name, its_name);
889 def_file_add_import_from (def_file *fdef,
894 const char *internal_name,
895 const char *its_name ATTRIBUTE_UNUSED)
900 int max_imports = ROUND_UP (fdef->num_imports, 16);
902 /* We need to avoid here duplicates. */
904 pos = find_import_in_list (fdef->imports, fdef->num_imports,
905 name, internal_name ? internal_name : name,
906 module, ordinal, &is_dup);
909 if (fdef->imports && pos != fdef->num_imports)
911 i = fdef->imports + pos;
912 if (i->module && strcmp (i->module->name, module) == 0)
916 if (fdef->num_imports + num_imports - 1 >= max_imports)
918 max_imports = ROUND_UP (fdef->num_imports + num_imports, 16);
921 fdef->imports = xrealloc (fdef->imports,
922 max_imports * sizeof (def_file_import));
924 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
926 i = fdef->imports + pos;
927 if (pos != fdef->num_imports)
928 memmove (i + num_imports, i,
929 sizeof (def_file_import) * (fdef->num_imports - pos));
935 def_file_add_import_at (def_file *fdef,
940 const char *internal_name,
941 const char *its_name)
943 def_file_import *i = fdef->imports + pos;
945 fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
946 internal_name, its_name);
959 { "-heap", HEAPSIZE },
960 { "-stack", STACKSIZE_K },
961 { "-attr", SECTIONS },
962 { "-export", EXPORTS },
963 { "-aligncomm", ALIGNCOMM },
964 { "-exclude-symbols", EXCLUDE_SYMBOLS },
969 def_file_add_directive (def_file *my_def, const char *param, int len)
971 def_file *save_def = def;
972 const char *pend = param + len;
973 char * tend = (char *) param;
981 && (ISSPACE (*param) || *param == '\n' || *param == 0))
987 /* Scan forward until we encounter any of:
988 - the end of the buffer
989 - the start of a new option
990 - a newline separating options
991 - a NUL separating options. */
992 for (tend = (char *) (param + 1);
994 && !(ISSPACE (tend[-1]) && *tend == '-')
995 && *tend != '\n' && *tend != 0);
999 for (i = 0; diropts[i].param; i++)
1001 len = strlen (diropts[i].param);
1003 if (tend - param >= len
1004 && strncmp (param, diropts[i].param, len) == 0
1005 && (param[len] == ':' || param[len] == ' '))
1007 lex_parse_string_end = tend;
1008 lex_parse_string = param + len + 1;
1009 lex_forced_token = diropts[i].token;
1017 if (!diropts[i].param)
1025 /* xgettext:c-format */
1026 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
1031 einfo (_("Warning: corrupt .drectve at end of def file\n"));
1035 lex_parse_string = 0;
1043 /* Parser Callbacks. */
1046 def_image_name (const char *name, bfd_vma base, int is_dll)
1048 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
1049 to do here. We retain the output filename specified on command line. */
1052 const char* image_name = lbasename (name);
1054 if (image_name != name)
1055 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
1056 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
1059 /* Append the default suffix, if none specified. */
1060 if (strchr (image_name, '.') == 0)
1062 const char * suffix = is_dll ? ".dll" : ".exe";
1064 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
1065 sprintf (def->name, "%s%s", image_name, suffix);
1068 def->name = xstrdup (image_name);
1071 /* Honor a BASE address statement, even if LIBRARY string is empty. */
1072 def->base_address = base;
1073 def->is_dll = is_dll;
1077 def_description (const char *text)
1079 int len = def->description ? strlen (def->description) : 0;
1081 len += strlen (text) + 1;
1082 if (def->description)
1084 def->description = xrealloc (def->description, len);
1085 strcat (def->description, text);
1089 def->description = xmalloc (len);
1090 strcpy (def->description, text);
1095 def_stacksize (int reserve, int commit)
1097 def->stack_reserve = reserve;
1098 def->stack_commit = commit;
1102 def_heapsize (int reserve, int commit)
1104 def->heap_reserve = reserve;
1105 def->heap_commit = commit;
1109 def_section (const char *name, int attr)
1111 def_file_section *s;
1112 int max_sections = ROUND_UP (def->num_section_defs, 4);
1114 if (def->num_section_defs >= max_sections)
1116 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1118 if (def->section_defs)
1119 def->section_defs = xrealloc (def->section_defs,
1120 max_sections * sizeof (def_file_import));
1122 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1124 s = def->section_defs + def->num_section_defs;
1125 memset (s, 0, sizeof (def_file_section));
1126 s->name = xstrdup (name);
1132 s->flag_execute = 1;
1136 def->num_section_defs++;
1140 def_section_alt (const char *name, const char *attr)
1144 for (; *attr; attr++)
1166 def_section (name, aval);
1170 def_exports (const char *external_name,
1171 const char *internal_name,
1174 const char *its_name)
1176 def_file_export *dfe;
1179 if (!internal_name && external_name)
1180 internal_name = external_name;
1182 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1185 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1188 /* We might check here for flag redefinition and warn. For now we
1189 ignore duplicates silently. */
1194 dfe->flag_noname = 1;
1196 dfe->flag_constant = 1;
1200 dfe->flag_private = 1;
1204 def_import (const char *internal_name,
1209 const char *its_name)
1212 const char *ext = dllext ? dllext : "dll";
1215 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1216 sprintf (buf, "%s.%s", module, ext);
1219 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1225 def_version (int major, int minor)
1227 def->version_major = major;
1228 def->version_minor = minor;
1232 def_directive (char *str)
1234 struct directive *d = xmalloc (sizeof (struct directive));
1236 d->next = directives;
1238 d->name = xstrdup (str);
1239 d->len = strlen (str);
1243 def_aligncomm (char *str, int align)
1245 def_file_aligncomm *c, *p;
1248 c = def->aligncomms;
1251 int e = strcmp (c->symbol_name, str);
1254 /* Not sure if we want to allow here duplicates with
1255 different alignments, but for now we keep them. */
1256 e = (int) c->alignment - align;
1265 c = xmalloc (sizeof (def_file_aligncomm));
1266 c->symbol_name = xstrdup (str);
1267 c->alignment = (unsigned int) align;
1270 c->next = def->aligncomms;
1271 def->aligncomms = c;
1281 def_exclude_symbols (char *str)
1283 def_file_exclude_symbol *c, *p;
1286 c = def->exclude_symbols;
1289 int e = strcmp (c->symbol_name, str);
1295 c = xmalloc (sizeof (def_file_exclude_symbol));
1296 c->symbol_name = xstrdup (str);
1299 c->next = def->exclude_symbols;
1300 def->exclude_symbols = c;
1310 def_error (const char *err)
1312 einfo ("%P: %s:%d: %s\n",
1313 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1317 /* Lexical Scanner. */
1322 /* Never freed, but always reused as needed, so no real leak. */
1323 static char *buffer = 0;
1324 static int buflen = 0;
1325 static int bufptr = 0;
1330 if (bufptr == buflen)
1332 buflen += 50; /* overly reasonable, eh? */
1334 buffer = xrealloc (buffer, buflen + 1);
1336 buffer = xmalloc (buflen + 1);
1338 buffer[bufptr++] = c;
1339 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1351 { "CONSTANT", CONSTANTU },
1352 { "constant", CONSTANTL },
1355 { "DESCRIPTION", DESCRIPTION },
1356 { "DIRECTIVE", DIRECTIVE },
1357 { "EXCLUDE_SYMBOLS", EXCLUDE_SYMBOLS },
1358 { "EXECUTE", EXECUTE },
1359 { "EXPORTS", EXPORTS },
1360 { "HEAPSIZE", HEAPSIZE },
1361 { "IMPORTS", IMPORTS },
1362 { "LIBRARY", LIBRARY },
1364 { "NONAME", NONAMEU },
1365 { "noname", NONAMEL },
1366 { "PRIVATE", PRIVATEU },
1367 { "private", PRIVATEL },
1369 { "SECTIONS", SECTIONS },
1370 { "SEGMENTS", SECTIONS },
1371 { "SHARED", SHARED_K },
1372 { "STACKSIZE", STACKSIZE_K },
1373 { "VERSION", VERSIONK },
1383 if (lex_parse_string)
1385 if (lex_parse_string >= lex_parse_string_end)
1388 rv = *lex_parse_string++;
1392 rv = fgetc (the_file);
1402 if (lex_parse_string)
1408 return ungetc (c, the_file);
1416 if (lex_forced_token)
1418 i = lex_forced_token;
1419 lex_forced_token = 0;
1421 printf ("lex: forcing token %d\n", i);
1428 /* Trim leading whitespace. */
1429 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1435 printf ("lex: EOF\n");
1440 if (saw_newline && c == ';')
1446 while (c != EOF && c != '\n');
1452 /* Must be something else. */
1458 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1465 yylval.digits = def_pool_strdup (buffer);
1467 printf ("lex: `%s' returns DIGITS\n", buffer);
1472 if (ISALPHA (c) || strchr ("$:-_?@", c))
1481 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1483 else if (ISDIGIT (c)) /* '@' followed by digit. */
1489 printf ("lex: @ returns itself\n");
1493 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1500 if (ISALPHA (q)) /* Check for tokens. */
1502 for (i = 0; tokens[i].name; i++)
1503 if (strcmp (tokens[i].name, buffer) == 0)
1506 printf ("lex: `%s' is a string token\n", buffer);
1508 return tokens[i].token;
1512 printf ("lex: `%s' returns ID\n", buffer);
1514 yylval.id = def_pool_strdup (buffer);
1518 if (c == '\'' || c == '"')
1524 while (c != EOF && c != q)
1529 yylval.id = def_pool_strdup (buffer);
1531 printf ("lex: `%s' returns ID\n", buffer);
1542 printf ("lex: `==' returns EQUAL\n");
1548 printf ("lex: `=' returns itself\n");
1552 if (c == '.' || c == ',')
1555 printf ("lex: `%c' returns itself\n", c);
1566 /*printf ("lex: 0x%02x ignored\n", c); */
1571 def_pool_alloc (size_t sz)
1575 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1576 e->next = pool_strs;
1582 def_pool_strdup (const char *str)
1588 len = strlen (str) + 1;
1589 s = def_pool_alloc (len);
1590 memcpy (s, str, len);
1595 def_pool_free (void)
1598 while ((p = pool_strs) != NULL)
1600 pool_strs = p->next;