home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / binutils-2.7-src.tgz / tar.out / fsf / binutils / ld / ldexp.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  22KB  |  909 lines

  1. /* This module handles expression trees.
  2. Copyright (C) 1991, 1993, 1994, 1995, 1996 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 == NULL)
  153.     einfo ("%F%P: %s uses undefined section %s\n", op, name);
  154.   if (! os->processed)
  155.     einfo ("%F%P: %s forward reference of section %s\n", op, name);
  156. }
  157.  
  158. etree_type *
  159. exp_intop (value)
  160.      bfd_vma value;
  161. {
  162.   etree_type *new = (etree_type *) stat_alloc(sizeof(new->value));
  163.   new->type.node_code = INT;
  164.   new->value.value = value;
  165.   new->type.node_class = etree_value;
  166.   return new;
  167.  
  168. }
  169.  
  170. /* Build an expression representing an unnamed relocateable value.  */
  171.  
  172. etree_type *
  173. exp_relop (section, value)
  174.      asection *section;
  175.      bfd_vma value;
  176. {
  177.   etree_type *new = (etree_type *) stat_alloc (sizeof (new->rel));
  178.   new->type.node_code = REL;
  179.   new->type.node_class = etree_rel;
  180.   new->rel.section = section;
  181.   new->rel.value = value;
  182.   return new;
  183. }
  184.  
  185. static etree_value_type
  186. new_rel (value, section)
  187.      bfd_vma value;
  188.      lang_output_section_statement_type *section;
  189. {
  190.   etree_value_type new;
  191.   new.valid = true;
  192.   new.value = value;
  193.   new.section = section;
  194.   return new;
  195. }
  196.  
  197. static etree_value_type
  198. new_rel_from_section (value, section)
  199.      bfd_vma value;
  200.      lang_output_section_statement_type *section;
  201. {
  202.   etree_value_type new;
  203.   new.valid = true;
  204.   new.value = value;
  205.   new.section = section;
  206.  
  207.     new.value -= section->bfd_section->vma;
  208.  
  209.   return new;
  210. }
  211.  
  212. static etree_value_type 
  213. fold_binary (tree, current_section, allocation_done, dot, dotp)
  214.      etree_type *tree;
  215.      lang_output_section_statement_type *current_section;
  216.      lang_phase_type allocation_done;
  217.      bfd_vma dot;
  218.      bfd_vma *dotp;
  219. {
  220.   etree_value_type result;
  221.  
  222.   result = exp_fold_tree (tree->binary.lhs, current_section,
  223.               allocation_done, dot, dotp);
  224.   if (result.valid)
  225.     {
  226.       etree_value_type other;
  227.  
  228.       other = exp_fold_tree (tree->binary.rhs,
  229.                  current_section,
  230.                  allocation_done, dot,dotp) ;
  231.       if (other.valid)
  232.     {
  233.       /* If the values are from different sections, or this is an
  234.          absolute expression, make both the source arguments
  235.          absolute.  However, adding or subtracting an absolute
  236.          value from a relative value is meaningful, and is an
  237.          exception.  */
  238.       if (current_section != abs_output_section
  239.           && (other.section == abs_output_section
  240.           || (result.section == abs_output_section
  241.               && tree->type.node_code == '+'))
  242.           && (tree->type.node_code == '+'
  243.           || tree->type.node_code == '-'))
  244.         {
  245.           etree_value_type hold;
  246.  
  247.           /* If there is only one absolute term, make sure it is the
  248.          second one.  */
  249.           if (other.section != abs_output_section)
  250.         {
  251.           hold = result;
  252.           result = other;
  253.           other = hold;
  254.         }
  255.         }
  256.       else if (result.section != other.section
  257.            || current_section == abs_output_section)
  258.         {
  259.           make_abs(&result);
  260.           make_abs(&other);
  261.         }
  262.  
  263.       switch (tree->type.node_code) 
  264.         {
  265.         case '%':
  266.           if (other.value == 0)
  267.         einfo ("%F%S %% by zero\n");
  268.           result.value = ((bfd_signed_vma) result.value
  269.                   % (bfd_signed_vma) other.value);
  270.           break;
  271.  
  272.         case '/':
  273.           if (other.value == 0)
  274.         einfo ("%F%S / by zero\n");
  275.           result.value = ((bfd_signed_vma) result.value
  276.                   / (bfd_signed_vma) other.value);
  277.           break;
  278.  
  279. #define BOP(x,y) case x : result.value = result.value y other.value; break;
  280.           BOP('+',+);
  281.           BOP('*',*);
  282.           BOP('-',-);
  283.           BOP(LSHIFT,<<);
  284.           BOP(RSHIFT,>>);
  285.           BOP(EQ,==);
  286.           BOP(NE,!=);
  287.           BOP('<',<);
  288.           BOP('>',>);
  289.           BOP(LE,<=);
  290.           BOP(GE,>=);
  291.           BOP('&',&);
  292.           BOP('^',^);
  293.           BOP('|',|);
  294.           BOP(ANDAND,&&);
  295.           BOP(OROR,||);
  296.  
  297.         default:
  298.           FAIL();
  299.         }
  300.     }
  301.       else
  302.     {
  303.       result.valid = false;
  304.     }
  305.     }
  306.  
  307.   return result;
  308. }
  309.  
  310. etree_value_type 
  311. invalid ()
  312. {
  313.   etree_value_type new;
  314.   new.valid = false;
  315.   return new;
  316. }
  317.  
  318. static etree_value_type 
  319. fold_name (tree, current_section, allocation_done, dot)
  320.      etree_type *tree;
  321.      lang_output_section_statement_type *current_section;
  322.      lang_phase_type  allocation_done;
  323.      bfd_vma dot;
  324. {
  325.   etree_value_type result;
  326.   switch (tree->type.node_code) 
  327.       {
  328.       case SIZEOF_HEADERS:
  329.     if (allocation_done != lang_first_phase_enum) 
  330.       {
  331.         result = new_abs ((bfd_vma)
  332.                   bfd_sizeof_headers (output_bfd,
  333.                           link_info.relocateable));
  334.       }
  335.     else
  336.       {
  337.         result.valid = false;
  338.       }
  339.     break;
  340.       case DEFINED:
  341.     if (allocation_done == lang_first_phase_enum)
  342.       result.valid = false;
  343.     else
  344.       {
  345.         struct bfd_link_hash_entry *h;
  346.  
  347.         h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
  348.                           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_defweak
  353.                 || h->type == bfd_link_hash_common));
  354.         result.section = 0;
  355.         result.valid = true;
  356.       }
  357.     break;
  358.       case NAME:
  359.     result.valid = false;
  360.     if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
  361.       {
  362.         if (allocation_done != lang_first_phase_enum)
  363.           result = new_rel_from_section(dot, current_section);
  364.         else
  365.           result = invalid();
  366.       }
  367.     else if (allocation_done != lang_first_phase_enum)
  368.       {
  369.         struct bfd_link_hash_entry *h;
  370.  
  371.         h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
  372.                           tree->name.name,
  373.                           false, false, true);
  374.         if (h != NULL
  375.         && (h->type == bfd_link_hash_defined
  376.             || h->type == bfd_link_hash_defweak))
  377.           {
  378.         if (bfd_is_abs_section (h->u.def.section))
  379.           result = new_abs (h->u.def.value);
  380.         else if (allocation_done == lang_final_phase_enum
  381.              || allocation_done == lang_allocating_phase_enum)
  382.           {
  383.             lang_output_section_statement_type *os;
  384.         
  385.             os = (lang_output_section_statement_lookup
  386.               (h->u.def.section->output_section->name));
  387.  
  388.             /* FIXME: Is this correct if this section is being
  389.                linked with -R?  */
  390.             result = new_rel ((h->u.def.value
  391.                        + h->u.def.section->output_offset),
  392.                       os);
  393.           }
  394.           }
  395.         else if (allocation_done == lang_final_phase_enum)
  396.           einfo ("%F%S: undefined symbol `%s' referenced in expression\n",
  397.              tree->name.name);
  398.       }
  399.     break;
  400.  
  401.       case ADDR:
  402.     if (allocation_done != lang_first_phase_enum)
  403.       {
  404.         lang_output_section_statement_type *os;
  405.  
  406.         os = lang_output_section_find (tree->name.name);
  407.         check (os, tree->name.name, "ADDR");
  408.         result = new_rel (0, os);
  409.       }
  410.     else
  411.       result = invalid ();
  412.     break;
  413.       case SIZEOF:
  414.     if (allocation_done != lang_first_phase_enum)
  415.       {
  416.         lang_output_section_statement_type *os;
  417.  
  418.         os = lang_output_section_find (tree->name.name);
  419.         check (os, tree->name.name, "SIZEOF");
  420.         result = new_abs (os->bfd_section->_raw_size);
  421.       }
  422.     else
  423.       result = invalid ();
  424.     break;
  425.  
  426.       default:
  427.     FAIL();
  428.     break;
  429.       }
  430.  
  431.   return result;
  432. }
  433. etree_value_type 
  434. exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
  435.      etree_type *tree;
  436.      lang_output_section_statement_type *current_section;
  437.      lang_phase_type  allocation_done;
  438.      bfd_vma dot;
  439.      bfd_vma *dotp;
  440. {
  441.   etree_value_type result;
  442.  
  443.   if (tree == NULL)
  444.     {
  445.       result.valid = false;
  446.       return result;
  447.     }
  448.  
  449.   switch (tree->type.node_class) 
  450.     {
  451.     case etree_value:
  452.       result = new_rel (tree->value.value, current_section);
  453.       break;
  454.  
  455.     case etree_rel:
  456.       if (allocation_done != lang_final_phase_enum)
  457.     result.valid = false;
  458.       else
  459.     result = new_rel ((tree->rel.value
  460.                + tree->rel.section->output_section->vma
  461.                + tree->rel.section->output_offset),
  462.               current_section);
  463.       break;
  464.  
  465.     case etree_unary:
  466.       result = exp_fold_tree (tree->unary.child,
  467.                   current_section,
  468.                   allocation_done, dot, dotp);
  469.       if (result.valid)
  470.     {
  471.       switch (tree->type.node_code) 
  472.         {
  473.         case ALIGN_K:
  474.           if (allocation_done != lang_first_phase_enum)
  475.         result = new_rel_from_section (ALIGN_N (dot, result.value),
  476.                            current_section);
  477.           else
  478.         result.valid = false;
  479.           break;
  480.  
  481.         case ABSOLUTE:
  482.           if (allocation_done != lang_first_phase_enum && result.valid)
  483.         {
  484.           result.value += result.section->bfd_section->vma;
  485.           result.section = abs_output_section;
  486.         }
  487.           else 
  488.         result.valid = false;
  489.           break;
  490.  
  491.         case '~':
  492.           make_abs (&result);
  493.           result.value = ~result.value;
  494.           break;
  495.  
  496.         case '!':
  497.           make_abs (&result);
  498.           result.value = !result.value;
  499.           break;
  500.  
  501.         case '-':
  502.           make_abs (&result);
  503.           result.value = -result.value;
  504.           break;
  505.  
  506.         case NEXT:
  507.           /* Return next place aligned to value.  */
  508.           if (allocation_done == lang_allocating_phase_enum)
  509.         {
  510.           make_abs (&result);
  511.           result.value = ALIGN_N (dot, result.value);
  512.         }
  513.           else
  514.         result.valid = false;
  515.           break;
  516.  
  517.         default:
  518.           FAIL ();
  519.           break;
  520.         }
  521.     }
  522.       break;
  523.  
  524.     case etree_trinary:
  525.       result = exp_fold_tree (tree->trinary.cond, current_section,
  526.                   allocation_done, dot, dotp);
  527.       if (result.valid)
  528.     result = exp_fold_tree ((result.value
  529.                  ? tree->trinary.lhs
  530.                  : tree->trinary.rhs),
  531.                 current_section,
  532.                 allocation_done, dot, dotp);
  533.       break;
  534.  
  535.     case etree_binary:
  536.       result = fold_binary (tree, current_section, allocation_done,
  537.                 dot, dotp);
  538.       break;
  539.  
  540.     case etree_assign:
  541.     case etree_provide:
  542.       if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
  543.     {
  544.       /* Assignment to dot can only be done during allocation */
  545.       if (tree->type.node_class == etree_provide)
  546.         einfo ("%F%S can not PROVIDE assignment to location counter\n");
  547.       if (allocation_done == lang_allocating_phase_enum
  548.           || (allocation_done == lang_final_phase_enum
  549.           && current_section == abs_output_section))
  550.         {
  551.           result = exp_fold_tree (tree->assign.src,
  552.                       current_section,
  553.                       lang_allocating_phase_enum, dot,
  554.                       dotp);
  555.           if (! result.valid)
  556.         einfo ("%F%S invalid assignment to location counter\n");
  557.           else
  558.         {
  559.           if (current_section == NULL)
  560.             einfo ("%F%S assignment to location counter invalid outside of SECTION\n");
  561.           else
  562.             {
  563.               bfd_vma nextdot;
  564.  
  565.               nextdot = (result.value
  566.                  + current_section->bfd_section->vma);
  567.               if (nextdot < dot
  568.               && current_section != abs_output_section)
  569.             {
  570.               einfo ("%F%S cannot move location counter backwards (from %V to %V)\n",
  571.                  dot, nextdot);
  572.             }
  573.               else
  574.             *dotp = nextdot; 
  575.             }
  576.         }
  577.         }
  578.     }
  579.       else
  580.     {
  581.       result = exp_fold_tree (tree->assign.src,
  582.                   current_section, allocation_done,
  583.                   dot, dotp);
  584.       if (result.valid)
  585.         {
  586.           boolean create;
  587.           struct bfd_link_hash_entry *h;
  588.  
  589.           if (tree->type.node_class == etree_assign)
  590.         create = true;
  591.           else
  592.         create = false;
  593.           h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
  594.                     create, false, false);
  595.           if (h == (struct bfd_link_hash_entry *) NULL)
  596.         {
  597.           if (tree->type.node_class == etree_assign)
  598.             einfo ("%P%F:%s: hash creation failed\n",
  599.                tree->assign.dst);
  600.         }
  601.           else if (tree->type.node_class == etree_provide
  602.                && h->type != bfd_link_hash_undefined
  603.                && h->type != bfd_link_hash_common)
  604.         {
  605.           /* Do nothing.  The symbol was defined by some
  606.              object.  */
  607.         }
  608.           else
  609.         {
  610.           /* FIXME: Should we worry if the symbol is already
  611.              defined?  */
  612.           h->type = bfd_link_hash_defined;
  613.           h->u.def.value = result.value;
  614.           h->u.def.section = result.section->bfd_section;
  615.         }
  616.         }
  617.     }
  618.       break;
  619.  
  620.     case etree_name:
  621.       result = fold_name (tree, current_section, allocation_done, dot);
  622.       break;
  623.  
  624.     default:
  625.       FAIL ();
  626.       break;
  627.     }
  628.  
  629.   return result;
  630. }
  631.  
  632. static etree_value_type 
  633. exp_fold_tree_no_dot (tree, current_section, allocation_done)
  634.      etree_type *tree;
  635.      lang_output_section_statement_type *current_section;
  636.      lang_phase_type allocation_done;
  637. {
  638. return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
  639.              0, (bfd_vma *)NULL);
  640. }
  641.  
  642. etree_type *
  643. exp_binop (code, lhs, rhs)
  644.      int code;
  645.      etree_type *lhs;
  646.      etree_type *rhs;
  647. {
  648.   etree_type value, *new;
  649.   etree_value_type r;
  650.  
  651.   value.type.node_code = code;
  652.   value.binary.lhs = lhs;
  653.   value.binary.rhs = rhs;
  654.   value.type.node_class = etree_binary;
  655.   r = exp_fold_tree_no_dot(&value,
  656.                abs_output_section,
  657.                lang_first_phase_enum );
  658.   if (r.valid)
  659.     {
  660.       return exp_intop(r.value);
  661.     }
  662.   new = (etree_type *) stat_alloc (sizeof (new->binary));
  663.   memcpy((char *)new, (char *)&value, sizeof(new->binary));
  664.   return new;
  665. }
  666.  
  667. etree_type *
  668. exp_trinop (code, cond, lhs, rhs)
  669.      int code;
  670.      etree_type *cond;
  671.      etree_type *lhs;
  672.      etree_type *rhs;
  673. {
  674.   etree_type value, *new;
  675.   etree_value_type r;
  676.   value.type.node_code = code;
  677.   value.trinary.lhs = lhs;
  678.   value.trinary.cond = cond;
  679.   value.trinary.rhs = rhs;
  680.   value.type.node_class = etree_trinary;
  681.   r= exp_fold_tree_no_dot(&value,  (lang_output_section_statement_type
  682.                     *)NULL,lang_first_phase_enum);
  683.   if (r.valid) {
  684.     return exp_intop(r.value);
  685.   }
  686.   new = (etree_type *) stat_alloc (sizeof (new->trinary));
  687.   memcpy((char *)new,(char *) &value, sizeof(new->trinary));
  688.   return new;
  689. }
  690.  
  691.  
  692. etree_type *
  693. exp_unop (code, child)
  694.      int code;
  695.      etree_type *child;
  696. {
  697.   etree_type value, *new;
  698.  
  699.   etree_value_type r;
  700.   value.unary.type.node_code = code;
  701.   value.unary.child = child;
  702.   value.unary.type.node_class = etree_unary;
  703.   r = exp_fold_tree_no_dot(&value,abs_output_section,
  704.                lang_first_phase_enum);
  705.   if (r.valid) {
  706.     return exp_intop(r.value);
  707.   }
  708.   new = (etree_type *) stat_alloc (sizeof (new->unary));
  709.   memcpy((char *)new, (char *)&value, sizeof(new->unary));
  710.   return new;
  711. }
  712.  
  713.  
  714. etree_type *
  715. exp_nameop (code, name)
  716.      int code;
  717.      CONST char *name;
  718. {
  719.   etree_type value, *new;
  720.   etree_value_type r;
  721.   value.name.type.node_code = code;
  722.   value.name.name = name;
  723.   value.name.type.node_class = etree_name;
  724.  
  725.  
  726.   r = exp_fold_tree_no_dot(&value,
  727.                (lang_output_section_statement_type *)NULL,
  728.                lang_first_phase_enum);
  729.   if (r.valid) {
  730.     return exp_intop(r.value);
  731.   }
  732.   new = (etree_type *) stat_alloc (sizeof (new->name));
  733.   memcpy((char *)new, (char *)&value, sizeof(new->name));
  734.   return new;
  735.  
  736. }
  737.  
  738.  
  739.  
  740.  
  741. etree_type *
  742. exp_assop (code, dst, src)
  743.      int code;
  744.      CONST char *dst;
  745.      etree_type *src;
  746. {
  747.   etree_type value, *new;
  748.  
  749.   value.assign.type.node_code = code;
  750.  
  751.  
  752.   value.assign.src = src;
  753.   value.assign.dst = dst;
  754.   value.assign.type.node_class = etree_assign;
  755.  
  756. #if 0
  757.   if (exp_fold_tree_no_dot(&value, &result)) {
  758.     return exp_intop(result);
  759.   }
  760. #endif
  761.   new = (etree_type*) stat_alloc (sizeof (new->assign));
  762.   memcpy((char *)new, (char *)&value, sizeof(new->assign));
  763.   return new;
  764. }
  765.  
  766. /* Handle PROVIDE.  */
  767.  
  768. etree_type *
  769. exp_provide (dst, src)
  770.      const char *dst;
  771.      etree_type *src;
  772. {
  773.   etree_type *n;
  774.  
  775.   n = (etree_type *) stat_alloc (sizeof (n->assign));
  776.   n->assign.type.node_code = '=';
  777.   n->assign.type.node_class = etree_provide;
  778.   n->assign.src = src;
  779.   n->assign.dst = dst;
  780.   return n;
  781. }
  782.  
  783. void 
  784. exp_print_tree (tree)
  785.      etree_type *tree;
  786. {
  787.   switch (tree->type.node_class) {
  788.   case etree_value:
  789.     minfo ("0x%v", tree->value.value);
  790.     return;
  791.   case etree_rel:
  792.     if (tree->rel.section->owner != NULL)
  793.       minfo ("%B:", tree->rel.section->owner);
  794.     minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
  795.     return;
  796.   case etree_assign:
  797. #if 0
  798.     if (tree->assign.dst->sdefs != (asymbol *)NULL){
  799.       fprintf(config.map_file,"%s (%x) ",tree->assign.dst->name,
  800.           tree->assign.dst->sdefs->value);
  801.     }
  802.     else {
  803.       fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name);
  804.     }
  805. #endif
  806.     fprintf(config.map_file,"%s",tree->assign.dst);
  807.     exp_print_token(tree->type.node_code);
  808.     exp_print_tree(tree->assign.src);
  809.     break;
  810.   case etree_provide:
  811.     fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
  812.     exp_print_tree (tree->assign.src);
  813.     fprintf (config.map_file, ")");
  814.     break;
  815.   case etree_binary:
  816.     fprintf(config.map_file,"(");
  817.     exp_print_tree(tree->binary.lhs);
  818.     exp_print_token(tree->type.node_code);
  819.     exp_print_tree(tree->binary.rhs);
  820.     fprintf(config.map_file,")");
  821.     break;
  822.   case etree_trinary:
  823.     exp_print_tree(tree->trinary.cond);
  824.     fprintf(config.map_file,"?");
  825.     exp_print_tree(tree->trinary.lhs);
  826.     fprintf(config.map_file,":");
  827.     exp_print_tree(tree->trinary.rhs);
  828.     break;
  829.   case etree_unary:
  830.     exp_print_token(tree->unary.type.node_code);
  831.     if (tree->unary.child) 
  832.     {
  833.       
  834.     fprintf(config.map_file,"(");
  835.     exp_print_tree(tree->unary.child);
  836.     fprintf(config.map_file,")");
  837.   }
  838.     
  839.     break;
  840.   case etree_undef:
  841.     fprintf(config.map_file,"????????");
  842.     break;
  843.   case etree_name:
  844.     if (tree->type.node_code == NAME) {
  845.       fprintf(config.map_file,"%s", tree->name.name);
  846.     }
  847.     else {
  848.       exp_print_token(tree->type.node_code);
  849.       if (tree->name.name)
  850.       fprintf(config.map_file,"(%s)", tree->name.name);
  851.     }
  852.     break;
  853.   default:
  854.     FAIL();
  855.     break;
  856.   }
  857. }
  858.  
  859. bfd_vma
  860. exp_get_vma (tree, def, name, allocation_done)
  861.      etree_type *tree;
  862.      bfd_vma def;
  863.      char *name;
  864.      lang_phase_type allocation_done;
  865. {
  866.   etree_value_type r;
  867.  
  868.   if (tree != NULL)
  869.     {
  870.       r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
  871.       if (! r.valid && name != NULL)
  872.     einfo ("%F%S nonconstant expression for %s\n", name);
  873.       return r.value;
  874.     }
  875.   else
  876.     return def;
  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. bfd_vma
  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. }
  909.