include/elf/
[platform/upstream/binutils.git] / ld / deffilep.y
1 %{ /* deffilep.y - parser for .def files */
2
3 /*   Copyright 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006,
4      2007, 2009 Free Software Foundation, Inc.
5
6      This file is part of GNU Binutils.
7
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.
12
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.
17
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.  */
22
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"
30
31 #define TRACE 0
32
33 #define ROUND_UP(a, b) (((a)+((b)-1))&~((b)-1))
34
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.  */
41
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
80
81 typedef struct def_pool_str {
82   struct def_pool_str *next;
83   char data[1];
84 } def_pool_str;
85
86 static def_pool_str *pool_strs = NULL;
87
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);
91
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 *, 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);
107
108 static int lex_forced_token = 0;
109 static const char *lex_parse_string = 0;
110 static const char *lex_parse_string_end = 0;
111
112 %}
113
114 %union {
115   char *id;
116   const char *id_const;
117   int number;
118   bfd_vma vma;
119   char *digits;
120 };
121
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
126 %token <id> ID
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
136
137 %%
138
139 start: start command
140         | command
141         ;
142
143 command:
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);}
151         |       SECTIONS seclist
152         |       EXPORTS explist
153         |       IMPORTS implist
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);}
158         ;
159
160
161 explist:
162                 /* EMPTY */
163         |       expline
164         |       explist expline
165         ;
166
167 expline:
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); }
173         ;
174 exp_opt_list:
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; }
179         |       { $$ = 0; }
180         ;
181 exp_opt:
182                 NONAMEU         { $$ = 1; }
183         |       NONAMEL         { $$ = 1; }
184         |       CONSTANTU       { $$ = 2; }
185         |       CONSTANTL       { $$ = 2; }
186         |       DATAU           { $$ = 4; }
187         |       DATAL           { $$ = 4; }
188         |       PRIVATEU        { $$ = 8; }
189         |       PRIVATEL        { $$ = 8; }
190         ;
191 implist:
192                 implist impline
193         |       impline
194         ;
195
196 impline:
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); }
209 ;
210
211 seclist:
212                 seclist secline
213         |       secline
214         ;
215
216 secline:
217         ID attr_list { def_section ($1, $2);}
218         | ID ID { def_section_alt ($1, $2);}
219         ;
220
221 attr_list:
222         attr_list opt_comma attr { $$ = $1 | $3; }
223         | attr { $$ = $1; }
224         ;
225
226 opt_comma:
227         ','
228         |
229         ;
230 opt_number: ',' NUMBER { $$=$2;}
231         |          { $$=-1;}
232         ;
233
234 attr:
235                 READ    { $$ = 1;}
236         |       WRITE   { $$ = 2;}
237         |       EXECUTE { $$=4;}
238         |       SHARED  { $$=8;}
239         ;
240
241
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"; }
270          ;
271
272 opt_name2: ID { $$ = $1; }
273         | '.' keyword_as_name
274           {
275             char *name = xmalloc (strlen ($2) + 2);
276             sprintf (name, ".%s", $2);
277             $$ = name;
278           }
279         | '.' opt_name2
280           {
281             char *name = def_pool_alloc (strlen ($2) + 2);
282             sprintf (name, ".%s", $2);
283             $$ = name;
284           }
285         | keyword_as_name '.' opt_name2
286           {
287             char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
288             sprintf (name, "%s.%s", $1, $3);
289             $$ = name;
290           }
291         | ID '.' opt_name2
292           {
293             char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
294             sprintf (name, "%s.%s", $1, $3);
295             $$ = name;
296           }
297         ;
298
299 opt_name: opt_name2 { $$ = $1; }
300         |               { $$ = ""; }
301         ;
302
303 opt_equalequal_name: EQUAL ID   { $$ = $2; }
304         |                                                       { $$ = 0; }
305         ;
306
307 opt_ordinal:
308           '@' NUMBER     { $$ = $2;}
309         |                { $$ = -1;}
310         ;
311
312 opt_equal_name:
313           '=' opt_name2 { $$ = $2; }
314         |               { $$ =  0; }
315         ;
316
317 opt_base: BASE  '=' VMA { $$ = $3;}
318         |       { $$ = (bfd_vma) -1;}
319         ;
320
321 anylang_id: ID          { $$ = $1; }
322         | '.' ID
323           {
324             char *id = def_pool_alloc (strlen ($2) + 2);
325             sprintf (id, ".%s", $2);
326             $$ = id;
327           }
328         | anylang_id '.' opt_digits opt_id
329           {
330             char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
331             sprintf (id, "%s.%s%s", $1, $3, $4);
332             $$ = id;
333           }
334         ;
335
336 opt_digits: DIGITS      { $$ = $1; }
337         |               { $$ = ""; }
338         ;
339
340 opt_id: ID              { $$ = $1; }
341         |               { $$ = ""; }
342         ;
343
344 NUMBER: DIGITS          { $$ = strtoul ($1, 0, 0); }
345         ;
346 VMA: DIGITS             { $$ = (bfd_vma) strtoull ($1, 0, 0); }
347
348 %%
349
350 /*****************************************************************************
351  API
352  *****************************************************************************/
353
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;
359
360 struct directive
361   {
362     struct directive *next;
363     char *name;
364     int len;
365   };
366
367 static struct directive *directives = 0;
368
369 def_file *
370 def_file_empty (void)
371 {
372   def_file *rv = xmalloc (sizeof (def_file));
373   memset (rv, 0, sizeof (def_file));
374   rv->is_dll = -1;
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;
379   return rv;
380 }
381
382 def_file *
383 def_file_parse (const char *filename, def_file *add_to)
384 {
385   struct directive *d;
386
387   the_file = fopen (filename, "r");
388   def_filename = filename;
389   linenumber = 1;
390   if (!the_file)
391     {
392       perror (filename);
393       return 0;
394     }
395   if (add_to)
396     {
397       def = add_to;
398     }
399   else
400     {
401       def = def_file_empty ();
402     }
403
404   saw_newline = 1;
405   if (def_parse ())
406     {
407       def_file_free (def);
408       fclose (the_file);
409       def_pool_free ();
410       return 0;
411     }
412
413   fclose (the_file);
414
415   while ((d = directives) != NULL)
416     {
417 #if TRACE
418       printf ("Adding directive %08x `%s'\n", d->name, d->name);
419 #endif
420       def_file_add_directive (def, d->name, d->len);
421       directives = d->next;
422       free (d->name);
423       free (d);
424     }
425   def_pool_free ();
426
427   return def;
428 }
429
430 void
431 def_file_free (def_file *fdef)
432 {
433   int i;
434
435   if (!fdef)
436     return;
437   if (fdef->name)
438     free (fdef->name);
439   if (fdef->description)
440     free (fdef->description);
441
442   if (fdef->section_defs)
443     {
444       for (i = 0; i < fdef->num_section_defs; i++)
445         {
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);
450         }
451       free (fdef->section_defs);
452     }
453
454   if (fdef->exports)
455     {
456       for (i = 0; i < fdef->num_exports; i++)
457         {
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);
465         }
466       free (fdef->exports);
467     }
468
469   if (fdef->imports)
470     {
471       for (i = 0; i < fdef->num_imports; i++)
472         {
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);
480         }
481       free (fdef->imports);
482     }
483
484   while (fdef->modules)
485     {
486       def_file_module *m = fdef->modules;
487
488       fdef->modules = fdef->modules->next;
489       free (m);
490     }
491
492   while (fdef->aligncomms)
493     {
494       def_file_aligncomm *c = fdef->aligncomms;
495
496       fdef->aligncomms = fdef->aligncomms->next;
497       free (c->symbol_name);
498       free (c);
499     }
500
501   free (fdef);
502 }
503
504 #ifdef DEF_FILE_PRINT
505 void
506 def_file_print (FILE *file, def_file *fdef)
507 {
508   int i;
509
510   fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
511   if (fdef->name)
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)
516     {
517       fprintf (file, "  base address: 0x");
518       fprintf_vma (file, fdef->base_address);
519       fprintf (file, "\n");
520     }
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);
531
532   if (fdef->num_section_defs > 0)
533     {
534       fprintf (file, "  section defs:\n");
535
536       for (i = 0; i < fdef->num_section_defs; i++)
537         {
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");
549         }
550     }
551
552   if (fdef->num_exports > 0)
553     {
554       fprintf (file, "  exports:\n");
555
556       for (i = 0; i < fdef->num_exports; i++)
557         {
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");
570         }
571     }
572
573   if (fdef->num_imports > 0)
574     {
575       fprintf (file, "  imports:\n");
576
577       for (i = 0; i < fdef->num_imports; i++)
578         {
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);
584         }
585     }
586
587   if (fdef->version_major != -1)
588     fprintf (file, "  version: %d.%d\n", fdef->version_major, fdef->version_minor);
589
590   fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
591 }
592 #endif
593
594 /* Helper routine to check for identity of string pointers,
595    which might be NULL.  */
596
597 static int
598 are_names_equal (const char *s1, const char *s2)
599 {
600   if (!s1 && !s2)
601     return 0;
602   if (!s1 || !s2)
603     return (!s1 ? -1 : 1);
604   return strcmp (s1, s2);
605 }
606
607 static int
608 cmp_export_elem (const def_file_export *e, const char *ex_name,
609                  const char *in_name, const char *its_name,
610                  int ord)
611 {
612   int r;
613
614   if ((r = are_names_equal (ex_name, e->name)) != 0)
615     return r;
616   if ((r = are_names_equal (in_name, e->internal_name)) != 0)
617     return r;
618   if ((r = are_names_equal (its_name, e->its_name)) != 0)
619     return r;
620   return (ord - e->ordinal);
621 }
622
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
625    is returned.  */
626
627 static int
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)
631 {
632   int e, l, r, p;
633
634   *is_ident = 0;
635   if (!max)
636     return 0;
637   if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
638     {
639       if (!e)
640         *is_ident = 1;
641       return 0;
642     }
643   if (max == 1)
644     return 1;
645   if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
646     return max;
647   else if (!e || max == 2)
648     {
649       if (!e)
650         *is_ident = 1;
651       return max - 1;
652     }
653   l = 0; r = max - 1;
654   while (l < r)
655     {
656       p = (l + r) / 2;
657       e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
658       if (!e)
659         {
660           *is_ident = 1;
661           return p;
662         }
663       else if (e < 0)
664         r = p - 1;
665       else if (e > 0)
666         l = p + 1;
667     }
668   if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
669     ++l;
670   else if (!e)
671     *is_ident = 1;
672   return l;
673 }
674
675 def_file_export *
676 def_file_add_export (def_file *fdef,
677                      const char *external_name,
678                      const char *internal_name,
679                      int ordinal,
680                      const char *its_name,
681                      int *is_dup)
682 {
683   def_file_export *e;
684   int pos;
685   int max_exports = ROUND_UP(fdef->num_exports, 32);
686
687   if (internal_name && !external_name)
688     external_name = internal_name;
689   if (external_name && !internal_name)
690     internal_name = external_name;
691
692   /* We need to avoid duplicates.  */
693   *is_dup = 0;
694   pos = find_export_in_list (fdef->exports, fdef->num_exports,
695                      external_name, internal_name,
696                      its_name, ordinal, is_dup);
697
698   if (*is_dup != 0)
699     return (fdef->exports + pos);
700
701   if (fdef->num_exports >= max_exports)
702     {
703       max_exports = ROUND_UP(fdef->num_exports + 1, 32);
704       if (fdef->exports)
705         fdef->exports = xrealloc (fdef->exports,
706                                  max_exports * sizeof (def_file_export));
707       else
708         fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
709     }
710
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;
719   fdef->num_exports++;
720   return e;
721 }
722
723 def_file_module *
724 def_get_module (def_file *fdef, const char *name)
725 {
726   def_file_module *s;
727
728   for (s = fdef->modules; s; s = s->next)
729     if (strcmp (s->name, name) == 0)
730       return s;
731
732   return NULL;
733 }
734
735 static def_file_module *
736 def_stash_module (def_file *fdef, const char *name)
737 {
738   def_file_module *s;
739
740   if ((s = def_get_module (fdef, name)) != NULL)
741       return s;
742   s = xmalloc (sizeof (def_file_module) + strlen (name));
743   s->next = fdef->modules;
744   fdef->modules = s;
745   s->user_data = 0;
746   strcpy (s->name, name);
747   return s;
748 }
749
750 static int
751 cmp_import_elem (const def_file_import *e, const char *ex_name,
752                  const char *in_name, const char *module,
753                  int ord)
754 {
755   int r;
756
757   if ((r = are_names_equal (module, (e->module ? e->module->name : NULL))))
758     return r;
759   if ((r = are_names_equal (ex_name, e->name)) != 0)
760     return r;
761   if ((r = are_names_equal (in_name, e->internal_name)) != 0)
762     return r;
763   if (ord != e->ordinal)
764     return (ord < e->ordinal ? -1 : 1);
765   return 0;
766 }
767
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
770    is returned.  */
771
772 static int
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)
776 {
777   int e, l, r, p;
778
779   *is_ident = 0;
780   if (!max)
781     return 0;
782   if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
783     {
784       if (!e)
785         *is_ident = 1;
786       return 0;
787     }
788   if (max == 1)
789     return 1;
790   if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
791     return max;
792   else if (!e || max == 2)
793     {
794       if (!e)
795         *is_ident = 1;
796       return max - 1;
797     }
798   l = 0; r = max - 1;
799   while (l < r)
800     {
801       p = (l + r) / 2;
802       e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
803       if (!e)
804         {
805           *is_ident = 1;
806           return p;
807         }
808       else if (e < 0)
809         r = p - 1;
810       else if (e > 0)
811         l = p + 1;
812     }
813   if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
814     ++l;
815   else if (!e)
816     *is_ident = 1;
817   return l;
818 }
819
820 def_file_import *
821 def_file_add_import (def_file *fdef,
822                      const char *name,
823                      const char *module,
824                      int ordinal,
825                      const char *internal_name,
826                      const char *its_name,
827                      int *is_dup)
828 {
829   def_file_import *i;
830   int pos;
831   int max_imports = ROUND_UP (fdef->num_imports, 16);
832
833   /* We need to avoid here duplicates.  */
834   *is_dup = 0;
835   pos = find_import_in_list (fdef->imports, fdef->num_imports,
836                              name,
837                              (!internal_name ? name : internal_name),
838                              module, ordinal, is_dup);
839   if (*is_dup != 0)
840     return fdef->imports + pos;
841
842   if (fdef->num_imports >= max_imports)
843     {
844       max_imports = ROUND_UP (fdef->num_imports+1, 16);
845
846       if (fdef->imports)
847         fdef->imports = xrealloc (fdef->imports,
848                                  max_imports * sizeof (def_file_import));
849       else
850         fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
851     }
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));
856   if (name)
857     i->name = xstrdup (name);
858   if (module)
859     i->module = def_stash_module (fdef, module);
860   i->ordinal = ordinal;
861   if (internal_name)
862     i->internal_name = xstrdup (internal_name);
863   else
864     i->internal_name = i->name;
865   i->its_name = (its_name ? xstrdup (its_name) : NULL);
866   fdef->num_imports++;
867
868   return i;
869 }
870
871 struct
872 {
873   char *param;
874   int token;
875 }
876 diropts[] =
877 {
878   { "-heap", HEAPSIZE },
879   { "-stack", STACKSIZE_K },
880   { "-attr", SECTIONS },
881   { "-export", EXPORTS },
882   { "-aligncomm", ALIGNCOMM },
883   { 0, 0 }
884 };
885
886 void
887 def_file_add_directive (def_file *my_def, const char *param, int len)
888 {
889   def_file *save_def = def;
890   const char *pend = param + len;
891   char * tend = (char *) param;
892   int i;
893
894   def = my_def;
895
896   while (param < pend)
897     {
898       while (param < pend
899              && (ISSPACE (*param) || *param == '\n' || *param == 0))
900         param++;
901
902       if (param == pend)
903         break;
904
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);
911            (tend < pend
912             && !(ISSPACE (tend[-1]) && *tend == '-')
913             && *tend != '\n' && *tend != 0);
914            tend++)
915         ;
916
917       for (i = 0; diropts[i].param; i++)
918         {
919           len = strlen (diropts[i].param);
920
921           if (tend - param >= len
922               && strncmp (param, diropts[i].param, len) == 0
923               && (param[len] == ':' || param[len] == ' '))
924             {
925               lex_parse_string_end = tend;
926               lex_parse_string = param + len + 1;
927               lex_forced_token = diropts[i].token;
928               saw_newline = 0;
929               if (def_parse ())
930                 continue;
931               break;
932             }
933         }
934
935       if (!diropts[i].param)
936         {
937           char saved;
938
939           saved = * tend;
940           * tend = 0;
941           /* xgettext:c-format */
942           einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
943           * tend = saved;
944         }
945
946       lex_parse_string = 0;
947       param = tend;
948     }
949
950   def = save_def;
951   def_pool_free ();
952 }
953
954 /* Parser Callbacks.  */
955
956 static void
957 def_image_name (const char *name, bfd_vma base, int is_dll)
958 {
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.  */
961   if (*name)
962     {
963       const char* image_name = lbasename (name);
964
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",
968                name);
969       if (def->name)
970         free (def->name);
971       /* Append the default suffix, if none specified.  */
972       if (strchr (image_name, '.') == 0)
973         {
974           const char * suffix = is_dll ? ".dll" : ".exe";
975
976           def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
977           sprintf (def->name, "%s%s", image_name, suffix);
978         }
979       else
980         def->name = xstrdup (image_name);
981     }
982
983   /* Honor a BASE address statement, even if LIBRARY string is empty.  */
984   def->base_address = base;
985   def->is_dll = is_dll;
986 }
987
988 static void
989 def_description (const char *text)
990 {
991   int len = def->description ? strlen (def->description) : 0;
992
993   len += strlen (text) + 1;
994   if (def->description)
995     {
996       def->description = xrealloc (def->description, len);
997       strcat (def->description, text);
998     }
999   else
1000     {
1001       def->description = xmalloc (len);
1002       strcpy (def->description, text);
1003     }
1004 }
1005
1006 static void
1007 def_stacksize (int reserve, int commit)
1008 {
1009   def->stack_reserve = reserve;
1010   def->stack_commit = commit;
1011 }
1012
1013 static void
1014 def_heapsize (int reserve, int commit)
1015 {
1016   def->heap_reserve = reserve;
1017   def->heap_commit = commit;
1018 }
1019
1020 static void
1021 def_section (const char *name, int attr)
1022 {
1023   def_file_section *s;
1024   int max_sections = ROUND_UP (def->num_section_defs, 4);
1025
1026   if (def->num_section_defs >= max_sections)
1027     {
1028       max_sections = ROUND_UP (def->num_section_defs+1, 4);
1029
1030       if (def->section_defs)
1031         def->section_defs = xrealloc (def->section_defs,
1032                                       max_sections * sizeof (def_file_import));
1033       else
1034         def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1035     }
1036   s = def->section_defs + def->num_section_defs;
1037   memset (s, 0, sizeof (def_file_section));
1038   s->name = xstrdup (name);
1039   if (attr & 1)
1040     s->flag_read = 1;
1041   if (attr & 2)
1042     s->flag_write = 1;
1043   if (attr & 4)
1044     s->flag_execute = 1;
1045   if (attr & 8)
1046     s->flag_shared = 1;
1047
1048   def->num_section_defs++;
1049 }
1050
1051 static void
1052 def_section_alt (const char *name, const char *attr)
1053 {
1054   int aval = 0;
1055
1056   for (; *attr; attr++)
1057     {
1058       switch (*attr)
1059         {
1060         case 'R':
1061         case 'r':
1062           aval |= 1;
1063           break;
1064         case 'W':
1065         case 'w':
1066           aval |= 2;
1067           break;
1068         case 'X':
1069         case 'x':
1070           aval |= 4;
1071           break;
1072         case 'S':
1073         case 's':
1074           aval |= 8;
1075           break;
1076         }
1077     }
1078   def_section (name, aval);
1079 }
1080
1081 static void
1082 def_exports (const char *external_name,
1083              const char *internal_name,
1084              int ordinal,
1085              int flags,
1086              const char *its_name)
1087 {
1088   def_file_export *dfe;
1089   int is_dup = 0;
1090
1091   if (!internal_name && external_name)
1092     internal_name = external_name;
1093 #if TRACE
1094   printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1095 #endif
1096
1097   dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1098                              its_name, &is_dup);
1099
1100   /* We might check here for flag redefinition and warn.  For now we
1101      ignore duplicates silently.  */
1102   if (is_dup)
1103     return;
1104
1105   if (flags & 1)
1106     dfe->flag_noname = 1;
1107   if (flags & 2)
1108     dfe->flag_constant = 1;
1109   if (flags & 4)
1110     dfe->flag_data = 1;
1111   if (flags & 8)
1112     dfe->flag_private = 1;
1113 }
1114
1115 static void
1116 def_import (const char *internal_name,
1117             const char *module,
1118             const char *dllext,
1119             const char *name,
1120             int ordinal,
1121             const char *its_name)
1122 {
1123   char *buf = 0;
1124   const char *ext = dllext ? dllext : "dll";
1125   int is_dup = 0;
1126
1127   buf = xmalloc (strlen (module) + strlen (ext) + 2);
1128   sprintf (buf, "%s.%s", module, ext);
1129   module = buf;
1130
1131   def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1132                        &is_dup);
1133   free (buf);
1134 }
1135
1136 static void
1137 def_version (int major, int minor)
1138 {
1139   def->version_major = major;
1140   def->version_minor = minor;
1141 }
1142
1143 static void
1144 def_directive (char *str)
1145 {
1146   struct directive *d = xmalloc (sizeof (struct directive));
1147
1148   d->next = directives;
1149   directives = d;
1150   d->name = xstrdup (str);
1151   d->len = strlen (str);
1152 }
1153
1154 static void
1155 def_aligncomm (char *str, int align)
1156 {
1157   def_file_aligncomm *c, *p;
1158
1159   p = NULL;
1160   c = def->aligncomms;
1161   while (c != NULL)
1162     {
1163       int e = strcmp (c->symbol_name, str);
1164       if (!e)
1165         {
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;
1169           if (!e)
1170             return;
1171         }
1172       if (e > 0)
1173         break;
1174       c = (p = c)->next;
1175     }
1176
1177   c = xmalloc (sizeof (def_file_aligncomm));
1178   c->symbol_name = xstrdup (str);
1179   c->alignment = (unsigned int) align;
1180   if (!p)
1181     {
1182       c->next = def->aligncomms;
1183       def->aligncomms = c;
1184     }
1185   else
1186     {
1187       c->next = p->next;
1188       p->next = c;
1189     }
1190 }
1191
1192 static int
1193 def_error (const char *err)
1194 {
1195   einfo ("%P: %s:%d: %s\n",
1196          def_filename ? def_filename : "<unknown-file>", linenumber, err);
1197   return 0;
1198 }
1199
1200
1201 /* Lexical Scanner.  */
1202
1203 #undef TRACE
1204 #define TRACE 0
1205
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;
1210
1211 static void
1212 put_buf (char c)
1213 {
1214   if (bufptr == buflen)
1215     {
1216       buflen += 50;             /* overly reasonable, eh?  */
1217       if (buffer)
1218         buffer = xrealloc (buffer, buflen + 1);
1219       else
1220         buffer = xmalloc (buflen + 1);
1221     }
1222   buffer[bufptr++] = c;
1223   buffer[bufptr] = 0;           /* not optimal, but very convenient.  */
1224 }
1225
1226 static struct
1227 {
1228   char *name;
1229   int token;
1230 }
1231 tokens[] =
1232 {
1233   { "BASE", BASE },
1234   { "CODE", CODE },
1235   { "CONSTANT", CONSTANTU },
1236   { "constant", CONSTANTL },
1237   { "DATA", DATAU },
1238   { "data", DATAL },
1239   { "DESCRIPTION", DESCRIPTION },
1240   { "DIRECTIVE", DIRECTIVE },
1241   { "EXECUTE", EXECUTE },
1242   { "EXPORTS", EXPORTS },
1243   { "HEAPSIZE", HEAPSIZE },
1244   { "IMPORTS", IMPORTS },
1245   { "LIBRARY", LIBRARY },
1246   { "NAME", NAME },
1247   { "NONAME", NONAMEU },
1248   { "noname", NONAMEL },
1249   { "PRIVATE", PRIVATEU },
1250   { "private", PRIVATEL },
1251   { "READ", READ },
1252   { "SECTIONS", SECTIONS },
1253   { "SEGMENTS", SECTIONS },
1254   { "SHARED", SHARED },
1255   { "STACKSIZE", STACKSIZE_K },
1256   { "VERSION", VERSIONK },
1257   { "WRITE", WRITE },
1258   { 0, 0 }
1259 };
1260
1261 static int
1262 def_getc (void)
1263 {
1264   int rv;
1265
1266   if (lex_parse_string)
1267     {
1268       if (lex_parse_string >= lex_parse_string_end)
1269         rv = EOF;
1270       else
1271         rv = *lex_parse_string++;
1272     }
1273   else
1274     {
1275       rv = fgetc (the_file);
1276     }
1277   if (rv == '\n')
1278     saw_newline = 1;
1279   return rv;
1280 }
1281
1282 static int
1283 def_ungetc (int c)
1284 {
1285   if (lex_parse_string)
1286     {
1287       lex_parse_string--;
1288       return c;
1289     }
1290   else
1291     return ungetc (c, the_file);
1292 }
1293
1294 static int
1295 def_lex (void)
1296 {
1297   int c, i, q;
1298
1299   if (lex_forced_token)
1300     {
1301       i = lex_forced_token;
1302       lex_forced_token = 0;
1303 #if TRACE
1304       printf ("lex: forcing token %d\n", i);
1305 #endif
1306       return i;
1307     }
1308
1309   c = def_getc ();
1310
1311   /* Trim leading whitespace.  */
1312   while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1313     c = def_getc ();
1314
1315   if (c == EOF)
1316     {
1317 #if TRACE
1318       printf ("lex: EOF\n");
1319 #endif
1320       return 0;
1321     }
1322
1323   if (saw_newline && c == ';')
1324     {
1325       do
1326         {
1327           c = def_getc ();
1328         }
1329       while (c != EOF && c != '\n');
1330       if (c == '\n')
1331         return def_lex ();
1332       return 0;
1333     }
1334
1335   /* Must be something else.  */
1336   saw_newline = 0;
1337
1338   if (ISDIGIT (c))
1339     {
1340       bufptr = 0;
1341       while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1342         {
1343           put_buf (c);
1344           c = def_getc ();
1345         }
1346       if (c != EOF)
1347         def_ungetc (c);
1348       yylval.digits = def_pool_strdup (buffer);
1349 #if TRACE
1350       printf ("lex: `%s' returns DIGITS\n", buffer);
1351 #endif
1352       return DIGITS;
1353     }
1354
1355   if (ISALPHA (c) || strchr ("$:-_?@", c))
1356     {
1357       bufptr = 0;
1358       q = c;
1359       put_buf (c);
1360       c = def_getc ();
1361
1362       if (q == '@')
1363         {
1364           if (ISBLANK (c) ) /* '@' followed by whitespace.  */
1365             return (q);
1366           else if (ISDIGIT (c)) /* '@' followed by digit.  */
1367             {
1368               def_ungetc (c);
1369               return (q);
1370             }
1371 #if TRACE
1372           printf ("lex: @ returns itself\n");
1373 #endif
1374         }
1375
1376       while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1377         {
1378           put_buf (c);
1379           c = def_getc ();
1380         }
1381       if (c != EOF)
1382         def_ungetc (c);
1383       if (ISALPHA (q)) /* Check for tokens.  */
1384         {
1385           for (i = 0; tokens[i].name; i++)
1386             if (strcmp (tokens[i].name, buffer) == 0)
1387               {
1388 #if TRACE
1389                 printf ("lex: `%s' is a string token\n", buffer);
1390 #endif
1391                 return tokens[i].token;
1392               }
1393         }
1394 #if TRACE
1395       printf ("lex: `%s' returns ID\n", buffer);
1396 #endif
1397       yylval.id = def_pool_strdup (buffer);
1398       return ID;
1399     }
1400
1401   if (c == '\'' || c == '"')
1402     {
1403       q = c;
1404       c = def_getc ();
1405       bufptr = 0;
1406
1407       while (c != EOF && c != q)
1408         {
1409           put_buf (c);
1410           c = def_getc ();
1411         }
1412       yylval.id = def_pool_strdup (buffer);
1413 #if TRACE
1414       printf ("lex: `%s' returns ID\n", buffer);
1415 #endif
1416       return ID;
1417     }
1418
1419   if ( c == '=')
1420     {
1421       c = def_getc ();
1422       if (c == '=')
1423         {
1424 #if TRACE
1425           printf ("lex: `==' returns EQUAL\n");
1426 #endif
1427                   return EQUAL;
1428         }
1429       def_ungetc (c);
1430 #if TRACE
1431       printf ("lex: `=' returns itself\n");
1432 #endif
1433       return '=';
1434     }
1435   if (c == '.' || c == ',')
1436     {
1437 #if TRACE
1438       printf ("lex: `%c' returns itself\n", c);
1439 #endif
1440       return c;
1441     }
1442
1443   if (c == '\n')
1444     {
1445       linenumber++;
1446       saw_newline = 1;
1447     }
1448
1449   /*printf ("lex: 0x%02x ignored\n", c); */
1450   return def_lex ();
1451 }
1452
1453 static char *
1454 def_pool_alloc (size_t sz)
1455 {
1456   def_pool_str *e;
1457
1458   e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1459   e->next = pool_strs;
1460   pool_strs = e;
1461   return e->data;
1462 }
1463
1464 static char *
1465 def_pool_strdup (const char *str)
1466 {
1467   char *s;
1468   size_t len;
1469   if (!str)
1470     return NULL;
1471   len = strlen (str) + 1;
1472   s = def_pool_alloc (len);
1473   memcpy (s, str, len);
1474   return s;
1475 }
1476
1477 static void
1478 def_pool_free (void)
1479 {
1480   def_pool_str *p;
1481   while ((p = pool_strs) != NULL)
1482     {
1483       pool_strs = p->next;
1484       free (p);
1485     }
1486 }