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 *, int, 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;
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 <digits> opt_digits
129 %type <number> opt_base opt_ordinal
130 %type <number> attr attr_list opt_number exp_opt_list exp_opt
131 %type <id> opt_name opt_name2 opt_equal_name anylang_id opt_id
132 %type <id> opt_equalequal_name
133 %type <id_const> keyword_as_name
142 NAME opt_name opt_base { def_image_name ($2, $3, 0); }
143 | LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
144 | DESCRIPTION ID { def_description ($2);}
145 | STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
146 | HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
147 | CODE attr_list { def_section ("CODE", $2);}
148 | DATAU attr_list { def_section ("DATA", $2);}
152 | VERSIONK NUMBER { def_version ($2, 0);}
153 | VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
154 | DIRECTIVE ID { def_directive ($2);}
155 | ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
166 /* The opt_comma is necessary to support both the usual
167 DEF file syntax as well as .drectve syntax which
168 mandates <expsym>,<expoptlist>. */
169 opt_name2 opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
170 { def_exports ($1, $2, $3, $5, $7); }
173 /* The opt_comma is necessary to support both the usual
174 DEF file syntax as well as .drectve syntax which
175 allows for comma separated opt list. */
176 exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
181 | NONAMEL { $$ = 1; }
182 | CONSTANTU { $$ = 2; }
183 | CONSTANTL { $$ = 2; }
186 | PRIVATEU { $$ = 8; }
187 | PRIVATEL { $$ = 8; }
195 ID '=' ID '.' ID '.' ID opt_equalequal_name
196 { def_import ($1, $3, $5, $7, -1, $8); }
197 | ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
198 { def_import ($1, $3, $5, 0, $7, $8); }
199 | ID '=' ID '.' ID opt_equalequal_name
200 { def_import ($1, $3, 0, $5, -1, $6); }
201 | ID '=' ID '.' NUMBER opt_equalequal_name
202 { def_import ($1, $3, 0, 0, $5, $6); }
203 | ID '.' ID '.' ID opt_equalequal_name
204 { def_import( 0, $1, $3, $5, -1, $6); }
205 | ID '.' ID opt_equalequal_name
206 { def_import ( 0, $1, 0, $3, -1, $4); }
215 ID attr_list { def_section ($1, $2);}
216 | ID ID { def_section_alt ($1, $2);}
220 attr_list opt_comma attr { $$ = $1 | $3; }
228 opt_number: ',' NUMBER { $$=$2;}
240 keyword_as_name: BASE { $$ = "BASE"; }
241 | CODE { $$ = "CODE"; }
242 | CONSTANTU { $$ = "CONSTANT"; }
243 | CONSTANTL { $$ = "constant"; }
244 | DATAU { $$ = "DATA"; }
245 | DATAL { $$ = "data"; }
246 | DESCRIPTION { $$ = "DESCRIPTION"; }
247 | DIRECTIVE { $$ = "DIRECTIVE"; }
248 | EXECUTE { $$ = "EXECUTE"; }
249 | EXPORTS { $$ = "EXPORTS"; }
250 | HEAPSIZE { $$ = "HEAPSIZE"; }
251 | IMPORTS { $$ = "IMPORTS"; }
252 | LIBRARY { $$ = "LIBRARY"; }
253 | NAME { $$ = "NAME"; }
254 | NONAMEU { $$ = "NONAME"; }
255 | NONAMEL { $$ = "noname"; }
256 | PRIVATEU { $$ = "PRIVATE"; }
257 | PRIVATEL { $$ = "private"; }
258 | READ { $$ = "READ"; }
259 | SHARED { $$ = "SHARED"; }
260 | STACKSIZE_K { $$ = "STACKSIZE"; }
261 | VERSIONK { $$ = "VERSION"; }
262 | WRITE { $$ = "WRITE"; }
265 opt_name2: ID { $$ = $1; }
266 | '.' keyword_as_name
268 char *name = xmalloc (strlen ($2) + 2);
269 sprintf (name, ".%s", $2);
274 char *name = def_pool_alloc (strlen ($2) + 2);
275 sprintf (name, ".%s", $2);
278 | keyword_as_name '.' opt_name2
280 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
281 sprintf (name, "%s.%s", $1, $3);
286 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
287 sprintf (name, "%s.%s", $1, $3);
292 opt_name: opt_name2 { $$ = $1; }
296 opt_equalequal_name: EQUAL ID { $$ = $2; }
301 '@' NUMBER { $$ = $2;}
306 '=' opt_name2 { $$ = $2; }
310 opt_base: BASE '=' NUMBER { $$ = $3;}
314 anylang_id: ID { $$ = $1; }
317 char *id = def_pool_alloc (strlen ($2) + 2);
318 sprintf (id, ".%s", $2);
321 | anylang_id '.' opt_digits opt_id
323 char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
324 sprintf (id, "%s.%s%s", $1, $3, $4);
329 opt_digits: DIGITS { $$ = $1; }
333 opt_id: ID { $$ = $1; }
337 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
341 /*****************************************************************************
343 *****************************************************************************/
345 static FILE *the_file;
346 static const char *def_filename;
347 static int linenumber;
348 static def_file *def;
349 static int saw_newline;
353 struct directive *next;
358 static struct directive *directives = 0;
361 def_file_empty (void)
363 def_file *rv = xmalloc (sizeof (def_file));
364 memset (rv, 0, sizeof (def_file));
366 rv->base_address = (bfd_vma) -1;
367 rv->stack_reserve = rv->stack_commit = -1;
368 rv->heap_reserve = rv->heap_commit = -1;
369 rv->version_major = rv->version_minor = -1;
374 def_file_parse (const char *filename, def_file *add_to)
378 the_file = fopen (filename, "r");
379 def_filename = filename;
392 def = def_file_empty ();
406 while ((d = directives) != NULL)
409 printf ("Adding directive %08x `%s'\n", d->name, d->name);
411 def_file_add_directive (def, d->name, d->len);
412 directives = d->next;
422 def_file_free (def_file *fdef)
430 if (fdef->description)
431 free (fdef->description);
433 if (fdef->section_defs)
435 for (i = 0; i < fdef->num_section_defs; i++)
437 if (fdef->section_defs[i].name)
438 free (fdef->section_defs[i].name);
439 if (fdef->section_defs[i].class)
440 free (fdef->section_defs[i].class);
442 free (fdef->section_defs);
447 for (i = 0; i < fdef->num_exports; i++)
449 if (fdef->exports[i].internal_name
450 && fdef->exports[i].internal_name != fdef->exports[i].name)
451 free (fdef->exports[i].internal_name);
452 if (fdef->exports[i].name)
453 free (fdef->exports[i].name);
454 if (fdef->exports[i].its_name)
455 free (fdef->exports[i].its_name);
457 free (fdef->exports);
462 for (i = 0; i < fdef->num_imports; i++)
464 if (fdef->imports[i].internal_name
465 && fdef->imports[i].internal_name != fdef->imports[i].name)
466 free (fdef->imports[i].internal_name);
467 if (fdef->imports[i].name)
468 free (fdef->imports[i].name);
469 if (fdef->imports[i].its_name)
470 free (fdef->imports[i].its_name);
472 free (fdef->imports);
475 while (fdef->modules)
477 def_file_module *m = fdef->modules;
479 fdef->modules = fdef->modules->next;
483 while (fdef->aligncomms)
485 def_file_aligncomm *c = fdef->aligncomms;
487 fdef->aligncomms = fdef->aligncomms->next;
488 free (c->symbol_name);
495 #ifdef DEF_FILE_PRINT
497 def_file_print (FILE *file, def_file *fdef)
501 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
503 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
504 if (fdef->is_dll != -1)
505 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
506 if (fdef->base_address != (bfd_vma) -1)
507 fprintf (file, " base address: 0x%08x\n", fdef->base_address);
508 if (fdef->description)
509 fprintf (file, " description: `%s'\n", fdef->description);
510 if (fdef->stack_reserve != -1)
511 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
512 if (fdef->stack_commit != -1)
513 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
514 if (fdef->heap_reserve != -1)
515 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
516 if (fdef->heap_commit != -1)
517 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
519 if (fdef->num_section_defs > 0)
521 fprintf (file, " section defs:\n");
523 for (i = 0; i < fdef->num_section_defs; i++)
525 fprintf (file, " name: `%s', class: `%s', flags:",
526 fdef->section_defs[i].name, fdef->section_defs[i].class);
527 if (fdef->section_defs[i].flag_read)
528 fprintf (file, " R");
529 if (fdef->section_defs[i].flag_write)
530 fprintf (file, " W");
531 if (fdef->section_defs[i].flag_execute)
532 fprintf (file, " X");
533 if (fdef->section_defs[i].flag_shared)
534 fprintf (file, " S");
535 fprintf (file, "\n");
539 if (fdef->num_exports > 0)
541 fprintf (file, " exports:\n");
543 for (i = 0; i < fdef->num_exports; i++)
545 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
546 fdef->exports[i].name, fdef->exports[i].internal_name,
547 fdef->exports[i].ordinal);
548 if (fdef->exports[i].flag_private)
549 fprintf (file, " P");
550 if (fdef->exports[i].flag_constant)
551 fprintf (file, " C");
552 if (fdef->exports[i].flag_noname)
553 fprintf (file, " N");
554 if (fdef->exports[i].flag_data)
555 fprintf (file, " D");
556 fprintf (file, "\n");
560 if (fdef->num_imports > 0)
562 fprintf (file, " imports:\n");
564 for (i = 0; i < fdef->num_imports; i++)
566 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
567 fdef->imports[i].internal_name,
568 fdef->imports[i].module,
569 fdef->imports[i].name,
570 fdef->imports[i].ordinal);
574 if (fdef->version_major != -1)
575 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
577 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
581 /* Helper routine to check for identity of string pointers,
582 which might be NULL. */
585 are_names_equal (const char *s1, const char *s2)
590 return (!s1 ? -1 : 1);
591 return strcmp (s1, s2);
595 cmp_export_elem (const def_file_export *e, const char *ex_name,
596 const char *in_name, const char *its_name,
601 if ((r = are_names_equal (ex_name, e->name)) != 0)
603 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
605 if ((r = are_names_equal (its_name, e->its_name)) != 0)
607 return (ord - e->ordinal);
610 /* Search the position of the identical element, or returns the position
611 of the next higher element. If last valid element is smaller, then MAX
615 find_export_in_list (def_file_export *b, int max,
616 const char *ex_name, const char *in_name,
617 const char *its_name, int ord, int *is_ident)
624 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
628 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
630 else if (!e || max == 2)
636 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
647 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
655 def_file_add_export (def_file *fdef,
656 const char *external_name,
657 const char *internal_name,
659 const char *its_name,
664 int max_exports = ROUND_UP(fdef->num_exports, 32);
666 if (internal_name && !external_name)
667 external_name = internal_name;
668 if (external_name && !internal_name)
669 internal_name = external_name;
671 /* We need to avoid duplicates. */
673 pos = find_export_in_list (fdef->exports, fdef->num_exports,
674 external_name, internal_name,
675 its_name, ordinal, is_dup);
678 return (fdef->exports + pos);
680 if (fdef->num_exports >= max_exports)
682 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
684 fdef->exports = xrealloc (fdef->exports,
685 max_exports * sizeof (def_file_export));
687 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
690 e = fdef->exports + pos;
691 if (pos != fdef->num_exports)
692 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
693 memset (e, 0, sizeof (def_file_export));
694 e->name = xstrdup (external_name);
695 e->internal_name = xstrdup (internal_name);
696 e->its_name = (its_name ? xstrdup (its_name) : NULL);
697 e->ordinal = ordinal;
703 def_get_module (def_file *fdef, const char *name)
707 for (s = fdef->modules; s; s = s->next)
708 if (strcmp (s->name, name) == 0)
714 static def_file_module *
715 def_stash_module (def_file *fdef, const char *name)
719 if ((s = def_get_module (fdef, name)) != NULL)
721 s = xmalloc (sizeof (def_file_module) + strlen (name));
722 s->next = fdef->modules;
725 strcpy (s->name, name);
730 cmp_import_elem (const def_file_import *e, const char *ex_name,
731 const char *in_name, const char *module,
736 if ((r = are_names_equal (ex_name, e->name)) != 0)
738 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
740 if (ord != e->ordinal)
741 return (ord < e->ordinal ? -1 : 1);
742 return are_names_equal (module, (e->module ? e->module->name : NULL));
745 /* Search the position of the identical element, or returns the position
746 of the next higher element. If last valid element is smaller, then MAX
750 find_import_in_list (def_file_import *b, int max,
751 const char *ex_name, const char *in_name,
752 const char *module, int ord, int *is_ident)
759 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
763 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
765 else if (!e || max == 2)
771 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
782 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
790 def_file_add_import (def_file *fdef,
794 const char *internal_name,
795 const char *its_name,
800 int max_imports = ROUND_UP (fdef->num_imports, 16);
802 /* We need to avoid here duplicates. */
804 pos = find_import_in_list (fdef->imports, fdef->num_imports,
806 (!internal_name ? name : internal_name),
807 module, ordinal, is_dup);
809 return fdef->imports + pos;
811 if (fdef->num_imports >= max_imports)
813 max_imports = ROUND_UP (fdef->num_imports+1, 16);
816 fdef->imports = xrealloc (fdef->imports,
817 max_imports * sizeof (def_file_import));
819 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
821 i = fdef->imports + pos;
822 if (pos != fdef->num_imports)
823 memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
824 memset (i, 0, sizeof (def_file_import));
826 i->name = xstrdup (name);
828 i->module = def_stash_module (fdef, module);
829 i->ordinal = ordinal;
831 i->internal_name = xstrdup (internal_name);
833 i->internal_name = i->name;
834 i->its_name = (its_name ? xstrdup (its_name) : NULL);
847 { "-heap", HEAPSIZE },
848 { "-stack", STACKSIZE_K },
849 { "-attr", SECTIONS },
850 { "-export", EXPORTS },
851 { "-aligncomm", ALIGNCOMM },
856 def_file_add_directive (def_file *my_def, const char *param, int len)
858 def_file *save_def = def;
859 const char *pend = param + len;
860 char * tend = (char *) param;
868 && (ISSPACE (*param) || *param == '\n' || *param == 0))
874 /* Scan forward until we encounter any of:
875 - the end of the buffer
876 - the start of a new option
877 - a newline seperating options
878 - a NUL seperating options. */
879 for (tend = (char *) (param + 1);
881 && !(ISSPACE (tend[-1]) && *tend == '-')
882 && *tend != '\n' && *tend != 0);
886 for (i = 0; diropts[i].param; i++)
888 len = strlen (diropts[i].param);
890 if (tend - param >= len
891 && strncmp (param, diropts[i].param, len) == 0
892 && (param[len] == ':' || param[len] == ' '))
894 lex_parse_string_end = tend;
895 lex_parse_string = param + len + 1;
896 lex_forced_token = diropts[i].token;
904 if (!diropts[i].param)
910 /* xgettext:c-format */
911 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
915 lex_parse_string = 0;
923 /* Parser Callbacks. */
926 def_image_name (const char *name, int base, int is_dll)
928 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
929 to do here. We retain the output filename specified on command line. */
932 const char* image_name = lbasename (name);
934 if (image_name != name)
935 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
936 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
940 /* Append the default suffix, if none specified. */
941 if (strchr (image_name, '.') == 0)
943 const char * suffix = is_dll ? ".dll" : ".exe";
945 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
946 sprintf (def->name, "%s%s", image_name, suffix);
949 def->name = xstrdup (image_name);
952 /* Honor a BASE address statement, even if LIBRARY string is empty. */
953 def->base_address = base;
954 def->is_dll = is_dll;
958 def_description (const char *text)
960 int len = def->description ? strlen (def->description) : 0;
962 len += strlen (text) + 1;
963 if (def->description)
965 def->description = xrealloc (def->description, len);
966 strcat (def->description, text);
970 def->description = xmalloc (len);
971 strcpy (def->description, text);
976 def_stacksize (int reserve, int commit)
978 def->stack_reserve = reserve;
979 def->stack_commit = commit;
983 def_heapsize (int reserve, int commit)
985 def->heap_reserve = reserve;
986 def->heap_commit = commit;
990 def_section (const char *name, int attr)
993 int max_sections = ROUND_UP (def->num_section_defs, 4);
995 if (def->num_section_defs >= max_sections)
997 max_sections = ROUND_UP (def->num_section_defs+1, 4);
999 if (def->section_defs)
1000 def->section_defs = xrealloc (def->section_defs,
1001 max_sections * sizeof (def_file_import));
1003 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1005 s = def->section_defs + def->num_section_defs;
1006 memset (s, 0, sizeof (def_file_section));
1007 s->name = xstrdup (name);
1013 s->flag_execute = 1;
1017 def->num_section_defs++;
1021 def_section_alt (const char *name, const char *attr)
1025 for (; *attr; attr++)
1047 def_section (name, aval);
1051 def_exports (const char *external_name,
1052 const char *internal_name,
1055 const char *its_name)
1057 def_file_export *dfe;
1060 if (!internal_name && external_name)
1061 internal_name = external_name;
1063 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1066 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1069 /* We might check here for flag redefinition and warn. For now we
1070 ignore duplicates silently. */
1075 dfe->flag_noname = 1;
1077 dfe->flag_constant = 1;
1081 dfe->flag_private = 1;
1085 def_import (const char *internal_name,
1090 const char *its_name)
1093 const char *ext = dllext ? dllext : "dll";
1096 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1097 sprintf (buf, "%s.%s", module, ext);
1100 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1106 def_version (int major, int minor)
1108 def->version_major = major;
1109 def->version_minor = minor;
1113 def_directive (char *str)
1115 struct directive *d = xmalloc (sizeof (struct directive));
1117 d->next = directives;
1119 d->name = xstrdup (str);
1120 d->len = strlen (str);
1124 def_aligncomm (char *str, int align)
1126 def_file_aligncomm *c, *p;
1129 c = def->aligncomms;
1132 int e = strcmp (c->symbol_name, str);
1135 /* Not sure if we want to allow here duplicates with
1136 different alignments, but for now we keep them. */
1137 e = (int) c->alignment - align;
1146 c = xmalloc (sizeof (def_file_aligncomm));
1147 c->symbol_name = xstrdup (str);
1148 c->alignment = (unsigned int) align;
1151 c->next = def->aligncomms;
1152 def->aligncomms = c;
1162 def_error (const char *err)
1164 einfo ("%P: %s:%d: %s\n",
1165 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1170 /* Lexical Scanner. */
1175 /* Never freed, but always reused as needed, so no real leak. */
1176 static char *buffer = 0;
1177 static int buflen = 0;
1178 static int bufptr = 0;
1183 if (bufptr == buflen)
1185 buflen += 50; /* overly reasonable, eh? */
1187 buffer = xrealloc (buffer, buflen + 1);
1189 buffer = xmalloc (buflen + 1);
1191 buffer[bufptr++] = c;
1192 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1204 { "CONSTANT", CONSTANTU },
1205 { "constant", CONSTANTL },
1208 { "DESCRIPTION", DESCRIPTION },
1209 { "DIRECTIVE", DIRECTIVE },
1210 { "EXECUTE", EXECUTE },
1211 { "EXPORTS", EXPORTS },
1212 { "HEAPSIZE", HEAPSIZE },
1213 { "IMPORTS", IMPORTS },
1214 { "LIBRARY", LIBRARY },
1216 { "NONAME", NONAMEU },
1217 { "noname", NONAMEL },
1218 { "PRIVATE", PRIVATEU },
1219 { "private", PRIVATEL },
1221 { "SECTIONS", SECTIONS },
1222 { "SEGMENTS", SECTIONS },
1223 { "SHARED", SHARED },
1224 { "STACKSIZE", STACKSIZE_K },
1225 { "VERSION", VERSIONK },
1235 if (lex_parse_string)
1237 if (lex_parse_string >= lex_parse_string_end)
1240 rv = *lex_parse_string++;
1244 rv = fgetc (the_file);
1254 if (lex_parse_string)
1260 return ungetc (c, the_file);
1268 if (lex_forced_token)
1270 i = lex_forced_token;
1271 lex_forced_token = 0;
1273 printf ("lex: forcing token %d\n", i);
1280 /* Trim leading whitespace. */
1281 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1287 printf ("lex: EOF\n");
1292 if (saw_newline && c == ';')
1298 while (c != EOF && c != '\n');
1304 /* Must be something else. */
1310 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1317 yylval.digits = def_pool_strdup (buffer);
1319 printf ("lex: `%s' returns DIGITS\n", buffer);
1324 if (ISALPHA (c) || strchr ("$:-_?@", c))
1333 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1335 else if (ISDIGIT (c)) /* '@' followed by digit. */
1341 printf ("lex: @ returns itself\n");
1345 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1352 if (ISALPHA (q)) /* Check for tokens. */
1354 for (i = 0; tokens[i].name; i++)
1355 if (strcmp (tokens[i].name, buffer) == 0)
1358 printf ("lex: `%s' is a string token\n", buffer);
1360 return tokens[i].token;
1364 printf ("lex: `%s' returns ID\n", buffer);
1366 yylval.id = def_pool_strdup (buffer);
1370 if (c == '\'' || c == '"')
1376 while (c != EOF && c != q)
1381 yylval.id = def_pool_strdup (buffer);
1383 printf ("lex: `%s' returns ID\n", buffer);
1394 printf ("lex: `==' returns EQUAL\n");
1400 printf ("lex: `=' returns itself\n");
1404 if (c == '.' || c == ',')
1407 printf ("lex: `%c' returns itself\n", c);
1418 /*printf ("lex: 0x%02x ignored\n", c); */
1423 def_pool_alloc (size_t sz)
1427 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1428 e->next = pool_strs;
1434 def_pool_strdup (const char *str)
1440 len = strlen (str) + 1;
1441 s = def_pool_alloc (len);
1442 memcpy (s, str, len);
1447 def_pool_free (void)
1450 while ((p = pool_strs) != NULL)
1452 pool_strs = p->next;