]> Git Repo - binutils.git/blob - ld/deffilep.y
[gdb/testsuite] Add XFAILs in gdb.rust/simple.exp for incorrect DWARF
[binutils.git] / ld / deffilep.y
1 %{ /* deffilep.y - parser for .def files */
2
3 /*   Copyright (C) 1995-2019 Free Software Foundation, Inc.
4
5      This file is part of GNU Binutils.
6
7      This program is free software; you can redistribute it and/or modify
8      it under the terms of the GNU General Public License as published by
9      the Free Software Foundation; either version 3 of the License, or
10      (at your option) any later version.
11
12      This program is distributed in the hope that it will be useful,
13      but WITHOUT ANY WARRANTY; without even the implied warranty of
14      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15      GNU General Public License for more details.
16
17      You should have received a copy of the GNU General Public License
18      along with this program; if not, write to the Free Software
19      Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20      MA 02110-1301, USA.  */
21
22 #include "sysdep.h"
23 #include "libiberty.h"
24 #include "safe-ctype.h"
25 #include "bfd.h"
26 #include "bfdlink.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 static void
821 fill_in_import (def_file_import *i,
822                 const char *name,
823                 def_file_module *module,
824                 int ordinal,
825                 const char *internal_name,
826                 const char *its_name)
827 {
828   memset (i, 0, sizeof (def_file_import));
829   if (name)
830     i->name = xstrdup (name);
831   i->module = module;
832   i->ordinal = ordinal;
833   if (internal_name)
834     i->internal_name = xstrdup (internal_name);
835   else
836     i->internal_name = i->name;
837   i->its_name = (its_name ? xstrdup (its_name) : NULL);
838 }
839
840 def_file_import *
841 def_file_add_import (def_file *fdef,
842                      const char *name,
843                      const char *module,
844                      int ordinal,
845                      const char *internal_name,
846                      const char *its_name,
847                      int *is_dup)
848 {
849   def_file_import *i;
850   int pos;
851   int max_imports = ROUND_UP (fdef->num_imports, 16);
852
853   /* We need to avoid here duplicates.  */
854   *is_dup = 0;
855   pos = find_import_in_list (fdef->imports, fdef->num_imports,
856                              name,
857                              (!internal_name ? name : internal_name),
858                              module, ordinal, is_dup);
859   if (*is_dup != 0)
860     return fdef->imports + pos;
861
862   if (fdef->num_imports >= max_imports)
863     {
864       max_imports = ROUND_UP (fdef->num_imports+1, 16);
865
866       if (fdef->imports)
867         fdef->imports = xrealloc (fdef->imports,
868                                  max_imports * sizeof (def_file_import));
869       else
870         fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
871     }
872   i = fdef->imports + pos;
873   if (pos != fdef->num_imports)
874     memmove (i + 1, i, sizeof (def_file_import) * (fdef->num_imports - pos));
875
876   fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
877                   internal_name, its_name);
878   fdef->num_imports++;
879
880   return i;
881 }
882
883 int
884 def_file_add_import_from (def_file *fdef,
885                           int num_imports,
886                           const char *name,
887                           const char *module,
888                           int ordinal,
889                           const char *internal_name,
890                           const char *its_name ATTRIBUTE_UNUSED)
891 {
892   def_file_import *i;
893   int is_dup;
894   int pos;
895   int max_imports = ROUND_UP (fdef->num_imports, 16);
896
897   /* We need to avoid here duplicates.  */
898   is_dup = 0;
899   pos = find_import_in_list (fdef->imports, fdef->num_imports,
900                              name, internal_name ? internal_name : name,
901                              module, ordinal, &is_dup);
902   if (is_dup != 0)
903     return -1;
904   if (fdef->imports && pos != fdef->num_imports)
905     {
906       i = fdef->imports + pos;
907       if (i->module && strcmp (i->module->name, module) == 0)
908         return -1;
909     }
910
911   if (fdef->num_imports + num_imports - 1 >= max_imports)
912     {
913       max_imports = ROUND_UP (fdef->num_imports + num_imports, 16);
914
915       if (fdef->imports)
916         fdef->imports = xrealloc (fdef->imports,
917                                  max_imports * sizeof (def_file_import));
918       else
919         fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
920     }
921   i = fdef->imports + pos;
922   if (pos != fdef->num_imports)
923     memmove (i + num_imports, i,
924              sizeof (def_file_import) * (fdef->num_imports - pos));
925
926   return pos;
927 }
928
929 def_file_import *
930 def_file_add_import_at (def_file *fdef,
931                         int pos,
932                         const char *name,
933                         const char *module,
934                         int ordinal,
935                         const char *internal_name,
936                         const char *its_name)
937 {
938   def_file_import *i = fdef->imports + pos;
939
940   fill_in_import (i, name, def_stash_module (fdef, module), ordinal,
941                   internal_name, its_name);
942   fdef->num_imports++;
943
944   return i;
945 }
946
947 struct
948 {
949   char *param;
950   int token;
951 }
952 diropts[] =
953 {
954   { "-heap", HEAPSIZE },
955   { "-stack", STACKSIZE_K },
956   { "-attr", SECTIONS },
957   { "-export", EXPORTS },
958   { "-aligncomm", ALIGNCOMM },
959   { 0, 0 }
960 };
961
962 void
963 def_file_add_directive (def_file *my_def, const char *param, int len)
964 {
965   def_file *save_def = def;
966   const char *pend = param + len;
967   char * tend = (char *) param;
968   int i;
969
970   def = my_def;
971
972   while (param < pend)
973     {
974       while (param < pend
975              && (ISSPACE (*param) || *param == '\n' || *param == 0))
976         param++;
977
978       if (param == pend)
979         break;
980
981       /* Scan forward until we encounter any of:
982           - the end of the buffer
983           - the start of a new option
984           - a newline separating options
985           - a NUL separating options.  */
986       for (tend = (char *) (param + 1);
987            (tend < pend
988             && !(ISSPACE (tend[-1]) && *tend == '-')
989             && *tend != '\n' && *tend != 0);
990            tend++)
991         ;
992
993       for (i = 0; diropts[i].param; i++)
994         {
995           len = strlen (diropts[i].param);
996
997           if (tend - param >= len
998               && strncmp (param, diropts[i].param, len) == 0
999               && (param[len] == ':' || param[len] == ' '))
1000             {
1001               lex_parse_string_end = tend;
1002               lex_parse_string = param + len + 1;
1003               lex_forced_token = diropts[i].token;
1004               saw_newline = 0;
1005               if (def_parse ())
1006                 continue;
1007               break;
1008             }
1009         }
1010
1011       if (!diropts[i].param)
1012         {
1013           if (tend < pend)
1014             {
1015               char saved;
1016
1017               saved = * tend;
1018               * tend = 0;
1019               /* xgettext:c-format */
1020               einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
1021               * tend = saved;
1022             }
1023           else
1024             {
1025               einfo (_("Warning: corrupt .drectve at end of def file\n"));
1026             }
1027         }
1028
1029       lex_parse_string = 0;
1030       param = tend;
1031     }
1032
1033   def = save_def;
1034   def_pool_free ();
1035 }
1036
1037 /* Parser Callbacks.  */
1038
1039 static void
1040 def_image_name (const char *name, bfd_vma base, int is_dll)
1041 {
1042   /* If a LIBRARY or NAME statement is specified without a name, there is nothing
1043      to do here.  We retain the output filename specified on command line.  */
1044   if (*name)
1045     {
1046       const char* image_name = lbasename (name);
1047
1048       if (image_name != name)
1049         einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
1050                def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
1051                name);
1052       if (def->name)
1053         free (def->name);
1054       /* Append the default suffix, if none specified.  */
1055       if (strchr (image_name, '.') == 0)
1056         {
1057           const char * suffix = is_dll ? ".dll" : ".exe";
1058
1059           def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
1060           sprintf (def->name, "%s%s", image_name, suffix);
1061         }
1062       else
1063         def->name = xstrdup (image_name);
1064     }
1065
1066   /* Honor a BASE address statement, even if LIBRARY string is empty.  */
1067   def->base_address = base;
1068   def->is_dll = is_dll;
1069 }
1070
1071 static void
1072 def_description (const char *text)
1073 {
1074   int len = def->description ? strlen (def->description) : 0;
1075
1076   len += strlen (text) + 1;
1077   if (def->description)
1078     {
1079       def->description = xrealloc (def->description, len);
1080       strcat (def->description, text);
1081     }
1082   else
1083     {
1084       def->description = xmalloc (len);
1085       strcpy (def->description, text);
1086     }
1087 }
1088
1089 static void
1090 def_stacksize (int reserve, int commit)
1091 {
1092   def->stack_reserve = reserve;
1093   def->stack_commit = commit;
1094 }
1095
1096 static void
1097 def_heapsize (int reserve, int commit)
1098 {
1099   def->heap_reserve = reserve;
1100   def->heap_commit = commit;
1101 }
1102
1103 static void
1104 def_section (const char *name, int attr)
1105 {
1106   def_file_section *s;
1107   int max_sections = ROUND_UP (def->num_section_defs, 4);
1108
1109   if (def->num_section_defs >= max_sections)
1110     {
1111       max_sections = ROUND_UP (def->num_section_defs+1, 4);
1112
1113       if (def->section_defs)
1114         def->section_defs = xrealloc (def->section_defs,
1115                                       max_sections * sizeof (def_file_import));
1116       else
1117         def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
1118     }
1119   s = def->section_defs + def->num_section_defs;
1120   memset (s, 0, sizeof (def_file_section));
1121   s->name = xstrdup (name);
1122   if (attr & 1)
1123     s->flag_read = 1;
1124   if (attr & 2)
1125     s->flag_write = 1;
1126   if (attr & 4)
1127     s->flag_execute = 1;
1128   if (attr & 8)
1129     s->flag_shared = 1;
1130
1131   def->num_section_defs++;
1132 }
1133
1134 static void
1135 def_section_alt (const char *name, const char *attr)
1136 {
1137   int aval = 0;
1138
1139   for (; *attr; attr++)
1140     {
1141       switch (*attr)
1142         {
1143         case 'R':
1144         case 'r':
1145           aval |= 1;
1146           break;
1147         case 'W':
1148         case 'w':
1149           aval |= 2;
1150           break;
1151         case 'X':
1152         case 'x':
1153           aval |= 4;
1154           break;
1155         case 'S':
1156         case 's':
1157           aval |= 8;
1158           break;
1159         }
1160     }
1161   def_section (name, aval);
1162 }
1163
1164 static void
1165 def_exports (const char *external_name,
1166              const char *internal_name,
1167              int ordinal,
1168              int flags,
1169              const char *its_name)
1170 {
1171   def_file_export *dfe;
1172   int is_dup = 0;
1173
1174   if (!internal_name && external_name)
1175     internal_name = external_name;
1176 #if TRACE
1177   printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1178 #endif
1179
1180   dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1181                              its_name, &is_dup);
1182
1183   /* We might check here for flag redefinition and warn.  For now we
1184      ignore duplicates silently.  */
1185   if (is_dup)
1186     return;
1187
1188   if (flags & 1)
1189     dfe->flag_noname = 1;
1190   if (flags & 2)
1191     dfe->flag_constant = 1;
1192   if (flags & 4)
1193     dfe->flag_data = 1;
1194   if (flags & 8)
1195     dfe->flag_private = 1;
1196 }
1197
1198 static void
1199 def_import (const char *internal_name,
1200             const char *module,
1201             const char *dllext,
1202             const char *name,
1203             int ordinal,
1204             const char *its_name)
1205 {
1206   char *buf = 0;
1207   const char *ext = dllext ? dllext : "dll";
1208   int is_dup = 0;
1209
1210   buf = xmalloc (strlen (module) + strlen (ext) + 2);
1211   sprintf (buf, "%s.%s", module, ext);
1212   module = buf;
1213
1214   def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1215                        &is_dup);
1216   free (buf);
1217 }
1218
1219 static void
1220 def_version (int major, int minor)
1221 {
1222   def->version_major = major;
1223   def->version_minor = minor;
1224 }
1225
1226 static void
1227 def_directive (char *str)
1228 {
1229   struct directive *d = xmalloc (sizeof (struct directive));
1230
1231   d->next = directives;
1232   directives = d;
1233   d->name = xstrdup (str);
1234   d->len = strlen (str);
1235 }
1236
1237 static void
1238 def_aligncomm (char *str, int align)
1239 {
1240   def_file_aligncomm *c, *p;
1241
1242   p = NULL;
1243   c = def->aligncomms;
1244   while (c != NULL)
1245     {
1246       int e = strcmp (c->symbol_name, str);
1247       if (!e)
1248         {
1249           /* Not sure if we want to allow here duplicates with
1250              different alignments, but for now we keep them.  */
1251           e = (int) c->alignment - align;
1252           if (!e)
1253             return;
1254         }
1255       if (e > 0)
1256         break;
1257       c = (p = c)->next;
1258     }
1259
1260   c = xmalloc (sizeof (def_file_aligncomm));
1261   c->symbol_name = xstrdup (str);
1262   c->alignment = (unsigned int) align;
1263   if (!p)
1264     {
1265       c->next = def->aligncomms;
1266       def->aligncomms = c;
1267     }
1268   else
1269     {
1270       c->next = p->next;
1271       p->next = c;
1272     }
1273 }
1274
1275 static int
1276 def_error (const char *err)
1277 {
1278   einfo ("%P: %s:%d: %s\n",
1279          def_filename ? def_filename : "<unknown-file>", linenumber, err);
1280   return 0;
1281 }
1282
1283
1284 /* Lexical Scanner.  */
1285
1286 #undef TRACE
1287 #define TRACE 0
1288
1289 /* Never freed, but always reused as needed, so no real leak.  */
1290 static char *buffer = 0;
1291 static int buflen = 0;
1292 static int bufptr = 0;
1293
1294 static void
1295 put_buf (char c)
1296 {
1297   if (bufptr == buflen)
1298     {
1299       buflen += 50;             /* overly reasonable, eh?  */
1300       if (buffer)
1301         buffer = xrealloc (buffer, buflen + 1);
1302       else
1303         buffer = xmalloc (buflen + 1);
1304     }
1305   buffer[bufptr++] = c;
1306   buffer[bufptr] = 0;           /* not optimal, but very convenient.  */
1307 }
1308
1309 static struct
1310 {
1311   char *name;
1312   int token;
1313 }
1314 tokens[] =
1315 {
1316   { "BASE", BASE },
1317   { "CODE", CODE },
1318   { "CONSTANT", CONSTANTU },
1319   { "constant", CONSTANTL },
1320   { "DATA", DATAU },
1321   { "data", DATAL },
1322   { "DESCRIPTION", DESCRIPTION },
1323   { "DIRECTIVE", DIRECTIVE },
1324   { "EXECUTE", EXECUTE },
1325   { "EXPORTS", EXPORTS },
1326   { "HEAPSIZE", HEAPSIZE },
1327   { "IMPORTS", IMPORTS },
1328   { "LIBRARY", LIBRARY },
1329   { "NAME", NAME },
1330   { "NONAME", NONAMEU },
1331   { "noname", NONAMEL },
1332   { "PRIVATE", PRIVATEU },
1333   { "private", PRIVATEL },
1334   { "READ", READ },
1335   { "SECTIONS", SECTIONS },
1336   { "SEGMENTS", SECTIONS },
1337   { "SHARED", SHARED },
1338   { "STACKSIZE", STACKSIZE_K },
1339   { "VERSION", VERSIONK },
1340   { "WRITE", WRITE },
1341   { 0, 0 }
1342 };
1343
1344 static int
1345 def_getc (void)
1346 {
1347   int rv;
1348
1349   if (lex_parse_string)
1350     {
1351       if (lex_parse_string >= lex_parse_string_end)
1352         rv = EOF;
1353       else
1354         rv = *lex_parse_string++;
1355     }
1356   else
1357     {
1358       rv = fgetc (the_file);
1359     }
1360   if (rv == '\n')
1361     saw_newline = 1;
1362   return rv;
1363 }
1364
1365 static int
1366 def_ungetc (int c)
1367 {
1368   if (lex_parse_string)
1369     {
1370       lex_parse_string--;
1371       return c;
1372     }
1373   else
1374     return ungetc (c, the_file);
1375 }
1376
1377 static int
1378 def_lex (void)
1379 {
1380   int c, i, q;
1381
1382   if (lex_forced_token)
1383     {
1384       i = lex_forced_token;
1385       lex_forced_token = 0;
1386 #if TRACE
1387       printf ("lex: forcing token %d\n", i);
1388 #endif
1389       return i;
1390     }
1391
1392   c = def_getc ();
1393
1394   /* Trim leading whitespace.  */
1395   while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1396     c = def_getc ();
1397
1398   if (c == EOF)
1399     {
1400 #if TRACE
1401       printf ("lex: EOF\n");
1402 #endif
1403       return 0;
1404     }
1405
1406   if (saw_newline && c == ';')
1407     {
1408       do
1409         {
1410           c = def_getc ();
1411         }
1412       while (c != EOF && c != '\n');
1413       if (c == '\n')
1414         return def_lex ();
1415       return 0;
1416     }
1417
1418   /* Must be something else.  */
1419   saw_newline = 0;
1420
1421   if (ISDIGIT (c))
1422     {
1423       bufptr = 0;
1424       while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1425         {
1426           put_buf (c);
1427           c = def_getc ();
1428         }
1429       if (c != EOF)
1430         def_ungetc (c);
1431       yylval.digits = def_pool_strdup (buffer);
1432 #if TRACE
1433       printf ("lex: `%s' returns DIGITS\n", buffer);
1434 #endif
1435       return DIGITS;
1436     }
1437
1438   if (ISALPHA (c) || strchr ("$:-_?@", c))
1439     {
1440       bufptr = 0;
1441       q = c;
1442       put_buf (c);
1443       c = def_getc ();
1444
1445       if (q == '@')
1446         {
1447           if (ISBLANK (c) ) /* '@' followed by whitespace.  */
1448             return (q);
1449           else if (ISDIGIT (c)) /* '@' followed by digit.  */
1450             {
1451               def_ungetc (c);
1452               return (q);
1453             }
1454 #if TRACE
1455           printf ("lex: @ returns itself\n");
1456 #endif
1457         }
1458
1459       while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1460         {
1461           put_buf (c);
1462           c = def_getc ();
1463         }
1464       if (c != EOF)
1465         def_ungetc (c);
1466       if (ISALPHA (q)) /* Check for tokens.  */
1467         {
1468           for (i = 0; tokens[i].name; i++)
1469             if (strcmp (tokens[i].name, buffer) == 0)
1470               {
1471 #if TRACE
1472                 printf ("lex: `%s' is a string token\n", buffer);
1473 #endif
1474                 return tokens[i].token;
1475               }
1476         }
1477 #if TRACE
1478       printf ("lex: `%s' returns ID\n", buffer);
1479 #endif
1480       yylval.id = def_pool_strdup (buffer);
1481       return ID;
1482     }
1483
1484   if (c == '\'' || c == '"')
1485     {
1486       q = c;
1487       c = def_getc ();
1488       bufptr = 0;
1489
1490       while (c != EOF && c != q)
1491         {
1492           put_buf (c);
1493           c = def_getc ();
1494         }
1495       yylval.id = def_pool_strdup (buffer);
1496 #if TRACE
1497       printf ("lex: `%s' returns ID\n", buffer);
1498 #endif
1499       return ID;
1500     }
1501
1502   if ( c == '=')
1503     {
1504       c = def_getc ();
1505       if (c == '=')
1506         {
1507 #if TRACE
1508           printf ("lex: `==' returns EQUAL\n");
1509 #endif
1510           return EQUAL;
1511         }
1512       def_ungetc (c);
1513 #if TRACE
1514       printf ("lex: `=' returns itself\n");
1515 #endif
1516       return '=';
1517     }
1518   if (c == '.' || c == ',')
1519     {
1520 #if TRACE
1521       printf ("lex: `%c' returns itself\n", c);
1522 #endif
1523       return c;
1524     }
1525
1526   if (c == '\n')
1527     {
1528       linenumber++;
1529       saw_newline = 1;
1530     }
1531
1532   /*printf ("lex: 0x%02x ignored\n", c); */
1533   return def_lex ();
1534 }
1535
1536 static char *
1537 def_pool_alloc (size_t sz)
1538 {
1539   def_pool_str *e;
1540
1541   e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1542   e->next = pool_strs;
1543   pool_strs = e;
1544   return e->data;
1545 }
1546
1547 static char *
1548 def_pool_strdup (const char *str)
1549 {
1550   char *s;
1551   size_t len;
1552   if (!str)
1553     return NULL;
1554   len = strlen (str) + 1;
1555   s = def_pool_alloc (len);
1556   memcpy (s, str, len);
1557   return s;
1558 }
1559
1560 static void
1561 def_pool_free (void)
1562 {
1563   def_pool_str *p;
1564   while ((p = pool_strs) != NULL)
1565     {
1566       pool_strs = p->next;
1567       free (p);
1568     }
1569 }
This page took 0.117812 seconds and 4 git commands to generate.