2001-02-13 H.J. Lu <hjl@gnu.org>
[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     case etree_provided:
597       if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
598         {
599           /* Assignment to dot can only be done during allocation */
600           if (tree->type.node_class != etree_assign)
601             einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
602           if (allocation_done == lang_allocating_phase_enum
603               || (allocation_done == lang_final_phase_enum
604                   && current_section == abs_output_section))
605             {
606               result = exp_fold_tree (tree->assign.src,
607                                       current_section,
608                                       lang_allocating_phase_enum, dot,
609                                       dotp);
610               if (! result.valid_p)
611                 einfo (_("%F%S invalid assignment to location counter\n"));
612               else
613                 {
614                   if (current_section == NULL)
615                     einfo (_("%F%S assignment to location counter invalid outside of SECTION\n"));
616                   else
617                     {
618                       bfd_vma nextdot;
619
620                       nextdot = (result.value
621                                  + current_section->bfd_section->vma);
622                       if (nextdot < dot
623                           && current_section != abs_output_section)
624                         {
625                           einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"),
626                                  dot, nextdot);
627                         }
628                       else
629                         *dotp = nextdot;
630                     }
631                 }
632             }
633         }
634       else
635         {
636           result = exp_fold_tree (tree->assign.src,
637                                   current_section, allocation_done,
638                                   dot, dotp);
639           if (result.valid_p)
640             {
641               boolean create;
642               struct bfd_link_hash_entry *h;
643
644               if (tree->type.node_class == etree_assign)
645                 create = true;
646               else
647                 create = false;
648               h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
649                                         create, false, false);
650               if (h == (struct bfd_link_hash_entry *) NULL)
651                 {
652                   if (tree->type.node_class == etree_assign)
653                     einfo (_("%P%F:%s: hash creation failed\n"),
654                            tree->assign.dst);
655                 }
656               else if (tree->type.node_class == etree_provide
657                        && h->type != bfd_link_hash_undefined
658                        && h->type != bfd_link_hash_common)
659                 {
660                   /* Do nothing.  The symbol was defined by some
661                      object.  */
662                 }
663               else
664                 {
665                   /* FIXME: Should we worry if the symbol is already
666                      defined?  */
667                   h->type = bfd_link_hash_defined;
668                   h->u.def.value = result.value;
669                   h->u.def.section = result.section->bfd_section;
670                   if (tree->type.node_class == etree_provide)
671                     tree->type.node_class = etree_provided;
672                 }
673             }
674         }
675       break;
676
677     case etree_name:
678       result = fold_name (tree, current_section, allocation_done, dot);
679       break;
680
681     default:
682       FAIL ();
683       break;
684     }
685
686   return result;
687 }
688
689 static etree_value_type
690 exp_fold_tree_no_dot (tree, current_section, allocation_done)
691      etree_type *tree;
692      lang_output_section_statement_type *current_section;
693      lang_phase_type allocation_done;
694 {
695   return exp_fold_tree (tree, current_section, allocation_done,
696                         (bfd_vma) 0, (bfd_vma *) NULL);
697 }
698
699 etree_type *
700 exp_binop (code, lhs, rhs)
701      int code;
702      etree_type *lhs;
703      etree_type *rhs;
704 {
705   etree_type value, *new;
706   etree_value_type r;
707
708   value.type.node_code = code;
709   value.binary.lhs = lhs;
710   value.binary.rhs = rhs;
711   value.type.node_class = etree_binary;
712   r = exp_fold_tree_no_dot (&value,
713                             abs_output_section,
714                             lang_first_phase_enum);
715   if (r.valid_p)
716     {
717       return exp_intop (r.value);
718     }
719   new = (etree_type *) stat_alloc (sizeof (new->binary));
720   memcpy ((char *) new, (char *) &value, sizeof (new->binary));
721   return new;
722 }
723
724 etree_type *
725 exp_trinop (code, cond, lhs, rhs)
726      int code;
727      etree_type *cond;
728      etree_type *lhs;
729      etree_type *rhs;
730 {
731   etree_type value, *new;
732   etree_value_type r;
733   value.type.node_code = code;
734   value.trinary.lhs = lhs;
735   value.trinary.cond = cond;
736   value.trinary.rhs = rhs;
737   value.type.node_class = etree_trinary;
738   r = exp_fold_tree_no_dot (&value,
739                             (lang_output_section_statement_type *) NULL,
740                             lang_first_phase_enum);
741   if (r.valid_p)
742     {
743       return exp_intop (r.value);
744     }
745   new = (etree_type *) stat_alloc (sizeof (new->trinary));
746   memcpy ((char *) new, (char *) &value, sizeof (new->trinary));
747   return new;
748 }
749
750 etree_type *
751 exp_unop (code, child)
752      int code;
753      etree_type *child;
754 {
755   etree_type value, *new;
756
757   etree_value_type r;
758   value.unary.type.node_code = code;
759   value.unary.child = child;
760   value.unary.type.node_class = etree_unary;
761   r = exp_fold_tree_no_dot (&value, abs_output_section,
762                             lang_first_phase_enum);
763   if (r.valid_p)
764     {
765       return exp_intop (r.value);
766     }
767   new = (etree_type *) stat_alloc (sizeof (new->unary));
768   memcpy ((char *) new, (char *) &value, sizeof (new->unary));
769   return new;
770 }
771
772 etree_type *
773 exp_nameop (code, name)
774      int code;
775      CONST char *name;
776 {
777   etree_type value, *new;
778   etree_value_type r;
779   value.name.type.node_code = code;
780   value.name.name = name;
781   value.name.type.node_class = etree_name;
782
783   r = exp_fold_tree_no_dot (&value,
784                             (lang_output_section_statement_type *) NULL,
785                             lang_first_phase_enum);
786   if (r.valid_p)
787     {
788       return exp_intop (r.value);
789     }
790   new = (etree_type *) stat_alloc (sizeof (new->name));
791   memcpy ((char *) new, (char *) &value, sizeof (new->name));
792   return new;
793
794 }
795
796 etree_type *
797 exp_assop (code, dst, src)
798      int code;
799      CONST char *dst;
800      etree_type *src;
801 {
802   etree_type value, *new;
803
804   value.assign.type.node_code = code;
805
806   value.assign.src = src;
807   value.assign.dst = dst;
808   value.assign.type.node_class = etree_assign;
809
810 #if 0
811   if (exp_fold_tree_no_dot (&value, &result))
812     {
813       return exp_intop (result);
814     }
815 #endif
816   new = (etree_type *) stat_alloc (sizeof (new->assign));
817   memcpy ((char *) new, (char *) &value, sizeof (new->assign));
818   return new;
819 }
820
821 /* Handle PROVIDE.  */
822
823 etree_type *
824 exp_provide (dst, src)
825      const char *dst;
826      etree_type *src;
827 {
828   etree_type *n;
829
830   n = (etree_type *) stat_alloc (sizeof (n->assign));
831   n->assign.type.node_code = '=';
832   n->assign.type.node_class = etree_provide;
833   n->assign.src = src;
834   n->assign.dst = dst;
835   return n;
836 }
837
838 /* Handle ASSERT.  */
839
840 etree_type *
841 exp_assert (exp, message)
842      etree_type *exp;
843      const char *message;
844 {
845   etree_type *n;
846
847   n = (etree_type *) stat_alloc (sizeof (n->assert_s));
848   n->assert_s.type.node_code = '!';
849   n->assert_s.type.node_class = etree_assert;
850   n->assert_s.child = exp;
851   n->assert_s.message = message;
852   return n;
853 }
854
855 void
856 exp_print_tree (tree)
857      etree_type *tree;
858 {
859   switch (tree->type.node_class)
860     {
861     case etree_value:
862       minfo ("0x%v", tree->value.value);
863       return;
864     case etree_rel:
865       if (tree->rel.section->owner != NULL)
866         minfo ("%B:", tree->rel.section->owner);
867       minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
868       return;
869     case etree_assign:
870 #if 0
871       if (tree->assign.dst->sdefs != (asymbol *) NULL)
872         {
873           fprintf (config.map_file, "%s (%x) ", tree->assign.dst->name,
874                    tree->assign.dst->sdefs->value);
875         }
876       else
877         {
878           fprintf (config.map_file, "%s (UNDEFINED)", tree->assign.dst->name);
879         }
880 #endif
881       fprintf (config.map_file, "%s", tree->assign.dst);
882       exp_print_token (tree->type.node_code);
883       exp_print_tree (tree->assign.src);
884       break;
885     case etree_provide:
886     case etree_provided:
887       fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
888       exp_print_tree (tree->assign.src);
889       fprintf (config.map_file, ")");
890       break;
891     case etree_binary:
892       fprintf (config.map_file, "(");
893       exp_print_tree (tree->binary.lhs);
894       exp_print_token (tree->type.node_code);
895       exp_print_tree (tree->binary.rhs);
896       fprintf (config.map_file, ")");
897       break;
898     case etree_trinary:
899       exp_print_tree (tree->trinary.cond);
900       fprintf (config.map_file, "?");
901       exp_print_tree (tree->trinary.lhs);
902       fprintf (config.map_file, ":");
903       exp_print_tree (tree->trinary.rhs);
904       break;
905     case etree_unary:
906       exp_print_token (tree->unary.type.node_code);
907       if (tree->unary.child)
908         {
909           fprintf (config.map_file, "(");
910           exp_print_tree (tree->unary.child);
911           fprintf (config.map_file, ")");
912         }
913       break;
914
915     case etree_assert:
916       fprintf (config.map_file, "ASSERT (");
917       exp_print_tree (tree->assert_s.child);
918       fprintf (config.map_file, ", %s)", tree->assert_s.message);
919       break;
920
921     case etree_undef:
922       fprintf (config.map_file, "????????");
923       break;
924     case etree_name:
925       if (tree->type.node_code == NAME)
926         {
927           fprintf (config.map_file, "%s", tree->name.name);
928         }
929       else
930         {
931           exp_print_token (tree->type.node_code);
932           if (tree->name.name)
933             fprintf (config.map_file, "(%s)", tree->name.name);
934         }
935       break;
936     default:
937       FAIL ();
938       break;
939     }
940 }
941
942 bfd_vma
943 exp_get_vma (tree, def, name, allocation_done)
944      etree_type *tree;
945      bfd_vma def;
946      char *name;
947      lang_phase_type allocation_done;
948 {
949   etree_value_type r;
950
951   if (tree != NULL)
952     {
953       r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
954       if (! r.valid_p && name != NULL)
955         einfo (_("%F%S nonconstant expression for %s\n"), name);
956       return r.value;
957     }
958   else
959     return def;
960 }
961
962 int
963 exp_get_value_int (tree, def, name, allocation_done)
964      etree_type *tree;
965      int def;
966      char *name;
967      lang_phase_type allocation_done;
968 {
969   return (int) exp_get_vma (tree, (bfd_vma) def, name, allocation_done);
970 }
971
972 bfd_vma
973 exp_get_abs_int (tree, def, name, allocation_done)
974      etree_type *tree;
975      int def ATTRIBUTE_UNUSED;
976      char *name;
977      lang_phase_type allocation_done;
978 {
979   etree_value_type res;
980   res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
981
982   if (res.valid_p)
983     {
984       res.value += res.section->bfd_section->vma;
985     }
986   else
987     {
988       einfo (_("%F%S non constant expression for %s\n"), name);
989     }
990   return res.value;
991 }