1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995-2024 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 #define SYMBOL_LIST_ARRAY_GROW 64
37 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
38 as well as gratuitiously global symbol names, so we can have multiple
39 yacc generated parsers in ld. Note that these are only the variables
40 produced by yacc. If other parser generators (bison, byacc, etc) produce
41 additional global names that conflict at link time, then those parser
42 generators need to be fixed instead of adding those names to this list. */
44 #define yymaxdepth def_maxdepth
45 #define yyparse def_parse
47 #define yyerror def_error
48 #define yylval def_lval
49 #define yychar def_char
50 #define yydebug def_debug
51 #define yypact def_pact
58 #define yyexca def_exca
59 #define yyerrflag def_errflag
60 #define yynerrs def_nerrs
64 #define yy_yys def_yys
65 #define yystate def_state
68 #define yy_yyv def_yyv
70 #define yylloc def_lloc
71 #define yyreds def_reds /* With YYDEBUG defined. */
72 #define yytoks def_toks /* With YYDEBUG defined. */
73 #define yylhs def_yylhs
74 #define yylen def_yylen
75 #define yydefred def_yydefred
76 #define yydgoto def_yydgoto
77 #define yysindex def_yysindex
78 #define yyrindex def_yyrindex
79 #define yygindex def_yygindex
80 #define yytable def_yytable
81 #define yycheck def_yycheck
83 typedef struct def_pool_str {
84 struct def_pool_str *next;
88 static def_pool_str *pool_strs = NULL;
90 static char *def_pool_alloc (size_t sz);
91 static char *def_pool_strdup (const char *str);
92 static void def_pool_free (void);
94 static void def_description (const char *);
95 static void def_exports (const char *, const char *, int, int, const char *);
96 static void def_heapsize (int, int);
97 static void def_import (const char *, const char *, const char *, const char *,
99 static void def_image_name (const char *, bfd_vma, int);
100 static void def_section (const char *, int);
101 static void def_section_alt (const char *, const char *);
102 static void def_stacksize (int, int);
103 static void def_version (int, int);
104 static void def_directive (char *);
105 static void def_aligncomm (char *str, int align);
106 static void def_exclude_symbols (char *str);
107 static int def_parse (void);
108 static void def_error (const char *);
109 static int def_lex (void);
111 static int lex_forced_token = 0;
112 static const char *lex_parse_string = 0;
113 static const char *lex_parse_string_end = 0;
119 const char *id_const;
125 %token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
126 %token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
127 %token PRIVATEU PRIVATEL ALIGNCOMM EXCLUDE_SYMBOLS
128 %token READ WRITE EXECUTE SHARED_K NONAMEU NONAMEL DIRECTIVE EQUAL
130 %token <digits> DIGITS
131 %type <number> NUMBER
132 %type <vma> VMA opt_base
133 %type <digits> opt_digits
134 %type <number> opt_ordinal
135 %type <number> attr attr_list opt_number exp_opt_list exp_opt
136 %type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
137 %type <id> opt_equalequal_name symbol_list
138 %type <id_const> keyword_as_name
147 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
148 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
149 | DESCRIPTION ID { def_description ($2);}
150 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
151 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
152 | CODE attr_list { def_section ("CODE", $2);}
153 | DATAU attr_list { def_section ("DATA", $2);}
157 | VERSIONK NUMBER { def_version ($2, 0);}
158 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
159 | DIRECTIVE ID { def_directive ($2);}
160 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
161 | EXCLUDE_SYMBOLS symbol_list
172 /* The opt_comma is necessary to support both the usual
173 DEF file syntax as well as .drectve syntax which
174 mandates <expsym>,<expoptlist>. */
175 opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
176 { def_exports ($1, $2, $3, $5, $7); }
179 /* The opt_comma is necessary to support both the usual
180 DEF file syntax as well as .drectve syntax which
181 allows for comma separated opt list. */
182 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
187 | NONAMEL { $$ = 1; }
188 | CONSTANTU { $$ = 2; }
189 | CONSTANTL { $$ = 2; }
192 | PRIVATEU { $$ = 8; }
193 | PRIVATEL { $$ = 8; }
201 ID '=' ID '.' ID '.' ID opt_equalequal_name
202 { def_import ($1, $3, $5, $7, -1, $8); }
203 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
204 { def_import ($1, $3, $5, 0, $7, $8); }
205 | ID '=' ID '.' ID opt_equalequal_name
206 { def_import ($1, $3, 0, $5, -1, $6); }
207 | ID '=' ID '.' NUMBER opt_equalequal_name
208 { def_import ($1, $3, 0, 0, $5, $6); }
209 | ID '.' ID '.' ID opt_equalequal_name
210 { def_import( 0, $1, $3, $5, -1, $6); }
211 | ID '.' ID opt_equalequal_name
212 { def_import ( 0, $1, 0, $3, -1, $4); }
221 ID attr_list { def_section ($1, $2);}
222 | ID ID { def_section_alt ($1, $2);}
226 attr_list opt_comma attr { $$ = $1 | $3; }
234 opt_number: ',' NUMBER { $$=$2;}
246 keyword_as_name: BASE { $$ = "BASE"; }
247 | CODE { $$ = "CODE"; }
248 | CONSTANTU { $$ = "CONSTANT"; }
249 | CONSTANTL { $$ = "constant"; }
250 | DATAU { $$ = "DATA"; }
251 | DATAL { $$ = "data"; }
252 | DESCRIPTION { $$ = "DESCRIPTION"; }
253 | DIRECTIVE { $$ = "DIRECTIVE"; }
254 | EXCLUDE_SYMBOLS { $$ = "EXCLUDE_SYMBOLS"; }
255 | EXECUTE { $$ = "EXECUTE"; }
256 | EXPORTS { $$ = "EXPORTS"; }
257 | HEAPSIZE { $$ = "HEAPSIZE"; }
258 | IMPORTS { $$ = "IMPORTS"; }
259 /* Disable LIBRARY keyword as valid symbol-name. This is necessary
260 for libtool, which places this command after EXPORTS command.
261 This behavior is illegal by specification, but sadly required by
262 by compatibility reasons.
263 See PR binutils/13710
264 | LIBRARY { $$ = "LIBRARY"; } */
265 | NAME { $$ = "NAME"; }
266 | NONAMEU { $$ = "NONAME"; }
267 | NONAMEL { $$ = "noname"; }
268 | PRIVATEU { $$ = "PRIVATE"; }
269 | PRIVATEL { $$ = "private"; }
270 | READ { $$ = "READ"; }
271 | SHARED_K { $$ = "SHARED"; }
272 | STACKSIZE_K { $$ = "STACKSIZE"; }
273 | VERSIONK { $$ = "VERSION"; }
274 | WRITE { $$ = "WRITE"; }
277 opt_name2: ID { $$ = $1; }
278 | '.' keyword_as_name
280 char *name = xmalloc (strlen ($2) + 2);
281 sprintf (name, ".%s", $2);
286 char *name = def_pool_alloc (strlen ($2) + 2);
287 sprintf (name, ".%s", $2);
290 | keyword_as_name '.' opt_name2
292 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
293 sprintf (name, "%s.%s", $1, $3);
298 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
299 sprintf (name, "%s.%s", $1, $3);
304 opt_name: opt_name2 { $$ = $1; }
308 opt_equalequal_name: EQUAL ID { $$ = $2; }
313 '@' NUMBER { $$ = $2;}
318 '=' opt_name2 { $$ = $2; }
322 opt_base: BASE '=' VMA { $$ = $3;}
323 | { $$ = (bfd_vma) -1;}
326 anylang_id: ID { $$ = $1; }
329 char *id = def_pool_alloc (strlen ($2) + 2);
330 sprintf (id, ".%s", $2);
333 | anylang_id '.' opt_digits opt_id
335 char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
336 sprintf (id, "%s.%s%s", $1, $3, $4);
342 anylang_id { def_exclude_symbols ($1); }
343 | symbol_list anylang_id { def_exclude_symbols ($2); }
344 | symbol_list ',' anylang_id { def_exclude_symbols ($3); }
347 opt_digits: DIGITS { $$ = $1; }
351 opt_id: ID { $$ = $1; }
355 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
357 VMA: DIGITS { $$ = (bfd_vma) strtoull ($1, 0, 0); }
361 /*****************************************************************************
363 *****************************************************************************/
365 static FILE *the_file;
366 static const char *def_filename;
367 static int linenumber;
368 static def_file *def;
369 static int saw_newline;
373 struct directive *next;
378 static struct directive *directives = 0;
381 def_file_empty (void)
383 def_file *rv = xmalloc (sizeof (def_file));
384 memset (rv, 0, sizeof (def_file));
386 rv->base_address = (bfd_vma) -1;
387 rv->stack_reserve = rv->stack_commit = -1;
388 rv->heap_reserve = rv->heap_commit = -1;
389 rv->version_major = rv->version_minor = -1;
394 def_file_parse (const char *filename, def_file *add_to)
398 the_file = fopen (filename, "r");
399 def_filename = filename;
412 def = def_file_empty ();
426 while ((d = directives) != NULL)
429 printf ("Adding directive %08x `%s'\n", d->name, d->name);
431 def_file_add_directive (def, d->name, d->len);
432 directives = d->next;
442 def_file_free (def_file *fdef)
450 free (fdef->description);
452 if (fdef->section_defs)
454 for (i = 0; i < fdef->num_section_defs; i++)
456 free (fdef->section_defs[i].name);
457 free (fdef->section_defs[i].class);
459 free (fdef->section_defs);
462 for (i = 0; i < fdef->num_exports; i++)
464 if (fdef->exports[i].internal_name != fdef->exports[i].name)
465 free (fdef->exports[i].internal_name);
466 free (fdef->exports[i].name);
467 free (fdef->exports[i].its_name);
469 free (fdef->exports);
471 for (i = 0; i < fdef->num_imports; i++)
473 if (fdef->imports[i].internal_name != fdef->imports[i].name)
474 free (fdef->imports[i].internal_name);
475 free (fdef->imports[i].name);
476 free (fdef->imports[i].its_name);
478 free (fdef->imports);
480 while (fdef->modules)
482 def_file_module *m = fdef->modules;
484 fdef->modules = fdef->modules->next;
488 while (fdef->aligncomms)
490 def_file_aligncomm *c = fdef->aligncomms;
492 fdef->aligncomms = fdef->aligncomms->next;
493 free (c->symbol_name);
497 for (ui = 0; ui < fdef->num_exclude_symbols; ui++)
499 free (fdef->exclude_symbols[ui].symbol_name);
501 free (fdef->exclude_symbols);
506 #ifdef DEF_FILE_PRINT
508 def_file_print (FILE *file, def_file *fdef)
512 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
514 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
515 if (fdef->is_dll != -1)
516 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
517 if (fdef->base_address != (bfd_vma) -1)
518 fprintf (file, " base address: 0x%" PRIx64 "\n",
519 (uint64_t) fdef->base_address);
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
624 is returned. The max parameter indicates the number of elements in the
625 array. On return, *is_ident indicates whether the returned array index
626 points at an element which is identical to the one searched for. */
629 find_export_in_list (def_file_export *b, unsigned int max,
630 const char *ex_name, const char *in_name,
631 const char *its_name, int ord, bool *is_ident)
634 unsigned int l, r, p;
639 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
647 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
649 else if (!e || max == 2)
659 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
670 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
678 def_file_add_export (def_file *fdef,
679 const char *external_name,
680 const char *internal_name,
682 const char *its_name,
688 if (internal_name && !external_name)
689 external_name = internal_name;
690 if (external_name && !internal_name)
691 internal_name = external_name;
693 /* We need to avoid duplicates. */
695 pos = find_export_in_list (fdef->exports, fdef->num_exports,
696 external_name, internal_name,
697 its_name, ordinal, is_dup);
700 return (fdef->exports + pos);
702 if ((unsigned)fdef->num_exports >= fdef->max_exports)
704 fdef->max_exports += SYMBOL_LIST_ARRAY_GROW;
705 fdef->exports = xrealloc (fdef->exports,
706 fdef->max_exports * sizeof (def_file_export));
709 e = fdef->exports + pos;
710 /* If we're inserting in the middle of the array, we need to move the
711 following elements forward. */
712 if (pos != (unsigned)fdef->num_exports)
713 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
714 /* Wipe the element for use as a new entry. */
715 memset (e, 0, sizeof (def_file_export));
716 e->name = xstrdup (external_name);
717 e->internal_name = xstrdup (internal_name);
718 e->its_name = (its_name ? xstrdup (its_name) : NULL);
719 e->ordinal = ordinal;
725 def_get_module (def_file *fdef, const char *name)
729 for (s = fdef->modules; s; s = s->next)
730 if (strcmp (s->name, name) == 0)
736 static def_file_module *
737 def_stash_module (def_file *fdef, const char *name)
741 if ((s = def_get_module (fdef, name)) != NULL)
743 s = xmalloc (sizeof (def_file_module) + strlen (name));
744 s->next = fdef->modules;
747 strcpy (s->name, name);
752 cmp_import_elem (const def_file_import *e, const char *ex_name,
753 const char *in_name, const char *module,
758 if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
760 if ((r = are_names_equal (ex_name, e->name)) != 0)
762 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
764 if (ord != e->ordinal)
765 return (ord < e->ordinal ? -1 : 1);
769 /* Search the position of the identical element, or returns the position
770 of the next higher element. If last valid element is smaller, then MAX
771 is returned. The max parameter indicates the number of elements in the
772 array. On return, *is_ident indicates whether the returned array index
773 points at an element which is identical to the one searched for. */
776 find_import_in_list (def_file_import *b, unsigned int max,
777 const char *ex_name, const char *in_name,
778 const char *module, int ord, bool *is_ident)
781 unsigned int l, r, p;
786 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
794 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
796 else if (!e || max == 2)
806 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
817 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
825 fill_in_import (def_file_import *i,
827 def_file_module *module,
829 const char *internal_name,
830 const char *its_name)
832 memset (i, 0, sizeof (def_file_import));
834 i->name = xstrdup (name);
836 i->ordinal = ordinal;
838 i->internal_name = xstrdup (internal_name);
840 i->internal_name = i->name;
841 i->its_name = (its_name ? xstrdup (its_name) : NULL);
845 def_file_add_import (def_file *fdef,
849 const char *internal_name,
850 const char *its_name,
856 /* We need to avoid here duplicates. */
858 pos = find_import_in_list (fdef->imports, fdef->num_imports,
860 (!internal_name ? name : internal_name),
861 module, ordinal, is_dup);
863 return fdef->imports + pos;
865 if ((unsigned)fdef->num_imports >= fdef->max_imports)
867 fdef->max_imports += SYMBOL_LIST_ARRAY_GROW;
868 fdef->imports = xrealloc (fdef->imports,
869 fdef->max_imports * sizeof (def_file_import));
871 i = fdef->imports + pos;
872 /* If we're inserting in the middle of the array, we need to move the
873 following elements forward. */
874 if (pos != (unsigned)fdef->num_imports)
875 memmove (i + 1, i, sizeof (def_file_import) * (fdef->num_imports - pos));
877 fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
878 internal_name, its_name);
885 def_file_add_import_from (def_file *fdef,
890 const char *internal_name,
891 const char *its_name ATTRIBUTE_UNUSED)
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 != (unsigned)fdef->num_imports)
906 i = fdef->imports + pos;
907 if (i->module && strcmp (i->module->name, module) == 0)
911 if ((unsigned)fdef->num_imports + num_imports - 1 >= fdef->max_imports)
913 fdef->max_imports = fdef->num_imports + num_imports +
914 SYMBOL_LIST_ARRAY_GROW;
916 fdef->imports = xrealloc (fdef->imports,
917 fdef->max_imports * sizeof (def_file_import));
919 i = fdef->imports + pos;
920 /* If we're inserting in the middle of the array, we need to move the
921 following elements forward. */
922 if (pos != (unsigned)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);
947 /* Search the position of the identical element, or returns the position
948 of the next higher element. If last valid element is smaller, then MAX
949 is returned. The max parameter indicates the number of elements in the
950 array. On return, *is_ident indicates whether the returned array index
951 points at an element which is identical to the one searched for. */
954 find_exclude_in_list (def_file_exclude_symbol *b, unsigned int max,
955 const char *name, bool *is_ident)
958 unsigned int l, r, p;
963 if ((e = strcmp (b[0].symbol_name, name)) <= 0)
971 if ((e = strcmp (b[max - 1].symbol_name, name)) > 0)
973 else if (!e || max == 2)
983 e = strcmp (b[p].symbol_name, name);
994 if ((e = strcmp (b[l].symbol_name, name)) > 0)
1001 static def_file_exclude_symbol *
1002 def_file_add_exclude_symbol (def_file *fdef, const char *name)
1004 def_file_exclude_symbol *e;
1006 bool is_dup = false;
1008 pos = find_exclude_in_list (fdef->exclude_symbols, fdef->num_exclude_symbols,
1011 /* We need to avoid duplicates. */
1013 return (fdef->exclude_symbols + pos);
1015 if (fdef->num_exclude_symbols >= fdef->max_exclude_symbols)
1017 fdef->max_exclude_symbols += SYMBOL_LIST_ARRAY_GROW;
1018 fdef->exclude_symbols = xrealloc (fdef->exclude_symbols,
1019 fdef->max_exclude_symbols * sizeof (def_file_exclude_symbol));
1022 e = fdef->exclude_symbols + pos;
1023 /* If we're inserting in the middle of the array, we need to move the
1024 following elements forward. */
1025 if (pos != fdef->num_exclude_symbols)
1026 memmove (&e[1], e, (sizeof (def_file_exclude_symbol) * (fdef->num_exclude_symbols - pos)));
1027 /* Wipe the element for use as a new entry. */
1028 memset (e, 0, sizeof (def_file_exclude_symbol));
1029 e->symbol_name = xstrdup (name);
1030 fdef->num_exclude_symbols++;
1041 { "-heap", HEAPSIZE },
1042 { "-stack", STACKSIZE_K },
1043 { "-attr", SECTIONS },
1044 { "-export", EXPORTS },
1045 { "-aligncomm", ALIGNCOMM },
1046 { "-exclude-symbols", EXCLUDE_SYMBOLS },
1051 def_file_add_directive (def_file *my_def, const char *param, int len)
1053 def_file *save_def = def;
1054 const char *pend = param + len;
1055 char * tend = (char *) param;
1060 while (param < pend)
1063 && (ISSPACE (*param) || *param == '\n' || *param == 0))
1069 /* Scan forward until we encounter any of:
1070 - the end of the buffer
1071 - the start of a new option
1072 - a newline separating options
1073 - a NUL separating options. */
1074 for (tend = (char *) (param + 1);
1076 && !(ISSPACE (tend[-1]) && *tend == '-')
1077 && *tend != '\n' && *tend != 0);
1081 for (i = 0; diropts[i].param; i++)
1083 len = strlen (diropts[i].param);
1085 if (tend - param >= len
1086 && strncmp (param, diropts[i].param, len) == 0
1087 && (param[len] == ':' || param[len] == ' '))
1089 lex_parse_string_end = tend;
1090 lex_parse_string = param + len + 1;
1091 lex_forced_token = diropts[i].token;
1099 if (!diropts[i].param)
1107 /* xgettext:c-format */
1108 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
1113 einfo (_("Warning: corrupt .drectve at end of def file\n"));
1117 lex_parse_string = 0;
1125 /* Parser Callbacks. */
1128 def_image_name (const char *name, bfd_vma base, int is_dll)
1130 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
1131 to do here. We retain the output filename specified on command line. */
1134 const char* image_name = lbasename (name);
1136 if (image_name != name)
1137 einfo (_("%s:%d: Warning: path components stripped from %s, '%s'\n"),
1138 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
1141 /* Append the default suffix, if none specified. */
1142 if (strchr (image_name, '.') == 0)
1144 const char * suffix = is_dll ? ".dll" : ".exe";
1146 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
1147 sprintf (def->name, "%s%s", image_name, suffix);
1150 def->name = xstrdup (image_name);
1153 /* Honor a BASE address statement, even if LIBRARY string is empty. */
1154 def->base_address = base;
1155 def->is_dll = is_dll;
1159 def_description (const char *text)
1161 int len = def->description ? strlen (def->description) : 0;
1163 len += strlen (text) + 1;
1164 if (def->description)
1166 def->description = xrealloc (def->description, len);
1167 strcat (def->description, text);
1171 def->description = xmalloc (len);
1172 strcpy (def->description, text);
1177 def_stacksize (int reserve, int commit)
1179 def->stack_reserve = reserve;
1180 def->stack_commit = commit;
1184 def_heapsize (int reserve, int commit)
1186 def->heap_reserve = reserve;
1187 def->heap_commit = commit;
1191 def_section (const char *name, int attr)
1193 def_file_section *s;
1194 int max_sections = ROUND_UP (def->num_section_defs, 4);
1196 if (def->num_section_defs >= max_sections)
1198 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1200 if (def->section_defs)
1201 def->section_defs = xrealloc (def->section_defs,
1202 max_sections * sizeof (def_file_import));
1204 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1206 s = def->section_defs + def->num_section_defs;
1207 memset (s, 0, sizeof (def_file_section));
1208 s->name = xstrdup (name);
1214 s->flag_execute = 1;
1218 def->num_section_defs++;
1222 def_section_alt (const char *name, const char *attr)
1226 for (; *attr; attr++)
1248 def_section (name, aval);
1252 def_exports (const char *external_name,
1253 const char *internal_name,
1256 const char *its_name)
1258 def_file_export *dfe;
1259 bool is_dup = false;
1261 if (!internal_name && external_name)
1262 internal_name = external_name;
1264 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1267 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1270 /* We might check here for flag redefinition and warn. For now we
1271 ignore duplicates silently. */
1276 dfe->flag_noname = 1;
1278 dfe->flag_constant = 1;
1282 dfe->flag_private = 1;
1286 def_import (const char *internal_name,
1291 const char *its_name)
1294 const char *ext = dllext ? dllext : "dll";
1295 bool is_dup = false;
1297 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1298 sprintf (buf, "%s.%s", module, ext);
1301 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1307 def_version (int major, int minor)
1309 def->version_major = major;
1310 def->version_minor = minor;
1314 def_directive (char *str)
1316 struct directive *d = xmalloc (sizeof (struct directive));
1318 d->next = directives;
1320 d->name = xstrdup (str);
1321 d->len = strlen (str);
1325 def_aligncomm (char *str, int align)
1327 def_file_aligncomm *c, *p;
1330 c = def->aligncomms;
1333 int e = strcmp (c->symbol_name, str);
1336 /* Not sure if we want to allow here duplicates with
1337 different alignments, but for now we keep them. */
1338 e = (int) c->alignment - align;
1347 c = xmalloc (sizeof (def_file_aligncomm));
1348 c->symbol_name = xstrdup (str);
1349 c->alignment = (unsigned int) align;
1352 c->next = def->aligncomms;
1353 def->aligncomms = c;
1363 def_exclude_symbols (char *str)
1365 def_file_add_exclude_symbol (def, str);
1369 def_error (const char *err)
1371 einfo ("%P: %s:%d: %s\n",
1372 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1376 /* Lexical Scanner. */
1381 /* Never freed, but always reused as needed, so no real leak. */
1382 static char *buffer = 0;
1383 static int buflen = 0;
1384 static int bufptr = 0;
1389 if (bufptr == buflen)
1391 buflen += 50; /* overly reasonable, eh? */
1393 buffer = xrealloc (buffer, buflen + 1);
1395 buffer = xmalloc (buflen + 1);
1397 buffer[bufptr++] = c;
1398 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1410 { "CONSTANT", CONSTANTU },
1411 { "constant", CONSTANTL },
1414 { "DESCRIPTION", DESCRIPTION },
1415 { "DIRECTIVE", DIRECTIVE },
1416 { "EXCLUDE_SYMBOLS", EXCLUDE_SYMBOLS },
1417 { "EXECUTE", EXECUTE },
1418 { "EXPORTS", EXPORTS },
1419 { "HEAPSIZE", HEAPSIZE },
1420 { "IMPORTS", IMPORTS },
1421 { "LIBRARY", LIBRARY },
1423 { "NONAME", NONAMEU },
1424 { "noname", NONAMEL },
1425 { "PRIVATE", PRIVATEU },
1426 { "private", PRIVATEL },
1428 { "SECTIONS", SECTIONS },
1429 { "SEGMENTS", SECTIONS },
1430 { "SHARED", SHARED_K },
1431 { "STACKSIZE", STACKSIZE_K },
1432 { "VERSION", VERSIONK },
1442 if (lex_parse_string)
1444 if (lex_parse_string >= lex_parse_string_end)
1447 rv = *lex_parse_string++;
1451 rv = fgetc (the_file);
1461 if (lex_parse_string)
1467 return ungetc (c, the_file);
1475 if (lex_forced_token)
1477 i = lex_forced_token;
1478 lex_forced_token = 0;
1480 printf ("lex: forcing token %d\n", i);
1487 /* Trim leading whitespace. */
1488 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1494 printf ("lex: EOF\n");
1499 if (saw_newline && c == ';')
1505 while (c != EOF && c != '\n');
1511 /* Must be something else. */
1517 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1524 yylval.digits = def_pool_strdup (buffer);
1526 printf ("lex: `%s' returns DIGITS\n", buffer);
1531 if (ISALPHA (c) || strchr ("$:-_?@", c))
1540 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1542 else if (ISDIGIT (c)) /* '@' followed by digit. */
1548 printf ("lex: @ returns itself\n");
1552 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1559 if (ISALPHA (q)) /* Check for tokens. */
1561 for (i = 0; tokens[i].name; i++)
1562 if (strcmp (tokens[i].name, buffer) == 0)
1565 printf ("lex: `%s' is a string token\n", buffer);
1567 return tokens[i].token;
1571 printf ("lex: `%s' returns ID\n", buffer);
1573 yylval.id = def_pool_strdup (buffer);
1577 if (c == '\'' || c == '"')
1583 while (c != EOF && c != q)
1588 yylval.id = def_pool_strdup (buffer);
1590 printf ("lex: `%s' returns ID\n", buffer);
1601 printf ("lex: `==' returns EQUAL\n");
1607 printf ("lex: `=' returns itself\n");
1611 if (c == '.' || c == ',')
1614 printf ("lex: `%c' returns itself\n", c);
1625 /*printf ("lex: 0x%02x ignored\n", c); */
1630 def_pool_alloc (size_t sz)
1634 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1635 e->next = pool_strs;
1641 def_pool_strdup (const char *str)
1647 len = strlen (str) + 1;
1648 s = def_pool_alloc (len);
1649 memcpy (s, str, len);
1654 def_pool_free (void)
1657 while ((p = pool_strs) != NULL)
1659 pool_strs = p->next;