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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [ld/] [ldexp.c] - Blame information for rev 17

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

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

powered by: WebSVN 2.1.0

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