Rename index to indx
[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           if (tend < pend)
938             {
939               char saved;
940
941               saved = * tend;
942               * tend = 0;
943               /* xgettext:c-format */
944               einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
945               * tend = saved;
946             }
947           else
948             {
949               einfo (_("Warning: corrupt .drectve at end of def file\n"));
950             }
951         }
952
953       lex_parse_string = 0;
954       param = tend;
955     }
956
957   def = save_def;
958   def_pool_free ();
959 }
960
961 /* Parser Callbacks.  */
962
963 static void
964 def_image_name (const char *name, bfd_vma base, int is_dll)
965 {
966   /* If a LIBRARY or NAME statement is specified without a name, there is nothing
967      to do here.  We retain the output filename specified on command line.  */
968   if (*name)
969     {
970       const char* image_name = lbasename (name);
971
972       if (image_name != name)
973         einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
974                def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
975                name);
976       if (def->name)
977         free (def->name);
978       /* Append the default suffix, if none specified.  */
979       if (strchr (image_name, '.') == 0)
980         {
981           const char * suffix = is_dll ? ".dll" : ".exe";
982
983           def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
984           sprintf (def->name, "%s%s", image_name, suffix);
985         }
986       else
987         def->name = xstrdup (image_name);
988     }
989
990   /* Honor a BASE address statement, even if LIBRARY string is empty.  */
991   def->base_address = base;
992   def->is_dll = is_dll;
993 }
994
995 static void
996 def_description (const char *text)
997 {
998   int len = def->description ? strlen (def->description) : 0;
999
1000   len += strlen (text) + 1;
1001   if (def->description)
1002     {
1003       def->description = xrealloc (def->description, len);
1004       strcat (def->description, text);
1005     }
1006   else
1007     {
1008       def->description = xmalloc (len);
1009       strcpy (def->description, text);
1010     }
1011 }
1012
1013 static void
1014 def_stacksize (int reserve, int commit)
1015 {
1016   def->stack_reserve = reserve;
1017   def->stack_commit = commit;
1018 }
1019
1020 static void
1021 def_heapsize (int reserve, int commit)
1022 {
1023   def->heap_reserve = reserve;
1024   def->heap_commit = commit;
1025 }
1026
1027 static void
1028 def_section (const char *name, int attr)
1029 {
1030   def_file_section *s;
1031   int max_sections = ROUND_UP (def->num_section_defs, 4);
1032
1033   if (def->num_section_defs >= max_sections)
1034     {
1035       max_sections = ROUND_UP (def->num_section_defs+1, 4);
1036
1037       if (def->section_defs)
1038         def->section_defs = xrealloc (def->section_defs,
1039                                       max_sections * sizeof (def_file_import));
1040       else
1041         def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1042     }
1043   s = def->section_defs + def->num_section_defs;
1044   memset (s, 0, sizeof (def_file_section));
1045   s->name = xstrdup (name);
1046   if (attr & 1)
1047     s->flag_read = 1;
1048   if (attr & 2)
1049     s->flag_write = 1;
1050   if (attr & 4)
1051     s->flag_execute = 1;
1052   if (attr & 8)
1053     s->flag_shared = 1;
1054
1055   def->num_section_defs++;
1056 }
1057
1058 static void
1059 def_section_alt (const char *name, const char *attr)
1060 {
1061   int aval = 0;
1062
1063   for (; *attr; attr++)
1064     {
1065       switch (*attr)
1066         {
1067         case 'R':
1068         case 'r':
1069           aval |= 1;
1070           break;
1071         case 'W':
1072         case 'w':
1073           aval |= 2;
1074           break;
1075         case 'X':
1076         case 'x':
1077           aval |= 4;
1078           break;
1079         case 'S':
1080         case 's':
1081           aval |= 8;
1082           break;
1083         }
1084     }
1085   def_section (name, aval);
1086 }
1087
1088 static void
1089 def_exports (const char *external_name,
1090              const char *internal_name,
1091              int ordinal,
1092              int flags,
1093              const char *its_name)
1094 {
1095   def_file_export *dfe;
1096   int is_dup = 0;
1097
1098   if (!internal_name && external_name)
1099     internal_name = external_name;
1100 #if TRACE
1101   printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1102 #endif
1103
1104   dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1105                              its_name, &is_dup);
1106
1107   /* We might check here for flag redefinition and warn.  For now we
1108      ignore duplicates silently.  */
1109   if (is_dup)
1110     return;
1111
1112   if (flags & 1)
1113     dfe->flag_noname = 1;
1114   if (flags & 2)
1115     dfe->flag_constant = 1;
1116   if (flags & 4)
1117     dfe->flag_data = 1;
1118   if (flags & 8)
1119     dfe->flag_private = 1;
1120 }
1121
1122 static void
1123 def_import (const char *internal_name,
1124             const char *module,
1125             const char *dllext,
1126             const char *name,
1127             int ordinal,
1128             const char *its_name)
1129 {
1130   char *buf = 0;
1131   const char *ext = dllext ? dllext : "dll";
1132   int is_dup = 0;
1133
1134   buf = xmalloc (strlen (module) + strlen (ext) + 2);
1135   sprintf (buf, "%s.%s", module, ext);
1136   module = buf;
1137
1138   def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1139                        &is_dup);
1140   free (buf);
1141 }
1142
1143 static void
1144 def_version (int major, int minor)
1145 {
1146   def->version_major = major;
1147   def->version_minor = minor;
1148 }
1149
1150 static void
1151 def_directive (char *str)
1152 {
1153   struct directive *d = xmalloc (sizeof (struct directive));
1154
1155   d->next = directives;
1156   directives = d;
1157   d->name = xstrdup (str);
1158   d->len = strlen (str);
1159 }
1160
1161 static void
1162 def_aligncomm (char *str, int align)
1163 {
1164   def_file_aligncomm *c, *p;
1165
1166   p = NULL;
1167   c = def->aligncomms;
1168   while (c != NULL)
1169     {
1170       int e = strcmp (c->symbol_name, str);
1171       if (!e)
1172         {
1173           /* Not sure if we want to allow here duplicates with
1174              different alignments, but for now we keep them.  */
1175           e = (int) c->alignment - align;
1176           if (!e)
1177             return;
1178         }
1179       if (e > 0)
1180         break;
1181       c = (p = c)->next;
1182     }
1183
1184   c = xmalloc (sizeof (def_file_aligncomm));
1185   c->symbol_name = xstrdup (str);
1186   c->alignment = (unsigned int) align;
1187   if (!p)
1188     {
1189       c->next = def->aligncomms;
1190       def->aligncomms = c;
1191     }
1192   else
1193     {
1194       c->next = p->next;
1195       p->next = c;
1196     }
1197 }
1198
1199 static int
1200 def_error (const char *err)
1201 {
1202   einfo ("%P: %s:%d: %s\n",
1203          def_filename ? def_filename : "<unknown-file>", linenumber, err);
1204   return 0;
1205 }
1206
1207
1208 /* Lexical Scanner.  */
1209
1210 #undef TRACE
1211 #define TRACE 0
1212
1213 /* Never freed, but always reused as needed, so no real leak.  */
1214 static char *buffer = 0;
1215 static int buflen = 0;
1216 static int bufptr = 0;
1217
1218 static void
1219 put_buf (char c)
1220 {
1221   if (bufptr == buflen)
1222     {
1223       buflen += 50;             /* overly reasonable, eh?  */
1224       if (buffer)
1225         buffer = xrealloc (buffer, buflen + 1);
1226       else
1227         buffer = xmalloc (buflen + 1);
1228     }
1229   buffer[bufptr++] = c;
1230   buffer[bufptr] = 0;           /* not optimal, but very convenient.  */
1231 }
1232
1233 static struct
1234 {
1235   char *name;
1236   int token;
1237 }
1238 tokens[] =
1239 {
1240   { "BASE", BASE },
1241   { "CODE", CODE },
1242   { "CONSTANT", CONSTANTU },
1243   { "constant", CONSTANTL },
1244   { "DATA", DATAU },
1245   { "data", DATAL },
1246   { "DESCRIPTION", DESCRIPTION },
1247   { "DIRECTIVE", DIRECTIVE },
1248   { "EXECUTE", EXECUTE },
1249   { "EXPORTS", EXPORTS },
1250   { "HEAPSIZE", HEAPSIZE },
1251   { "IMPORTS", IMPORTS },
1252   { "LIBRARY", LIBRARY },
1253   { "NAME", NAME },
1254   { "NONAME", NONAMEU },
1255   { "noname", NONAMEL },
1256   { "PRIVATE", PRIVATEU },
1257   { "private", PRIVATEL },
1258   { "READ", READ },
1259   { "SECTIONS", SECTIONS },
1260   { "SEGMENTS", SECTIONS },
1261   { "SHARED", SHARED },
1262   { "STACKSIZE", STACKSIZE_K },
1263   { "VERSION", VERSIONK },
1264   { "WRITE", WRITE },
1265   { 0, 0 }
1266 };
1267
1268 static int
1269 def_getc (void)
1270 {
1271   int rv;
1272
1273   if (lex_parse_string)
1274     {
1275       if (lex_parse_string >= lex_parse_string_end)
1276         rv = EOF;
1277       else
1278         rv = *lex_parse_string++;
1279     }
1280   else
1281     {
1282       rv = fgetc (the_file);
1283     }
1284   if (rv == '\n')
1285     saw_newline = 1;
1286   return rv;
1287 }
1288
1289 static int
1290 def_ungetc (int c)
1291 {
1292   if (lex_parse_string)
1293     {
1294       lex_parse_string--;
1295       return c;
1296     }
1297   else
1298     return ungetc (c, the_file);
1299 }
1300
1301 static int
1302 def_lex (void)
1303 {
1304   int c, i, q;
1305
1306   if (lex_forced_token)
1307     {
1308       i = lex_forced_token;
1309       lex_forced_token = 0;
1310 #if TRACE
1311       printf ("lex: forcing token %d\n", i);
1312 #endif
1313       return i;
1314     }
1315
1316   c = def_getc ();
1317
1318   /* Trim leading whitespace.  */
1319   while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1320     c = def_getc ();
1321
1322   if (c == EOF)
1323     {
1324 #if TRACE
1325       printf ("lex: EOF\n");
1326 #endif
1327       return 0;
1328     }
1329
1330   if (saw_newline && c == ';')
1331     {
1332       do
1333         {
1334           c = def_getc ();
1335         }
1336       while (c != EOF && c != '\n');
1337       if (c == '\n')
1338         return def_lex ();
1339       return 0;
1340     }
1341
1342   /* Must be something else.  */
1343   saw_newline = 0;
1344
1345   if (ISDIGIT (c))
1346     {
1347       bufptr = 0;
1348       while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1349         {
1350           put_buf (c);
1351           c = def_getc ();
1352         }
1353       if (c != EOF)
1354         def_ungetc (c);
1355       yylval.digits = def_pool_strdup (buffer);
1356 #if TRACE
1357       printf ("lex: `%s' returns DIGITS\n", buffer);
1358 #endif
1359       return DIGITS;
1360     }
1361
1362   if (ISALPHA (c) || strchr ("$:-_?@", c))
1363     {
1364       bufptr = 0;
1365       q = c;
1366       put_buf (c);
1367       c = def_getc ();
1368
1369       if (q == '@')
1370         {
1371           if (ISBLANK (c) ) /* '@' followed by whitespace.  */
1372             return (q);
1373           else if (ISDIGIT (c)) /* '@' followed by digit.  */
1374             {
1375               def_ungetc (c);
1376               return (q);
1377             }
1378 #if TRACE
1379           printf ("lex: @ returns itself\n");
1380 #endif
1381         }
1382
1383       while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1384         {
1385           put_buf (c);
1386           c = def_getc ();
1387         }
1388       if (c != EOF)
1389         def_ungetc (c);
1390       if (ISALPHA (q)) /* Check for tokens.  */
1391         {
1392           for (i = 0; tokens[i].name; i++)
1393             if (strcmp (tokens[i].name, buffer) == 0)
1394               {
1395 #if TRACE
1396                 printf ("lex: `%s' is a string token\n", buffer);
1397 #endif
1398                 return tokens[i].token;
1399               }
1400         }
1401 #if TRACE
1402       printf ("lex: `%s' returns ID\n", buffer);
1403 #endif
1404       yylval.id = def_pool_strdup (buffer);
1405       return ID;
1406     }
1407
1408   if (c == '\'' || c == '"')
1409     {
1410       q = c;
1411       c = def_getc ();
1412       bufptr = 0;
1413
1414       while (c != EOF && c != q)
1415         {
1416           put_buf (c);
1417           c = def_getc ();
1418         }
1419       yylval.id = def_pool_strdup (buffer);
1420 #if TRACE
1421       printf ("lex: `%s' returns ID\n", buffer);
1422 #endif
1423       return ID;
1424     }
1425
1426   if ( c == '=')
1427     {
1428       c = def_getc ();
1429       if (c == '=')
1430         {
1431 #if TRACE
1432           printf ("lex: `==' returns EQUAL\n");
1433 #endif
1434                   return EQUAL;
1435         }
1436       def_ungetc (c);
1437 #if TRACE
1438       printf ("lex: `=' returns itself\n");
1439 #endif
1440       return '=';
1441     }
1442   if (c == '.' || c == ',')
1443     {
1444 #if TRACE
1445       printf ("lex: `%c' returns itself\n", c);
1446 #endif
1447       return c;
1448     }
1449
1450   if (c == '\n')
1451     {
1452       linenumber++;
1453       saw_newline = 1;
1454     }
1455
1456   /*printf ("lex: 0x%02x ignored\n", c); */
1457   return def_lex ();
1458 }
1459
1460 static char *
1461 def_pool_alloc (size_t sz)
1462 {
1463   def_pool_str *e;
1464
1465   e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1466   e->next = pool_strs;
1467   pool_strs = e;
1468   return e->data;
1469 }
1470
1471 static char *
1472 def_pool_strdup (const char *str)
1473 {
1474   char *s;
1475   size_t len;
1476   if (!str)
1477     return NULL;
1478   len = strlen (str) + 1;
1479   s = def_pool_alloc (len);
1480   memcpy (s, str, len);
1481   return s;
1482 }
1483
1484 static void
1485 def_pool_free (void)
1486 {
1487   def_pool_str *p;
1488   while ((p = pool_strs) != NULL)
1489     {
1490       pool_strs = p->next;
1491       free (p);
1492     }
1493 }