2000-10-09 Kazu Hirata <kazu@hxi.com>
[external/binutils.git] / ld / ldexp.c
1 /* This module handles expression trees.
2    Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
3    Free Software Foundation, Inc.
4    Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
5
6 This file is part of GLD, the Gnu Linker.
7
8 GLD 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 2, or (at your option)
11 any later version.
12
13 GLD 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 GLD; see the file COPYING.  If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA.  */
22
23 /* This module is in charge of working out the contents of expressions.
24
25    It has to keep track of the relative/absness of a symbol etc. This
26    is done by keeping all values in a struct (an etree_value_type)
27    which contains a value, a section to which it is relative and a
28    valid bit.  */
29
30 #include "bfd.h"
31 #include "sysdep.h"
32 #include "bfdlink.h"
33
34 #include "ld.h"
35 #include "ldmain.h"
36 #include "ldmisc.h"
37 #include "ldexp.h"
38 #include "ldgram.h"
39 #include "ldlang.h"
40
41 static void exp_print_token PARAMS ((token_code_type code));
42 static void make_abs PARAMS ((etree_value_type *ptr));
43 static etree_value_type new_abs PARAMS ((bfd_vma value));
44 static void check PARAMS ((lang_output_section_statement_type *os,
45                            const char *name, const char *op));
46 static etree_value_type new_rel
47   PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
48 static etree_value_type new_rel_from_section
49   PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
50 static etree_value_type fold_binary
51   PARAMS ((etree_type *tree,
52            lang_output_section_statement_type *current_section,
53            lang_phase_type allocation_done,
54            bfd_vma dot, bfd_vma *dotp));
55 static etree_value_type fold_name
56   PARAMS ((etree_type *tree,
57            lang_output_section_statement_type *current_section,
58            lang_phase_type allocation_done,
59            bfd_vma dot));
60 static etree_value_type exp_fold_tree_no_dot
61   PARAMS ((etree_type *tree,
62            lang_output_section_statement_type *current_section,
63            lang_phase_type allocation_done));
64
65 static void
66 exp_print_token (code)
67      token_code_type code;
68 {
69   static CONST struct {
70     token_code_type code;
71     char *name;
72   } table[] = {
73     { INT, "int" },
74     { REL, "relocateable" },
75     { NAME, "NAME" },
76     { PLUSEQ, "+=" },
77     { MINUSEQ, "-=" },
78     { MULTEQ, "*=" },
79     { DIVEQ, "/=" },
80     { LSHIFTEQ, "<<=" },
81     { RSHIFTEQ, ">>=" },
82     { ANDEQ, "&=" },
83     { OREQ, "|=" },
84     { OROR, "||" },
85     { ANDAND, "&&" },
86     { EQ, "==" },
87     { NE, "!=" },
88     { LE, "<=" },
89     { GE, ">=" },
90     { LSHIFT, "<<" },
91     { RSHIFT, ">>=" },
92     { ALIGN_K, "ALIGN" },
93     { BLOCK, "BLOCK" },
94     { SECTIONS, "SECTIONS" },
95     { SIZEOF_HEADERS, "SIZEOF_HEADERS" },
96     { NEXT, "NEXT" },
97     { SIZEOF, "SIZEOF" },
98     { ADDR, "ADDR" },
99     { LOADADDR, "LOADADDR" },
100     { MEMORY, "MEMORY" },
101     { DEFINED, "DEFINED" },
102     { TARGET_K, "TARGET" },
103     { SEARCH_DIR, "SEARCH_DIR" },
104     { MAP, "MAP" },
105     { QUAD, "QUAD" },
106     { SQUAD, "SQUAD" },
107     { LONG, "LONG" },
108     { SHORT, "SHORT" },
109     { BYTE, "BYTE" },
110     { ENTRY, "ENTRY" },
111     { 0, (char *) NULL }
112   };
113   unsigned int idx;
114
115   for (idx = 0; table[idx].name != (char *) NULL; idx++)
116     {
117       if (table[idx].code == code)
118         {
119           fprintf (config.map_file, "%s", table[idx].name);
120           return;
121         }
122     }
123   /* Not in table, just print it alone */
124   fprintf (config.map_file, "%c", code);
125 }
126
127 static void
128 make_abs (ptr)
129      etree_value_type *ptr;
130 {
131   asection *s = ptr->section->bfd_section;
132   ptr->value += s->vma;
133   ptr->section = abs_output_section;
134 }
135
136 static etree_value_type
137 new_abs (value)
138      bfd_vma value;
139 {
140   etree_value_type new;
141   new.valid_p = true;
142   new.section = abs_output_section;
143   new.value = value;
144   return new;
145 }
146
147 static void
148 check (os, name, op)
149      lang_output_section_statement_type *os;
150      const char *name;
151      const char *op;
152 {
153   if (os == NULL)
154     einfo (_("%F%P: %s uses undefined section %s\n"), op, name);
155   if (! os->processed)
156     einfo (_("%F%P: %s forward reference of section %s\n"), op, name);
157 }
158
159 etree_type *
160 exp_intop (value)
161      bfd_vma value;
162 {
163   etree_type *new = (etree_type *) stat_alloc (sizeof (new->value));
164   new->type.node_code = INT;
165   new->value.value = value;
166   new->type.node_class = etree_value;
167   return new;
168
169 }
170
171 /* Build an expression representing an unnamed relocateable value.  */
172
173 etree_type *
174 exp_relop (section, value)
175      asection *section;
176      bfd_vma value;
177 {
178   etree_type *new = (etree_type *) stat_alloc (sizeof (new->rel));
179   new->type.node_code = REL;
180   new->type.node_class = etree_rel;
181   new->rel.section = section;
182   new->rel.value = value;
183   return new;
184 }
185
186 static etree_value_type
187 new_rel (value, section)
188      bfd_vma value;
189      lang_output_section_statement_type *section;
190 {
191   etree_value_type new;
192   new.valid_p = true;
193   new.value = value;
194   new.section = section;
195   return new;
196 }
197
198 static etree_value_type
199 new_rel_from_section (value, section)
200      bfd_vma value;
201      lang_output_section_statement_type *section;
202 {
203   etree_value_type new;
204   new.valid_p = true;
205   new.value = value;
206   new.section = section;
207
208   new.value -= section->bfd_section->vma;
209
210   return new;
211 }
212
213 static etree_value_type
214 fold_binary (tree, current_section, allocation_done, dot, dotp)
215      etree_type *tree;
216      lang_output_section_statement_type *current_section;
217      lang_phase_type allocation_done;
218      bfd_vma dot;
219      bfd_vma *dotp;
220 {
221   etree_value_type result;
222
223   result = exp_fold_tree (tree->binary.lhs, current_section,
224                           allocation_done, dot, dotp);
225   if (result.valid_p)
226     {
227       etree_value_type other;
228
229       other = exp_fold_tree (tree->binary.rhs,
230                              current_section,
231                              allocation_done, dot, dotp);
232       if (other.valid_p)
233         {
234           /* If the values are from different sections, or this is an
235              absolute expression, make both the source arguments
236              absolute.  However, adding or subtracting an absolute
237              value from a relative value is meaningful, and is an
238              exception.  */
239           if (current_section != abs_output_section
240               && (other.section == abs_output_section
241                   || (result.section == abs_output_section
242                       && tree->type.node_code == '+'))
243               && (tree->type.node_code == '+'
244                   || tree->type.node_code == '-'))
245             {
246               etree_value_type hold;
247
248               /* If there is only one absolute term, make sure it is the
249                  second one.  */
250               if (other.section != abs_output_section)
251                 {
252                   hold = result;
253                   result = other;
254                   other = hold;
255                 }
256             }
257           else if (result.section != other.section
258                    || current_section == abs_output_section)
259             {
260               make_abs (&result);
261               make_abs (&other);
262             }
263
264           switch (tree->type.node_code)
265             {
266             case '%':
267               if (other.value == 0)
268                 einfo (_("%F%S %% by zero\n"));
269               result.value = ((bfd_signed_vma) result.value
270                               % (bfd_signed_vma) other.value);
271               break;
272
273             case '/':
274               if (other.value == 0)
275                 einfo (_("%F%S / by zero\n"));
276               result.value = ((bfd_signed_vma) result.value
277                               / (bfd_signed_vma) other.value);
278               break;
279
280 #define BOP(x,y) case x : result.value = result.value y other.value; break;
281               BOP ('+', +);
282               BOP ('*', *);
283               BOP ('-', -);
284               BOP (LSHIFT, <<);
285               BOP (RSHIFT, >>);
286               BOP (EQ, ==);
287               BOP (NE, !=);
288               BOP ('<', <);
289               BOP ('>', >);
290               BOP (LE, <=);
291               BOP (GE, >=);
292               BOP ('&', &);
293               BOP ('^', ^);
294               BOP ('|', |);
295               BOP (ANDAND, &&);
296               BOP (OROR, ||);
297
298             case MAX_K:
299               if (result.value < other.value)
300                 result = other;
301               break;
302
303             case MIN_K:
304               if (result.value > other.value)
305                 result = other;
306               break;
307
308             default:
309               FAIL ();
310             }
311         }
312       else
313         {
314           result.valid_p = false;
315         }
316     }
317
318   return result;
319 }
320
321 etree_value_type
322 invalid ()
323 {
324   etree_value_type new;
325   new.valid_p = false;
326   return new;
327 }
328
329 static etree_value_type
330 fold_name (tree, current_section, allocation_done, dot)
331      etree_type *tree;
332      lang_output_section_statement_type *current_section;
333      lang_phase_type allocation_done;
334      bfd_vma dot;
335 {
336   etree_value_type result;
337   switch (tree->type.node_code)
338     {
339     case SIZEOF_HEADERS:
340       if (allocation_done != lang_first_phase_enum)
341         {
342           result = new_abs ((bfd_vma)
343                             bfd_sizeof_headers (output_bfd,
344                                                 link_info.relocateable));
345         }
346       else
347         {
348           result.valid_p = false;
349         }
350       break;
351     case DEFINED:
352       if (allocation_done == lang_first_phase_enum)
353         result.valid_p = false;
354       else
355         {
356           struct bfd_link_hash_entry *h;
357
358           h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
359                                             tree->name.name,
360                                             false, false, true);
361           result.value = (h != (struct bfd_link_hash_entry *) NULL
362                           && (h->type == bfd_link_hash_defined
363                               || h->type == bfd_link_hash_defweak
364                               || h->type == bfd_link_hash_common));
365           result.section = 0;
366           result.valid_p = true;
367         }
368       break;
369     case NAME:
370       result.valid_p = false;
371       if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
372         {
373           if (allocation_done != lang_first_phase_enum)
374             result = new_rel_from_section (dot, current_section);
375           else
376             result = invalid ();
377         }
378       else if (allocation_done != lang_first_phase_enum)
379         {
380           struct bfd_link_hash_entry *h;
381
382           h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
383                                             tree->name.name,
384                                             false, false, true);
385           if (h != NULL
386               && (h->type == bfd_link_hash_defined
387                   || h->type == bfd_link_hash_defweak))
388             {
389               if (bfd_is_abs_section (h->u.def.section))
390                 result = new_abs (h->u.def.value);
391               else if (allocation_done == lang_final_phase_enum
392                        || allocation_done == lang_allocating_phase_enum)
393                 {
394                   asection *output_section;
395
396                   output_section = h->u.def.section->output_section;
397                   if (output_section == NULL)
398                     einfo (_("%X%S: unresolvable symbol `%s' referenced in expression\n"),
399                            tree->name.name);
400                   else
401                     {
402                       lang_output_section_statement_type *os;
403
404                       os = (lang_output_section_statement_lookup
405                             (bfd_get_section_name (output_bfd,
406                                                    output_section)));
407
408                       /* FIXME: Is this correct if this section is
409                          being linked with -R?  */
410                       result = new_rel ((h->u.def.value
411                                          + h->u.def.section->output_offset),
412                                         os);
413                     }
414                 }
415             }
416           else if (allocation_done == lang_final_phase_enum)
417             einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
418                    tree->name.name);
419         }
420       break;
421
422     case ADDR:
423       if (allocation_done != lang_first_phase_enum)
424         {
425           lang_output_section_statement_type *os;
426
427           os = lang_output_section_find (tree->name.name);
428           check (os, tree->name.name, "ADDR");
429           result = new_rel (0, os);
430         }
431       else
432         result = invalid ();
433       break;
434
435     case LOADADDR:
436       if (allocation_done != lang_first_phase_enum)
437         {
438           lang_output_section_statement_type *os;
439
440           os = lang_output_section_find (tree->name.name);
441           check (os, tree->name.name, "LOADADDR");
442           if (os->load_base == NULL)
443             result = new_rel (0, os);
444           else
445             result = exp_fold_tree_no_dot (os->load_base,
446                                            abs_output_section,
447                                            allocation_done);
448         }
449       else
450         result = invalid ();
451       break;
452
453     case SIZEOF:
454       if (allocation_done != lang_first_phase_enum)
455         {
456           int opb = bfd_octets_per_byte (output_bfd);
457           lang_output_section_statement_type *os;
458
459           os = lang_output_section_find (tree->name.name);
460           check (os, tree->name.name, "SIZEOF");
461           result = new_abs (os->bfd_section->_raw_size / opb);
462         }
463       else
464         result = invalid ();
465       break;
466
467     default:
468       FAIL ();
469       break;
470     }
471
472   return result;
473 }
474
475 etree_value_type
476 exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
477      etree_type *tree;
478      lang_output_section_statement_type *current_section;
479      lang_phase_type allocation_done;
480      bfd_vma dot;
481      bfd_vma *dotp;
482 {
483   etree_value_type result;
484
485   if (tree == NULL)
486     {
487       result.valid_p = false;
488       return result;
489     }
490
491   switch (tree->type.node_class)
492     {
493     case etree_value:
494       result = new_rel (tree->value.value, current_section);
495       break;
496
497     case etree_rel:
498       if (allocation_done != lang_final_phase_enum)
499         result.valid_p = false;
500       else
501         result = new_rel ((tree->rel.value
502                            + tree->rel.section->output_section->vma
503                            + tree->rel.section->output_offset),
504                           current_section);
505       break;
506
507     case etree_assert:
508       result = exp_fold_tree (tree->assert_s.child,
509                               current_section,
510                               allocation_done, dot, dotp);
511       if (result.valid_p)
512         {
513           if (! result.value)
514             einfo ("%F%P: %s\n", tree->assert_s.message);
515           return result;
516         }
517       break;
518
519     case etree_unary:
520       result = exp_fold_tree (tree->unary.child,
521                               current_section,
522                               allocation_done, dot, dotp);
523       if (result.valid_p)
524         {
525           switch (tree->type.node_code)
526             {
527             case ALIGN_K:
528               if (allocation_done != lang_first_phase_enum)
529                 result = new_rel_from_section (ALIGN_N (dot, result.value),
530                                                current_section);
531               else
532                 result.valid_p = false;
533               break;
534
535             case ABSOLUTE:
536               if (allocation_done != lang_first_phase_enum && result.valid_p)
537                 {
538                   result.value += result.section->bfd_section->vma;
539                   result.section = abs_output_section;
540                 }
541               else
542                 result.valid_p = false;
543               break;
544
545             case '~':
546               make_abs (&result);
547               result.value = ~result.value;
548               break;
549
550             case '!':
551               make_abs (&result);
552               result.value = !result.value;
553               break;
554
555             case '-':
556               make_abs (&result);
557               result.value = -result.value;
558               break;
559
560             case NEXT:
561               /* Return next place aligned to value.  */
562               if (allocation_done == lang_allocating_phase_enum)
563                 {
564                   make_abs (&result);
565                   result.value = ALIGN_N (dot, result.value);
566                 }
567               else
568                 result.valid_p = false;
569               break;
570
571             default:
572               FAIL ();
573               break;
574             }
575         }
576       break;
577
578     case etree_trinary:
579       result = exp_fold_tree (tree->trinary.cond, current_section,
580                               allocation_done, dot, dotp);
581       if (result.valid_p)
582         result = exp_fold_tree ((result.value
583                                  ? tree->trinary.lhs
584                                  : tree->trinary.rhs),
585                                 current_section,
586                                 allocation_done, dot, dotp);
587       break;
588
589     case etree_binary:
590       result = fold_binary (tree, current_section, allocation_done,
591                             dot, dotp);
592       break;
593
594     case etree_assign:
595     case etree_provide:
596       if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
597         {
598           /* Assignment to dot can only be done during allocation */
599           if (tree->type.node_class == etree_provide)
600             einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
601           if (allocation_done == lang_allocating_phase_enum
602               || (allocation_done == lang_final_phase_enum
603                   && current_section == abs_output_section))
604             {
605               result = exp_fold_tree (tree->assign.src,
606                                       current_section,
607                                       lang_allocating_phase_enum, dot,
608                                       dotp);
609               if (! result.valid_p)
610                 einfo (_("%F%S invalid assignment to location counter\n"));
611               else
612                 {
613                   if (current_section == NULL)
614                     einfo (_("%F%S assignment to location counter invalid outside of SECTION\n"));
615                   else
616                     {
617                       bfd_vma nextdot;
618
619                       nextdot = (result.value
620                                  + current_section->bfd_section->vma);
621                       if (nextdot < dot
622                           && current_section != abs_output_section)
623                         {
624                           einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"),
625                                  dot, nextdot);
626                         }
627                       else
628                         *dotp = nextdot;
629                     }
630                 }
631             }
632         }
633       else
634         {
635           result = exp_fold_tree (tree->assign.src,
636                                   current_section, allocation_done,
637                                   dot, dotp);
638           if (result.valid_p)
639             {
640               boolean create;
641               struct bfd_link_hash_entry *h;
642
643               if (tree->type.node_class == etree_assign)
644                 create = true;
645               else
646                 create = false;
647               h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
648                                         create, false, false);
649               if (h == (struct bfd_link_hash_entry *) NULL)
650                 {
651                   if (tree->type.node_class == etree_assign)
652                     einfo (_("%P%F:%s: hash creation failed\n"),
653                            tree->assign.dst);
654                 }
655               else if (tree->type.node_class == etree_provide
656                        && h->type != bfd_link_hash_undefined
657                        && h->type != bfd_link_hash_common)
658                 {
659                   /* Do nothing.  The symbol was defined by some
660                      object.  */
661                 }
662               else
663                 {
664                   /* FIXME: Should we worry if the symbol is already
665                      defined?  */
666                   h->type = bfd_link_hash_defined;
667                   h->u.def.value = result.value;
668                   h->u.def.section = result.section->bfd_section;
669                 }
670             }
671         }
672       break;
673
674     case etree_name:
675       result = fold_name (tree, current_section, allocation_done, dot);
676       break;
677
678     default:
679       FAIL ();
680       break;
681     }
682
683   return result;
684 }
685
686 static etree_value_type
687 exp_fold_tree_no_dot (tree, current_section, allocation_done)
688      etree_type *tree;
689      lang_output_section_statement_type *current_section;
690      lang_phase_type allocation_done;
691 {
692   return exp_fold_tree (tree, current_section, allocation_done,
693                         (bfd_vma) 0, (bfd_vma *) NULL);
694 }
695
696 etree_type *
697 exp_binop (code, lhs, rhs)
698      int code;
699      etree_type *lhs;
700      etree_type *rhs;
701 {
702   etree_type value, *new;
703   etree_value_type r;
704
705   value.type.node_code = code;
706   value.binary.lhs = lhs;
707   value.binary.rhs = rhs;
708   value.type.node_class = etree_binary;
709   r = exp_fold_tree_no_dot (&value,
710                             abs_output_section,
711                             lang_first_phase_enum);
712   if (r.valid_p)
713     {
714       return exp_intop (r.value);
715     }
716   new = (etree_type *) stat_alloc (sizeof (new->binary));
717   memcpy ((char *) new, (char *) &value, sizeof (new->binary));
718   return new;
719 }
720
721 etree_type *
722 exp_trinop (code, cond, lhs, rhs)
723      int code;
724      etree_type *cond;
725      etree_type *lhs;
726      etree_type *rhs;
727 {
728   etree_type value, *new;
729   etree_value_type r;
730   value.type.node_code = code;
731   value.trinary.lhs = lhs;
732   value.trinary.cond = cond;
733   value.trinary.rhs = rhs;
734   value.type.node_class = etree_trinary;
735   r = exp_fold_tree_no_dot (&value,
736                             (lang_output_section_statement_type *) NULL,
737                             lang_first_phase_enum);
738   if (r.valid_p)
739     {
740       return exp_intop (r.value);
741     }
742   new = (etree_type *) stat_alloc (sizeof (new->trinary));
743   memcpy ((char *) new, (char *) &value, sizeof (new->trinary));
744   return new;
745 }
746
747 etree_type *
748 exp_unop (code, child)
749      int code;
750      etree_type *child;
751 {
752   etree_type value, *new;
753
754   etree_value_type r;
755   value.unary.type.node_code = code;
756   value.unary.child = child;
757   value.unary.type.node_class = etree_unary;
758   r = exp_fold_tree_no_dot (&value, abs_output_section,
759                             lang_first_phase_enum);
760   if (r.valid_p)
761     {
762       return exp_intop (r.value);
763     }
764   new = (etree_type *) stat_alloc (sizeof (new->unary));
765   memcpy ((char *) new, (char *) &value, sizeof (new->unary));
766   return new;
767 }
768
769 etree_type *
770 exp_nameop (code, name)
771      int code;
772      CONST char *name;
773 {
774   etree_type value, *new;
775   etree_value_type r;
776   value.name.type.node_code = code;
777   value.name.name = name;
778   value.name.type.node_class = etree_name;
779
780   r = exp_fold_tree_no_dot (&value,
781                             (lang_output_section_statement_type *) NULL,
782                             lang_first_phase_enum);
783   if (r.valid_p)
784     {
785       return exp_intop (r.value);
786     }
787   new = (etree_type *) stat_alloc (sizeof (new->name));
788   memcpy ((char *) new, (char *) &value, sizeof (new->name));
789   return new;
790
791 }
792
793 etree_type *
794 exp_assop (code, dst, src)
795      int code;
796      CONST char *dst;
797      etree_type *src;
798 {
799   etree_type value, *new;
800
801   value.assign.type.node_code = code;
802
803   value.assign.src = src;
804   value.assign.dst = dst;
805   value.assign.type.node_class = etree_assign;
806
807 #if 0
808   if (exp_fold_tree_no_dot (&value, &result))
809     {
810       return exp_intop (result);
811     }
812 #endif
813   new = (etree_type *) stat_alloc (sizeof (new->assign));
814   memcpy ((char *) new, (char *) &value, sizeof (new->assign));
815   return new;
816 }
817
818 /* Handle PROVIDE.  */
819
820 etree_type *
821 exp_provide (dst, src)
822      const char *dst;
823      etree_type *src;
824 {
825   etree_type *n;
826
827   n = (etree_type *) stat_alloc (sizeof (n->assign));
828   n->assign.type.node_code = '=';
829   n->assign.type.node_class = etree_provide;
830   n->assign.src = src;
831   n->assign.dst = dst;
832   return n;
833 }
834
835 /* Handle ASSERT.  */
836
837 etree_type *
838 exp_assert (exp, message)
839      etree_type *exp;
840      const char *message;
841 {
842   etree_type *n;
843
844   n = (etree_type *) stat_alloc (sizeof (n->assert_s));
845   n->assert_s.type.node_code = '!';
846   n->assert_s.type.node_class = etree_assert;
847   n->assert_s.child = exp;
848   n->assert_s.message = message;
849   return n;
850 }
851
852 void
853 exp_print_tree (tree)
854      etree_type *tree;
855 {
856   switch (tree->type.node_class)
857     {
858     case etree_value:
859       minfo ("0x%v", tree->value.value);
860       return;
861     case etree_rel:
862       if (tree->rel.section->owner != NULL)
863         minfo ("%B:", tree->rel.section->owner);
864       minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
865       return;
866     case etree_assign:
867 #if 0
868       if (tree->assign.dst->sdefs != (asymbol *) NULL)
869         {
870           fprintf (config.map_file, "%s (%x) ", tree->assign.dst->name,
871                    tree->assign.dst->sdefs->value);
872         }
873       else
874         {
875           fprintf (config.map_file, "%s (UNDEFINED)", tree->assign.dst->name);
876         }
877 #endif
878       fprintf (config.map_file, "%s", tree->assign.dst);
879       exp_print_token (tree->type.node_code);
880       exp_print_tree (tree->assign.src);
881       break;
882     case etree_provide:
883       fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
884       exp_print_tree (tree->assign.src);
885       fprintf (config.map_file, ")");
886       break;
887     case etree_binary:
888       fprintf (config.map_file, "(");
889       exp_print_tree (tree->binary.lhs);
890       exp_print_token (tree->type.node_code);
891       exp_print_tree (tree->binary.rhs);
892       fprintf (config.map_file, ")");
893       break;
894     case etree_trinary:
895       exp_print_tree (tree->trinary.cond);
896       fprintf (config.map_file, "?");
897       exp_print_tree (tree->trinary.lhs);
898       fprintf (config.map_file, ":");
899       exp_print_tree (tree->trinary.rhs);
900       break;
901     case etree_unary:
902       exp_print_token (tree->unary.type.node_code);
903       if (tree->unary.child)
904         {
905           fprintf (config.map_file, "(");
906           exp_print_tree (tree->unary.child);
907           fprintf (config.map_file, ")");
908         }
909       break;
910
911     case etree_assert:
912       fprintf (config.map_file, "ASSERT (");
913       exp_print_tree (tree->assert_s.child);
914       fprintf (config.map_file, ", %s)", tree->assert_s.message);
915       break;
916
917     case etree_undef:
918       fprintf (config.map_file, "????????");
919       break;
920     case etree_name:
921       if (tree->type.node_code == NAME)
922         {
923           fprintf (config.map_file, "%s", tree->name.name);
924         }
925       else
926         {
927           exp_print_token (tree->type.node_code);
928           if (tree->name.name)
929             fprintf (config.map_file, "(%s)", tree->name.name);
930         }
931       break;
932     default:
933       FAIL ();
934       break;
935     }
936 }
937
938 bfd_vma
939 exp_get_vma (tree, def, name, allocation_done)
940      etree_type *tree;
941      bfd_vma def;
942      char *name;
943      lang_phase_type allocation_done;
944 {
945   etree_value_type r;
946
947   if (tree != NULL)
948     {
949       r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
950       if (! r.valid_p && name != NULL)
951         einfo (_("%F%S nonconstant expression for %s\n"), name);
952       return r.value;
953     }
954   else
955     return def;
956 }
957
958 int
959 exp_get_value_int (tree, def, name, allocation_done)
960      etree_type *tree;
961      int def;
962      char *name;
963      lang_phase_type allocation_done;
964 {
965   return (int) exp_get_vma (tree, (bfd_vma) def, name, allocation_done);
966 }
967
968 bfd_vma
969 exp_get_abs_int (tree, def, name, allocation_done)
970      etree_type *tree;
971      int def ATTRIBUTE_UNUSED;
972      char *name;
973      lang_phase_type allocation_done;
974 {
975   etree_value_type res;
976   res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
977
978   if (res.valid_p)
979     {
980       res.value += res.section->bfd_section->vma;
981     }
982   else
983     {
984       einfo (_("%F%S non constant expression for %s\n"), name);
985     }
986   return res.value;
987 }