/* This module handles expression trees.
Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support (sac@cygnus.com).

This file is part of GLD, the Gnu Linker.

GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */

/*
This module is in charge of working out the contents of expressions.

It has to keep track of the relative/absness of a symbol etc. This is
done by keeping all values in a struct (an etree_value_type) which
contains a value, a section to which it is relative and a valid bit.

*/


#include "bfd.h"
#include "sysdep.h"
#include "bfdlink.h"

#include "ld.h"
#include "ldmain.h"
#include "ldmisc.h"
#include "ldexp.h"
#include "ldgram.h"
#include "ldlang.h"

static void exp_print_token PARAMS ((token_code_type code));
static void make_abs PARAMS ((etree_value_type *ptr));
static etree_value_type new_abs PARAMS ((bfd_vma value));
static void check PARAMS ((lang_output_section_statement_type *os,
			   const char *name, const char *op));
static etree_value_type new_rel
  PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
static etree_value_type new_rel_from_section
  PARAMS ((bfd_vma value, lang_output_section_statement_type *section));
static etree_value_type fold_binary
  PARAMS ((etree_type *tree,
	   lang_output_section_statement_type *current_section,
	   lang_phase_type allocation_done,
	   bfd_vma dot, bfd_vma *dotp));
static etree_value_type fold_name
  PARAMS ((etree_type *tree,
	   lang_output_section_statement_type *current_section,
	   lang_phase_type allocation_done,
	   bfd_vma dot));
static etree_value_type exp_fold_tree_no_dot
  PARAMS ((etree_type *tree,
	   lang_output_section_statement_type *current_section,
	   lang_phase_type allocation_done));

static void
exp_print_token (code)
     token_code_type code;
{
  static CONST struct
    {
      token_code_type code;
      char *name;
    } table[] =
      {
	{ INT,	"int" },
	{ REL, "relocateable" },
	{ NAME,"NAME" },
	{ PLUSEQ,"+=" },
	{ MINUSEQ,"-=" },
	{ MULTEQ,"*=" },
	{ DIVEQ,"/=" },
	{ LSHIFTEQ,"<<=" },
	{ RSHIFTEQ,">>=" },
	{ ANDEQ,"&=" },
	{ OREQ,"|=" },
	{ OROR,"||" },
	{ ANDAND,"&&" },
	{ EQ,"==" },
	{ NE,"!=" },
	{ LE,"<=" },
	{ GE,">=" },
	{ LSHIFT,"<<" },
	{ RSHIFT,">>=" },
	{ ALIGN_K,"ALIGN" },
	{ BLOCK,"BLOCK" },
	{ SECTIONS,"SECTIONS" },
	{ SIZEOF_HEADERS,"SIZEOF_HEADERS" },
	{ NEXT,"NEXT" },
	{ SIZEOF,"SIZEOF" },
	{ ADDR,"ADDR" },
	{ LOADADDR,"LOADADDR" },
	{ MEMORY,"MEMORY" },
	{ DEFINED,"DEFINED" },
	{ TARGET_K,"TARGET" },
	{ SEARCH_DIR,"SEARCH_DIR" },
	{ MAP,"MAP" },
	{ QUAD,"QUAD" },
	{ SQUAD,"SQUAD" },
	{ LONG,"LONG" },
	{ SHORT,"SHORT" },
	{ BYTE,"BYTE" },
	{ ENTRY,"ENTRY" },
	{ 0,(char *)NULL }
      };
  unsigned int idx;

  for (idx = 0; table[idx].name != (char*)NULL; idx++) {
    if (table[idx].code == code) {
      fprintf(config.map_file, "%s", table[idx].name);
      return;
    }
  }
  /* Not in table, just print it alone */
  fprintf(config.map_file, "%c",code);
}

static void 
make_abs (ptr)
     etree_value_type *ptr;
{
    asection *s = ptr->section->bfd_section;
    ptr->value += s->vma;
    ptr->section = abs_output_section;
}

static etree_value_type
new_abs (value)
     bfd_vma value;
{
  etree_value_type new;
  new.valid_p = true;
  new.section = abs_output_section;
  new.value = value;
  return new;
}

static void 
check (os, name, op)
     lang_output_section_statement_type *os;
     const char *name;
     const char *op;
{
  if (os == NULL)
    einfo (_("%F%P: %s uses undefined section %s\n"), op, name);
  if (! os->processed)
    einfo (_("%F%P: %s forward reference of section %s\n"), op, name);
}

etree_type *
exp_intop (value)
     bfd_vma value;
{
  etree_type *new = (etree_type *) stat_alloc(sizeof(new->value));
  new->type.node_code = INT;
  new->value.value = value;
  new->type.node_class = etree_value;
  return new;

}

/* Build an expression representing an unnamed relocateable value.  */

etree_type *
exp_relop (section, value)
     asection *section;
     bfd_vma value;
{
  etree_type *new = (etree_type *) stat_alloc (sizeof (new->rel));
  new->type.node_code = REL;
  new->type.node_class = etree_rel;
  new->rel.section = section;
  new->rel.value = value;
  return new;
}

static etree_value_type
new_rel (value, section)
     bfd_vma value;
     lang_output_section_statement_type *section;
{
  etree_value_type new;
  new.valid_p = true;
  new.value = value;
  new.section = section;
  return new;
}

static etree_value_type
new_rel_from_section (value, section)
     bfd_vma value;
     lang_output_section_statement_type *section;
{
  etree_value_type new;
  new.valid_p = true;
  new.value = value;
  new.section = section;

    new.value -= section->bfd_section->vma;

  return new;
}

static etree_value_type 
fold_binary (tree, current_section, allocation_done, dot, dotp)
     etree_type *tree;
     lang_output_section_statement_type *current_section;
     lang_phase_type allocation_done;
     bfd_vma dot;
     bfd_vma *dotp;
{
  etree_value_type result;

  result = exp_fold_tree (tree->binary.lhs, current_section,
			  allocation_done, dot, dotp);
  if (result.valid_p)
    {
      etree_value_type other;

      other = exp_fold_tree (tree->binary.rhs,
			     current_section,
			     allocation_done, dot,dotp) ;
      if (other.valid_p)
	{
	  /* If the values are from different sections, or this is an
	     absolute expression, make both the source arguments
	     absolute.  However, adding or subtracting an absolute
	     value from a relative value is meaningful, and is an
	     exception.  */
	  if (current_section != abs_output_section
	      && (other.section == abs_output_section
		  || (result.section == abs_output_section
		      && tree->type.node_code == '+'))
	      && (tree->type.node_code == '+'
		  || tree->type.node_code == '-'))
	    {
	      etree_value_type hold;

	      /* If there is only one absolute term, make sure it is the
		 second one.  */
	      if (other.section != abs_output_section)
		{
		  hold = result;
		  result = other;
		  other = hold;
		}
	    }
	  else if (result.section != other.section
		   || current_section == abs_output_section)
	    {
	      make_abs(&result);
	      make_abs(&other);
	    }

	  switch (tree->type.node_code) 
	    {
	    case '%':
	      if (other.value == 0)
		einfo (_("%F%S %% by zero\n"));
	      result.value = ((bfd_signed_vma) result.value
			      % (bfd_signed_vma) other.value);
	      break;

	    case '/':
	      if (other.value == 0)
		einfo (_("%F%S / by zero\n"));
	      result.value = ((bfd_signed_vma) result.value
			      / (bfd_signed_vma) other.value);
	      break;

#define BOP(x,y) case x : result.value = result.value y other.value; break;
	      BOP('+',+);
	      BOP('*',*);
	      BOP('-',-);
	      BOP(LSHIFT,<<);
	      BOP(RSHIFT,>>);
	      BOP(EQ,==);
	      BOP(NE,!=);
	      BOP('<',<);
	      BOP('>',>);
	      BOP(LE,<=);
	      BOP(GE,>=);
	      BOP('&',&);
	      BOP('^',^);
	      BOP('|',|);
	      BOP(ANDAND,&&);
	      BOP(OROR,||);

	    case MAX_K:
	      if (result.value < other.value)
		result = other;
	      break;

	    case MIN_K:
	      if (result.value > other.value)
		result = other;
	      break;

	    default:
	      FAIL();
	    }
	}
      else
	{
	  result.valid_p = false;
	}
    }

  return result;
}

etree_value_type 
invalid ()
{
  etree_value_type new;
  new.valid_p = false;
  return new;
}

static etree_value_type 
fold_name (tree, current_section, allocation_done, dot)
     etree_type *tree;
     lang_output_section_statement_type *current_section;
     lang_phase_type  allocation_done;
     bfd_vma dot;
{
  etree_value_type result;
  switch (tree->type.node_code) 
      {
      case SIZEOF_HEADERS:
	if (allocation_done != lang_first_phase_enum) 
	  {
	    result = new_abs ((bfd_vma)
			      bfd_sizeof_headers (output_bfd,
						  link_info.relocateable));
	  }
	else
	  {
	    result.valid_p = false;
	  }
	break;
      case DEFINED:
	if (allocation_done == lang_first_phase_enum)
	  result.valid_p = false;
	else
	  {
	    struct bfd_link_hash_entry *h;

	    h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
					      tree->name.name,
					      false, false, true);
	    result.value = (h != (struct bfd_link_hash_entry *) NULL
			    && (h->type == bfd_link_hash_defined
				|| h->type == bfd_link_hash_defweak
				|| h->type == bfd_link_hash_common));
	    result.section = 0;
	    result.valid_p = true;
	  }
	break;
      case NAME:
	result.valid_p = false;
	if (tree->name.name[0] == '.' && tree->name.name[1] == 0)
	  {
	    if (allocation_done != lang_first_phase_enum)
	      result = new_rel_from_section(dot, current_section);
	    else
	      result = invalid();
	  }
	else if (allocation_done != lang_first_phase_enum)
	  {
	    struct bfd_link_hash_entry *h;

	    h = bfd_wrapped_link_hash_lookup (output_bfd, &link_info,
					      tree->name.name,
					      false, false, true);
	    if (h != NULL
		&& (h->type == bfd_link_hash_defined
		    || h->type == bfd_link_hash_defweak))
	      {
		if (bfd_is_abs_section (h->u.def.section))
		  result = new_abs (h->u.def.value);
		else if (allocation_done == lang_final_phase_enum
			 || allocation_done == lang_allocating_phase_enum)
		  {
		    asection *output_section;

		    output_section = h->u.def.section->output_section;
		    if (output_section == NULL)
		      einfo (_("%X%S: unresolvable symbol `%s' referenced in expression\n"),
			     tree->name.name);
		    else
		      {
			lang_output_section_statement_type *os;

			os = (lang_output_section_statement_lookup
			      (bfd_get_section_name (output_bfd,
						     output_section)));

			/* FIXME: Is this correct if this section is
			   being linked with -R?  */
			result = new_rel ((h->u.def.value
					   + h->u.def.section->output_offset),
					  os);
		      }
		  }
	      }
	    else if (allocation_done == lang_final_phase_enum)
	      einfo (_("%F%S: undefined symbol `%s' referenced in expression\n"),
		     tree->name.name);
	  }
	break;

      case ADDR:
	if (allocation_done != lang_first_phase_enum)
	  {
	    lang_output_section_statement_type *os;

	    os = lang_output_section_find (tree->name.name);
	    check (os, tree->name.name, "ADDR");
	    result = new_rel (0, os);
	  }
	else
	  result = invalid ();
	break;

      case LOADADDR:
	if (allocation_done != lang_first_phase_enum)
	  {
	    lang_output_section_statement_type *os;

	    os = lang_output_section_find (tree->name.name);
	    check (os, tree->name.name, "LOADADDR");
	    if (os->load_base == NULL)
	      result = new_rel (0, os);
	    else
	      result = exp_fold_tree_no_dot (os->load_base,
					     abs_output_section,
					     allocation_done);
	  }
	else
	  result = invalid ();
	break;

      case SIZEOF:
	if (allocation_done != lang_first_phase_enum)
	  {
	    lang_output_section_statement_type *os;

	    os = lang_output_section_find (tree->name.name);
	    check (os, tree->name.name, "SIZEOF");
	    result = new_abs (os->bfd_section->_raw_size);
	  }
	else
	  result = invalid ();
	break;

      default:
	FAIL();
	break;
      }

  return result;
}
etree_value_type 
exp_fold_tree (tree, current_section, allocation_done, dot, dotp)
     etree_type *tree;
     lang_output_section_statement_type *current_section;
     lang_phase_type  allocation_done;
     bfd_vma dot;
     bfd_vma *dotp;
{
  etree_value_type result;

  if (tree == NULL)
    {
      result.valid_p = false;
      return result;
    }

  switch (tree->type.node_class) 
    {
    case etree_value:
      result = new_rel (tree->value.value, current_section);
      break;

    case etree_rel:
      if (allocation_done != lang_final_phase_enum)
	result.valid_p = false;
      else
	result = new_rel ((tree->rel.value
			   + tree->rel.section->output_section->vma
			   + tree->rel.section->output_offset),
			  current_section);
      break;

    case etree_assert:
      result = exp_fold_tree (tree->assert_s.child,
                              current_section,
                              allocation_done, dot, dotp);
      if (result.valid_p)
	{
	  if (! result.value)
	    einfo ("%F%P: %s\n", tree->assert_s.message);
	  return result;
	}
      break;

    case etree_unary:
      result = exp_fold_tree (tree->unary.child,
			      current_section,
			      allocation_done, dot, dotp);
      if (result.valid_p)
	{
	  switch (tree->type.node_code) 
	    {
	    case ALIGN_K:
	      if (allocation_done != lang_first_phase_enum)
		result = new_rel_from_section (ALIGN_N (dot, result.value),
					       current_section);
	      else
		result.valid_p = false;
	      break;

	    case ABSOLUTE:
	      if (allocation_done != lang_first_phase_enum && result.valid_p)
		{
		  result.value += result.section->bfd_section->vma;
		  result.section = abs_output_section;
		}
	      else 
		result.valid_p = false;
	      break;

	    case '~':
	      make_abs (&result);
	      result.value = ~result.value;
	      break;

	    case '!':
	      make_abs (&result);
	      result.value = !result.value;
	      break;

	    case '-':
	      make_abs (&result);
	      result.value = -result.value;
	      break;

	    case NEXT:
	      /* Return next place aligned to value.  */
	      if (allocation_done == lang_allocating_phase_enum)
		{
		  make_abs (&result);
		  result.value = ALIGN_N (dot, result.value);
		}
	      else
		result.valid_p = false;
	      break;

	    default:
	      FAIL ();
	      break;
	    }
	}
      break;

    case etree_trinary:
      result = exp_fold_tree (tree->trinary.cond, current_section,
			      allocation_done, dot, dotp);
      if (result.valid_p)
	result = exp_fold_tree ((result.value
				 ? tree->trinary.lhs
				 : tree->trinary.rhs),
				current_section,
				allocation_done, dot, dotp);
      break;

    case etree_binary:
      result = fold_binary (tree, current_section, allocation_done,
			    dot, dotp);
      break;

    case etree_assign:
    case etree_provide:
      if (tree->assign.dst[0] == '.' && tree->assign.dst[1] == 0)
	{
	  /* Assignment to dot can only be done during allocation */
	  if (tree->type.node_class == etree_provide)
	    einfo (_("%F%S can not PROVIDE assignment to location counter\n"));
	  if (allocation_done == lang_allocating_phase_enum
	      || (allocation_done == lang_final_phase_enum
		  && current_section == abs_output_section))
	    {
	      result = exp_fold_tree (tree->assign.src,
				      current_section,
				      lang_allocating_phase_enum, dot,
				      dotp);
	      if (! result.valid_p)
		einfo (_("%F%S invalid assignment to location counter\n"));
	      else
		{
		  if (current_section == NULL)
		    einfo (_("%F%S assignment to location counter invalid outside of SECTION\n"));
		  else
		    {
		      bfd_vma nextdot;

		      nextdot = (result.value
				 + current_section->bfd_section->vma);
		      if (nextdot < dot
			  && current_section != abs_output_section)
			{
			  einfo (_("%F%S cannot move location counter backwards (from %V to %V)\n"),
				 dot, nextdot);
			}
		      else
			*dotp = nextdot; 
		    }
		}
	    }
	}
      else
	{
	  result = exp_fold_tree (tree->assign.src,
				  current_section, allocation_done,
				  dot, dotp);
	  if (result.valid_p)
	    {
	      boolean create;
	      struct bfd_link_hash_entry *h;

	      if (tree->type.node_class == etree_assign)
		create = true;
	      else
		create = false;
	      h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst,
					create, false, false);
	      if (h == (struct bfd_link_hash_entry *) NULL)
		{
		  if (tree->type.node_class == etree_assign)
		    einfo (_("%P%F:%s: hash creation failed\n"),
			   tree->assign.dst);
		}
	      else if (tree->type.node_class == etree_provide
		       && h->type != bfd_link_hash_undefined
		       && h->type != bfd_link_hash_common)
		{
		  /* Do nothing.  The symbol was defined by some
		     object.  */
		}
	      else
		{
		  /* FIXME: Should we worry if the symbol is already
		     defined?  */
		  h->type = bfd_link_hash_defined;
		  h->u.def.value = result.value;
		  h->u.def.section = result.section->bfd_section;
		}
	    }
	}
      break;

    case etree_name:
      result = fold_name (tree, current_section, allocation_done, dot);
      break;

    default:
      FAIL ();
      break;
    }

  return result;
}

static etree_value_type 
exp_fold_tree_no_dot (tree, current_section, allocation_done)
     etree_type *tree;
     lang_output_section_statement_type *current_section;
     lang_phase_type allocation_done;
{
return exp_fold_tree(tree, current_section, allocation_done, (bfd_vma)
		     0, (bfd_vma *)NULL);
}

etree_type *
exp_binop (code, lhs, rhs)
     int code;
     etree_type *lhs;
     etree_type *rhs;
{
  etree_type value, *new;
  etree_value_type r;

  value.type.node_code = code;
  value.binary.lhs = lhs;
  value.binary.rhs = rhs;
  value.type.node_class = etree_binary;
  r = exp_fold_tree_no_dot(&value,
			   abs_output_section,
			   lang_first_phase_enum );
  if (r.valid_p)
    {
      return exp_intop(r.value);
    }
  new = (etree_type *) stat_alloc (sizeof (new->binary));
  memcpy((char *)new, (char *)&value, sizeof(new->binary));
  return new;
}

etree_type *
exp_trinop (code, cond, lhs, rhs)
     int code;
     etree_type *cond;
     etree_type *lhs;
     etree_type *rhs;
{
  etree_type value, *new;
  etree_value_type r;
  value.type.node_code = code;
  value.trinary.lhs = lhs;
  value.trinary.cond = cond;
  value.trinary.rhs = rhs;
  value.type.node_class = etree_trinary;
  r= exp_fold_tree_no_dot(&value,  (lang_output_section_statement_type
				    *)NULL,lang_first_phase_enum);
  if (r.valid_p) {
    return exp_intop(r.value);
  }
  new = (etree_type *) stat_alloc (sizeof (new->trinary));
  memcpy((char *)new,(char *) &value, sizeof(new->trinary));
  return new;
}


etree_type *
exp_unop (code, child)
     int code;
     etree_type *child;
{
  etree_type value, *new;

  etree_value_type r;
  value.unary.type.node_code = code;
  value.unary.child = child;
  value.unary.type.node_class = etree_unary;
  r = exp_fold_tree_no_dot(&value,abs_output_section,
			   lang_first_phase_enum);
  if (r.valid_p) {
    return exp_intop(r.value);
  }
  new = (etree_type *) stat_alloc (sizeof (new->unary));
  memcpy((char *)new, (char *)&value, sizeof(new->unary));
  return new;
}


etree_type *
exp_nameop (code, name)
     int code;
     CONST char *name;
{
  etree_type value, *new;
  etree_value_type r;
  value.name.type.node_code = code;
  value.name.name = name;
  value.name.type.node_class = etree_name;


  r = exp_fold_tree_no_dot(&value,
			   (lang_output_section_statement_type *)NULL,
			   lang_first_phase_enum);
  if (r.valid_p) {
    return exp_intop(r.value);
  }
  new = (etree_type *) stat_alloc (sizeof (new->name));
  memcpy((char *)new, (char *)&value, sizeof(new->name));
  return new;

}




etree_type *
exp_assop (code, dst, src)
     int code;
     CONST char *dst;
     etree_type *src;
{
  etree_type value, *new;

  value.assign.type.node_code = code;


  value.assign.src = src;
  value.assign.dst = dst;
  value.assign.type.node_class = etree_assign;

#if 0
  if (exp_fold_tree_no_dot(&value, &result)) {
    return exp_intop(result);
  }
#endif
  new = (etree_type*) stat_alloc (sizeof (new->assign));
  memcpy((char *)new, (char *)&value, sizeof(new->assign));
  return new;
}

/* Handle PROVIDE.  */

etree_type *
exp_provide (dst, src)
     const char *dst;
     etree_type *src;
{
  etree_type *n;

  n = (etree_type *) stat_alloc (sizeof (n->assign));
  n->assign.type.node_code = '=';
  n->assign.type.node_class = etree_provide;
  n->assign.src = src;
  n->assign.dst = dst;
  return n;
}

/* Handle ASSERT.  */

etree_type *
exp_assert (exp, message)
     etree_type *exp;
     const char *message;
{
  etree_type *n;

  n = (etree_type *) stat_alloc (sizeof (n->assert_s));
  n->assert_s.type.node_code = '!';
  n->assert_s.type.node_class = etree_assert;
  n->assert_s.child = exp;
  n->assert_s.message = message;
  return n;
}

void 
exp_print_tree (tree)
     etree_type *tree;
{
  switch (tree->type.node_class) {
  case etree_value:
    minfo ("0x%v", tree->value.value);
    return;
  case etree_rel:
    if (tree->rel.section->owner != NULL)
      minfo ("%B:", tree->rel.section->owner);
    minfo ("%s+0x%v", tree->rel.section->name, tree->rel.value);
    return;
  case etree_assign:
#if 0
    if (tree->assign.dst->sdefs != (asymbol *)NULL){
      fprintf(config.map_file,"%s (%x) ",tree->assign.dst->name,
	      tree->assign.dst->sdefs->value);
    }
    else {
      fprintf(config.map_file,"%s (UNDEFINED)",tree->assign.dst->name);
    }
#endif
    fprintf(config.map_file,"%s",tree->assign.dst);
    exp_print_token(tree->type.node_code);
    exp_print_tree(tree->assign.src);
    break;
  case etree_provide:
    fprintf (config.map_file, "PROVIDE (%s, ", tree->assign.dst);
    exp_print_tree (tree->assign.src);
    fprintf (config.map_file, ")");
    break;
  case etree_binary:
    fprintf(config.map_file,"(");
    exp_print_tree(tree->binary.lhs);
    exp_print_token(tree->type.node_code);
    exp_print_tree(tree->binary.rhs);
    fprintf(config.map_file,")");
    break;
  case etree_trinary:
    exp_print_tree(tree->trinary.cond);
    fprintf(config.map_file,"?");
    exp_print_tree(tree->trinary.lhs);
    fprintf(config.map_file,":");
    exp_print_tree(tree->trinary.rhs);
    break;
  case etree_unary:
    exp_print_token(tree->unary.type.node_code);
    if (tree->unary.child) 
    {
    fprintf(config.map_file,"(");
    exp_print_tree(tree->unary.child);
    fprintf(config.map_file,")");
  }
    
    break;

  case etree_assert:
    fprintf (config.map_file, "ASSERT (");
    exp_print_tree (tree->assert_s.child);
    fprintf (config.map_file, ", %s)", tree->assert_s.message);
    break;

  case etree_undef:
    fprintf(config.map_file,"????????");
    break;
  case etree_name:
    if (tree->type.node_code == NAME) {
      fprintf(config.map_file,"%s", tree->name.name);
    }
    else {
      exp_print_token(tree->type.node_code);
      if (tree->name.name)
      fprintf(config.map_file,"(%s)", tree->name.name);
    }
    break;
  default:
    FAIL();
    break;
  }
}

bfd_vma
exp_get_vma (tree, def, name, allocation_done)
     etree_type *tree;
     bfd_vma def;
     char *name;
     lang_phase_type allocation_done;
{
  etree_value_type r;

  if (tree != NULL)
    {
      r = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);
      if (! r.valid_p && name != NULL)
	einfo (_("%F%S nonconstant expression for %s\n"), name);
      return r.value;
    }
  else
    return def;
}

int 
exp_get_value_int (tree,def,name, allocation_done)
     etree_type *tree;
     int def;
     char *name;
     lang_phase_type allocation_done;
{
  return (int)exp_get_vma(tree,(bfd_vma)def,name, allocation_done);
}


bfd_vma
exp_get_abs_int (tree, def, name, allocation_done)
     etree_type *tree;
     int def;
     char *name;
     lang_phase_type allocation_done;
{
  etree_value_type res;
  res = exp_fold_tree_no_dot (tree, abs_output_section, allocation_done);

  if (res.valid_p)
    {
      res.value += res.section->bfd_section->vma;
    }
  else {
    einfo (_("%F%S non constant expression for %s\n"),name);
  }
  return res.value;
}
