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