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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [ld/] [deffilep.y] - Blame information for rev 822

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

Line No. Rev Author Line
1 205 julius
%{ /* 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
static void def_description (const char *);
82
static void def_exports (const char *, const char *, int, int);
83
static void def_heapsize (int, int);
84
static void def_import (const char *, const char *, const char *, const char *,
85
                        int);
86
static void def_image_name (const char *, int, int);
87
static void def_section (const char *, int);
88
static void def_section_alt (const char *, const char *);
89
static void def_stacksize (int, int);
90
static void def_version (int, int);
91
static void def_directive (char *);
92
static void def_aligncomm (char *str, int align);
93
static int def_parse (void);
94
static int def_error (const char *);
95
static int def_lex (void);
96
 
97
static int lex_forced_token = 0;
98
static const char *lex_parse_string = 0;
99
static const char *lex_parse_string_end = 0;
100
 
101
%}
102
 
103
%union {
104
  char *id;
105
  int number;
106
  char *digits;
107
};
108
 
109
%token NAME LIBRARY DESCRIPTION STACKSIZE_K HEAPSIZE CODE DATAU DATAL
110
%token SECTIONS EXPORTS IMPORTS VERSIONK BASE CONSTANTU CONSTANTL
111
%token PRIVATEU PRIVATEL ALIGNCOMM
112
%token READ WRITE EXECUTE SHARED NONAMEU NONAMEL DIRECTIVE
113
%token  ID
114
%token  DIGITS
115
%type   NUMBER
116
%type   opt_digits
117
%type   opt_base opt_ordinal
118
%type   attr attr_list opt_number exp_opt_list exp_opt
119
%type   opt_name opt_equal_name dot_name anylang_id opt_id
120
 
121
%%
122
 
123
start: start command
124
        | command
125
        ;
126
 
127
command:
128
                NAME opt_name opt_base { def_image_name ($2, $3, 0); }
129
        |       LIBRARY opt_name opt_base { def_image_name ($2, $3, 1); }
130
        |       DESCRIPTION ID { def_description ($2);}
131
        |       STACKSIZE_K NUMBER opt_number { def_stacksize ($2, $3);}
132
        |       HEAPSIZE NUMBER opt_number { def_heapsize ($2, $3);}
133
        |       CODE attr_list { def_section ("CODE", $2);}
134
        |       DATAU attr_list  { def_section ("DATA", $2);}
135
        |       SECTIONS seclist
136
        |       EXPORTS explist
137
        |       IMPORTS implist
138
        |       VERSIONK NUMBER { def_version ($2, 0);}
139
        |       VERSIONK NUMBER '.' NUMBER { def_version ($2, $4);}
140
        |       DIRECTIVE ID { def_directive ($2);}
141
        |       ALIGNCOMM anylang_id ',' NUMBER { def_aligncomm ($2, $4);}
142
        ;
143
 
144
 
145
explist:
146
                /* EMPTY */
147
        |       expline
148
        |       explist expline
149
        ;
150
 
151
expline:
152
                /* The opt_comma is necessary to support both the usual
153
                  DEF file syntax as well as .drectve syntax which
154
                  mandates ,.  */
155
                dot_name opt_equal_name opt_ordinal opt_comma exp_opt_list
156
                        { def_exports ($1, $2, $3, $5); }
157
        ;
158
exp_opt_list:
159
                /* The opt_comma is necessary to support both the usual
160
                   DEF file syntax as well as .drectve syntax which
161
                   allows for comma separated opt list.  */
162
                exp_opt opt_comma exp_opt_list { $$ = $1 | $3; }
163
        |       { $$ = 0; }
164
        ;
165
exp_opt:
166
                NONAMEU         { $$ = 1; }
167
        |       NONAMEL         { $$ = 1; }
168
        |       CONSTANTU       { $$ = 2; }
169
        |       CONSTANTL       { $$ = 2; }
170
        |       DATAU           { $$ = 4; }
171
        |       DATAL           { $$ = 4; }
172
        |       PRIVATEU        { $$ = 8; }
173
        |       PRIVATEL        { $$ = 8; }
174
        ;
175
implist:
176
                implist impline
177
        |       impline
178
        ;
179
 
180
impline:
181
               ID '=' ID '.' ID '.' ID     { def_import ($1, $3, $5, $7, -1); }
182
       |       ID '=' ID '.' ID '.' NUMBER { def_import ($1, $3, $5,  0, $7); }
183
       |       ID '=' ID '.' ID            { def_import ($1, $3,  0, $5, -1); }
184
       |       ID '=' ID '.' NUMBER        { def_import ($1, $3,  0,  0, $5); }
185
       |       ID '.' ID '.' ID            { def_import ( 0, $1, $3, $5, -1); }
186
       |       ID '.' ID                   { def_import ( 0, $1,  0, $3, -1); }
187
;
188
 
189
seclist:
190
                seclist secline
191
        |       secline
192
        ;
193
 
194
secline:
195
        ID attr_list { def_section ($1, $2);}
196
        | ID ID { def_section_alt ($1, $2);}
197
        ;
198
 
199
attr_list:
200
        attr_list opt_comma attr { $$ = $1 | $3; }
201
        | attr { $$ = $1; }
202
        ;
203
 
204
opt_comma:
205
        ','
206
        |
207
        ;
208
opt_number: ',' NUMBER { $$=$2;}
209
        |          { $$=-1;}
210
        ;
211
 
212
attr:
213
                READ    { $$ = 1;}
214
        |       WRITE   { $$ = 2;}
215
        |       EXECUTE { $$=4;}
216
        |       SHARED  { $$=8;}
217
        ;
218
 
219
opt_name: ID            { $$ = $1; }
220
        | ID '.' ID
221
          {
222
            char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
223
            sprintf (name, "%s.%s", $1, $3);
224
            $$ = name;
225
          }
226
        |               { $$ = ""; }
227
        ;
228
 
229
opt_ordinal:
230
          '@' NUMBER     { $$ = $2;}
231
        |                { $$ = -1;}
232
        ;
233
 
234
opt_equal_name:
235
          '=' dot_name  { $$ = $2; }
236
        |               { $$ =  0; }
237
        ;
238
 
239
opt_base: BASE  '=' NUMBER      { $$ = $3;}
240
        |       { $$ = -1;}
241
        ;
242
 
243
dot_name: ID            { $$ = $1; }
244
        | dot_name '.' ID
245
          {
246
            char *name = xmalloc (strlen ($1) + 1 + strlen ($3) + 1);
247
            sprintf (name, "%s.%s", $1, $3);
248
            $$ = name;
249
          }
250
        ;
251
 
252
anylang_id: ID          { $$ = $1; }
253
        | anylang_id '.' opt_digits opt_id
254
          {
255
            char *id = xmalloc (strlen ($1) + 1 + strlen ($3) + strlen ($4) + 1);
256
            sprintf (id, "%s.%s%s", $1, $3, $4);
257
            $$ = id;
258
          }
259
        ;
260
 
261
opt_digits: DIGITS      { $$ = $1; }
262
        |               { $$ = ""; }
263
        ;
264
 
265
opt_id: ID              { $$ = $1; }
266
        |               { $$ = ""; }
267
        ;
268
 
269
NUMBER: DIGITS          { $$ = strtoul ($1, 0, 0); }
270
 
271
%%
272
 
273
/*****************************************************************************
274
 API
275
 *****************************************************************************/
276
 
277
static FILE *the_file;
278
static const char *def_filename;
279
static int linenumber;
280
static def_file *def;
281
static int saw_newline;
282
 
283
struct directive
284
  {
285
    struct directive *next;
286
    char *name;
287
    int len;
288
  };
289
 
290
static struct directive *directives = 0;
291
 
292
def_file *
293
def_file_empty (void)
294
{
295
  def_file *rv = xmalloc (sizeof (def_file));
296
  memset (rv, 0, sizeof (def_file));
297
  rv->is_dll = -1;
298
  rv->base_address = (bfd_vma) -1;
299
  rv->stack_reserve = rv->stack_commit = -1;
300
  rv->heap_reserve = rv->heap_commit = -1;
301
  rv->version_major = rv->version_minor = -1;
302
  return rv;
303
}
304
 
305
def_file *
306
def_file_parse (const char *filename, def_file *add_to)
307
{
308
  struct directive *d;
309
 
310
  the_file = fopen (filename, "r");
311
  def_filename = filename;
312
  linenumber = 1;
313
  if (!the_file)
314
    {
315
      perror (filename);
316
      return 0;
317
    }
318
  if (add_to)
319
    {
320
      def = add_to;
321
    }
322
  else
323
    {
324
      def = def_file_empty ();
325
    }
326
 
327
  saw_newline = 1;
328
  if (def_parse ())
329
    {
330
      def_file_free (def);
331
      fclose (the_file);
332
      return 0;
333
    }
334
 
335
  fclose (the_file);
336
 
337
  for (d = directives; d; d = d->next)
338
    {
339
#if TRACE
340
      printf ("Adding directive %08x `%s'\n", d->name, d->name);
341
#endif
342
      def_file_add_directive (def, d->name, d->len);
343
    }
344
 
345
  return def;
346
}
347
 
348
void
349
def_file_free (def_file *def)
350
{
351
  int i;
352
 
353
  if (!def)
354
    return;
355
  if (def->name)
356
    free (def->name);
357
  if (def->description)
358
    free (def->description);
359
 
360
  if (def->section_defs)
361
    {
362
      for (i = 0; i < def->num_section_defs; i++)
363
        {
364
          if (def->section_defs[i].name)
365
            free (def->section_defs[i].name);
366
          if (def->section_defs[i].class)
367
            free (def->section_defs[i].class);
368
        }
369
      free (def->section_defs);
370
    }
371
 
372
  if (def->exports)
373
    {
374
      for (i = 0; i < def->num_exports; i++)
375
        {
376
          if (def->exports[i].internal_name
377
              && def->exports[i].internal_name != def->exports[i].name)
378
            free (def->exports[i].internal_name);
379
          if (def->exports[i].name)
380
            free (def->exports[i].name);
381
        }
382
      free (def->exports);
383
    }
384
 
385
  if (def->imports)
386
    {
387
      for (i = 0; i < def->num_imports; i++)
388
        {
389
          if (def->imports[i].internal_name
390
              && def->imports[i].internal_name != def->imports[i].name)
391
            free (def->imports[i].internal_name);
392
          if (def->imports[i].name)
393
            free (def->imports[i].name);
394
        }
395
      free (def->imports);
396
    }
397
 
398
  while (def->modules)
399
    {
400
      def_file_module *m = def->modules;
401
      def->modules = def->modules->next;
402
      free (m);
403
    }
404
 
405
  while (def->aligncomms)
406
    {
407
      def_file_aligncomm *c = def->aligncomms;
408
      def->aligncomms = def->aligncomms->next;
409
      free (c->symbol_name);
410
      free (c);
411
    }
412
 
413
  free (def);
414
}
415
 
416
#ifdef DEF_FILE_PRINT
417
void
418
def_file_print (FILE *file, def_file *def)
419
{
420
  int i;
421
 
422
  fprintf (file, ">>>> def_file at 0x%08x\n", def);
423
  if (def->name)
424
    fprintf (file, "  name: %s\n", def->name ? def->name : "(unspecified)");
425
  if (def->is_dll != -1)
426
    fprintf (file, "  is dll: %s\n", def->is_dll ? "yes" : "no");
427
  if (def->base_address != (bfd_vma) -1)
428
    fprintf (file, "  base address: 0x%08x\n", def->base_address);
429
  if (def->description)
430
    fprintf (file, "  description: `%s'\n", def->description);
431
  if (def->stack_reserve != -1)
432
    fprintf (file, "  stack reserve: 0x%08x\n", def->stack_reserve);
433
  if (def->stack_commit != -1)
434
    fprintf (file, "  stack commit: 0x%08x\n", def->stack_commit);
435
  if (def->heap_reserve != -1)
436
    fprintf (file, "  heap reserve: 0x%08x\n", def->heap_reserve);
437
  if (def->heap_commit != -1)
438
    fprintf (file, "  heap commit: 0x%08x\n", def->heap_commit);
439
 
440
  if (def->num_section_defs > 0)
441
    {
442
      fprintf (file, "  section defs:\n");
443
 
444
      for (i = 0; i < def->num_section_defs; i++)
445
        {
446
          fprintf (file, "    name: `%s', class: `%s', flags:",
447
                   def->section_defs[i].name, def->section_defs[i].class);
448
          if (def->section_defs[i].flag_read)
449
            fprintf (file, " R");
450
          if (def->section_defs[i].flag_write)
451
            fprintf (file, " W");
452
          if (def->section_defs[i].flag_execute)
453
            fprintf (file, " X");
454
          if (def->section_defs[i].flag_shared)
455
            fprintf (file, " S");
456
          fprintf (file, "\n");
457
        }
458
    }
459
 
460
  if (def->num_exports > 0)
461
    {
462
      fprintf (file, "  exports:\n");
463
 
464
      for (i = 0; i < def->num_exports; i++)
465
        {
466
          fprintf (file, "    name: `%s', int: `%s', ordinal: %d, flags:",
467
                   def->exports[i].name, def->exports[i].internal_name,
468
                   def->exports[i].ordinal);
469
          if (def->exports[i].flag_private)
470
            fprintf (file, " P");
471
          if (def->exports[i].flag_constant)
472
            fprintf (file, " C");
473
          if (def->exports[i].flag_noname)
474
            fprintf (file, " N");
475
          if (def->exports[i].flag_data)
476
            fprintf (file, " D");
477
          fprintf (file, "\n");
478
        }
479
    }
480
 
481
  if (def->num_imports > 0)
482
    {
483
      fprintf (file, "  imports:\n");
484
 
485
      for (i = 0; i < def->num_imports; i++)
486
        {
487
          fprintf (file, "    int: %s, from: `%s', name: `%s', ordinal: %d\n",
488
                   def->imports[i].internal_name,
489
                   def->imports[i].module,
490
                   def->imports[i].name,
491
                   def->imports[i].ordinal);
492
        }
493
    }
494
 
495
  if (def->version_major != -1)
496
    fprintf (file, "  version: %d.%d\n", def->version_major, def->version_minor);
497
 
498
  fprintf (file, "<<<< def_file at 0x%08x\n", def);
499
}
500
#endif
501
 
502
def_file_export *
503
def_file_add_export (def_file *def,
504
                     const char *external_name,
505
                     const char *internal_name,
506
                     int ordinal)
507
{
508
  def_file_export *e;
509
  int max_exports = ROUND_UP(def->num_exports, 32);
510
 
511
  if (def->num_exports >= max_exports)
512
    {
513
      max_exports = ROUND_UP(def->num_exports + 1, 32);
514
      if (def->exports)
515
        def->exports = xrealloc (def->exports,
516
                                 max_exports * sizeof (def_file_export));
517
      else
518
        def->exports = xmalloc (max_exports * sizeof (def_file_export));
519
    }
520
  e = def->exports + def->num_exports;
521
  memset (e, 0, sizeof (def_file_export));
522
  if (internal_name && !external_name)
523
    external_name = internal_name;
524
  if (external_name && !internal_name)
525
    internal_name = external_name;
526
  e->name = xstrdup (external_name);
527
  e->internal_name = xstrdup (internal_name);
528
  e->ordinal = ordinal;
529
  def->num_exports++;
530
  return e;
531
}
532
 
533
def_file_module *
534
def_get_module (def_file *def, const char *name)
535
{
536
  def_file_module *s;
537
 
538
  for (s = def->modules; s; s = s->next)
539
    if (strcmp (s->name, name) == 0)
540
      return s;
541
 
542
  return NULL;
543
}
544
 
545
static def_file_module *
546
def_stash_module (def_file *def, const char *name)
547
{
548
  def_file_module *s;
549
 
550
  if ((s = def_get_module (def, name)) != NULL)
551
      return s;
552
  s = xmalloc (sizeof (def_file_module) + strlen (name));
553
  s->next = def->modules;
554
  def->modules = s;
555
  s->user_data = 0;
556
  strcpy (s->name, name);
557
  return s;
558
}
559
 
560
def_file_import *
561
def_file_add_import (def_file *def,
562
                     const char *name,
563
                     const char *module,
564
                     int ordinal,
565
                     const char *internal_name)
566
{
567
  def_file_import *i;
568
  int max_imports = ROUND_UP (def->num_imports, 16);
569
 
570
  if (def->num_imports >= max_imports)
571
    {
572
      max_imports = ROUND_UP (def->num_imports+1, 16);
573
 
574
      if (def->imports)
575
        def->imports = xrealloc (def->imports,
576
                                 max_imports * sizeof (def_file_import));
577
      else
578
        def->imports = xmalloc (max_imports * sizeof (def_file_import));
579
    }
580
  i = def->imports + def->num_imports;
581
  memset (i, 0, sizeof (def_file_import));
582
  if (name)
583
    i->name = xstrdup (name);
584
  if (module)
585
    i->module = def_stash_module (def, module);
586
  i->ordinal = ordinal;
587
  if (internal_name)
588
    i->internal_name = xstrdup (internal_name);
589
  else
590
    i->internal_name = i->name;
591
  def->num_imports++;
592
 
593
  return i;
594
}
595
 
596
struct
597
{
598
  char *param;
599
  int token;
600
}
601
diropts[] =
602
{
603
  { "-heap", HEAPSIZE },
604
  { "-stack", STACKSIZE_K },
605
  { "-attr", SECTIONS },
606
  { "-export", EXPORTS },
607
  { "-aligncomm", ALIGNCOMM },
608
  { 0, 0 }
609
};
610
 
611
void
612
def_file_add_directive (def_file *my_def, const char *param, int len)
613
{
614
  def_file *save_def = def;
615
  const char *pend = param + len;
616
  char * tend = (char *) param;
617
  int i;
618
 
619
  def = my_def;
620
 
621
  while (param < pend)
622
    {
623
      while (param < pend
624
             && (ISSPACE (*param) || *param == '\n' || *param == 0))
625
        param++;
626
 
627
      if (param == pend)
628
        break;
629
 
630
      /* Scan forward until we encounter any of:
631
          - the end of the buffer
632
          - the start of a new option
633
          - a newline seperating options
634
          - a NUL seperating options.  */
635
      for (tend = (char *) (param + 1);
636
           (tend < pend
637
            && !(ISSPACE (tend[-1]) && *tend == '-')
638
            && *tend != '\n' && *tend != 0);
639
           tend++)
640
        ;
641
 
642
      for (i = 0; diropts[i].param; i++)
643
        {
644
          int len = strlen (diropts[i].param);
645
 
646
          if (tend - param >= len
647
              && strncmp (param, diropts[i].param, len) == 0
648
              && (param[len] == ':' || param[len] == ' '))
649
            {
650
              lex_parse_string_end = tend;
651
              lex_parse_string = param + len + 1;
652
              lex_forced_token = diropts[i].token;
653
              saw_newline = 0;
654
              if (def_parse ())
655
                continue;
656
              break;
657
            }
658
        }
659
 
660
      if (!diropts[i].param)
661
        {
662
          char saved;
663
 
664
          saved = * tend;
665
          * tend = 0;
666
          /* xgettext:c-format */
667
          einfo (_("Warning: .drectve `%s' unrecognized\n"), param);
668
          * tend = saved;
669
        }
670
 
671
      lex_parse_string = 0;
672
      param = tend;
673
    }
674
 
675
  def = save_def;
676
}
677
 
678
/* Parser Callbacks.  */
679
 
680
static void
681
def_image_name (const char *name, int base, int is_dll)
682
{
683
  /* If a LIBRARY or NAME statement is specified without a name, there is nothing
684
     to do here.  We retain the output filename specified on command line.  */
685
  if (*name)
686
    {
687
      const char* image_name = lbasename (name);
688
      if (image_name != name)
689
        einfo ("%s:%d: Warning: path components stripped from %s, '%s'\n",
690
               def_filename, linenumber, is_dll ? "LIBRARY" : "NAME",
691
               name);
692
      if (def->name)
693
        free (def->name);
694
      /* Append the default suffix, if none specified.  */
695
      if (strchr (image_name, '.') == 0)
696
        {
697
          const char * suffix = is_dll ? ".dll" : ".exe";
698
 
699
          def->name = xmalloc (strlen (image_name) + strlen (suffix) + 1);
700
          sprintf (def->name, "%s%s", image_name, suffix);
701
        }
702
      else
703
        def->name = xstrdup (image_name);
704
    }
705
 
706
  /* Honor a BASE address statement, even if LIBRARY string is empty.  */
707
  def->base_address = base;
708
  def->is_dll = is_dll;
709
}
710
 
711
static void
712
def_description (const char *text)
713
{
714
  int len = def->description ? strlen (def->description) : 0;
715
 
716
  len += strlen (text) + 1;
717
  if (def->description)
718
    {
719
      def->description = xrealloc (def->description, len);
720
      strcat (def->description, text);
721
    }
722
  else
723
    {
724
      def->description = xmalloc (len);
725
      strcpy (def->description, text);
726
    }
727
}
728
 
729
static void
730
def_stacksize (int reserve, int commit)
731
{
732
  def->stack_reserve = reserve;
733
  def->stack_commit = commit;
734
}
735
 
736
static void
737
def_heapsize (int reserve, int commit)
738
{
739
  def->heap_reserve = reserve;
740
  def->heap_commit = commit;
741
}
742
 
743
static void
744
def_section (const char *name, int attr)
745
{
746
  def_file_section *s;
747
  int max_sections = ROUND_UP (def->num_section_defs, 4);
748
 
749
  if (def->num_section_defs >= max_sections)
750
    {
751
      max_sections = ROUND_UP (def->num_section_defs+1, 4);
752
 
753
      if (def->section_defs)
754
        def->section_defs = xrealloc (def->section_defs,
755
                                      max_sections * sizeof (def_file_import));
756
      else
757
        def->section_defs = xmalloc (max_sections * sizeof (def_file_import));
758
    }
759
  s = def->section_defs + def->num_section_defs;
760
  memset (s, 0, sizeof (def_file_section));
761
  s->name = xstrdup (name);
762
  if (attr & 1)
763
    s->flag_read = 1;
764
  if (attr & 2)
765
    s->flag_write = 1;
766
  if (attr & 4)
767
    s->flag_execute = 1;
768
  if (attr & 8)
769
    s->flag_shared = 1;
770
 
771
  def->num_section_defs++;
772
}
773
 
774
static void
775
def_section_alt (const char *name, const char *attr)
776
{
777
  int aval = 0;
778
 
779
  for (; *attr; attr++)
780
    {
781
      switch (*attr)
782
        {
783
        case 'R':
784
        case 'r':
785
          aval |= 1;
786
          break;
787
        case 'W':
788
        case 'w':
789
          aval |= 2;
790
          break;
791
        case 'X':
792
        case 'x':
793
          aval |= 4;
794
          break;
795
        case 'S':
796
        case 's':
797
          aval |= 8;
798
          break;
799
        }
800
    }
801
  def_section (name, aval);
802
}
803
 
804
static void
805
def_exports (const char *external_name,
806
             const char *internal_name,
807
             int ordinal,
808
             int flags)
809
{
810
  def_file_export *dfe;
811
 
812
  if (!internal_name && external_name)
813
    internal_name = external_name;
814
#if TRACE
815
  printf ("def_exports, ext=%s int=%s\n", external_name, internal_name);
816
#endif
817
 
818
  dfe = def_file_add_export (def, external_name, internal_name, ordinal);
819
  if (flags & 1)
820
    dfe->flag_noname = 1;
821
  if (flags & 2)
822
    dfe->flag_constant = 1;
823
  if (flags & 4)
824
    dfe->flag_data = 1;
825
  if (flags & 8)
826
    dfe->flag_private = 1;
827
}
828
 
829
static void
830
def_import (const char *internal_name,
831
            const char *module,
832
            const char *dllext,
833
            const char *name,
834
            int ordinal)
835
{
836
  char *buf = 0;
837
  const char *ext = dllext ? dllext : "dll";
838
 
839
  buf = xmalloc (strlen (module) + strlen (ext) + 2);
840
  sprintf (buf, "%s.%s", module, ext);
841
  module = buf;
842
 
843
  def_file_add_import (def, name, module, ordinal, internal_name);
844
  if (buf)
845
    free (buf);
846
}
847
 
848
static void
849
def_version (int major, int minor)
850
{
851
  def->version_major = major;
852
  def->version_minor = minor;
853
}
854
 
855
static void
856
def_directive (char *str)
857
{
858
  struct directive *d = xmalloc (sizeof (struct directive));
859
 
860
  d->next = directives;
861
  directives = d;
862
  d->name = xstrdup (str);
863
  d->len = strlen (str);
864
}
865
 
866
static void
867
def_aligncomm (char *str, int align)
868
{
869
  def_file_aligncomm *c = xmalloc (sizeof (def_file_aligncomm));
870
 
871
  c->symbol_name = xstrdup (str);
872
  c->alignment = (unsigned int) align;
873
 
874
  c->next = def->aligncomms;
875
  def->aligncomms = c;
876
}
877
 
878
static int
879
def_error (const char *err)
880
{
881
  einfo ("%P: %s:%d: %s\n",
882
         def_filename ? def_filename : "", linenumber, err);
883
  return 0;
884
}
885
 
886
 
887
/* Lexical Scanner.  */
888
 
889
#undef TRACE
890
#define TRACE 0
891
 
892
/* Never freed, but always reused as needed, so no real leak.  */
893
static char *buffer = 0;
894
static int buflen = 0;
895
static int bufptr = 0;
896
 
897
static void
898
put_buf (char c)
899
{
900
  if (bufptr == buflen)
901
    {
902
      buflen += 50;             /* overly reasonable, eh?  */
903
      if (buffer)
904
        buffer = xrealloc (buffer, buflen + 1);
905
      else
906
        buffer = xmalloc (buflen + 1);
907
    }
908
  buffer[bufptr++] = c;
909
  buffer[bufptr] = 0;           /* not optimal, but very convenient.  */
910
}
911
 
912
static struct
913
{
914
  char *name;
915
  int token;
916
}
917
tokens[] =
918
{
919
  { "BASE", BASE },
920
  { "CODE", CODE },
921
  { "CONSTANT", CONSTANTU },
922
  { "constant", CONSTANTL },
923
  { "DATA", DATAU },
924
  { "data", DATAL },
925
  { "DESCRIPTION", DESCRIPTION },
926
  { "DIRECTIVE", DIRECTIVE },
927
  { "EXECUTE", EXECUTE },
928
  { "EXPORTS", EXPORTS },
929
  { "HEAPSIZE", HEAPSIZE },
930
  { "IMPORTS", IMPORTS },
931
  { "LIBRARY", LIBRARY },
932
  { "NAME", NAME },
933
  { "NONAME", NONAMEU },
934
  { "noname", NONAMEL },
935
  { "PRIVATE", PRIVATEU },
936
  { "private", PRIVATEL },
937
  { "READ", READ },
938
  { "SECTIONS", SECTIONS },
939
  { "SEGMENTS", SECTIONS },
940
  { "SHARED", SHARED },
941
  { "STACKSIZE", STACKSIZE_K },
942
  { "VERSION", VERSIONK },
943
  { "WRITE", WRITE },
944
  { 0, 0 }
945
};
946
 
947
static int
948
def_getc (void)
949
{
950
  int rv;
951
 
952
  if (lex_parse_string)
953
    {
954
      if (lex_parse_string >= lex_parse_string_end)
955
        rv = EOF;
956
      else
957
        rv = *lex_parse_string++;
958
    }
959
  else
960
    {
961
      rv = fgetc (the_file);
962
    }
963
  if (rv == '\n')
964
    saw_newline = 1;
965
  return rv;
966
}
967
 
968
static int
969
def_ungetc (int c)
970
{
971
  if (lex_parse_string)
972
    {
973
      lex_parse_string--;
974
      return c;
975
    }
976
  else
977
    return ungetc (c, the_file);
978
}
979
 
980
static int
981
def_lex (void)
982
{
983
  int c, i, q;
984
 
985
  if (lex_forced_token)
986
    {
987
      i = lex_forced_token;
988
      lex_forced_token = 0;
989
#if TRACE
990
      printf ("lex: forcing token %d\n", i);
991
#endif
992
      return i;
993
    }
994
 
995
  c = def_getc ();
996
 
997
  /* Trim leading whitespace.  */
998
  while (c != EOF && (c == ' ' || c == '\t') && saw_newline)
999
    c = def_getc ();
1000
 
1001
  if (c == EOF)
1002
    {
1003
#if TRACE
1004
      printf ("lex: EOF\n");
1005
#endif
1006
      return 0;
1007
    }
1008
 
1009
  if (saw_newline && c == ';')
1010
    {
1011
      do
1012
        {
1013
          c = def_getc ();
1014
        }
1015
      while (c != EOF && c != '\n');
1016
      if (c == '\n')
1017
        return def_lex ();
1018
      return 0;
1019
    }
1020
 
1021
  /* Must be something else.  */
1022
  saw_newline = 0;
1023
 
1024
  if (ISDIGIT (c))
1025
    {
1026
      bufptr = 0;
1027
      while (c != EOF && (ISXDIGIT (c) || (c == 'x')))
1028
        {
1029
          put_buf (c);
1030
          c = def_getc ();
1031
        }
1032
      if (c != EOF)
1033
        def_ungetc (c);
1034
      yylval.digits = xstrdup (buffer);
1035
#if TRACE
1036
      printf ("lex: `%s' returns DIGITS\n", buffer);
1037
#endif
1038
      return DIGITS;
1039
    }
1040
 
1041
  if (ISALPHA (c) || strchr ("$:-_?@", c))
1042
    {
1043
      bufptr = 0;
1044
      q = c;
1045
      put_buf (c);
1046
      c = def_getc ();
1047
 
1048
      if (q == '@')
1049
        {
1050
          if (ISBLANK (c) ) /* '@' followed by whitespace.  */
1051
            return (q);
1052
          else if (ISDIGIT (c)) /* '@' followed by digit.  */
1053
            {
1054
              def_ungetc (c);
1055
              return (q);
1056
            }
1057
#if TRACE
1058
          printf ("lex: @ returns itself\n");
1059
#endif
1060
        }
1061
 
1062
      while (c != EOF && (ISALNUM (c) || strchr ("$:-_?/@", c)))
1063
        {
1064
          put_buf (c);
1065
          c = def_getc ();
1066
        }
1067
      if (c != EOF)
1068
        def_ungetc (c);
1069
      if (ISALPHA (q)) /* Check for tokens.  */
1070
        {
1071
          for (i = 0; tokens[i].name; i++)
1072
            if (strcmp (tokens[i].name, buffer) == 0)
1073
              {
1074
#if TRACE
1075
                printf ("lex: `%s' is a string token\n", buffer);
1076
#endif
1077
                return tokens[i].token;
1078
              }
1079
        }
1080
#if TRACE
1081
      printf ("lex: `%s' returns ID\n", buffer);
1082
#endif
1083
      yylval.id = xstrdup (buffer);
1084
      return ID;
1085
    }
1086
 
1087
  if (c == '\'' || c == '"')
1088
    {
1089
      q = c;
1090
      c = def_getc ();
1091
      bufptr = 0;
1092
 
1093
      while (c != EOF && c != q)
1094
        {
1095
          put_buf (c);
1096
          c = def_getc ();
1097
        }
1098
      yylval.id = xstrdup (buffer);
1099
#if TRACE
1100
      printf ("lex: `%s' returns ID\n", buffer);
1101
#endif
1102
      return ID;
1103
    }
1104
 
1105
  if (c == '=' || c == '.' || c == ',')
1106
    {
1107
#if TRACE
1108
      printf ("lex: `%c' returns itself\n", c);
1109
#endif
1110
      return c;
1111
    }
1112
 
1113
  if (c == '\n')
1114
    {
1115
      linenumber++;
1116
      saw_newline = 1;
1117
    }
1118
 
1119
  /*printf ("lex: 0x%02x ignored\n", c); */
1120
  return def_lex ();
1121
}

powered by: WebSVN 2.1.0

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