* elf32-spu.c (build_stub): Fix malloc under-allocation.
[binutils.git] / ld / deffilep.y
blob3afb3ce3ce859ffcd370f53c99afbeadb3136c2e
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. */
23 #include "sysdep.h"
24 #include "libiberty.h"
25 #include "safe-ctype.h"
26 #include "bfd.h"
27 #include "ld.h"
28 #include "ldmisc.h"
29 #include "deffile.h"
31 #define TRACE 0
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
44 #define yylex def_lex
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
50 #define yyr1 def_r1
51 #define yyr2 def_r2
52 #define yydef def_def
53 #define yychk def_chk
54 #define yypgo def_pgo
55 #define yyact def_act
56 #define yyexca def_exca
57 #define yyerrflag def_errflag
58 #define yynerrs def_nerrs
59 #define yyps def_ps
60 #define yypv def_pv
61 #define yys def_s
62 #define yy_yys def_yys
63 #define yystate def_state
64 #define yytmp def_tmp
65 #define yyv def_v
66 #define yy_yyv def_yyv
67 #define yyval def_val
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;
83 char data[1];
84 } def_pool_str;
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 *,
96 int, 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;
114 %union {
115 char *id;
116 const char *id_const;
117 int number;
118 char *digits;
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
125 %token <id> ID
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
137 start: start command
138 | command
141 command:
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);}
149 | SECTIONS seclist
150 | EXPORTS explist
151 | IMPORTS implist
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);}
159 explist:
160 /* EMPTY */
161 | expline
162 | explist expline
165 expline:
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); }
172 exp_opt_list:
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; }
177 | { $$ = 0; }
179 exp_opt:
180 NONAMEU { $$ = 1; }
181 | NONAMEL { $$ = 1; }
182 | CONSTANTU { $$ = 2; }
183 | CONSTANTL { $$ = 2; }
184 | DATAU { $$ = 4; }
185 | DATAL { $$ = 4; }
186 | PRIVATEU { $$ = 8; }
187 | PRIVATEL { $$ = 8; }
189 implist:
190 implist impline
191 | impline
194 impline:
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); }
209 seclist:
210 seclist secline
211 | secline
214 secline:
215 ID attr_list { def_section ($1, $2);}
216 | ID ID { def_section_alt ($1, $2);}
219 attr_list:
220 attr_list opt_comma attr { $$ = $1 | $3; }
221 | attr { $$ = $1; }
224 opt_comma:
228 opt_number: ',' NUMBER { $$=$2;}
229 | { $$=-1;}
232 attr:
233 READ { $$ = 1;}
234 | WRITE { $$ = 2;}
235 | EXECUTE { $$=4;}
236 | SHARED { $$=8;}
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 /* Disable LIBRARY keyword as valid symbol-name. This is necessary
253 for libtool, which places this command after EXPORTS command.
254 This behavior is illegal by specification, but sadly required by
255 by compatibility reasons.
256 See PR binutils/13710
257 | LIBRARY { $$ = "LIBRARY"; } */
258 | NAME { $$ = "NAME"; }
259 | NONAMEU { $$ = "NONAME"; }
260 | NONAMEL { $$ = "noname"; }
261 | PRIVATEU { $$ = "PRIVATE"; }
262 | PRIVATEL { $$ = "private"; }
263 | READ { $$ = "READ"; }
264 | SHARED { $$ = "SHARED"; }
265 | STACKSIZE_K { $$ = "STACKSIZE"; }
266 | VERSIONK { $$ = "VERSION"; }
267 | WRITE { $$ = "WRITE"; }
270 opt_name2: ID { $$ = $1; }
271 | '.' keyword_as_name
273 char *name = xmalloc (strlen ($2) + 2);
274 sprintf (name, ".%s", $2);
275 $$ = name;
277 | '.' opt_name2
279 char *name = def_pool_alloc (strlen ($2) + 2);
280 sprintf (name, ".%s", $2);
281 $$ = name;
283 | keyword_as_name '.' opt_name2
285 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
286 sprintf (name, "%s.%s", $1, $3);
287 $$ = name;
289 | ID '.' opt_name2
291 char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
292 sprintf (name, "%s.%s", $1, $3);
293 $$ = name;
297 opt_name: opt_name2 { $$ = $1; }
298 | { $$ = ""; }
301 opt_equalequal_name: EQUAL ID { $$ = $2; }
302 | { $$ = 0; }
305 opt_ordinal:
306 '@' NUMBER { $$ = $2;}
307 | { $$ = -1;}
310 opt_equal_name:
311 '=' opt_name2 { $$ = $2; }
312 | { $$ = 0; }
315 opt_base: BASE '=' NUMBER { $$ = $3;}
316 | { $$ = -1;}
319 anylang_id: ID { $$ = $1; }
320 | '.' ID
322 char *id = def_pool_alloc (strlen ($2) + 2);
323 sprintf (id, ".%s", $2);
324 $$ = id;
326 | anylang_id '.' opt_digits opt_id
328 char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
329 sprintf (id, "%s.%s%s", $1, $3, $4);
330 $$ = id;
334 opt_digits: DIGITS { $$ = $1; }
335 | { $$ = ""; }
338 opt_id: ID { $$ = $1; }
339 | { $$ = ""; }
342 NUMBER: DIGITS { $$ = strtoul ($1, 0, 0); }
346 /*****************************************************************************
348 *****************************************************************************/
350 static FILE *the_file;
351 static const char *def_filename;
352 static int linenumber;
353 static def_file *def;
354 static int saw_newline;
356 struct directive
358 struct directive *next;
359 char *name;
360 int len;
363 static struct directive *directives = 0;
365 def_file *
366 def_file_empty (void)
368 def_file *rv = xmalloc (sizeof (def_file));
369 memset (rv, 0, sizeof (def_file));
370 rv->is_dll = -1;
371 rv->base_address = (bfd_vma) -1;
372 rv->stack_reserve = rv->stack_commit = -1;
373 rv->heap_reserve = rv->heap_commit = -1;
374 rv->version_major = rv->version_minor = -1;
375 return rv;
378 def_file *
379 def_file_parse (const char *filename, def_file *add_to)
381 struct directive *d;
383 the_file = fopen (filename, "r");
384 def_filename = filename;
385 linenumber = 1;
386 if (!the_file)
388 perror (filename);
389 return 0;
391 if (add_to)
393 def = add_to;
395 else
397 def = def_file_empty ();
400 saw_newline = 1;
401 if (def_parse ())
403 def_file_free (def);
404 fclose (the_file);
405 def_pool_free ();
406 return 0;
409 fclose (the_file);
411 while ((d = directives) != NULL)
413 #if TRACE
414 printf ("Adding directive %08x `%s'\n", d->name, d->name);
415 #endif
416 def_file_add_directive (def, d->name, d->len);
417 directives = d->next;
418 free (d->name);
419 free (d);
421 def_pool_free ();
423 return def;
426 void
427 def_file_free (def_file *fdef)
429 int i;
431 if (!fdef)
432 return;
433 if (fdef->name)
434 free (fdef->name);
435 if (fdef->description)
436 free (fdef->description);
438 if (fdef->section_defs)
440 for (i = 0; i < fdef->num_section_defs; i++)
442 if (fdef->section_defs[i].name)
443 free (fdef->section_defs[i].name);
444 if (fdef->section_defs[i].class)
445 free (fdef->section_defs[i].class);
447 free (fdef->section_defs);
450 if (fdef->exports)
452 for (i = 0; i < fdef->num_exports; i++)
454 if (fdef->exports[i].internal_name
455 && fdef->exports[i].internal_name != fdef->exports[i].name)
456 free (fdef->exports[i].internal_name);
457 if (fdef->exports[i].name)
458 free (fdef->exports[i].name);
459 if (fdef->exports[i].its_name)
460 free (fdef->exports[i].its_name);
462 free (fdef->exports);
465 if (fdef->imports)
467 for (i = 0; i < fdef->num_imports; i++)
469 if (fdef->imports[i].internal_name
470 && fdef->imports[i].internal_name != fdef->imports[i].name)
471 free (fdef->imports[i].internal_name);
472 if (fdef->imports[i].name)
473 free (fdef->imports[i].name);
474 if (fdef->imports[i].its_name)
475 free (fdef->imports[i].its_name);
477 free (fdef->imports);
480 while (fdef->modules)
482 def_file_module *m = fdef->modules;
484 fdef->modules = fdef->modules->next;
485 free (m);
488 while (fdef->aligncomms)
490 def_file_aligncomm *c = fdef->aligncomms;
492 fdef->aligncomms = fdef->aligncomms->next;
493 free (c->symbol_name);
494 free (c);
497 free (fdef);
500 #ifdef DEF_FILE_PRINT
501 void
502 def_file_print (FILE *file, def_file *fdef)
504 int i;
506 fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
507 if (fdef->name)
508 fprintf (file, " name: %s\n", fdef->name ? fdef->name : "(unspecified)");
509 if (fdef->is_dll != -1)
510 fprintf (file, " is dll: %s\n", fdef->is_dll ? "yes" : "no");
511 if (fdef->base_address != (bfd_vma) -1)
512 fprintf (file, " base address: 0x%08x\n", fdef->base_address);
513 if (fdef->description)
514 fprintf (file, " description: `%s'\n", fdef->description);
515 if (fdef->stack_reserve != -1)
516 fprintf (file, " stack reserve: 0x%08x\n", fdef->stack_reserve);
517 if (fdef->stack_commit != -1)
518 fprintf (file, " stack commit: 0x%08x\n", fdef->stack_commit);
519 if (fdef->heap_reserve != -1)
520 fprintf (file, " heap reserve: 0x%08x\n", fdef->heap_reserve);
521 if (fdef->heap_commit != -1)
522 fprintf (file, " heap commit: 0x%08x\n", fdef->heap_commit);
524 if (fdef->num_section_defs > 0)
526 fprintf (file, " section defs:\n");
528 for (i = 0; i < fdef->num_section_defs; i++)
530 fprintf (file, " name: `%s', class: `%s', flags:",
531 fdef->section_defs[i].name, fdef->section_defs[i].class);
532 if (fdef->section_defs[i].flag_read)
533 fprintf (file, " R");
534 if (fdef->section_defs[i].flag_write)
535 fprintf (file, " W");
536 if (fdef->section_defs[i].flag_execute)
537 fprintf (file, " X");
538 if (fdef->section_defs[i].flag_shared)
539 fprintf (file, " S");
540 fprintf (file, "\n");
544 if (fdef->num_exports > 0)
546 fprintf (file, " exports:\n");
548 for (i = 0; i < fdef->num_exports; i++)
550 fprintf (file, " name: `%s', int: `%s', ordinal: %d, flags:",
551 fdef->exports[i].name, fdef->exports[i].internal_name,
552 fdef->exports[i].ordinal);
553 if (fdef->exports[i].flag_private)
554 fprintf (file, " P");
555 if (fdef->exports[i].flag_constant)
556 fprintf (file, " C");
557 if (fdef->exports[i].flag_noname)
558 fprintf (file, " N");
559 if (fdef->exports[i].flag_data)
560 fprintf (file, " D");
561 fprintf (file, "\n");
565 if (fdef->num_imports > 0)
567 fprintf (file, " imports:\n");
569 for (i = 0; i < fdef->num_imports; i++)
571 fprintf (file, " int: %s, from: `%s', name: `%s', ordinal: %d\n",
572 fdef->imports[i].internal_name,
573 fdef->imports[i].module,
574 fdef->imports[i].name,
575 fdef->imports[i].ordinal);
579 if (fdef->version_major != -1)
580 fprintf (file, " version: %d.%d\n", fdef->version_major, fdef->version_minor);
582 fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
584 #endif
586 /* Helper routine to check for identity of string pointers,
587 which might be NULL. */
589 static int
590 are_names_equal (const char *s1, const char *s2)
592 if (!s1 && !s2)
593 return 0;
594 if (!s1 || !s2)
595 return (!s1 ? -1 : 1);
596 return strcmp (s1, s2);
599 static int
600 cmp_export_elem (const def_file_export *e, const char *ex_name,
601 const char *in_name, const char *its_name,
602 int ord)
604 int r;
606 if ((r = are_names_equal (ex_name, e->name)) != 0)
607 return r;
608 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
609 return r;
610 if ((r = are_names_equal (its_name, e->its_name)) != 0)
611 return r;
612 return (ord - e->ordinal);
615 /* Search the position of the identical element, or returns the position
616 of the next higher element. If last valid element is smaller, then MAX
617 is returned. */
619 static int
620 find_export_in_list (def_file_export *b, int max,
621 const char *ex_name, const char *in_name,
622 const char *its_name, int ord, int *is_ident)
624 int e, l, r, p;
626 *is_ident = 0;
627 if (!max)
628 return 0;
629 if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
631 if (!e)
632 *is_ident = 1;
633 return 0;
635 if (max == 1)
636 return 1;
637 if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
638 return max;
639 else if (!e || max == 2)
641 if (!e)
642 *is_ident = 1;
643 return max - 1;
645 l = 0; r = max - 1;
646 while (l < r)
648 p = (l + r) / 2;
649 e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
650 if (!e)
652 *is_ident = 1;
653 return p;
655 else if (e < 0)
656 r = p - 1;
657 else if (e > 0)
658 l = p + 1;
660 if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
661 ++l;
662 else if (!e)
663 *is_ident = 1;
664 return l;
667 def_file_export *
668 def_file_add_export (def_file *fdef,
669 const char *external_name,
670 const char *internal_name,
671 int ordinal,
672 const char *its_name,
673 int *is_dup)
675 def_file_export *e;
676 int pos;
677 int max_exports = ROUND_UP(fdef->num_exports, 32);
679 if (internal_name && !external_name)
680 external_name = internal_name;
681 if (external_name && !internal_name)
682 internal_name = external_name;
684 /* We need to avoid duplicates. */
685 *is_dup = 0;
686 pos = find_export_in_list (fdef->exports, fdef->num_exports,
687 external_name, internal_name,
688 its_name, ordinal, is_dup);
690 if (*is_dup != 0)
691 return (fdef->exports + pos);
693 if (fdef->num_exports >= max_exports)
695 max_exports = ROUND_UP(fdef->num_exports + 1, 32);
696 if (fdef->exports)
697 fdef->exports = xrealloc (fdef->exports,
698 max_exports * sizeof (def_file_export));
699 else
700 fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
703 e = fdef->exports + pos;
704 if (pos != fdef->num_exports)
705 memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
706 memset (e, 0, sizeof (def_file_export));
707 e->name = xstrdup (external_name);
708 e->internal_name = xstrdup (internal_name);
709 e->its_name = (its_name ? xstrdup (its_name) : NULL);
710 e->ordinal = ordinal;
711 fdef->num_exports++;
712 return e;
715 def_file_module *
716 def_get_module (def_file *fdef, const char *name)
718 def_file_module *s;
720 for (s = fdef->modules; s; s = s->next)
721 if (strcmp (s->name, name) == 0)
722 return s;
724 return NULL;
727 static def_file_module *
728 def_stash_module (def_file *fdef, const char *name)
730 def_file_module *s;
732 if ((s = def_get_module (fdef, name)) != NULL)
733 return s;
734 s = xmalloc (sizeof (def_file_module) + strlen (name));
735 s->next = fdef->modules;
736 fdef->modules = s;
737 s->user_data = 0;
738 strcpy (s->name, name);
739 return s;
742 static int
743 cmp_import_elem (const def_file_import *e, const char *ex_name,
744 const char *in_name, const char *module,
745 int ord)
747 int r;
749 if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
750 return r;
751 if ((r = are_names_equal (ex_name, e->name)) != 0)
752 return r;
753 if ((r = are_names_equal (in_name, e->internal_name)) != 0)
754 return r;
755 if (ord != e->ordinal)
756 return (ord < e->ordinal ? -1 : 1);
757 return 0;
760 /* Search the position of the identical element, or returns the position
761 of the next higher element. If last valid element is smaller, then MAX
762 is returned. */
764 static int
765 find_import_in_list (def_file_import *b, int max,
766 const char *ex_name, const char *in_name,
767 const char *module, int ord, int *is_ident)
769 int e, l, r, p;
771 *is_ident = 0;
772 if (!max)
773 return 0;
774 if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
776 if (!e)
777 *is_ident = 1;
778 return 0;
780 if (max == 1)
781 return 1;
782 if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
783 return max;
784 else if (!e || max == 2)
786 if (!e)
787 *is_ident = 1;
788 return max - 1;
790 l = 0; r = max - 1;
791 while (l < r)
793 p = (l + r) / 2;
794 e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
795 if (!e)
797 *is_ident = 1;
798 return p;
800 else if (e < 0)
801 r = p - 1;
802 else if (e > 0)
803 l = p + 1;
805 if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
806 ++l;
807 else if (!e)
808 *is_ident = 1;
809 return l;
812 def_file_import *
813 def_file_add_import (def_file *fdef,
814 const char *name,
815 const char *module,
816 int ordinal,
817 const char *internal_name,
818 const char *its_name,
819 int *is_dup)
821 def_file_import *i;
822 int pos;
823 int max_imports = ROUND_UP (fdef->num_imports, 16);
825 /* We need to avoid here duplicates. */
826 *is_dup = 0;
827 pos = find_import_in_list (fdef->imports, fdef->num_imports,
828 name,
829 (!internal_name ? name : internal_name),
830 module, ordinal, is_dup);
831 if (*is_dup != 0)
832 return fdef->imports + pos;
834 if (fdef->num_imports >= max_imports)
836 max_imports = ROUND_UP (fdef->num_imports+1, 16);
838 if (fdef->imports)
839 fdef->imports = xrealloc (fdef->imports,
840 max_imports * sizeof (def_file_import));
841 else
842 fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
844 i = fdef->imports + pos;
845 if (pos != fdef->num_imports)
846 memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
847 memset (i, 0, sizeof (def_file_import));
848 if (name)
849 i->name = xstrdup (name);
850 if (module)
851 i->module = def_stash_module (fdef, module);
852 i->ordinal = ordinal;
853 if (internal_name)
854 i->internal_name = xstrdup (internal_name);
855 else
856 i->internal_name = i->name;
857 i->its_name = (its_name ? xstrdup (its_name) : NULL);
858 fdef->num_imports++;
860 return i;
863 struct
865 char *param;
866 int token;
868 diropts[] =
870 { "-heap", HEAPSIZE },
871 { "-stack", STACKSIZE_K },
872 { "-attr", SECTIONS },
873 { "-export", EXPORTS },
874 { "-aligncomm", ALIGNCOMM },
875 { 0, 0 }
878 void
879 def_file_add_directive (def_file *my_def, const char *param, int len)
881 def_file *save_def = def;
882 const char *pend = param + len;
883 char * tend = (char *) param;
884 int i;
886 def = my_def;
888 while (param < pend)
890 while (param < pend
891 && (ISSPACE (*param) || *param == '\n' || *param == 0))
892 param++;
894 if (param == pend)
895 break;
897 /* Scan forward until we encounter any of:
898 - the end of the buffer
899 - the start of a new option
900 - a newline seperating options
901 - a NUL seperating options. */
902 for (tend = (char *) (param + 1);
903 (tend < pend
904 && !(ISSPACE (tend[-1]) && *tend == '-')
905 && *tend != '\n' && *tend != 0);
906 tend++)
909 for (i = 0; diropts[i].param; i++)
911 len = strlen (diropts[i].param);
913 if (tend - param >= len
914 && strncmp (param, diropts[i].param, len) == 0
915 && (param[len] == ':' || param[len] == ' '))
917 lex_parse_string_end = tend;
918 lex_parse_string = param + len + 1;
919 lex_forced_token = diropts[i].token;
920 saw_newline = 0;
921 if (def_parse ())
922 continue;
923 break;
927 if (!diropts[i].param)
929 char saved;
931 saved = * tend;
932 * tend = 0;
933 /* xgettext:c-format */
934 einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
935 * tend = saved;
938 lex_parse_string = 0;
939 param = tend;
942 def = save_def;
943 def_pool_free ();
946 /* Parser Callbacks. */
948 static void
949 def_image_name (const char *name, int base, int is_dll)
951 /* If a LIBRARY or NAME statement is specified without a name, there is nothing
952 to do here. We retain the output filename specified on command line. */
953 if (*name)
955 const char* image_name = lbasename (name);
957 if (image_name != name)
958 einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
959 def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
960 name);
961 if (def->name)
962 free (def->name);
963 /* Append the default suffix, if none specified. */
964 if (strchr (image_name, '.') == 0)
966 const char * suffix = is_dll ? ".dll" : ".exe";
968 def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
969 sprintf (def->name, "%s%s", image_name, suffix);
971 else
972 def->name = xstrdup (image_name);
975 /* Honor a BASE address statement, even if LIBRARY string is empty. */
976 def->base_address = base;
977 def->is_dll = is_dll;
980 static void
981 def_description (const char *text)
983 int len = def->description ? strlen (def->description) : 0;
985 len += strlen (text) + 1;
986 if (def->description)
988 def->description = xrealloc (def->description, len);
989 strcat (def->description, text);
991 else
993 def->description = xmalloc (len);
994 strcpy (def->description, text);
998 static void
999 def_stacksize (int reserve, int commit)
1001 def->stack_reserve = reserve;
1002 def->stack_commit = commit;
1005 static void
1006 def_heapsize (int reserve, int commit)
1008 def->heap_reserve = reserve;
1009 def->heap_commit = commit;
1012 static void
1013 def_section (const char *name, int attr)
1015 def_file_section *s;
1016 int max_sections = ROUND_UP (def->num_section_defs, 4);
1018 if (def->num_section_defs >= max_sections)
1020 max_sections = ROUND_UP (def->num_section_defs+1, 4);
1022 if (def->section_defs)
1023 def->section_defs = xrealloc (def->section_defs,
1024 max_sections * sizeof (def_file_import));
1025 else
1026 def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1028 s = def->section_defs + def->num_section_defs;
1029 memset (s, 0, sizeof (def_file_section));
1030 s->name = xstrdup (name);
1031 if (attr & 1)
1032 s->flag_read = 1;
1033 if (attr & 2)
1034 s->flag_write = 1;
1035 if (attr & 4)
1036 s->flag_execute = 1;
1037 if (attr & 8)
1038 s->flag_shared = 1;
1040 def->num_section_defs++;
1043 static void
1044 def_section_alt (const char *name, const char *attr)
1046 int aval = 0;
1048 for (; *attr; attr++)
1050 switch (*attr)
1052 case 'R':
1053 case 'r':
1054 aval |= 1;
1055 break;
1056 case 'W':
1057 case 'w':
1058 aval |= 2;
1059 break;
1060 case 'X':
1061 case 'x':
1062 aval |= 4;
1063 break;
1064 case 'S':
1065 case 's':
1066 aval |= 8;
1067 break;
1070 def_section (name, aval);
1073 static void
1074 def_exports (const char *external_name,
1075 const char *internal_name,
1076 int ordinal,
1077 int flags,
1078 const char *its_name)
1080 def_file_export *dfe;
1081 int is_dup = 0;
1083 if (!internal_name && external_name)
1084 internal_name = external_name;
1085 #if TRACE
1086 printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1087 #endif
1089 dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1090 its_name, &is_dup);
1092 /* We might check here for flag redefinition and warn. For now we
1093 ignore duplicates silently. */
1094 if (is_dup)
1095 return;
1097 if (flags & 1)
1098 dfe->flag_noname = 1;
1099 if (flags & 2)
1100 dfe->flag_constant = 1;
1101 if (flags & 4)
1102 dfe->flag_data = 1;
1103 if (flags & 8)
1104 dfe->flag_private = 1;
1107 static void
1108 def_import (const char *internal_name,
1109 const char *module,
1110 const char *dllext,
1111 const char *name,
1112 int ordinal,
1113 const char *its_name)
1115 char *buf = 0;
1116 const char *ext = dllext ? dllext : "dll";
1117 int is_dup = 0;
1119 buf = xmalloc (strlen (module) + strlen (ext) + 2);
1120 sprintf (buf, "%s.%s", module, ext);
1121 module = buf;
1123 def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1124 &is_dup);
1125 free (buf);
1128 static void
1129 def_version (int major, int minor)
1131 def->version_major = major;
1132 def->version_minor = minor;
1135 static void
1136 def_directive (char *str)
1138 struct directive *d = xmalloc (sizeof (struct directive));
1140 d->next = directives;
1141 directives = d;
1142 d->name = xstrdup (str);
1143 d->len = strlen (str);
1146 static void
1147 def_aligncomm (char *str, int align)
1149 def_file_aligncomm *c, *p;
1151 p = NULL;
1152 c = def->aligncomms;
1153 while (c != NULL)
1155 int e = strcmp (c->symbol_name, str);
1156 if (!e)
1158 /* Not sure if we want to allow here duplicates with
1159 different alignments, but for now we keep them. */
1160 e = (int) c->alignment - align;
1161 if (!e)
1162 return;
1164 if (e > 0)
1165 break;
1166 c = (p = c)->next;
1169 c = xmalloc (sizeof (def_file_aligncomm));
1170 c->symbol_name = xstrdup (str);
1171 c->alignment = (unsigned int) align;
1172 if (!p)
1174 c->next = def->aligncomms;
1175 def->aligncomms = c;
1177 else
1179 c->next = p->next;
1180 p->next = c;
1184 static int
1185 def_error (const char *err)
1187 einfo ("%P: %s:%d: %s\n",
1188 def_filename ? def_filename : "<unknown-file>", linenumber, err);
1189 return 0;
1193 /* Lexical Scanner. */
1195 #undef TRACE
1196 #define TRACE 0
1198 /* Never freed, but always reused as needed, so no real leak. */
1199 static char *buffer = 0;
1200 static int buflen = 0;
1201 static int bufptr = 0;
1203 static void
1204 put_buf (char c)
1206 if (bufptr == buflen)
1208 buflen += 50; /* overly reasonable, eh? */
1209 if (buffer)
1210 buffer = xrealloc (buffer, buflen + 1);
1211 else
1212 buffer = xmalloc (buflen + 1);
1214 buffer[bufptr++] = c;
1215 buffer[bufptr] = 0; /* not optimal, but very convenient. */
1218 static struct
1220 char *name;
1221 int token;
1223 tokens[] =
1225 { "BASE", BASE },
1226 { "CODE", CODE },
1227 { "CONSTANT", CONSTANTU },
1228 { "constant", CONSTANTL },
1229 { "DATA", DATAU },
1230 { "data", DATAL },
1231 { "DESCRIPTION", DESCRIPTION },
1232 { "DIRECTIVE", DIRECTIVE },
1233 { "EXECUTE", EXECUTE },
1234 { "EXPORTS", EXPORTS },
1235 { "HEAPSIZE", HEAPSIZE },
1236 { "IMPORTS", IMPORTS },
1237 { "LIBRARY", LIBRARY },
1238 { "NAME", NAME },
1239 { "NONAME", NONAMEU },
1240 { "noname", NONAMEL },
1241 { "PRIVATE", PRIVATEU },
1242 { "private", PRIVATEL },
1243 { "READ", READ },
1244 { "SECTIONS", SECTIONS },
1245 { "SEGMENTS", SECTIONS },
1246 { "SHARED", SHARED },
1247 { "STACKSIZE", STACKSIZE_K },
1248 { "VERSION", VERSIONK },
1249 { "WRITE", WRITE },
1250 { 0, 0 }
1253 static int
1254 def_getc (void)
1256 int rv;
1258 if (lex_parse_string)
1260 if (lex_parse_string >= lex_parse_string_end)
1261 rv = EOF;
1262 else
1263 rv = *lex_parse_string++;
1265 else
1267 rv = fgetc (the_file);
1269 if (rv == '\n')
1270 saw_newline = 1;
1271 return rv;
1274 static int
1275 def_ungetc (int c)
1277 if (lex_parse_string)
1279 lex_parse_string--;
1280 return c;
1282 else
1283 return ungetc (c, the_file);
1286 static int
1287 def_lex (void)
1289 int c, i, q;
1291 if (lex_forced_token)
1293 i = lex_forced_token;
1294 lex_forced_token = 0;
1295 #if TRACE
1296 printf ("lex: forcing token %d\n", i);
1297 #endif
1298 return i;
1301 c = def_getc ();
1303 /* Trim leading whitespace. */
1304 while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1305 c = def_getc ();
1307 if (c == EOF)
1309 #if TRACE
1310 printf ("lex: EOF\n");
1311 #endif
1312 return 0;
1315 if (saw_newline && c == ';')
1319 c = def_getc ();
1321 while (c != EOF && c != '\n');
1322 if (c == '\n')
1323 return def_lex ();
1324 return 0;
1327 /* Must be something else. */
1328 saw_newline = 0;
1330 if (ISDIGIT (c))
1332 bufptr = 0;
1333 while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1335 put_buf (c);
1336 c = def_getc ();
1338 if (c != EOF)
1339 def_ungetc (c);
1340 yylval.digits = def_pool_strdup (buffer);
1341 #if TRACE
1342 printf ("lex: `%s' returns DIGITS\n", buffer);
1343 #endif
1344 return DIGITS;
1347 if (ISALPHA (c) || strchr ("$:-_?@", c))
1349 bufptr = 0;
1350 q = c;
1351 put_buf (c);
1352 c = def_getc ();
1354 if (q == '@')
1356 if (ISBLANK (c) ) /* '@' followed by whitespace. */
1357 return (q);
1358 else if (ISDIGIT (c)) /* '@' followed by digit. */
1360 def_ungetc (c);
1361 return (q);
1363 #if TRACE
1364 printf ("lex: @ returns itself\n");
1365 #endif
1368 while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1370 put_buf (c);
1371 c = def_getc ();
1373 if (c != EOF)
1374 def_ungetc (c);
1375 if (ISALPHA (q)) /* Check for tokens. */
1377 for (i = 0; tokens[i].name; i++)
1378 if (strcmp (tokens[i].name, buffer) == 0)
1380 #if TRACE
1381 printf ("lex: `%s' is a string token\n", buffer);
1382 #endif
1383 return tokens[i].token;
1386 #if TRACE
1387 printf ("lex: `%s' returns ID\n", buffer);
1388 #endif
1389 yylval.id = def_pool_strdup (buffer);
1390 return ID;
1393 if (c == '\'' || c == '"')
1395 q = c;
1396 c = def_getc ();
1397 bufptr = 0;
1399 while (c != EOF && c != q)
1401 put_buf (c);
1402 c = def_getc ();
1404 yylval.id = def_pool_strdup (buffer);
1405 #if TRACE
1406 printf ("lex: `%s' returns ID\n", buffer);
1407 #endif
1408 return ID;
1411 if ( c == '=')
1413 c = def_getc ();
1414 if (c == '=')
1416 #if TRACE
1417 printf ("lex: `==' returns EQUAL\n");
1418 #endif
1419 return EQUAL;
1421 def_ungetc (c);
1422 #if TRACE
1423 printf ("lex: `=' returns itself\n");
1424 #endif
1425 return '=';
1427 if (c == '.' || c == ',')
1429 #if TRACE
1430 printf ("lex: `%c' returns itself\n", c);
1431 #endif
1432 return c;
1435 if (c == '\n')
1437 linenumber++;
1438 saw_newline = 1;
1441 /*printf ("lex: 0x%02x ignored\n", c); */
1442 return def_lex ();
1445 static char *
1446 def_pool_alloc (size_t sz)
1448 def_pool_str *e;
1450 e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1451 e->next = pool_strs;
1452 pool_strs = e;
1453 return e->data;
1456 static char *
1457 def_pool_strdup (const char *str)
1459 char *s;
1460 size_t len;
1461 if (!str)
1462 return NULL;
1463 len = strlen (str) + 1;
1464 s = def_pool_alloc (len);
1465 memcpy (s, str, len);
1466 return s;
1469 static void
1470 def_pool_free (void)
1472 def_pool_str *p;
1473 while ((p = pool_strs) != NULL)
1475 pool_strs = p->next;
1476 free (p);