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 287

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

powered by: WebSVN 2.1.0

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