OSDN Git Service

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