OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [ld/] [deffilep.y] - Blame information for rev 146

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 khays
%{ /* 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 *, int, int);
98
static void def_section (const char *, int);
99
static void def_section_alt (const char *, const char *);
100
static void def_stacksize (int, int);
101
static void def_version (int, int);
102
static void def_directive (char *);
103
static void def_aligncomm (char *str, int align);
104
static int def_parse (void);
105
static int def_error (const char *);
106
static int def_lex (void);
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
  int number;
117
  char *digits;
118
};
119
 
120
%token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
121
%token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
122
%token PRIVATEU PRIVATEL ALIGNCOMM
123
%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE EQUAL
124
%token  ID
125
%token  DIGITS
126
%type   NUMBER
127
%type   opt_digits
128
%type   opt_base opt_ordinal
129
%type   attr attr_list opt_number exp_opt_list exp_opt
130
%type   opt_name opt_equal_name dot_name anylang_id opt_id
131
%type   opt_equalequal_name
132
 
133
%%
134
 
135
start: start command
136
        | command
137
        ;
138
 
139
command:
140
                NAME opt_name opt_base { def_image_name ($2, $3, 0); }
141
        |       LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
142
        |       DESCRIPTION ID { def_description ($2);}
143
        |       STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
144
        |       HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
145
        |       CODE attr_list { def_section ("CODE", $2);}
146
        |       DATAU attr_list  { def_section ("DATA", $2);}
147
        |       SECTIONS seclist
148
        |       EXPORTS explist
149
        |       IMPORTS implist
150
        |       VERSIONK NUMBER { def_version ($2, 0);}
151
        |       VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
152
        |       DIRECTIVE ID { def_directive ($2);}
153
        |       ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
154
        ;
155
 
156
 
157
explist:
158
                /* EMPTY */
159
        |       expline
160
        |       explist expline
161
        ;
162
 
163
expline:
164
                /* The opt_comma is necessary to support both the usual
165
                  DEF file syntax as well as .drectve syntax which
166
                  mandates ,.  */
167
                dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list opt_comma opt_equalequal_name
168
                        { def_exports ($1, $2, $3, $5, $7); }
169
        ;
170
exp_opt_list:
171
                /* The opt_comma is necessary to support both the usual
172
                   DEF file syntax as well as .drectve syntax which
173
                   allows for comma separated opt list.  */
174
                exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
175
        |       { $$ = 0; }
176
        ;
177
exp_opt:
178
                NONAMEU         { $$ = 1; }
179
        |       NONAMEL         { $$ = 1; }
180
        |       CONSTANTU       { $$ = 2; }
181
        |       CONSTANTL       { $$ = 2; }
182
        |       DATAU           { $$ = 4; }
183
        |       DATAL           { $$ = 4; }
184
        |       PRIVATEU        { $$ = 8; }
185
        |       PRIVATEL        { $$ = 8; }
186
        ;
187
implist:
188
                implist impline
189
        |       impline
190
        ;
191
 
192
impline:
193
               ID '=' ID '.' ID '.' ID opt_equalequal_name
194
                 { def_import ($1, $3, $5, $7, -1, $8); }
195
       |       ID '=' ID '.' ID '.' NUMBER opt_equalequal_name
196
                                 { def_import ($1, $3, $5,  0, $7, $8); }
197
       |       ID '=' ID '.' ID opt_equalequal_name
198
                 { def_import ($1, $3,  0, $5, -1, $6); }
199
       |       ID '=' ID '.' NUMBER opt_equalequal_name
200
                 { def_import ($1, $3,  0,  0, $5, $6); }
201
       |       ID '.' ID '.' ID opt_equalequal_name
202
                 { def_import( 0, $1, $3, $5, -1, $6); }
203
       |       ID '.' ID opt_equalequal_name
204
                 { def_import ( 0, $1,  0, $3, -1, $4); }
205
;
206
 
207
seclist:
208
                seclist secline
209
        |       secline
210
        ;
211
 
212
secline:
213
        ID attr_list { def_section ($1, $2);}
214
        | ID ID { def_section_alt ($1, $2);}
215
        ;
216
 
217
attr_list:
218
        attr_list opt_comma attr { $$ = $1 | $3; }
219
        | attr { $$ = $1; }
220
        ;
221
 
222
opt_comma:
223
        ','
224
        |
225
        ;
226
opt_number: ',' NUMBER { $$=$2;}
227
        |          { $$=-1;}
228
        ;
229
 
230
attr:
231
                READ    { $$ = 1;}
232
        |       WRITE   { $$ = 2;}
233
        |       EXECUTE { $$=4;}
234
        |       SHARED  { $$=8;}
235
        ;
236
 
237
opt_name: ID            { $$ = $1; }
238
        | '.' ID
239
          {
240
            char *name = def_pool_alloc (strlen ($2) + 2);
241
            sprintf (name, ".%s", $2);
242
            $$ = name;
243
          }
244
        | ID '.' ID
245
          {
246
            char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
247
            sprintf (name, "%s.%s", $1, $3);
248
            $$ = name;
249
          }
250
        |               { $$ = ""; }
251
        ;
252
 
253
opt_equalequal_name: EQUAL ID   { $$ = $2; }
254
        |                                                       { $$ = 0; }
255
        ;
256
 
257
opt_ordinal:
258
          '@' NUMBER     { $$ = $2;}
259
        |                { $$ = -1;}
260
        ;
261
 
262
opt_equal_name:
263
          '=' dot_name  { $$ = $2; }
264
        |               { $$ =  0; }
265
        ;
266
 
267
opt_base: BASE  '=' NUMBER      { $$ = $3;}
268
        |       { $$ = -1;}
269
        ;
270
 
271
dot_name: ID            { $$ = $1; }
272
        | '.' ID
273
          {
274
            char *name = def_pool_alloc (strlen ($2) + 2);
275
            sprintf (name, ".%s", $2);
276
            $$ = name;
277
          }
278
        | dot_name '.' ID
279
          {
280
            char *name = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + 1);
281
            sprintf (name, "%s.%s", $1, $3);
282
            $$ = name;
283
          }
284
        ;
285
 
286
anylang_id: ID          { $$ = $1; }
287
        | '.' ID
288
          {
289
            char *id = def_pool_alloc (strlen ($2) + 2);
290
            sprintf (id, ".%s", $2);
291
            $$ = id;
292
          }
293
        | anylang_id '.' opt_digits opt_id
294
          {
295
            char *id = def_pool_alloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
296
            sprintf (id, "%s.%s%s", $1, $3, $4);
297
            $$ = id;
298
          }
299
        ;
300
 
301
opt_digits: DIGITS      { $$ = $1; }
302
        |               { $$ = ""; }
303
        ;
304
 
305
opt_id: ID              { $$ = $1; }
306
        |               { $$ = ""; }
307
        ;
308
 
309
NUMBER: DIGITS          { $$ = strtoul ($1, 0, 0); }
310
 
311
%%
312
 
313
/*****************************************************************************
314
 API
315
 *****************************************************************************/
316
 
317
static FILE *the_file;
318
static const char *def_filename;
319
static int linenumber;
320
static def_file *def;
321
static int saw_newline;
322
 
323
struct directive
324
  {
325
    struct directive *next;
326
    char *name;
327
    int len;
328
  };
329
 
330
static struct directive *directives = 0;
331
 
332
def_file *
333
def_file_empty (void)
334
{
335
  def_file *rv = xmalloc (sizeof (def_file));
336
  memset (rv, 0, sizeof (def_file));
337
  rv->is_dll = -1;
338
  rv->base_address = (bfd_vma) -1;
339
  rv->stack_reserve = rv->stack_commit = -1;
340
  rv->heap_reserve = rv->heap_commit = -1;
341
  rv->version_major = rv->version_minor = -1;
342
  return rv;
343
}
344
 
345
def_file *
346
def_file_parse (const char *filename, def_file *add_to)
347
{
348
  struct directive *d;
349
 
350
  the_file = fopen (filename, "r");
351
  def_filename = filename;
352
  linenumber = 1;
353
  if (!the_file)
354
    {
355
      perror (filename);
356
      return 0;
357
    }
358
  if (add_to)
359
    {
360
      def = add_to;
361
    }
362
  else
363
    {
364
      def = def_file_empty ();
365
    }
366
 
367
  saw_newline = 1;
368
  if (def_parse ())
369
    {
370
      def_file_free (def);
371
      fclose (the_file);
372
      def_pool_free ();
373
      return 0;
374
    }
375
 
376
  fclose (the_file);
377
 
378
  while ((d = directives) != NULL)
379
    {
380
#if TRACE
381
      printf ("Adding directive %08x `%s'\n", d->name, d->name);
382
#endif
383
      def_file_add_directive (def, d->name, d->len);
384
      directives = d->next;
385
      free (d->name);
386
      free (d);
387
    }
388
  def_pool_free ();
389
 
390
  return def;
391
}
392
 
393
void
394
def_file_free (def_file *fdef)
395
{
396
  int i;
397
 
398
  if (!fdef)
399
    return;
400
  if (fdef->name)
401
    free (fdef->name);
402
  if (fdef->description)
403
    free (fdef->description);
404
 
405
  if (fdef->section_defs)
406
    {
407
      for (i = 0; i < fdef->num_section_defs; i++)
408
        {
409
          if (fdef->section_defs[i].name)
410
            free (fdef->section_defs[i].name);
411
          if (fdef->section_defs[i].class)
412
            free (fdef->section_defs[i].class);
413
        }
414
      free (fdef->section_defs);
415
    }
416
 
417
  if (fdef->exports)
418
    {
419
      for (i = 0; i < fdef->num_exports; i++)
420
        {
421
          if (fdef->exports[i].internal_name
422
              && fdef->exports[i].internal_name != fdef->exports[i].name)
423
            free (fdef->exports[i].internal_name);
424
          if (fdef->exports[i].name)
425
            free (fdef->exports[i].name);
426
          if (fdef->exports[i].its_name)
427
            free (fdef->exports[i].its_name);
428
        }
429
      free (fdef->exports);
430
    }
431
 
432
  if (fdef->imports)
433
    {
434
      for (i = 0; i < fdef->num_imports; i++)
435
        {
436
          if (fdef->imports[i].internal_name
437
              && fdef->imports[i].internal_name != fdef->imports[i].name)
438
            free (fdef->imports[i].internal_name);
439
          if (fdef->imports[i].name)
440
            free (fdef->imports[i].name);
441
          if (fdef->imports[i].its_name)
442
            free (fdef->imports[i].its_name);
443
        }
444
      free (fdef->imports);
445
    }
446
 
447
  while (fdef->modules)
448
    {
449
      def_file_module *m = fdef->modules;
450
 
451
      fdef->modules = fdef->modules->next;
452
      free (m);
453
    }
454
 
455
  while (fdef->aligncomms)
456
    {
457
      def_file_aligncomm *c = fdef->aligncomms;
458
 
459
      fdef->aligncomms = fdef->aligncomms->next;
460
      free (c->symbol_name);
461
      free (c);
462
    }
463
 
464
  free (fdef);
465
}
466
 
467
#ifdef DEF_FILE_PRINT
468
void
469
def_file_print (FILE *file, def_file *fdef)
470
{
471
  int i;
472
 
473
  fprintf (file, ">>>> def_file at 0x%08x\n", fdef);
474
  if (fdef->name)
475
    fprintf (file, "  name: %s\n", fdef->name ? fdef->name : "(unspecified)");
476
  if (fdef->is_dll != -1)
477
    fprintf (file, "  is dll: %s\n", fdef->is_dll ? "yes" : "no");
478
  if (fdef->base_address != (bfd_vma) -1)
479
    fprintf (file, "  base address: 0x%08x\n", fdef->base_address);
480
  if (fdef->description)
481
    fprintf (file, "  description: `%s'\n", fdef->description);
482
  if (fdef->stack_reserve != -1)
483
    fprintf (file, "  stack reserve: 0x%08x\n", fdef->stack_reserve);
484
  if (fdef->stack_commit != -1)
485
    fprintf (file, "  stack commit: 0x%08x\n", fdef->stack_commit);
486
  if (fdef->heap_reserve != -1)
487
    fprintf (file, "  heap reserve: 0x%08x\n", fdef->heap_reserve);
488
  if (fdef->heap_commit != -1)
489
    fprintf (file, "  heap commit: 0x%08x\n", fdef->heap_commit);
490
 
491
  if (fdef->num_section_defs > 0)
492
    {
493
      fprintf (file, "  section defs:\n");
494
 
495
      for (i = 0; i < fdef->num_section_defs; i++)
496
        {
497
          fprintf (file, "    name: `%s', class: `%s', flags:",
498
                   fdef->section_defs[i].name, fdef->section_defs[i].class);
499
          if (fdef->section_defs[i].flag_read)
500
            fprintf (file, " R");
501
          if (fdef->section_defs[i].flag_write)
502
            fprintf (file, " W");
503
          if (fdef->section_defs[i].flag_execute)
504
            fprintf (file, " X");
505
          if (fdef->section_defs[i].flag_shared)
506
            fprintf (file, " S");
507
          fprintf (file, "\n");
508
        }
509
    }
510
 
511
  if (fdef->num_exports > 0)
512
    {
513
      fprintf (file, "  exports:\n");
514
 
515
      for (i = 0; i < fdef->num_exports; i++)
516
        {
517
          fprintf (file, "    name: `%s', int: `%s', ordinal: %d, flags:",
518
                   fdef->exports[i].name, fdef->exports[i].internal_name,
519
                   fdef->exports[i].ordinal);
520
          if (fdef->exports[i].flag_private)
521
            fprintf (file, " P");
522
          if (fdef->exports[i].flag_constant)
523
            fprintf (file, " C");
524
          if (fdef->exports[i].flag_noname)
525
            fprintf (file, " N");
526
          if (fdef->exports[i].flag_data)
527
            fprintf (file, " D");
528
          fprintf (file, "\n");
529
        }
530
    }
531
 
532
  if (fdef->num_imports > 0)
533
    {
534
      fprintf (file, "  imports:\n");
535
 
536
      for (i = 0; i < fdef->num_imports; i++)
537
        {
538
          fprintf (file, "    int: %s, from: `%s', name: `%s', ordinal: %d\n",
539
                   fdef->imports[i].internal_name,
540
                   fdef->imports[i].module,
541
                   fdef->imports[i].name,
542
                   fdef->imports[i].ordinal);
543
        }
544
    }
545
 
546
  if (fdef->version_major != -1)
547
    fprintf (file, "  version: %d.%d\n", fdef->version_major, fdef->version_minor);
548
 
549
  fprintf (file, "<<<< def_file at 0x%08x\n", fdef);
550
}
551
#endif
552
 
553
/* Helper routine to check for identity of string pointers,
554
   which might be NULL.  */
555
 
556
static int
557
are_names_equal (const char *s1, const char *s2)
558
{
559
  if (!s1 && !s2)
560
    return 0;
561
  if (!s1 || !s2)
562
    return (!s1 ? -1 : 1);
563
  return strcmp (s1, s2);
564
}
565
 
566
static int
567
cmp_export_elem (const def_file_export *e, const char *ex_name,
568
                 const char *in_name, const char *its_name,
569
                 int ord)
570
{
571
  int r;
572
 
573
  if ((r = are_names_equal (ex_name, e->name)) != 0)
574
    return r;
575
  if ((r = are_names_equal (in_name, e->internal_name)) != 0)
576
    return r;
577
  if ((r = are_names_equal (its_name, e->its_name)) != 0)
578
    return r;
579
  return (ord - e->ordinal);
580
}
581
 
582
/* Search the position of the identical element, or returns the position
583
   of the next higher element. If last valid element is smaller, then MAX
584
   is returned.  */
585
 
586
static int
587
find_export_in_list (def_file_export *b, int max,
588
                     const char *ex_name, const char *in_name,
589
                     const char *its_name, int ord, int *is_ident)
590
{
591
  int e, l, r, p;
592
 
593
  *is_ident = 0;
594
  if (!max)
595
    return 0;
596
  if ((e = cmp_export_elem (b, ex_name, in_name, its_name, ord)) <= 0)
597
    return 0;
598
  if (max == 1)
599
    return 1;
600
  if ((e = cmp_export_elem (b + (max - 1), ex_name, in_name, its_name, ord)) > 0)
601
    return max;
602
  else if (!e || max == 2)
603
    return max - 1;
604
  l = 0; r = max - 1;
605
  while (l < r)
606
    {
607
      p = (l + r) / 2;
608
      e = cmp_export_elem (b + p, ex_name, in_name, its_name, ord);
609
      if (!e)
610
        {
611
          *is_ident = 1;
612
          return p;
613
        }
614
      else if (e < 0)
615
        r = p - 1;
616
      else if (e > 0)
617
        l = p + 1;
618
    }
619
  if ((e = cmp_export_elem (b + l, ex_name, in_name, its_name, ord)) > 0)
620
    ++l;
621
  else if (!e)
622
    *is_ident = 1;
623
  return l;
624
}
625
 
626
def_file_export *
627
def_file_add_export (def_file *fdef,
628
                     const char *external_name,
629
                     const char *internal_name,
630
                     int ordinal,
631
                     const char *its_name,
632
                     int *is_dup)
633
{
634
  def_file_export *e;
635
  int pos;
636
  int max_exports = ROUND_UP(fdef->num_exports, 32);
637
 
638
  if (internal_name && !external_name)
639
    external_name = internal_name;
640
  if (external_name && !internal_name)
641
    internal_name = external_name;
642
 
643
  /* We need to avoid duplicates.  */
644
  *is_dup = 0;
645
  pos = find_export_in_list (fdef->exports, fdef->num_exports,
646
                     external_name, internal_name,
647
                     its_name, ordinal, is_dup);
648
 
649
  if (*is_dup != 0)
650
    return (fdef->exports + pos);
651
 
652
  if (fdef->num_exports >= max_exports)
653
    {
654
      max_exports = ROUND_UP(fdef->num_exports + 1, 32);
655
      if (fdef->exports)
656
        fdef->exports = xrealloc (fdef->exports,
657
                                 max_exports * sizeof (def_file_export));
658
      else
659
        fdef->exports = xmalloc (max_exports * sizeof (def_file_export));
660
    }
661
 
662
  e = fdef->exports + pos;
663
  if (pos != fdef->num_exports)
664
    memmove (&e[1], e, (sizeof (def_file_export) * (fdef->num_exports - pos)));
665
  memset (e, 0, sizeof (def_file_export));
666
  e->name = xstrdup (external_name);
667
  e->internal_name = xstrdup (internal_name);
668
  e->its_name = (its_name ? xstrdup (its_name) : NULL);
669
  e->ordinal = ordinal;
670
  fdef->num_exports++;
671
  return e;
672
}
673
 
674
def_file_module *
675
def_get_module (def_file *fdef, const char *name)
676
{
677
  def_file_module *s;
678
 
679
  for (s = fdef->modules; s; s = s->next)
680
    if (strcmp (s->name, name) == 0)
681
      return s;
682
 
683
  return NULL;
684
}
685
 
686
static def_file_module *
687
def_stash_module (def_file *fdef, const char *name)
688
{
689
  def_file_module *s;
690
 
691
  if ((s = def_get_module (fdef, name)) != NULL)
692
      return s;
693
  s = xmalloc (sizeof (def_file_module) + strlen (name));
694
  s->next = fdef->modules;
695
  fdef->modules = s;
696
  s->user_data = 0;
697
  strcpy (s->name, name);
698
  return s;
699
}
700
 
701
static int
702
cmp_import_elem (const def_file_import *e, const char *ex_name,
703
                 const char *in_name, const char *module,
704
                 int ord)
705
{
706
  int r;
707
 
708
  if ((r = are_names_equal (ex_name, e->name)) != 0)
709
    return r;
710
  if ((r = are_names_equal (in_name, e->internal_name)) != 0)
711
    return r;
712
  if (ord != e->ordinal)
713
    return (ord < e->ordinal ? -1 : 1);
714
  return are_names_equal (module, (e->module ? e->module->name : NULL));
715
}
716
 
717
/* Search the position of the identical element, or returns the position
718
   of the next higher element. If last valid element is smaller, then MAX
719
   is returned.  */
720
 
721
static int
722
find_import_in_list (def_file_import *b, int max,
723
                     const char *ex_name, const char *in_name,
724
                     const char *module, int ord, int *is_ident)
725
{
726
  int e, l, r, p;
727
 
728
  *is_ident = 0;
729
  if (!max)
730
    return 0;
731
  if ((e = cmp_import_elem (b, ex_name, in_name, module, ord)) <= 0)
732
    return 0;
733
  if (max == 1)
734
    return 1;
735
  if ((e = cmp_import_elem (b + (max - 1), ex_name, in_name, module, ord)) > 0)
736
    return max;
737
  else if (!e || max == 2)
738
    return max - 1;
739
  l = 0; r = max - 1;
740
  while (l < r)
741
    {
742
      p = (l + r) / 2;
743
      e = cmp_import_elem (b + p, ex_name, in_name, module, ord);
744
      if (!e)
745
        {
746
          *is_ident = 1;
747
          return p;
748
        }
749
      else if (e < 0)
750
        r = p - 1;
751
      else if (e > 0)
752
        l = p + 1;
753
    }
754
  if ((e = cmp_import_elem (b + l, ex_name, in_name, module, ord)) > 0)
755
    ++l;
756
  else if (!e)
757
    *is_ident = 1;
758
  return l;
759
}
760
 
761
def_file_import *
762
def_file_add_import (def_file *fdef,
763
                     const char *name,
764
                     const char *module,
765
                     int ordinal,
766
                     const char *internal_name,
767
                     const char *its_name,
768
                     int *is_dup)
769
{
770
  def_file_import *i;
771
  int pos;
772
  int max_imports = ROUND_UP (fdef->num_imports, 16);
773
 
774
  /* We need to avoid here duplicates.  */
775
  *is_dup = 0;
776
  pos = find_import_in_list (fdef->imports, fdef->num_imports,
777
                             name,
778
                             (!internal_name ? name : internal_name),
779
                             module, ordinal, is_dup);
780
  if (*is_dup != 0)
781
    return fdef->imports + pos;
782
 
783
  if (fdef->num_imports >= max_imports)
784
    {
785
      max_imports = ROUND_UP (fdef->num_imports+1, 16);
786
 
787
      if (fdef->imports)
788
        fdef->imports = xrealloc (fdef->imports,
789
                                 max_imports * sizeof (def_file_import));
790
      else
791
        fdef->imports = xmalloc (max_imports * sizeof (def_file_import));
792
    }
793
  i = fdef->imports + pos;
794
  if (pos != fdef->num_imports)
795
    memmove (&i[1], i, (sizeof (def_file_import) * (fdef->num_imports - pos)));
796
  memset (i, 0, sizeof (def_file_import));
797
  if (name)
798
    i->name = xstrdup (name);
799
  if (module)
800
    i->module = def_stash_module (fdef, module);
801
  i->ordinal = ordinal;
802
  if (internal_name)
803
    i->internal_name = xstrdup (internal_name);
804
  else
805
    i->internal_name = i->name;
806
  i->its_name = (its_name ? xstrdup (its_name) : NULL);
807
  fdef->num_imports++;
808
 
809
  return i;
810
}
811
 
812
struct
813
{
814
  char *param;
815
  int token;
816
}
817
diropts[] =
818
{
819
  { "-heap", HEAPSIZE },
820
  { "-stack", STACKSIZE_K },
821
  { "-attr", SECTIONS },
822
  { "-export", EXPORTS },
823
  { "-aligncomm", ALIGNCOMM },
824
  { 0, 0 }
825
};
826
 
827
void
828
def_file_add_directive (def_file *my_def, const char *param, int len)
829
{
830
  def_file *save_def = def;
831
  const char *pend = param + len;
832
  char * tend = (char *) param;
833
  int i;
834
 
835
  def = my_def;
836
 
837
  while (param < pend)
838
    {
839
      while (param < pend
840
             && (ISSPACE (*param) || *param == '\n' || *param == 0))
841
        param++;
842
 
843
      if (param == pend)
844
        break;
845
 
846
      /* Scan forward until we encounter any of:
847
          - the end of the buffer
848
          - the start of a new option
849
          - a newline seperating options
850
          - a NUL seperating options.  */
851
      for (tend = (char *) (param + 1);
852
           (tend < pend
853
            && !(ISSPACE (tend[-1]) && *tend == '-')
854
            && *tend != '\n' && *tend != 0);
855
           tend++)
856
        ;
857
 
858
      for (i = 0; diropts[i].param; i++)
859
        {
860
          len = strlen (diropts[i].param);
861
 
862
          if (tend - param >= len
863
              && strncmp (param, diropts[i].param, len) == 0
864
              && (param[len] == ':' || param[len] == ' '))
865
            {
866
              lex_parse_string_end = tend;
867
              lex_parse_string = param + len + 1;
868
              lex_forced_token = diropts[i].token;
869
              saw_newline = 0;
870
              if (def_parse ())
871
                continue;
872
              break;
873
            }
874
        }
875
 
876
      if (!diropts[i].param)
877
        {
878
          char saved;
879
 
880
          saved = * tend;
881
          * tend = 0;
882
          /* xgettext:c-format */
883
          einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
884
          * tend = saved;
885
        }
886
 
887
      lex_parse_string = 0;
888
      param = tend;
889
    }
890
 
891
  def = save_def;
892
  def_pool_free ();
893
}
894
 
895
/* Parser Callbacks.  */
896
 
897
static void
898
def_image_name (const char *name, int base, int is_dll)
899
{
900
  /* If a LIBRARY or NAME statement is specified without a name, there is nothing
901
     to do here.  We retain the output filename specified on command line.  */
902
  if (*name)
903
    {
904
      const char* image_name = lbasename (name);
905
 
906
      if (image_name != name)
907
        einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
908
               def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
909
               name);
910
      if (def->name)
911
        free (def->name);
912
      /* Append the default suffix, if none specified.  */
913
      if (strchr (image_name, '.') == 0)
914
        {
915
          const char * suffix = is_dll ? ".dll" : ".exe";
916
 
917
          def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
918
          sprintf (def->name, "%s%s", image_name, suffix);
919
        }
920
      else
921
        def->name = xstrdup (image_name);
922
    }
923
 
924
  /* Honor a BASE address statement, even if LIBRARY string is empty.  */
925
  def->base_address = base;
926
  def->is_dll = is_dll;
927
}
928
 
929
static void
930
def_description (const char *text)
931
{
932
  int len = def->description ? strlen (def->description) : 0;
933
 
934
  len += strlen (text) + 1;
935
  if (def->description)
936
    {
937
      def->description = xrealloc (def->description, len);
938
      strcat (def->description, text);
939
    }
940
  else
941
    {
942
      def->description = xmalloc (len);
943
      strcpy (def->description, text);
944
    }
945
}
946
 
947
static void
948
def_stacksize (int reserve, int commit)
949
{
950
  def->stack_reserve = reserve;
951
  def->stack_commit = commit;
952
}
953
 
954
static void
955
def_heapsize (int reserve, int commit)
956
{
957
  def->heap_reserve = reserve;
958
  def->heap_commit = commit;
959
}
960
 
961
static void
962
def_section (const char *name, int attr)
963
{
964
  def_file_section *s;
965
  int max_sections = ROUND_UP (def->num_section_defs, 4);
966
 
967
  if (def->num_section_defs >= max_sections)
968
    {
969
      max_sections = ROUND_UP (def->num_section_defs+1, 4);
970
 
971
      if (def->section_defs)
972
        def->section_defs = xrealloc (def->section_defs,
973
                                      max_sections * sizeof (def_file_import));
974
      else
975
        def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
976
    }
977
  s = def->section_defs + def->num_section_defs;
978
  memset (s, 0, sizeof (def_file_section));
979
  s->name = xstrdup (name);
980
  if (attr & 1)
981
    s->flag_read = 1;
982
  if (attr & 2)
983
    s->flag_write = 1;
984
  if (attr & 4)
985
    s->flag_execute = 1;
986
  if (attr & 8)
987
    s->flag_shared = 1;
988
 
989
  def->num_section_defs++;
990
}
991
 
992
static void
993
def_section_alt (const char *name, const char *attr)
994
{
995
  int aval = 0;
996
 
997
  for (; *attr; attr++)
998
    {
999
      switch (*attr)
1000
        {
1001
        case 'R':
1002
        case 'r':
1003
          aval |= 1;
1004
          break;
1005
        case 'W':
1006
        case 'w':
1007
          aval |= 2;
1008
          break;
1009
        case 'X':
1010
        case 'x':
1011
          aval |= 4;
1012
          break;
1013
        case 'S':
1014
        case 's':
1015
          aval |= 8;
1016
          break;
1017
        }
1018
    }
1019
  def_section (name, aval);
1020
}
1021
 
1022
static void
1023
def_exports (const char *external_name,
1024
             const char *internal_name,
1025
             int ordinal,
1026
             int flags,
1027
             const char *its_name)
1028
{
1029
  def_file_export *dfe;
1030
  int is_dup = 0;
1031
 
1032
  if (!internal_name && external_name)
1033
    internal_name = external_name;
1034
#if TRACE
1035
  printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
1036
#endif
1037
 
1038
  dfe = def_file_add_export (def, external_name, internal_name, ordinal,
1039
                             its_name, &is_dup);
1040
 
1041
  /* We might check here for flag redefinition and warn.  For now we
1042
     ignore duplicates silently.  */
1043
  if (is_dup)
1044
    return;
1045
 
1046
  if (flags & 1)
1047
    dfe->flag_noname = 1;
1048
  if (flags & 2)
1049
    dfe->flag_constant = 1;
1050
  if (flags & 4)
1051
    dfe->flag_data = 1;
1052
  if (flags & 8)
1053
    dfe->flag_private = 1;
1054
}
1055
 
1056
static void
1057
def_import (const char *internal_name,
1058
            const char *module,
1059
            const char *dllext,
1060
            const char *name,
1061
            int ordinal,
1062
            const char *its_name)
1063
{
1064
  char *buf = 0;
1065
  const char *ext = dllext ? dllext : "dll";
1066
  int is_dup = 0;
1067
 
1068
  buf = xmalloc (strlen (module) + strlen (ext) + 2);
1069
  sprintf (buf, "%s.%s", module, ext);
1070
  module = buf;
1071
 
1072
  def_file_add_import (def, name, module, ordinal, internal_name, its_name,
1073
                       &is_dup);
1074
  free (buf);
1075
}
1076
 
1077
static void
1078
def_version (int major, int minor)
1079
{
1080
  def->version_major = major;
1081
  def->version_minor = minor;
1082
}
1083
 
1084
static void
1085
def_directive (char *str)
1086
{
1087
  struct directive *d = xmalloc (sizeof (struct directive));
1088
 
1089
  d->next = directives;
1090
  directives = d;
1091
  d->name = xstrdup (str);
1092
  d->len = strlen (str);
1093
}
1094
 
1095
static void
1096
def_aligncomm (char *str, int align)
1097
{
1098
  def_file_aligncomm *c, *p;
1099
 
1100
  p = NULL;
1101
  c = def->aligncomms;
1102
  while (c != NULL)
1103
    {
1104
      int e = strcmp (c->symbol_name, str);
1105
      if (!e)
1106
        {
1107
          /* Not sure if we want to allow here duplicates with
1108
             different alignments, but for now we keep them.  */
1109
          e = (int) c->alignment - align;
1110
          if (!e)
1111
            return;
1112
        }
1113
      if (e > 0)
1114
        break;
1115
      c = (p = c)->next;
1116
    }
1117
 
1118
  c = xmalloc (sizeof (def_file_aligncomm));
1119
  c->symbol_name = xstrdup (str);
1120
  c->alignment = (unsigned int) align;
1121
  if (!p)
1122
    {
1123
      c->next = def->aligncomms;
1124
      def->aligncomms = c;
1125
    }
1126
  else
1127
    {
1128
      c->next = p->next;
1129
      p->next = c;
1130
    }
1131
}
1132
 
1133
static int
1134
def_error (const char *err)
1135
{
1136
  einfo ("%P: %s:%d: %s\n",
1137
         def_filename ? def_filename : "", linenumber, err);
1138
  return 0;
1139
}
1140
 
1141
 
1142
/* Lexical Scanner.  */
1143
 
1144
#undef TRACE
1145
#define TRACE 0
1146
 
1147
/* Never freed, but always reused as needed, so no real leak.  */
1148
static char *buffer = 0;
1149
static int buflen = 0;
1150
static int bufptr = 0;
1151
 
1152
static void
1153
put_buf (char c)
1154
{
1155
  if (bufptr == buflen)
1156
    {
1157
      buflen += 50;             /* overly reasonable, eh?  */
1158
      if (buffer)
1159
        buffer = xrealloc (buffer, buflen + 1);
1160
      else
1161
        buffer = xmalloc (buflen + 1);
1162
    }
1163
  buffer[bufptr++] = c;
1164
  buffer[bufptr] = 0;           /* not optimal, but very convenient.  */
1165
}
1166
 
1167
static struct
1168
{
1169
  char *name;
1170
  int token;
1171
}
1172
tokens[] =
1173
{
1174
  { "BASE", BASE },
1175
  { "CODE", CODE },
1176
  { "CONSTANT", CONSTANTU },
1177
  { "constant", CONSTANTL },
1178
  { "DATA", DATAU },
1179
  { "data", DATAL },
1180
  { "DESCRIPTION", DESCRIPTION },
1181
  { "DIRECTIVE", DIRECTIVE },
1182
  { "EXECUTE", EXECUTE },
1183
  { "EXPORTS", EXPORTS },
1184
  { "HEAPSIZE", HEAPSIZE },
1185
  { "IMPORTS", IMPORTS },
1186
  { "LIBRARY", LIBRARY },
1187
  { "NAME", NAME },
1188
  { "NONAME", NONAMEU },
1189
  { "noname", NONAMEL },
1190
  { "PRIVATE", PRIVATEU },
1191
  { "private", PRIVATEL },
1192
  { "READ", READ },
1193
  { "SECTIONS", SECTIONS },
1194
  { "SEGMENTS", SECTIONS },
1195
  { "SHARED", SHARED },
1196
  { "STACKSIZE", STACKSIZE_K },
1197
  { "VERSION", VERSIONK },
1198
  { "WRITE", WRITE },
1199
  { 0, 0 }
1200
};
1201
 
1202
static int
1203
def_getc (void)
1204
{
1205
  int rv;
1206
 
1207
  if (lex_parse_string)
1208
    {
1209
      if (lex_parse_string >= lex_parse_string_end)
1210
        rv = EOF;
1211
      else
1212
        rv = *lex_parse_string++;
1213
    }
1214
  else
1215
    {
1216
      rv = fgetc (the_file);
1217
    }
1218
  if (rv == '\n')
1219
    saw_newline = 1;
1220
  return rv;
1221
}
1222
 
1223
static int
1224
def_ungetc (int c)
1225
{
1226
  if (lex_parse_string)
1227
    {
1228
      lex_parse_string--;
1229
      return c;
1230
    }
1231
  else
1232
    return ungetc (c, the_file);
1233
}
1234
 
1235
static int
1236
def_lex (void)
1237
{
1238
  int c, i, q;
1239
 
1240
  if (lex_forced_token)
1241
    {
1242
      i = lex_forced_token;
1243
      lex_forced_token = 0;
1244
#if TRACE
1245
      printf ("lex: forcing token %d\n", i);
1246
#endif
1247
      return i;
1248
    }
1249
 
1250
  c = def_getc ();
1251
 
1252
  /* Trim leading whitespace.  */
1253
  while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
1254
    c = def_getc ();
1255
 
1256
  if (c == EOF)
1257
    {
1258
#if TRACE
1259
      printf ("lex: EOF\n");
1260
#endif
1261
      return 0;
1262
    }
1263
 
1264
  if (saw_newline && c == ';')
1265
    {
1266
      do
1267
        {
1268
          c = def_getc ();
1269
        }
1270
      while (c != EOF && c != '\n');
1271
      if (c == '\n')
1272
        return def_lex ();
1273
      return 0;
1274
    }
1275
 
1276
  /* Must be something else.  */
1277
  saw_newline = 0;
1278
 
1279
  if (ISDIGIT (c))
1280
    {
1281
      bufptr = 0;
1282
      while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1283
        {
1284
          put_buf (c);
1285
          c = def_getc ();
1286
        }
1287
      if (c != EOF)
1288
        def_ungetc (c);
1289
      yylval.digits = def_pool_strdup (buffer);
1290
#if TRACE
1291
      printf ("lex: `%s' returns DIGITS\n", buffer);
1292
#endif
1293
      return DIGITS;
1294
    }
1295
 
1296
  if (ISALPHA (c) || strchr ("$:-_?@", c))
1297
    {
1298
      bufptr = 0;
1299
      q = c;
1300
      put_buf (c);
1301
      c = def_getc ();
1302
 
1303
      if (q == '@')
1304
        {
1305
          if (ISBLANK (c) ) /* '@' followed by whitespace.  */
1306
            return (q);
1307
          else if (ISDIGIT (c)) /* '@' followed by digit.  */
1308
            {
1309
              def_ungetc (c);
1310
              return (q);
1311
            }
1312
#if TRACE
1313
          printf ("lex: @ returns itself\n");
1314
#endif
1315
        }
1316
 
1317
      while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@<>", c)))
1318
        {
1319
          put_buf (c);
1320
          c = def_getc ();
1321
        }
1322
      if (c != EOF)
1323
        def_ungetc (c);
1324
      if (ISALPHA (q)) /* Check for tokens.  */
1325
        {
1326
          for (i = 0; tokens[i].name; i++)
1327
            if (strcmp (tokens[i].name, buffer) == 0)
1328
              {
1329
#if TRACE
1330
                printf ("lex: `%s' is a string token\n", buffer);
1331
#endif
1332
                return tokens[i].token;
1333
              }
1334
        }
1335
#if TRACE
1336
      printf ("lex: `%s' returns ID\n", buffer);
1337
#endif
1338
      yylval.id = def_pool_strdup (buffer);
1339
      return ID;
1340
    }
1341
 
1342
  if (c == '\'' || c == '"')
1343
    {
1344
      q = c;
1345
      c = def_getc ();
1346
      bufptr = 0;
1347
 
1348
      while (c != EOF && c != q)
1349
        {
1350
          put_buf (c);
1351
          c = def_getc ();
1352
        }
1353
      yylval.id = def_pool_strdup (buffer);
1354
#if TRACE
1355
      printf ("lex: `%s' returns ID\n", buffer);
1356
#endif
1357
      return ID;
1358
    }
1359
 
1360
  if ( c == '=')
1361
    {
1362
      c = def_getc ();
1363
      if (c == '=')
1364
        {
1365
#if TRACE
1366
          printf ("lex: `==' returns EQUAL\n");
1367
#endif
1368
                  return EQUAL;
1369
        }
1370
      def_ungetc (c);
1371
#if TRACE
1372
      printf ("lex: `=' returns itself\n");
1373
#endif
1374
      return '=';
1375
    }
1376
  if (c == '.' || c == ',')
1377
    {
1378
#if TRACE
1379
      printf ("lex: `%c' returns itself\n", c);
1380
#endif
1381
      return c;
1382
    }
1383
 
1384
  if (c == '\n')
1385
    {
1386
      linenumber++;
1387
      saw_newline = 1;
1388
    }
1389
 
1390
  /*printf ("lex: 0x%02x ignored\n", c); */
1391
  return def_lex ();
1392
}
1393
 
1394
static char *
1395
def_pool_alloc (size_t sz)
1396
{
1397
  def_pool_str *e;
1398
 
1399
  e = (def_pool_str *) xmalloc (sizeof (def_pool_str) + sz);
1400
  e->next = pool_strs;
1401
  pool_strs = e;
1402
  return e->data;
1403
}
1404
 
1405
static char *
1406
def_pool_strdup (const char *str)
1407
{
1408
  char *s;
1409
  size_t len;
1410
  if (!str)
1411
    return NULL;
1412
  len = strlen (str) + 1;
1413
  s = def_pool_alloc (len);
1414
  memcpy (s, str, len);
1415
  return s;
1416
}
1417
 
1418
static void
1419
def_pool_free (void)
1420
{
1421
  def_pool_str *p;
1422
  while ((p = pool_strs) != NULL)
1423
    {
1424
      pool_strs = p->next;
1425
      free (p);
1426
    }
1427
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.