1 %{ /* deffilep.y - parser for .def files */
3 /* Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4 2007, 2009 Free Software Foundation, Inc.
6 This file is part of GNU Binutils.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
24 #include "libiberty.h"
25 #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 def_file_add_import (def_file *fdef,
825 const char *internal_name,
826 const char *its_name,
831 int max_imports = ROUND_UP (fdef->num_imports, 16);
833 /* We need to avoid here duplicates. */
835 pos = find_import_in_list (fdef->imports, fdef->num_imports,
837 (!internal_name ? name : internal_name),
838 module, ordinal, is_dup);
840 return fdef->imports + pos;
842 if (fdef->num_imports >= max_imports)
844 max_imports = ROUND_UP (fdef->num_imports+1, 16);
847 fdef->imports = xrealloc (fdef->imports,
848 max_imports * sizeof (def_file_import));
850 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
852 i = fdef->imports + pos;
853 if (pos != fdef->num_imports)
854 memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
855 memset (i, 0, sizeof (def_file_import));
857 i->name = xstrdup (name);
859 i->module = def_stash_module (fdef, module);
860 i->ordinal = ordinal;
862 i->internal_name = xstrdup (internal_name);
864 i->internal_name = i->name;
865 i->its_name = (its_name ? xstrdup (its_name) : NULL);
878 { "-heap", HEAPSIZE },
879 { "-stack", STACKSIZE_K },
880 { "-attr", SECTIONS },
881 { "-export", EXPORTS },
882 { "-aligncomm", ALIGNCOMM },
887 def_file_add_directive (def_file *my_def, const char *param, int len)
889 def_file *save_def = def;
890 const char *pend = param + len;
891 char * tend = (char *) param;
899 && (ISSPACE (*param) || *param == '\n' || *param == 0))
905 /* Scan forward until we encounter any of:
906 - the end of the buffer
907 - the start of a new option
908 - a newline seperating options
909 - a NUL seperating options. */
910 for (tend = (char *) (param + 1);
912 && !(ISSPACE (tend[-1]) && *tend == '-')
913 && *tend != '\n' && *tend != 0);
917 for (i = 0; diropts[i].param; i++)
919 len = strlen (diropts[i].param);
921 if (tend - param >= len
922 && strncmp (param, diropts[i].param, len) == 0
923 && (param[len] == ':' || param[len] == ' '))
925 lex_parse_string_end = tend;
926 lex_parse_string = param + len + 1;
927 lex_forced_token = diropts[i].token;
935 if (!diropts[i].param)
941 /* xgettext:c-format */
942 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
946 lex_parse_string = 0;
954 /* Parser Callbacks. */
957 def_image_name (const char *name, bfd_vma base, int is_dll)
959 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
960 to do here. We retain the output filename specified on command line. */
963 const char* image_name = lbasename (name);
965 if (image_name != name)
966 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
967 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
971 /* Append the default suffix, if none specified. */
972 if (strchr (image_name, '.') == 0)
974 const char * suffix = is_dll ? ".dll" : ".exe";
976 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
977 sprintf (def->name, "%s%s", image_name, suffix);
980 def->name = xstrdup (image_name);
983 /* Honor a BASE address statement, even if LIBRARY string is empty. */
984 def->base_address = base;
985 def->is_dll = is_dll;
989 def_description (const char *text)
991 int len = def->description ? strlen (def->description) : 0;
993 len += strlen (text) + 1;
994 if (def->description)
996 def->description = xrealloc (def->description, len);
997 strcat (def->description, text);
1001 def->description = xmalloc (len);
1002 strcpy (def->description, text);
1007 def_stacksize (int reserve, int commit)
1009 def->stack_reserve = reserve;
1010 def->stack_commit = commit;
1014 def_heapsize (int reserve, int commit)
1016 def->heap_reserve = reserve;
1017 def->heap_commit = commit;
1021 def_section (const char *name, int attr)
1023 def_file_section *s;
1024 int max_sections = ROUND_UP (def->num_section_defs, 4);
1026 if (def->num_section_defs >= max_sections)
1028 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1030 if (def->section_defs)
1031 def->section_defs = xrealloc (def->section_defs,
1032 max_sections * sizeof (def_file_import));
1034 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1036 s = def->section_defs + def->num_section_defs;
1037 memset (s, 0, sizeof (def_file_section));
1038 s->name = xstrdup (name);
1044 s->flag_execute = 1;
1048 def->num_section_defs++;
1052 def_section_alt (const char *name, const char *attr)
1056 for (; *attr; attr++)
1078 def_section (name, aval);
1082 def_exports (const char *external_name,
1083 const char *internal_name,
1086 const char *its_name)
1088 def_file_export *dfe;
1091 if (!internal_name && external_name)
1092 internal_name = external_name;
1094 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1097 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1100 /* We might check here for flag redefinition and warn. For now we
1101 ignore duplicates silently. */
1106 dfe->flag_noname = 1;
1108 dfe->flag_constant = 1;
1112 dfe->flag_private = 1;
1116 def_import (const char *internal_name,
1121 const char *its_name)
1124 const char *ext = dllext ? dllext : "dll";
1127 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1128 sprintf (buf, "%s.%s", module, ext);
1131 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1137 def_version (int major, int minor)
1139 def->version_major = major;
1140 def->version_minor = minor;
1144 def_directive (char *str)
1146 struct directive *d = xmalloc (sizeof (struct directive));
1148 d->next = directives;
1150 d->name = xstrdup (str);
1151 d->len = strlen (str);
1155 def_aligncomm (char *str, int align)
1157 def_file_aligncomm *c, *p;
1160 c = def->aligncomms;
1163 int e = strcmp (c->symbol_name, str);
1166 /* Not sure if we want to allow here duplicates with
1167 different alignments, but for now we keep them. */
1168 e = (int) c->alignment - align;
1177 c = xmalloc (sizeof (def_file_aligncomm));
1178 c->symbol_name = xstrdup (str);
1179 c->alignment = (unsigned int) align;
1182 c->next = def->aligncomms;
1183 def->aligncomms = c;
1193 def_error (const char *err)
1195 einfo ("%P: %s:%d: %s\n",
1196 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1201 /* Lexical Scanner. */
1206 /* Never freed, but always reused as needed, so no real leak. */
1207 static char *buffer = 0;
1208 static int buflen = 0;
1209 static int bufptr = 0;
1214 if (bufptr == buflen)
1216 buflen += 50; /* overly reasonable, eh? */
1218 buffer = xrealloc (buffer, buflen + 1);
1220 buffer = xmalloc (buflen + 1);
1222 buffer[bufptr++] = c;
1223 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1235 { "CONSTANT", CONSTANTU },
1236 { "constant", CONSTANTL },
1239 { "DESCRIPTION", DESCRIPTION },
1240 { "DIRECTIVE", DIRECTIVE },
1241 { "EXECUTE", EXECUTE },
1242 { "EXPORTS", EXPORTS },
1243 { "HEAPSIZE", HEAPSIZE },
1244 { "IMPORTS", IMPORTS },
1245 { "LIBRARY", LIBRARY },
1247 { "NONAME", NONAMEU },
1248 { "noname", NONAMEL },
1249 { "PRIVATE", PRIVATEU },
1250 { "private", PRIVATEL },
1252 { "SECTIONS", SECTIONS },
1253 { "SEGMENTS", SECTIONS },
1254 { "SHARED", SHARED },
1255 { "STACKSIZE", STACKSIZE_K },
1256 { "VERSION", VERSIONK },
1266 if (lex_parse_string)
1268 if (lex_parse_string >= lex_parse_string_end)
1271 rv = *lex_parse_string++;
1275 rv = fgetc (the_file);
1285 if (lex_parse_string)
1291 return ungetc (c, the_file);
1299 if (lex_forced_token)
1301 i = lex_forced_token;
1302 lex_forced_token = 0;
1304 printf ("lex: forcing token %d\n", i);
1311 /* Trim leading whitespace. */
1312 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1318 printf ("lex: EOF\n");
1323 if (saw_newline && c == ';')
1329 while (c != EOF && c != '\n');
1335 /* Must be something else. */
1341 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1348 yylval.digits = def_pool_strdup (buffer);
1350 printf ("lex: `%s' returns DIGITS\n", buffer);
1355 if (ISALPHA (c) || strchr ("$:-_?@", c))
1364 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1366 else if (ISDIGIT (c)) /* '@' followed by digit. */
1372 printf ("lex: @ returns itself\n");
1376 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1383 if (ISALPHA (q)) /* Check for tokens. */
1385 for (i = 0; tokens[i].name; i++)
1386 if (strcmp (tokens[i].name, buffer) == 0)
1389 printf ("lex: `%s' is a string token\n", buffer);
1391 return tokens[i].token;
1395 printf ("lex: `%s' returns ID\n", buffer);
1397 yylval.id = def_pool_strdup (buffer);
1401 if (c == '\'' || c == '"')
1407 while (c != EOF && c != q)
1412 yylval.id = def_pool_strdup (buffer);
1414 printf ("lex: `%s' returns ID\n", buffer);
1425 printf ("lex: `==' returns EQUAL\n");
1431 printf ("lex: `=' returns itself\n");
1435 if (c == '.' || c == ',')
1438 printf ("lex: `%c' returns itself\n", c);
1449 /*printf ("lex: 0x%02x ignored\n", c); */
1454 def_pool_alloc (size_t sz)
1458 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1459 e->next = pool_strs;
1465 def_pool_strdup (const char *str)
1471 len = strlen (str) + 1;
1472 s = def_pool_alloc (len);
1473 memcpy (s, str, len);
1478 def_pool_free (void)
1481 while ((p = pool_strs) != NULL)
1483 pool_strs = p->next;