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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.18.50/] [ld/] [ldexp.c] - Blame information for rev 231

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

Line No. Rev Author Line
1 38 julius
/* This module handles expression trees.
2
   Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3
   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4
   Free Software Foundation, Inc.
5
   Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
6
 
7
   This file is part of the GNU Binutils.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; if not, write to the Free Software
21
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22
   MA 02110-1301, USA.  */
23
 
24
 
25
/* This module is in charge of working out the contents of expressions.
26
 
27
   It has to keep track of the relative/absness of a symbol etc. This
28
   is done by keeping all values in a struct (an etree_value_type)
29
   which contains a value, a section to which it is relative and a
30
   valid bit.  */
31
 
32
#include "sysdep.h"
33
#include "bfd.h"
34
#include "bfdlink.h"
35
 
36
#include "ld.h"
37
#include "ldmain.h"
38
#include "ldmisc.h"
39
#include "ldexp.h"
40
#include "ldlex.h"
41
#include <ldgram.h>
42
#include "ldlang.h"
43
#include "libiberty.h"
44
#include "safe-ctype.h"
45
 
46
static void exp_fold_tree_1 (etree_type *);
47
static void exp_fold_tree_no_dot (etree_type *);
48
static bfd_vma align_n (bfd_vma, bfd_vma);
49
 
50
segment_type *segments;
51
 
52
struct ldexp_control expld;
53
 
54
/* Print the string representation of the given token.  Surround it
55
   with spaces if INFIX_P is TRUE.  */
56
 
57
static void
58
exp_print_token (token_code_type code, int infix_p)
59
{
60
  static const struct
61
  {
62
    token_code_type code;
63
    char * name;
64
  }
65
  table[] =
66
  {
67
    { INT, "int" },
68
    { NAME, "NAME" },
69
    { PLUSEQ, "+=" },
70
    { MINUSEQ, "-=" },
71
    { MULTEQ, "*=" },
72
    { DIVEQ, "/=" },
73
    { LSHIFTEQ, "<<=" },
74
    { RSHIFTEQ, ">>=" },
75
    { ANDEQ, "&=" },
76
    { OREQ, "|=" },
77
    { OROR, "||" },
78
    { ANDAND, "&&" },
79
    { EQ, "==" },
80
    { NE, "!=" },
81
    { LE, "<=" },
82
    { GE, ">=" },
83
    { LSHIFT, "<<" },
84
    { RSHIFT, ">>" },
85
    { ALIGN_K, "ALIGN" },
86
    { BLOCK, "BLOCK" },
87
    { QUAD, "QUAD" },
88
    { SQUAD, "SQUAD" },
89
    { LONG, "LONG" },
90
    { SHORT, "SHORT" },
91
    { BYTE, "BYTE" },
92
    { SECTIONS, "SECTIONS" },
93
    { SIZEOF_HEADERS, "SIZEOF_HEADERS" },
94
    { MEMORY, "MEMORY" },
95
    { DEFINED, "DEFINED" },
96
    { TARGET_K, "TARGET" },
97
    { SEARCH_DIR, "SEARCH_DIR" },
98
    { MAP, "MAP" },
99
    { ENTRY, "ENTRY" },
100
    { NEXT, "NEXT" },
101
    { ALIGNOF, "ALIGNOF" },
102
    { SIZEOF, "SIZEOF" },
103
    { ADDR, "ADDR" },
104
    { LOADADDR, "LOADADDR" },
105
    { CONSTANT, "CONSTANT" },
106
    { MAX_K, "MAX_K" },
107
    { REL, "relocatable" },
108
    { DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
109
    { DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
110
    { DATA_SEGMENT_END, "DATA_SEGMENT_END" },
111
    { ORIGIN, "ORIGIN" },
112
    { LENGTH, "LENGTH" },
113
    { SEGMENT_START, "SEGMENT_START" }
114
  };
115
  unsigned int idx;
116
 
117
  for (idx = 0; idx < ARRAY_SIZE (table); idx++)
118
    if (table[idx].code == code)
119
      break;
120
 
121
  if (infix_p)
122
    fputc (' ', config.map_file);
123
 
124
  if (idx < ARRAY_SIZE (table))
125
    fputs (table[idx].name, config.map_file);
126
  else if (code < 127)
127
    fputc (code, config.map_file);
128
  else
129
    fprintf (config.map_file, "<code %d>", code);
130
 
131
  if (infix_p)
132
    fputc (' ', config.map_file);
133
}
134
 
135
static void
136
make_abs (void)
137
{
138
  expld.result.value += expld.result.section->vma;
139
  expld.result.section = bfd_abs_section_ptr;
140
}
141
 
142
static void
143
new_abs (bfd_vma value)
144
{
145
  expld.result.valid_p = TRUE;
146
  expld.result.section = bfd_abs_section_ptr;
147
  expld.result.value = value;
148
  expld.result.str = NULL;
149
}
150
 
151
etree_type *
152
exp_intop (bfd_vma value)
153
{
154
  etree_type *new = stat_alloc (sizeof (new->value));
155
  new->type.node_code = INT;
156
  new->type.lineno = lineno;
157
  new->value.value = value;
158
  new->value.str = NULL;
159
  new->type.node_class = etree_value;
160
  return new;
161
}
162
 
163
etree_type *
164
exp_bigintop (bfd_vma value, char *str)
165
{
166
  etree_type *new = stat_alloc (sizeof (new->value));
167
  new->type.node_code = INT;
168
  new->type.lineno = lineno;
169
  new->value.value = value;
170
  new->value.str = str;
171
  new->type.node_class = etree_value;
172
  return new;
173
}
174
 
175
/* Build an expression representing an unnamed relocatable value.  */
176
 
177
etree_type *
178
exp_relop (asection *section, bfd_vma value)
179
{
180
  etree_type *new = stat_alloc (sizeof (new->rel));
181
  new->type.node_code = REL;
182
  new->type.lineno = lineno;
183
  new->type.node_class = etree_rel;
184
  new->rel.section = section;
185
  new->rel.value = value;
186
  return new;
187
}
188
 
189
static void
190
new_rel (bfd_vma value, char *str, asection *section)
191
{
192
  expld.result.valid_p = TRUE;
193
  expld.result.value = value;
194
  expld.result.str = str;
195
  expld.result.section = section;
196
}
197
 
198
static void
199
new_rel_from_abs (bfd_vma value)
200
{
201
  expld.result.valid_p = TRUE;
202
  expld.result.value = value - expld.section->vma;
203
  expld.result.str = NULL;
204
  expld.result.section = expld.section;
205
}
206
 
207
static void
208
fold_unary (etree_type *tree)
209
{
210
  exp_fold_tree_1 (tree->unary.child);
211
  if (expld.result.valid_p)
212
    {
213
      switch (tree->type.node_code)
214
        {
215
        case ALIGN_K:
216
          if (expld.phase != lang_first_phase_enum)
217
            new_rel_from_abs (align_n (expld.dot, expld.result.value));
218
          else
219
            expld.result.valid_p = FALSE;
220
          break;
221
 
222
        case ABSOLUTE:
223
          make_abs ();
224
          break;
225
 
226
        case '~':
227
          make_abs ();
228
          expld.result.value = ~expld.result.value;
229
          break;
230
 
231
        case '!':
232
          make_abs ();
233
          expld.result.value = !expld.result.value;
234
          break;
235
 
236
        case '-':
237
          make_abs ();
238
          expld.result.value = -expld.result.value;
239
          break;
240
 
241
        case NEXT:
242
          /* Return next place aligned to value.  */
243
          if (expld.phase != lang_first_phase_enum)
244
            {
245
              make_abs ();
246
              expld.result.value = align_n (expld.dot, expld.result.value);
247
            }
248
          else
249
            expld.result.valid_p = FALSE;
250
          break;
251
 
252
        case DATA_SEGMENT_END:
253
          if (expld.phase != lang_first_phase_enum
254
              && expld.section == bfd_abs_section_ptr
255
              && (expld.dataseg.phase == exp_dataseg_align_seen
256
                  || expld.dataseg.phase == exp_dataseg_relro_seen
257
                  || expld.dataseg.phase == exp_dataseg_adjust
258
                  || expld.dataseg.phase == exp_dataseg_relro_adjust
259
                  || expld.phase == lang_final_phase_enum))
260
            {
261
              if (expld.dataseg.phase == exp_dataseg_align_seen
262
                  || expld.dataseg.phase == exp_dataseg_relro_seen)
263
                {
264
                  expld.dataseg.phase = exp_dataseg_end_seen;
265
                  expld.dataseg.end = expld.result.value;
266
                }
267
            }
268
          else
269
            expld.result.valid_p = FALSE;
270
          break;
271
 
272
        default:
273
          FAIL ();
274
          break;
275
        }
276
    }
277
}
278
 
279
static void
280
fold_binary (etree_type *tree)
281
{
282
  exp_fold_tree_1 (tree->binary.lhs);
283
 
284
  /* The SEGMENT_START operator is special because its first
285
     operand is a string, not the name of a symbol.  */
286
  if (expld.result.valid_p && tree->type.node_code == SEGMENT_START)
287
    {
288
      const char *segment_name;
289
      segment_type *seg;
290
      /* Check to see if the user has overridden the default
291
         value.  */
292
      segment_name = tree->binary.rhs->name.name;
293
      for (seg = segments; seg; seg = seg->next)
294
        if (strcmp (seg->name, segment_name) == 0)
295
          {
296
            seg->used = TRUE;
297
            expld.result.value = seg->value;
298
            expld.result.str = NULL;
299
            expld.result.section = NULL;
300
            break;
301
          }
302
    }
303
  else if (expld.result.valid_p)
304
    {
305
      etree_value_type lhs = expld.result;
306
 
307
      exp_fold_tree_1 (tree->binary.rhs);
308
      if (expld.result.valid_p)
309
        {
310
          /* If the values are from different sections, or this is an
311
             absolute expression, make both the source arguments
312
             absolute.  However, adding or subtracting an absolute
313
             value from a relative value is meaningful, and is an
314
             exception.  */
315
          if (expld.section != bfd_abs_section_ptr
316
              && lhs.section == bfd_abs_section_ptr
317
              && tree->type.node_code == '+')
318
            {
319
              /* Keep the section of the rhs term.  */
320
              expld.result.value = lhs.value + expld.result.value;
321
              return;
322
            }
323
          else if (expld.section != bfd_abs_section_ptr
324
              && expld.result.section == bfd_abs_section_ptr
325
              && (tree->type.node_code == '+'
326
                  || tree->type.node_code == '-'))
327
            {
328
              /* Keep the section of the lhs term.  */
329
              expld.result.section = lhs.section;
330
            }
331
          else if (expld.result.section != lhs.section
332
                   || expld.section == bfd_abs_section_ptr)
333
            {
334
              make_abs ();
335
              lhs.value += lhs.section->vma;
336
            }
337
 
338
          switch (tree->type.node_code)
339
            {
340
            case '%':
341
              if (expld.result.value != 0)
342
                expld.result.value = ((bfd_signed_vma) lhs.value
343
                                      % (bfd_signed_vma) expld.result.value);
344
              else if (expld.phase != lang_mark_phase_enum)
345
                einfo (_("%F%S %% by zero\n"));
346
              break;
347
 
348
            case '/':
349
              if (expld.result.value != 0)
350
                expld.result.value = ((bfd_signed_vma) lhs.value
351
                                      / (bfd_signed_vma) expld.result.value);
352
              else if (expld.phase != lang_mark_phase_enum)
353
                einfo (_("%F%S / by zero\n"));
354
              break;
355
 
356
#define BOP(x, y) \
357
            case x:                                                     \
358
              expld.result.value = lhs.value y expld.result.value;      \
359
              break;
360
 
361
              BOP ('+', +);
362
              BOP ('*', *);
363
              BOP ('-', -);
364
              BOP (LSHIFT, <<);
365
              BOP (RSHIFT, >>);
366
              BOP (EQ, ==);
367
              BOP (NE, !=);
368
              BOP ('<', <);
369
              BOP ('>', >);
370
              BOP (LE, <=);
371
              BOP (GE, >=);
372
              BOP ('&', &);
373
              BOP ('^', ^);
374
              BOP ('|', |);
375
              BOP (ANDAND, &&);
376
              BOP (OROR, ||);
377
 
378
            case MAX_K:
379
              if (lhs.value > expld.result.value)
380
                expld.result.value = lhs.value;
381
              break;
382
 
383
            case MIN_K:
384
              if (lhs.value < expld.result.value)
385
                expld.result.value = lhs.value;
386
              break;
387
 
388
            case ALIGN_K:
389
              expld.result.value = align_n (lhs.value, expld.result.value);
390
              break;
391
 
392
            case DATA_SEGMENT_ALIGN:
393
              expld.dataseg.relro = exp_dataseg_relro_start;
394
              if (expld.phase != lang_first_phase_enum
395
                  && expld.section == bfd_abs_section_ptr
396
                  && (expld.dataseg.phase == exp_dataseg_none
397
                      || expld.dataseg.phase == exp_dataseg_adjust
398
                      || expld.dataseg.phase == exp_dataseg_relro_adjust
399
                      || expld.phase == lang_final_phase_enum))
400
                {
401
                  bfd_vma maxpage = lhs.value;
402
                  bfd_vma commonpage = expld.result.value;
403
 
404
                  expld.result.value = align_n (expld.dot, maxpage);
405
                  if (expld.dataseg.phase == exp_dataseg_relro_adjust)
406
                    expld.result.value = expld.dataseg.base;
407
                  else if (expld.dataseg.phase != exp_dataseg_adjust)
408
                    {
409
                      expld.result.value += expld.dot & (maxpage - 1);
410
                      if (expld.phase == lang_allocating_phase_enum)
411
                        {
412
                          expld.dataseg.phase = exp_dataseg_align_seen;
413
                          expld.dataseg.min_base = align_n (expld.dot, maxpage);
414
                          expld.dataseg.base = expld.result.value;
415
                          expld.dataseg.pagesize = commonpage;
416
                          expld.dataseg.maxpagesize = maxpage;
417
                          expld.dataseg.relro_end = 0;
418
                        }
419
                    }
420
                  else if (commonpage < maxpage)
421
                    expld.result.value += ((expld.dot + commonpage - 1)
422
                                           & (maxpage - commonpage));
423
                }
424
              else
425
                expld.result.valid_p = FALSE;
426
              break;
427
 
428
            case DATA_SEGMENT_RELRO_END:
429
              expld.dataseg.relro = exp_dataseg_relro_end;
430
              if (expld.phase != lang_first_phase_enum
431
                  && (expld.dataseg.phase == exp_dataseg_align_seen
432
                      || expld.dataseg.phase == exp_dataseg_adjust
433
                      || expld.dataseg.phase == exp_dataseg_relro_adjust
434
                      || expld.phase == lang_final_phase_enum))
435
                {
436
                  if (expld.dataseg.phase == exp_dataseg_align_seen
437
                      || expld.dataseg.phase == exp_dataseg_relro_adjust)
438
                    expld.dataseg.relro_end = lhs.value + expld.result.value;
439
 
440
                  if (expld.dataseg.phase == exp_dataseg_relro_adjust
441
                      && (expld.dataseg.relro_end
442
                          & (expld.dataseg.pagesize - 1)))
443
                    {
444
                      expld.dataseg.relro_end += expld.dataseg.pagesize - 1;
445
                      expld.dataseg.relro_end &= ~(expld.dataseg.pagesize - 1);
446
                      expld.result.value = (expld.dataseg.relro_end
447
                                            - expld.result.value);
448
                    }
449
                  else
450
                    expld.result.value = lhs.value;
451
 
452
                  if (expld.dataseg.phase == exp_dataseg_align_seen)
453
                    expld.dataseg.phase = exp_dataseg_relro_seen;
454
                }
455
              else
456
                expld.result.valid_p = FALSE;
457
              break;
458
 
459
            default:
460
              FAIL ();
461
            }
462
        }
463
      else
464
        expld.result.valid_p = FALSE;
465
    }
466
}
467
 
468
static void
469
fold_trinary (etree_type *tree)
470
{
471
  exp_fold_tree_1 (tree->trinary.cond);
472
  if (expld.result.valid_p)
473
    exp_fold_tree_1 (expld.result.value
474
                     ? tree->trinary.lhs
475
                     : tree->trinary.rhs);
476
}
477
 
478
static void
479
fold_name (etree_type *tree)
480
{
481
  memset (&expld.result, 0, sizeof (expld.result));
482
 
483
  switch (tree->type.node_code)
484
    {
485
    case SIZEOF_HEADERS:
486
      if (expld.phase != lang_first_phase_enum)
487
        {
488
          bfd_vma hdr_size = 0;
489
          /* Don't find the real header size if only marking sections;
490
             The bfd function may cache incorrect data.  */
491
          if (expld.phase != lang_mark_phase_enum)
492
            hdr_size = bfd_sizeof_headers (link_info.output_bfd, &link_info);
493
          new_abs (hdr_size);
494
        }
495
      break;
496
 
497
    case DEFINED:
498
      if (expld.phase == lang_first_phase_enum)
499
        lang_track_definedness (tree->name.name);
500
      else
501
        {
502
          struct bfd_link_hash_entry *h;
503
          int def_iteration
504
            = lang_symbol_definition_iteration (tree->name.name);
505
 
506
          h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
507
                                            &link_info,
508
                                            tree->name.name,
509
                                            FALSE, FALSE, TRUE);
510
          expld.result.value = (h != NULL
511
                                && (h->type == bfd_link_hash_defined
512
                                    || h->type == bfd_link_hash_defweak
513
                                    || h->type == bfd_link_hash_common)
514
                                && (def_iteration == lang_statement_iteration
515
                                    || def_iteration == -1));
516
          expld.result.section = bfd_abs_section_ptr;
517
          expld.result.valid_p = TRUE;
518
        }
519
      break;
520
 
521
    case NAME:
522
      if (expld.phase == lang_first_phase_enum)
523
        ;
524
      else if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
525
        new_rel_from_abs (expld.dot);
526
      else
527
        {
528
          struct bfd_link_hash_entry *h;
529
 
530
          h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
531
                                            &link_info,
532
                                            tree->name.name,
533
                                            TRUE, FALSE, TRUE);
534
          if (!h)
535
            einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n"));
536
          else if (h->type == bfd_link_hash_defined
537
                   || h->type == bfd_link_hash_defweak)
538
            {
539
              if (bfd_is_abs_section (h->u.def.section))
540
                new_abs (h->u.def.value);
541
              else
542
                {
543
                  asection *output_section;
544
 
545
                  output_section = h->u.def.section->output_section;
546
                  if (output_section == NULL)
547
                    {
548
                      if (expld.phase != lang_mark_phase_enum)
549
                        einfo (_("%X%S: unresolvable symbol `%s'"
550
                                 " referenced in expression\n"),
551
                               tree->name.name);
552
                    }
553
                  else
554
                    new_rel (h->u.def.value + h->u.def.section->output_offset,
555
                             NULL, output_section);
556
                }
557
            }
558
          else if (expld.phase == lang_final_phase_enum
559
                   || expld.assigning_to_dot)
560
            einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
561
                   tree->name.name);
562
          else if (h->type == bfd_link_hash_new)
563
            {
564
              h->type = bfd_link_hash_undefined;
565
              h->u.undef.abfd = NULL;
566
              if (h->u.undef.next == NULL && h != link_info.hash->undefs_tail)
567
                bfd_link_add_undef (link_info.hash, h);
568
            }
569
        }
570
      break;
571
 
572
    case ADDR:
573
      if (expld.phase != lang_first_phase_enum)
574
        {
575
          lang_output_section_statement_type *os;
576
 
577
          os = lang_output_section_find (tree->name.name);
578
          if (os == NULL)
579
            {
580
              if (expld.phase == lang_final_phase_enum)
581
                einfo (_("%F%S: undefined section `%s' referenced in expression\n"),
582
                       tree->name.name);
583
            }
584
          else if (os->processed_vma)
585
            new_rel (0, NULL, os->bfd_section);
586
        }
587
      break;
588
 
589
    case LOADADDR:
590
      if (expld.phase != lang_first_phase_enum)
591
        {
592
          lang_output_section_statement_type *os;
593
 
594
          os = lang_output_section_find (tree->name.name);
595
          if (os == NULL)
596
            {
597
              if (expld.phase == lang_final_phase_enum)
598
                einfo (_("%F%S: undefined section `%s' referenced in expression\n"),
599
                       tree->name.name);
600
            }
601
          else if (os->processed_lma)
602
            {
603
              if (os->load_base == NULL)
604
                new_abs (os->bfd_section->lma);
605
              else
606
                {
607
                  exp_fold_tree_1 (os->load_base);
608
                  if (expld.result.valid_p)
609
                    make_abs ();
610
                }
611
            }
612
        }
613
      break;
614
 
615
    case SIZEOF:
616
    case ALIGNOF:
617
      if (expld.phase != lang_first_phase_enum)
618
        {
619
          lang_output_section_statement_type *os;
620
 
621
          os = lang_output_section_find (tree->name.name);
622
          if (os == NULL)
623
            {
624
              if (expld.phase == lang_final_phase_enum)
625
                einfo (_("%F%S: undefined section `%s' referenced in expression\n"),
626
                       tree->name.name);
627
              new_abs (0);
628
            }
629
          else if (os->processed_vma)
630
            {
631
              bfd_vma val;
632
 
633
              if (tree->type.node_code == SIZEOF)
634
                val = (os->bfd_section->size
635
                       / bfd_octets_per_byte (link_info.output_bfd));
636
              else
637
                val = (bfd_vma)1 << os->bfd_section->alignment_power;
638
 
639
              new_abs (val);
640
            }
641
        }
642
      break;
643
 
644
    case LENGTH:
645
      {
646
        lang_memory_region_type *mem;
647
 
648
        mem = lang_memory_region_lookup (tree->name.name, FALSE);
649
        if (mem != NULL)
650
          new_abs (mem->length);
651
        else
652
          einfo (_("%F%S: undefined MEMORY region `%s'"
653
                   " referenced in expression\n"), tree->name.name);
654
      }
655
      break;
656
 
657
    case ORIGIN:
658
      {
659
        lang_memory_region_type *mem;
660
 
661
        mem = lang_memory_region_lookup (tree->name.name, FALSE);
662
        if (mem != NULL)
663
          new_abs (mem->origin);
664
        else
665
          einfo (_("%F%S: undefined MEMORY region `%s'"
666
                   " referenced in expression\n"), tree->name.name);
667
      }
668
      break;
669
 
670
    case CONSTANT:
671
      if (strcmp (tree->name.name, "MAXPAGESIZE") == 0)
672
        new_abs (bfd_emul_get_maxpagesize (default_target));
673
      else if (strcmp (tree->name.name, "COMMONPAGESIZE") == 0)
674
        new_abs (bfd_emul_get_commonpagesize (default_target));
675
      else
676
        einfo (_("%F%S: unknown constant `%s' referenced in expression\n"),
677
               tree->name.name);
678
      break;
679
 
680
    default:
681
      FAIL ();
682
      break;
683
    }
684
}
685
 
686
static void
687
exp_fold_tree_1 (etree_type *tree)
688
{
689
  if (tree == NULL)
690
    {
691
      memset (&expld.result, 0, sizeof (expld.result));
692
      return;
693
    }
694
 
695
  switch (tree->type.node_class)
696
    {
697
    case etree_value:
698
      new_rel (tree->value.value, tree->value.str, expld.section);
699
      break;
700
 
701
    case etree_rel:
702
      if (expld.phase != lang_first_phase_enum)
703
        {
704
          asection *output_section = tree->rel.section->output_section;
705
          new_rel (tree->rel.value + tree->rel.section->output_offset,
706
                   NULL, output_section);
707
        }
708
      else
709
        memset (&expld.result, 0, sizeof (expld.result));
710
      break;
711
 
712
    case etree_assert:
713
      exp_fold_tree_1 (tree->assert_s.child);
714
      if (expld.phase == lang_final_phase_enum && !expld.result.value)
715
        einfo ("%X%P: %s\n", tree->assert_s.message);
716
      break;
717
 
718
    case etree_unary:
719
      fold_unary (tree);
720
      break;
721
 
722
    case etree_binary:
723
      fold_binary (tree);
724
      break;
725
 
726
    case etree_trinary:
727
      fold_trinary (tree);
728
      break;
729
 
730
    case etree_assign:
731
    case etree_provide:
732
    case etree_provided:
733
      if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
734
        {
735
          /* Assignment to dot can only be done during allocation.  */
736
          if (tree->type.node_class != etree_assign)
737
            einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
738
          if (expld.phase == lang_mark_phase_enum
739
              || expld.phase == lang_allocating_phase_enum
740
              || (expld.phase == lang_final_phase_enum
741
                  && expld.section == bfd_abs_section_ptr))
742
            {
743
              /* Notify the folder that this is an assignment to dot.  */
744
              expld.assigning_to_dot = TRUE;
745
              exp_fold_tree_1 (tree->assign.src);
746
              expld.assigning_to_dot = FALSE;
747
 
748
              if (!expld.result.valid_p)
749
                {
750
                  if (expld.phase != lang_mark_phase_enum)
751
                    einfo (_("%F%S invalid assignment to location counter\n"));
752
                }
753
              else if (expld.dotp == NULL)
754
                einfo (_("%F%S assignment to location counter"
755
                         " invalid outside of SECTION\n"));
756
              else
757
                {
758
                  bfd_vma nextdot;
759
 
760
                  nextdot = expld.result.value + expld.section->vma;
761
                  if (nextdot < expld.dot
762
                      && expld.section != bfd_abs_section_ptr)
763
                    einfo (_("%F%S cannot move location counter backwards"
764
                             " (from %V to %V)\n"), expld.dot, nextdot);
765
                  else
766
                    {
767
                      expld.dot = nextdot;
768
                      *expld.dotp = nextdot;
769
                    }
770
                }
771
            }
772
          else
773
            memset (&expld.result, 0, sizeof (expld.result));
774
        }
775
      else
776
        {
777
          struct bfd_link_hash_entry *h = NULL;
778
 
779
          if (tree->type.node_class == etree_provide)
780
            {
781
              h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
782
                                        FALSE, FALSE, TRUE);
783
              if (h == NULL
784
                  || (h->type != bfd_link_hash_new
785
                      && h->type != bfd_link_hash_undefined
786
                      && h->type != bfd_link_hash_common))
787
                {
788
                  /* Do nothing.  The symbol was never referenced, or was
789
                     defined by some object.  */
790
                  break;
791
                }
792
            }
793
 
794
          exp_fold_tree_1 (tree->assign.src);
795
          if (expld.result.valid_p)
796
            {
797
              if (h == NULL)
798
                {
799
                  h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
800
                                            TRUE, FALSE, TRUE);
801
                  if (h == NULL)
802
                    einfo (_("%P%F:%s: hash creation failed\n"),
803
                           tree->assign.dst);
804
                }
805
 
806
              /* FIXME: Should we worry if the symbol is already
807
                 defined?  */
808
              lang_update_definedness (tree->assign.dst, h);
809
              h->type = bfd_link_hash_defined;
810
              h->u.def.value = expld.result.value;
811
              h->u.def.section = expld.result.section;
812
              if (tree->type.node_class == etree_provide)
813
                tree->type.node_class = etree_provided;
814
            }
815
        }
816
      break;
817
 
818
    case etree_name:
819
      fold_name (tree);
820
      break;
821
 
822
    default:
823
      FAIL ();
824
      memset (&expld.result, 0, sizeof (expld.result));
825
      break;
826
    }
827
}
828
 
829
void
830
exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp)
831
{
832
  expld.dot = *dotp;
833
  expld.dotp = dotp;
834
  expld.section = current_section;
835
  exp_fold_tree_1 (tree);
836
}
837
 
838
static void
839
exp_fold_tree_no_dot (etree_type *tree)
840
{
841
  expld.dot = 0;
842
  expld.dotp = NULL;
843
  expld.section = bfd_abs_section_ptr;
844
  exp_fold_tree_1 (tree);
845
}
846
 
847
etree_type *
848
exp_binop (int code, etree_type *lhs, etree_type *rhs)
849
{
850
  etree_type value, *new;
851
 
852
  value.type.node_code = code;
853
  value.type.lineno = lhs->type.lineno;
854
  value.binary.lhs = lhs;
855
  value.binary.rhs = rhs;
856
  value.type.node_class = etree_binary;
857
  exp_fold_tree_no_dot (&value);
858
  if (expld.result.valid_p)
859
    return exp_intop (expld.result.value);
860
 
861
  new = stat_alloc (sizeof (new->binary));
862
  memcpy (new, &value, sizeof (new->binary));
863
  return new;
864
}
865
 
866
etree_type *
867
exp_trinop (int code, etree_type *cond, etree_type *lhs, etree_type *rhs)
868
{
869
  etree_type value, *new;
870
 
871
  value.type.node_code = code;
872
  value.type.lineno = lhs->type.lineno;
873
  value.trinary.lhs = lhs;
874
  value.trinary.cond = cond;
875
  value.trinary.rhs = rhs;
876
  value.type.node_class = etree_trinary;
877
  exp_fold_tree_no_dot (&value);
878
  if (expld.result.valid_p)
879
    return exp_intop (expld.result.value);
880
 
881
  new = stat_alloc (sizeof (new->trinary));
882
  memcpy (new, &value, sizeof (new->trinary));
883
  return new;
884
}
885
 
886
etree_type *
887
exp_unop (int code, etree_type *child)
888
{
889
  etree_type value, *new;
890
 
891
  value.unary.type.node_code = code;
892
  value.unary.type.lineno = child->type.lineno;
893
  value.unary.child = child;
894
  value.unary.type.node_class = etree_unary;
895
  exp_fold_tree_no_dot (&value);
896
  if (expld.result.valid_p)
897
    return exp_intop (expld.result.value);
898
 
899
  new = stat_alloc (sizeof (new->unary));
900
  memcpy (new, &value, sizeof (new->unary));
901
  return new;
902
}
903
 
904
etree_type *
905
exp_nameop (int code, const char *name)
906
{
907
  etree_type value, *new;
908
 
909
  value.name.type.node_code = code;
910
  value.name.type.lineno = lineno;
911
  value.name.name = name;
912
  value.name.type.node_class = etree_name;
913
 
914
  exp_fold_tree_no_dot (&value);
915
  if (expld.result.valid_p)
916
    return exp_intop (expld.result.value);
917
 
918
  new = stat_alloc (sizeof (new->name));
919
  memcpy (new, &value, sizeof (new->name));
920
  return new;
921
 
922
}
923
 
924
etree_type *
925
exp_assop (int code, const char *dst, etree_type *src)
926
{
927
  etree_type *new;
928
 
929
  new = stat_alloc (sizeof (new->assign));
930
  new->type.node_code = code;
931
  new->type.lineno = src->type.lineno;
932
  new->type.node_class = etree_assign;
933
  new->assign.src = src;
934
  new->assign.dst = dst;
935
  return new;
936
}
937
 
938
/* Handle PROVIDE.  */
939
 
940
etree_type *
941
exp_provide (const char *dst, etree_type *src, bfd_boolean hidden)
942
{
943
  etree_type *n;
944
 
945
  n = stat_alloc (sizeof (n->assign));
946
  n->assign.type.node_code = '=';
947
  n->assign.type.lineno = src->type.lineno;
948
  n->assign.type.node_class = etree_provide;
949
  n->assign.src = src;
950
  n->assign.dst = dst;
951
  n->assign.hidden = hidden;
952
  return n;
953
}
954
 
955
/* Handle ASSERT.  */
956
 
957
etree_type *
958
exp_assert (etree_type *exp, const char *message)
959
{
960
  etree_type *n;
961
 
962
  n = stat_alloc (sizeof (n->assert_s));
963
  n->assert_s.type.node_code = '!';
964
  n->assert_s.type.lineno = exp->type.lineno;
965
  n->assert_s.type.node_class = etree_assert;
966
  n->assert_s.child = exp;
967
  n->assert_s.message = message;
968
  return n;
969
}
970
 
971
void
972
exp_print_tree (etree_type *tree)
973
{
974
  if (config.map_file == NULL)
975
    config.map_file = stderr;
976
 
977
  if (tree == NULL)
978
    {
979
      minfo ("NULL TREE\n");
980
      return;
981
    }
982
 
983
  switch (tree->type.node_class)
984
    {
985
    case etree_value:
986
      minfo ("0x%v", tree->value.value);
987
      return;
988
    case etree_rel:
989
      if (tree->rel.section->owner != NULL)
990
        minfo ("%B:", tree->rel.section->owner);
991
      minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
992
      return;
993
    case etree_assign:
994
      fprintf (config.map_file, "%s", tree->assign.dst);
995
      exp_print_token (tree->type.node_code, TRUE);
996
      exp_print_tree (tree->assign.src);
997
      break;
998
    case etree_provide:
999
    case etree_provided:
1000
      fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
1001
      exp_print_tree (tree->assign.src);
1002
      fprintf (config.map_file, ")");
1003
      break;
1004
    case etree_binary:
1005
      fprintf (config.map_file, "(");
1006
      exp_print_tree (tree->binary.lhs);
1007
      exp_print_token (tree->type.node_code, TRUE);
1008
      exp_print_tree (tree->binary.rhs);
1009
      fprintf (config.map_file, ")");
1010
      break;
1011
    case etree_trinary:
1012
      exp_print_tree (tree->trinary.cond);
1013
      fprintf (config.map_file, "?");
1014
      exp_print_tree (tree->trinary.lhs);
1015
      fprintf (config.map_file, ":");
1016
      exp_print_tree (tree->trinary.rhs);
1017
      break;
1018
    case etree_unary:
1019
      exp_print_token (tree->unary.type.node_code, FALSE);
1020
      if (tree->unary.child)
1021
        {
1022
          fprintf (config.map_file, " (");
1023
          exp_print_tree (tree->unary.child);
1024
          fprintf (config.map_file, ")");
1025
        }
1026
      break;
1027
 
1028
    case etree_assert:
1029
      fprintf (config.map_file, "ASSERT (");
1030
      exp_print_tree (tree->assert_s.child);
1031
      fprintf (config.map_file, ", %s)", tree->assert_s.message);
1032
      break;
1033
 
1034
    case etree_name:
1035
      if (tree->type.node_code == NAME)
1036
        {
1037
          fprintf (config.map_file, "%s", tree->name.name);
1038
        }
1039
      else
1040
        {
1041
          exp_print_token (tree->type.node_code, FALSE);
1042
          if (tree->name.name)
1043
            fprintf (config.map_file, " (%s)", tree->name.name);
1044
        }
1045
      break;
1046
    default:
1047
      FAIL ();
1048
      break;
1049
    }
1050
}
1051
 
1052
bfd_vma
1053
exp_get_vma (etree_type *tree, bfd_vma def, char *name)
1054
{
1055
  if (tree != NULL)
1056
    {
1057
      exp_fold_tree_no_dot (tree);
1058
      if (expld.result.valid_p)
1059
        return expld.result.value;
1060
      else if (name != NULL && expld.phase != lang_mark_phase_enum)
1061
        einfo (_("%F%S: nonconstant expression for %s\n"), name);
1062
    }
1063
  return def;
1064
}
1065
 
1066
int
1067
exp_get_value_int (etree_type *tree, int def, char *name)
1068
{
1069
  return exp_get_vma (tree, def, name);
1070
}
1071
 
1072
fill_type *
1073
exp_get_fill (etree_type *tree, fill_type *def, char *name)
1074
{
1075
  fill_type *fill;
1076
  size_t len;
1077
  unsigned int val;
1078
 
1079
  if (tree == NULL)
1080
    return def;
1081
 
1082
  exp_fold_tree_no_dot (tree);
1083
  if (!expld.result.valid_p)
1084
    {
1085
      if (name != NULL && expld.phase != lang_mark_phase_enum)
1086
        einfo (_("%F%S: nonconstant expression for %s\n"), name);
1087
      return def;
1088
    }
1089
 
1090
  if (expld.result.str != NULL && (len = strlen (expld.result.str)) != 0)
1091
    {
1092
      unsigned char *dst;
1093
      unsigned char *s;
1094
      fill = xmalloc ((len + 1) / 2 + sizeof (*fill) - 1);
1095
      fill->size = (len + 1) / 2;
1096
      dst = fill->data;
1097
      s = (unsigned char *) expld.result.str;
1098
      val = 0;
1099
      do
1100
        {
1101
          unsigned int digit;
1102
 
1103
          digit = *s++ - '0';
1104
          if (digit > 9)
1105
            digit = (digit - 'A' + '0' + 10) & 0xf;
1106
          val <<= 4;
1107
          val += digit;
1108
          --len;
1109
          if ((len & 1) == 0)
1110
            {
1111
              *dst++ = val;
1112
              val = 0;
1113
            }
1114
        }
1115
      while (len != 0);
1116
    }
1117
  else
1118
    {
1119
      fill = xmalloc (4 + sizeof (*fill) - 1);
1120
      val = expld.result.value;
1121
      fill->data[0] = (val >> 24) & 0xff;
1122
      fill->data[1] = (val >> 16) & 0xff;
1123
      fill->data[2] = (val >>  8) & 0xff;
1124
      fill->data[3] = (val >>  0) & 0xff;
1125
      fill->size = 4;
1126
    }
1127
  return fill;
1128
}
1129
 
1130
bfd_vma
1131
exp_get_abs_int (etree_type *tree, int def, char *name)
1132
{
1133
  if (tree != NULL)
1134
    {
1135
      exp_fold_tree_no_dot (tree);
1136
 
1137
      if (expld.result.valid_p)
1138
        {
1139
          expld.result.value += expld.result.section->vma;
1140
          return expld.result.value;
1141
        }
1142
      else if (name != NULL && expld.phase != lang_mark_phase_enum)
1143
        {
1144
          lineno = tree->type.lineno;
1145
          einfo (_("%F%S: nonconstant expression for %s\n"), name);
1146
        }
1147
    }
1148
  return def;
1149
}
1150
 
1151
static bfd_vma
1152
align_n (bfd_vma value, bfd_vma align)
1153
{
1154
  if (align <= 1)
1155
    return value;
1156
 
1157
  value = (value + align - 1) / align;
1158
  return value * align;
1159
}

powered by: WebSVN 2.1.0

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