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)
943 /* xgettext:c-format */
944 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
949 einfo (_("Warning: corrupt .drectve at end of def file\n"));
953 lex_parse_string = 0;
961 /* Parser Callbacks. */
964 def_image_name (const char *name, bfd_vma base, int is_dll)
966 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
967 to do here. We retain the output filename specified on command line. */
970 const char* image_name = lbasename (name);
972 if (image_name != name)
973 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
974 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
978 /* Append the default suffix, if none specified. */
979 if (strchr (image_name, '.') == 0)
981 const char * suffix = is_dll ? ".dll" : ".exe";
983 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
984 sprintf (def->name, "%s%s", image_name, suffix);
987 def->name = xstrdup (image_name);
990 /* Honor a BASE address statement, even if LIBRARY string is empty. */
991 def->base_address = base;
992 def->is_dll = is_dll;
996 def_description (const char *text)
998 int len = def->description ? strlen (def->description) : 0;
1000 len += strlen (text) + 1;
1001 if (def->description)
1003 def->description = xrealloc (def->description, len);
1004 strcat (def->description, text);
1008 def->description = xmalloc (len);
1009 strcpy (def->description, text);
1014 def_stacksize (int reserve, int commit)
1016 def->stack_reserve = reserve;
1017 def->stack_commit = commit;
1021 def_heapsize (int reserve, int commit)
1023 def->heap_reserve = reserve;
1024 def->heap_commit = commit;
1028 def_section (const char *name, int attr)
1030 def_file_section *s;
1031 int max_sections = ROUND_UP (def->num_section_defs, 4);
1033 if (def->num_section_defs >= max_sections)
1035 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1037 if (def->section_defs)
1038 def->section_defs = xrealloc (def->section_defs,
1039 max_sections * sizeof (def_file_import));
1041 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1043 s = def->section_defs + def->num_section_defs;
1044 memset (s, 0, sizeof (def_file_section));
1045 s->name = xstrdup (name);
1051 s->flag_execute = 1;
1055 def->num_section_defs++;
1059 def_section_alt (const char *name, const char *attr)
1063 for (; *attr; attr++)
1085 def_section (name, aval);
1089 def_exports (const char *external_name,
1090 const char *internal_name,
1093 const char *its_name)
1095 def_file_export *dfe;
1098 if (!internal_name && external_name)
1099 internal_name = external_name;
1101 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1104 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1107 /* We might check here for flag redefinition and warn. For now we
1108 ignore duplicates silently. */
1113 dfe->flag_noname = 1;
1115 dfe->flag_constant = 1;
1119 dfe->flag_private = 1;
1123 def_import (const char *internal_name,
1128 const char *its_name)
1131 const char *ext = dllext ? dllext : "dll";
1134 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1135 sprintf (buf, "%s.%s", module, ext);
1138 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1144 def_version (int major, int minor)
1146 def->version_major = major;
1147 def->version_minor = minor;
1151 def_directive (char *str)
1153 struct directive *d = xmalloc (sizeof (struct directive));
1155 d->next = directives;
1157 d->name = xstrdup (str);
1158 d->len = strlen (str);
1162 def_aligncomm (char *str, int align)
1164 def_file_aligncomm *c, *p;
1167 c = def->aligncomms;
1170 int e = strcmp (c->symbol_name, str);
1173 /* Not sure if we want to allow here duplicates with
1174 different alignments, but for now we keep them. */
1175 e = (int) c->alignment - align;
1184 c = xmalloc (sizeof (def_file_aligncomm));
1185 c->symbol_name = xstrdup (str);
1186 c->alignment = (unsigned int) align;
1189 c->next = def->aligncomms;
1190 def->aligncomms = c;
1200 def_error (const char *err)
1202 einfo ("%P: %s:%d: %s\n",
1203 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1208 /* Lexical Scanner. */
1213 /* Never freed, but always reused as needed, so no real leak. */
1214 static char *buffer = 0;
1215 static int buflen = 0;
1216 static int bufptr = 0;
1221 if (bufptr == buflen)
1223 buflen += 50; /* overly reasonable, eh? */
1225 buffer = xrealloc (buffer, buflen + 1);
1227 buffer = xmalloc (buflen + 1);
1229 buffer[bufptr++] = c;
1230 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1242 { "CONSTANT", CONSTANTU },
1243 { "constant", CONSTANTL },
1246 { "DESCRIPTION", DESCRIPTION },
1247 { "DIRECTIVE", DIRECTIVE },
1248 { "EXECUTE", EXECUTE },
1249 { "EXPORTS", EXPORTS },
1250 { "HEAPSIZE", HEAPSIZE },
1251 { "IMPORTS", IMPORTS },
1252 { "LIBRARY", LIBRARY },
1254 { "NONAME", NONAMEU },
1255 { "noname", NONAMEL },
1256 { "PRIVATE", PRIVATEU },
1257 { "private", PRIVATEL },
1259 { "SECTIONS", SECTIONS },
1260 { "SEGMENTS", SECTIONS },
1261 { "SHARED", SHARED },
1262 { "STACKSIZE", STACKSIZE_K },
1263 { "VERSION", VERSIONK },
1273 if (lex_parse_string)
1275 if (lex_parse_string >= lex_parse_string_end)
1278 rv = *lex_parse_string++;
1282 rv = fgetc (the_file);
1292 if (lex_parse_string)
1298 return ungetc (c, the_file);
1306 if (lex_forced_token)
1308 i = lex_forced_token;
1309 lex_forced_token = 0;
1311 printf ("lex: forcing token %d\n", i);
1318 /* Trim leading whitespace. */
1319 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1325 printf ("lex: EOF\n");
1330 if (saw_newline && c == ';')
1336 while (c != EOF && c != '\n');
1342 /* Must be something else. */
1348 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1355 yylval.digits = def_pool_strdup (buffer);
1357 printf ("lex: `%s' returns DIGITS\n", buffer);
1362 if (ISALPHA (c) || strchr ("$:-_?@", c))
1371 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1373 else if (ISDIGIT (c)) /* '@' followed by digit. */
1379 printf ("lex: @ returns itself\n");
1383 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1390 if (ISALPHA (q)) /* Check for tokens. */
1392 for (i = 0; tokens[i].name; i++)
1393 if (strcmp (tokens[i].name, buffer) == 0)
1396 printf ("lex: `%s' is a string token\n", buffer);
1398 return tokens[i].token;
1402 printf ("lex: `%s' returns ID\n", buffer);
1404 yylval.id = def_pool_strdup (buffer);
1408 if (c == '\'' || c == '"')
1414 while (c != EOF && c != q)
1419 yylval.id = def_pool_strdup (buffer);
1421 printf ("lex: `%s' returns ID\n", buffer);
1432 printf ("lex: `==' returns EQUAL\n");
1438 printf ("lex: `=' returns itself\n");
1442 if (c == '.' || c == ',')
1445 printf ("lex: `%c' returns itself\n", c);
1456 /*printf ("lex: 0x%02x ignored\n", c); */
1461 def_pool_alloc (size_t sz)
1465 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1466 e->next = pool_strs;
1472 def_pool_strdup (const char *str)
1478 len = strlen (str) + 1;
1479 s = def_pool_alloc (len);
1480 memcpy (s, str, len);
1485 def_pool_free (void)
1488 while ((p = pool_strs) != NULL)
1490 pool_strs = p->next;