1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright (C) 1995-2015 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 def_file_add_import (def_file *fdef,
824 const char *internal_name,
825 const char *its_name,
830 int max_imports = ROUND_UP (fdef->num_imports, 16);
832 /* We need to avoid here duplicates. */
834 pos = find_import_in_list (fdef->imports, fdef->num_imports,
836 (!internal_name ? name : internal_name),
837 module, ordinal, is_dup);
839 return fdef->imports + pos;
841 if (fdef->num_imports >= max_imports)
843 max_imports = ROUND_UP (fdef->num_imports+1, 16);
846 fdef->imports = xrealloc (fdef->imports,
847 max_imports * sizeof (def_file_import));
849 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
851 i = fdef->imports + pos;
852 if (pos != fdef->num_imports)
853 memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
854 memset (i, 0, sizeof (def_file_import));
856 i->name = xstrdup (name);
858 i->module = def_stash_module (fdef, module);
859 i->ordinal = ordinal;
861 i->internal_name = xstrdup (internal_name);
863 i->internal_name = i->name;
864 i->its_name = (its_name ? xstrdup (its_name) : NULL);
877 { "-heap", HEAPSIZE },
878 { "-stack", STACKSIZE_K },
879 { "-attr", SECTIONS },
880 { "-export", EXPORTS },
881 { "-aligncomm", ALIGNCOMM },
886 def_file_add_directive (def_file *my_def, const char *param, int len)
888 def_file *save_def = def;
889 const char *pend = param + len;
890 char * tend = (char *) param;
898 && (ISSPACE (*param) || *param == '\n' || *param == 0))
904 /* Scan forward until we encounter any of:
905 - the end of the buffer
906 - the start of a new option
907 - a newline seperating options
908 - a NUL seperating options. */
909 for (tend = (char *) (param + 1);
911 && !(ISSPACE (tend[-1]) && *tend == '-')
912 && *tend != '\n' && *tend != 0);
916 for (i = 0; diropts[i].param; i++)
918 len = strlen (diropts[i].param);
920 if (tend - param >= len
921 && strncmp (param, diropts[i].param, len) == 0
922 && (param[len] == ':' || param[len] == ' '))
924 lex_parse_string_end = tend;
925 lex_parse_string = param + len + 1;
926 lex_forced_token = diropts[i].token;
934 if (!diropts[i].param)
942 /* xgettext:c-format */
943 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
948 einfo (_("Warning: corrupt .drectve at end of def file\n"));
952 lex_parse_string = 0;
960 /* Parser Callbacks. */
963 def_image_name (const char *name, bfd_vma base, int is_dll)
965 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
966 to do here. We retain the output filename specified on command line. */
969 const char* image_name = lbasename (name);
971 if (image_name != name)
972 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
973 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
977 /* Append the default suffix, if none specified. */
978 if (strchr (image_name, '.') == 0)
980 const char * suffix = is_dll ? ".dll" : ".exe";
982 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
983 sprintf (def->name, "%s%s", image_name, suffix);
986 def->name = xstrdup (image_name);
989 /* Honor a BASE address statement, even if LIBRARY string is empty. */
990 def->base_address = base;
991 def->is_dll = is_dll;
995 def_description (const char *text)
997 int len = def->description ? strlen (def->description) : 0;
999 len += strlen (text) + 1;
1000 if (def->description)
1002 def->description = xrealloc (def->description, len);
1003 strcat (def->description, text);
1007 def->description = xmalloc (len);
1008 strcpy (def->description, text);
1013 def_stacksize (int reserve, int commit)
1015 def->stack_reserve = reserve;
1016 def->stack_commit = commit;
1020 def_heapsize (int reserve, int commit)
1022 def->heap_reserve = reserve;
1023 def->heap_commit = commit;
1027 def_section (const char *name, int attr)
1029 def_file_section *s;
1030 int max_sections = ROUND_UP (def->num_section_defs, 4);
1032 if (def->num_section_defs >= max_sections)
1034 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1036 if (def->section_defs)
1037 def->section_defs = xrealloc (def->section_defs,
1038 max_sections * sizeof (def_file_import));
1040 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1042 s = def->section_defs + def->num_section_defs;
1043 memset (s, 0, sizeof (def_file_section));
1044 s->name = xstrdup (name);
1050 s->flag_execute = 1;
1054 def->num_section_defs++;
1058 def_section_alt (const char *name, const char *attr)
1062 for (; *attr; attr++)
1084 def_section (name, aval);
1088 def_exports (const char *external_name,
1089 const char *internal_name,
1092 const char *its_name)
1094 def_file_export *dfe;
1097 if (!internal_name && external_name)
1098 internal_name = external_name;
1100 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1103 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1106 /* We might check here for flag redefinition and warn. For now we
1107 ignore duplicates silently. */
1112 dfe->flag_noname = 1;
1114 dfe->flag_constant = 1;
1118 dfe->flag_private = 1;
1122 def_import (const char *internal_name,
1127 const char *its_name)
1130 const char *ext = dllext ? dllext : "dll";
1133 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1134 sprintf (buf, "%s.%s", module, ext);
1137 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1143 def_version (int major, int minor)
1145 def->version_major = major;
1146 def->version_minor = minor;
1150 def_directive (char *str)
1152 struct directive *d = xmalloc (sizeof (struct directive));
1154 d->next = directives;
1156 d->name = xstrdup (str);
1157 d->len = strlen (str);
1161 def_aligncomm (char *str, int align)
1163 def_file_aligncomm *c, *p;
1166 c = def->aligncomms;
1169 int e = strcmp (c->symbol_name, str);
1172 /* Not sure if we want to allow here duplicates with
1173 different alignments, but for now we keep them. */
1174 e = (int) c->alignment - align;
1183 c = xmalloc (sizeof (def_file_aligncomm));
1184 c->symbol_name = xstrdup (str);
1185 c->alignment = (unsigned int) align;
1188 c->next = def->aligncomms;
1189 def->aligncomms = c;
1199 def_error (const char *err)
1201 einfo ("%P: %s:%d: %s\n",
1202 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1207 /* Lexical Scanner. */
1212 /* Never freed, but always reused as needed, so no real leak. */
1213 static char *buffer = 0;
1214 static int buflen = 0;
1215 static int bufptr = 0;
1220 if (bufptr == buflen)
1222 buflen += 50; /* overly reasonable, eh? */
1224 buffer = xrealloc (buffer, buflen + 1);
1226 buffer = xmalloc (buflen + 1);
1228 buffer[bufptr++] = c;
1229 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1241 { "CONSTANT", CONSTANTU },
1242 { "constant", CONSTANTL },
1245 { "DESCRIPTION", DESCRIPTION },
1246 { "DIRECTIVE", DIRECTIVE },
1247 { "EXECUTE", EXECUTE },
1248 { "EXPORTS", EXPORTS },
1249 { "HEAPSIZE", HEAPSIZE },
1250 { "IMPORTS", IMPORTS },
1251 { "LIBRARY", LIBRARY },
1253 { "NONAME", NONAMEU },
1254 { "noname", NONAMEL },
1255 { "PRIVATE", PRIVATEU },
1256 { "private", PRIVATEL },
1258 { "SECTIONS", SECTIONS },
1259 { "SEGMENTS", SECTIONS },
1260 { "SHARED", SHARED },
1261 { "STACKSIZE", STACKSIZE_K },
1262 { "VERSION", VERSIONK },
1272 if (lex_parse_string)
1274 if (lex_parse_string >= lex_parse_string_end)
1277 rv = *lex_parse_string++;
1281 rv = fgetc (the_file);
1291 if (lex_parse_string)
1297 return ungetc (c, the_file);
1305 if (lex_forced_token)
1307 i = lex_forced_token;
1308 lex_forced_token = 0;
1310 printf ("lex: forcing token %d\n", i);
1317 /* Trim leading whitespace. */
1318 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1324 printf ("lex: EOF\n");
1329 if (saw_newline && c == ';')
1335 while (c != EOF && c != '\n');
1341 /* Must be something else. */
1347 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1354 yylval.digits = def_pool_strdup (buffer);
1356 printf ("lex: `%s' returns DIGITS\n", buffer);
1361 if (ISALPHA (c) || strchr ("$:-_?@", c))
1370 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1372 else if (ISDIGIT (c)) /* '@' followed by digit. */
1378 printf ("lex: @ returns itself\n");
1382 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1389 if (ISALPHA (q)) /* Check for tokens. */
1391 for (i = 0; tokens[i].name; i++)
1392 if (strcmp (tokens[i].name, buffer) == 0)
1395 printf ("lex: `%s' is a string token\n", buffer);
1397 return tokens[i].token;
1401 printf ("lex: `%s' returns ID\n", buffer);
1403 yylval.id = def_pool_strdup (buffer);
1407 if (c == '\'' || c == '"')
1413 while (c != EOF && c != q)
1418 yylval.id = def_pool_strdup (buffer);
1420 printf ("lex: `%s' returns ID\n", buffer);
1431 printf ("lex: `==' returns EQUAL\n");
1437 printf ("lex: `=' returns itself\n");
1441 if (c == '.' || c == ',')
1444 printf ("lex: `%c' returns itself\n", c);
1455 /*printf ("lex: 0x%02x ignored\n", c); */
1460 def_pool_alloc (size_t sz)
1464 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1465 e->next = pool_strs;
1471 def_pool_strdup (const char *str)
1477 len = strlen (str) + 1;
1478 s = def_pool_alloc (len);
1479 memcpy (s, str, len);
1484 def_pool_free (void)
1487 while ((p = pool_strs) != NULL)
1489 pool_strs = p->next;