// expression.cc -- expressions in linker scripts for gold

// Copyright (C) 2006-2016 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.

// This file is part of gold.

// This program 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 3 of the License, or
// (at your option) any later version.

// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.

#include "gold.h"

#include <string>

#include "elfcpp.h"
#include "parameters.h"
#include "symtab.h"
#include "layout.h"
#include "output.h"
#include "script.h"
#include "script-c.h"

namespace gold
{

// This file holds the code which handles linker expressions.

// The dot symbol, which linker scripts refer to simply as ".",
// requires special treatment.  The dot symbol is set several times,
// section addresses will refer to it, output sections will change it,
// and it can be set based on the value of other symbols.  We simplify
// the handling by prohibiting setting the dot symbol to the value of
// a non-absolute symbol.

// When evaluating the value of an expression, we pass in a pointer to
// this struct, so that the expression evaluation can find the
// information it needs.

struct Expression::Expression_eval_info
{
  // The symbol table.
  const Symbol_table* symtab;
  // The layout--we use this to get section information.
  const Layout* layout;
  // Whether to check assertions.
  bool check_assertions;
  // Whether expressions can refer to the dot symbol.  The dot symbol
  // is only available within a SECTIONS clause.
  bool is_dot_available;
  // The current value of the dot symbol.
  uint64_t dot_value;
  // The section in which the dot symbol is defined; this is NULL if
  // it is absolute.
  Output_section* dot_section;
  // Points to where the section of the result should be stored.
  Output_section** result_section_pointer;
  // Pointer to where the alignment of the result should be stored.
  uint64_t* result_alignment_pointer;
  // Pointer to where the type of the symbol on the RHS should be stored.
  elfcpp::STT* type_pointer;
  // Pointer to where the visibility of the symbol on the RHS should be stored.
  elfcpp::STV* vis_pointer;
  // Pointer to where the rest of the symbol's st_other field should be stored.
  unsigned char* nonvis_pointer;
  // Whether the value is valid.  In Symbol_assignment::set_if_absolute, we
  // may be trying to evaluate the address of a section whose address is not
  // yet finalized, and we need to fail the evaluation gracefully.
  bool *is_valid_pointer;
};

// Evaluate an expression.

uint64_t
Expression::eval(const Symbol_table* symtab, const Layout* layout,
		 bool check_assertions)
{
  return this->eval_maybe_dot(symtab, layout, check_assertions, false, 0,
			      NULL, NULL, NULL, NULL, NULL, NULL, false, NULL);
}

// Evaluate an expression which may refer to the dot symbol.

uint64_t
Expression::eval_with_dot(const Symbol_table* symtab, const Layout* layout,
			  bool check_assertions, uint64_t dot_value,
			  Output_section* dot_section,
			  Output_section** result_section_pointer,
			  uint64_t* result_alignment_pointer,
			  bool is_section_dot_assignment)
{
  return this->eval_maybe_dot(symtab, layout, check_assertions, true,
			      dot_value, dot_section, result_section_pointer,
			      result_alignment_pointer, NULL, NULL, NULL,
			      is_section_dot_assignment, NULL);
}

// Evaluate an expression which may or may not refer to the dot
// symbol.

uint64_t
Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout,
			   bool check_assertions, bool is_dot_available,
			   uint64_t dot_value, Output_section* dot_section,
			   Output_section** result_section_pointer,
			   uint64_t* result_alignment_pointer,
			   elfcpp::STT* type_pointer,
			   elfcpp::STV* vis_pointer,
			   unsigned char* nonvis_pointer,
			   bool is_section_dot_assignment,
			   bool* is_valid_pointer)
{
  Expression_eval_info eei;
  eei.symtab = symtab;
  eei.layout = layout;
  eei.check_assertions = check_assertions;
  eei.is_dot_available = is_dot_available;
  eei.dot_value = dot_value;
  eei.dot_section = dot_section;

  // We assume the value is absolute, and only set this to a section
  // if we find a section-relative reference.
  if (result_section_pointer != NULL)
    *result_section_pointer = NULL;
  eei.result_section_pointer = result_section_pointer;

  // For symbol=symbol assignments, we need to track the type, visibility,
  // and remaining st_other bits.
  eei.type_pointer = type_pointer;
  eei.vis_pointer = vis_pointer;
  eei.nonvis_pointer = nonvis_pointer;

  eei.result_alignment_pointer = result_alignment_pointer;

  // Assume the value is valid until we try to evaluate an expression
  // that can't be evaluated yet.
  bool is_valid = true;
  eei.is_valid_pointer = &is_valid;

  uint64_t val = this->value(&eei);

  if (is_valid_pointer != NULL)
    *is_valid_pointer = is_valid;
  else
    gold_assert(is_valid);

  // If this is an assignment to dot within a section, and the value
  // is absolute, treat it as a section-relative offset.
  if (is_section_dot_assignment && *result_section_pointer == NULL)
    {
      gold_assert(dot_section != NULL);
      val += dot_section->address();
      *result_section_pointer = dot_section;
    }
  return val;
}

// A number.

class Integer_expression : public Expression
{
 public:
  Integer_expression(uint64_t val)
    : val_(val)
  { }

  uint64_t
  value(const Expression_eval_info*)
  { return this->val_; }

  void
  print(FILE* f) const
  { fprintf(f, "0x%llx", static_cast<unsigned long long>(this->val_)); }

 private:
  uint64_t val_;
};

extern "C" Expression*
script_exp_integer(uint64_t val)
{
  return new Integer_expression(val);
}

// An expression whose value is the value of a symbol.

class Symbol_expression : public Expression
{
 public:
  Symbol_expression(const char* name, size_t length)
    : name_(name, length)
  { }

  uint64_t
  value(const Expression_eval_info*);

  void
  print(FILE* f) const
  { fprintf(f, "%s", this->name_.c_str()); }

 private:
  std::string name_;
};

uint64_t
Symbol_expression::value(const Expression_eval_info* eei)
{
  Symbol* sym = eei->symtab->lookup(this->name_.c_str());
  if (sym == NULL || !sym->is_defined())
    {
      gold_error(_("undefined symbol '%s' referenced in expression"),
		 this->name_.c_str());
      return 0;
    }

  if (eei->result_section_pointer != NULL)
    *eei->result_section_pointer = sym->output_section();
  if (eei->type_pointer != NULL)
    *eei->type_pointer = sym->type();
  if (eei->vis_pointer != NULL)
    *eei->vis_pointer = sym->visibility();
  if (eei->nonvis_pointer != NULL)
    *eei->nonvis_pointer = sym->nonvis();

  if (parameters->target().get_size() == 32)
    return eei->symtab->get_sized_symbol<32>(sym)->value();
  else if (parameters->target().get_size() == 64)
    return eei->symtab->get_sized_symbol<64>(sym)->value();
  else
    gold_unreachable();
}

// An expression whose value is the value of the special symbol ".".
// This is only valid within a SECTIONS clause.

class Dot_expression : public Expression
{
 public:
  Dot_expression()
  { }

  uint64_t
  value(const Expression_eval_info*);

  void
  print(FILE* f) const
  { fprintf(f, "."); }
};

uint64_t
Dot_expression::value(const Expression_eval_info* eei)
{
  if (!eei->is_dot_available)
    {
      gold_error(_("invalid reference to dot symbol outside of "
		   "SECTIONS clause"));
      return 0;
    }
  if (eei->result_section_pointer != NULL)
    *eei->result_section_pointer = eei->dot_section;
  return eei->dot_value;
}

// A string.  This is either the name of a symbol, or ".".

extern "C" Expression*
script_exp_string(const char* name, size_t length)
{
  if (length == 1 && name[0] == '.')
    return new Dot_expression();
  else
    return new Symbol_expression(name, length);
}

// A unary expression.

class Unary_expression : public Expression
{
 public:
  Unary_expression(Expression* arg)
    : arg_(arg)
  { }

  ~Unary_expression()
  { delete this->arg_; }

 protected:
  uint64_t
  arg_value(const Expression_eval_info* eei,
	    Output_section** arg_section_pointer) const
  {
    return this->arg_->eval_maybe_dot(eei->symtab, eei->layout,
				      eei->check_assertions,
				      eei->is_dot_available,
				      eei->dot_value,
				      eei->dot_section,
				      arg_section_pointer,
				      eei->result_alignment_pointer,
				      NULL,
				      NULL,
				      NULL,
				      false,
				      eei->is_valid_pointer);
  }

  void
  arg_print(FILE* f) const
  { this->arg_->print(f); }

 private:
  Expression* arg_;
};

// Handle unary operators.  We use a preprocessor macro as a hack to
// capture the C operator.

#define UNARY_EXPRESSION(NAME, OPERATOR)				\
  class Unary_ ## NAME : public Unary_expression			\
  {									\
  public:								\
    Unary_ ## NAME(Expression* arg)					\
      : Unary_expression(arg)						\
    { }									\
    									\
    uint64_t								\
    value(const Expression_eval_info* eei)				\
    {									\
      Output_section* arg_section;					\
      uint64_t ret = OPERATOR this->arg_value(eei, &arg_section);	\
      if (arg_section != NULL && parameters->options().relocatable())	\
	gold_warning(_("unary " #NAME " applied to section "		\
		       "relative value"));				\
      return ret;							\
    }									\
									\
    void								\
    print(FILE* f) const						\
    {									\
      fprintf(f, "(%s ", #OPERATOR);					\
      this->arg_print(f);						\
      fprintf(f, ")");							\
    }									\
  };									\
									\
  extern "C" Expression*						\
  script_exp_unary_ ## NAME(Expression* arg)				\
  {									\
      return new Unary_ ## NAME(arg);					\
  }

UNARY_EXPRESSION(minus, -)
UNARY_EXPRESSION(logical_not, !)
UNARY_EXPRESSION(bitwise_not, ~)

// A binary expression.

class Binary_expression : public Expression
{
 public:
  Binary_expression(Expression* left, Expression* right)
    : left_(left), right_(right)
  { }

  ~Binary_expression()
  {
    delete this->left_;
    delete this->right_;
  }

 protected:
  uint64_t
  left_value(const Expression_eval_info* eei,
	     Output_section** section_pointer,
	     uint64_t* alignment_pointer) const
  {
    return this->left_->eval_maybe_dot(eei->symtab, eei->layout,
				       eei->check_assertions,
				       eei->is_dot_available,
				       eei->dot_value,
				       eei->dot_section,
				       section_pointer,
				       alignment_pointer,
				       NULL,
				       NULL,
				       NULL,
				       false,
				       eei->is_valid_pointer);
  }

  uint64_t
  right_value(const Expression_eval_info* eei,
	      Output_section** section_pointer,
	      uint64_t* alignment_pointer) const
  {
    return this->right_->eval_maybe_dot(eei->symtab, eei->layout,
					eei->check_assertions,
					eei->is_dot_available,
					eei->dot_value,
					eei->dot_section,
					section_pointer,
					alignment_pointer,
					NULL,
					NULL,
					NULL,
					false,
					eei->is_valid_pointer);
  }

  void
  left_print(FILE* f) const
  { this->left_->print(f); }

  void
  right_print(FILE* f) const
  { this->right_->print(f); }

  // This is a call to function FUNCTION_NAME.  Print it.  This is for
  // debugging.
  void
  print_function(FILE* f, const char* function_name) const
  {
    fprintf(f, "%s(", function_name);
    this->left_print(f);
    fprintf(f, ", ");
    this->right_print(f);
    fprintf(f, ")");
  }

 private:
  Expression* left_;
  Expression* right_;
};

// Handle binary operators.  We use a preprocessor macro as a hack to
// capture the C operator.  KEEP_LEFT means that if the left operand
// is section relative and the right operand is not, the result uses
// the same section as the left operand.  KEEP_RIGHT is the same with
// left and right swapped.  IS_DIV means that we need to give an error
// if the right operand is zero.  WARN means that we should warn if
// used on section relative values in a relocatable link.  We always
// warn if used on values in different sections in a relocatable link.

#define BINARY_EXPRESSION(NAME, OPERATOR, KEEP_LEFT, KEEP_RIGHT, IS_DIV, WARN) \
  class Binary_ ## NAME : public Binary_expression			\
  {									\
  public:								\
    Binary_ ## NAME(Expression* left, Expression* right)		\
      : Binary_expression(left, right)					\
    { }									\
									\
    uint64_t								\
    value(const Expression_eval_info* eei)				\
    {									\
      Output_section* left_section;					\
      uint64_t left_alignment = 0;					\
      uint64_t left = this->left_value(eei, &left_section,		\
				       &left_alignment);		\
      Output_section* right_section;					\
      uint64_t right_alignment = 0;					\
      uint64_t right = this->right_value(eei, &right_section,		\
					 &right_alignment);		\
      if (KEEP_RIGHT && left_section == NULL && right_section != NULL)	\
	{								\
	  if (eei->result_section_pointer != NULL)			\
	    *eei->result_section_pointer = right_section;		\
	  if (eei->result_alignment_pointer != NULL			\
	      && right_alignment > *eei->result_alignment_pointer)	\
	    *eei->result_alignment_pointer = right_alignment;		\
	}								\
      else if (KEEP_LEFT						\
	       && left_section != NULL					\
	       && right_section == NULL)				\
	{								\
	  if (eei->result_section_pointer != NULL)			\
	    *eei->result_section_pointer = left_section;		\
	  if (eei->result_alignment_pointer != NULL			\
	      && left_alignment > *eei->result_alignment_pointer)	\
	    *eei->result_alignment_pointer = left_alignment;		\
	}								\
      else if ((WARN || left_section != right_section)			\
	       && (left_section != NULL || right_section != NULL)	\
	       && parameters->options().relocatable())			\
	gold_warning(_("binary " #NAME " applied to section "		\
		       "relative value"));				\
      if (IS_DIV && right == 0)						\
	{								\
	  gold_error(_(#NAME " by zero"));				\
	  return 0;							\
	}								\
      return left OPERATOR right;					\
    }									\
									\
    void								\
    print(FILE* f) const						\
    {									\
      fprintf(f, "(");							\
      this->left_print(f);						\
      fprintf(f, " %s ", #OPERATOR);					\
      this->right_print(f);						\
      fprintf(f, ")");							\
    }									\
  };									\
									\
  extern "C" Expression*						\
  script_exp_binary_ ## NAME(Expression* left, Expression* right)	\
  {									\
    return new Binary_ ## NAME(left, right);				\
  }

BINARY_EXPRESSION(mult, *, false, false, false, true)
BINARY_EXPRESSION(div, /, false, false, true, true)
BINARY_EXPRESSION(mod, %, false, false, true, true)
BINARY_EXPRESSION(add, +, true, true, false, true)
BINARY_EXPRESSION(sub, -, true, false, false, false)
BINARY_EXPRESSION(lshift, <<, false, false, false, true)
BINARY_EXPRESSION(rshift, >>, false, false, false, true)
BINARY_EXPRESSION(eq, ==, false, false, false, false)
BINARY_EXPRESSION(ne, !=, false, false, false, false)
BINARY_EXPRESSION(le, <=, false, false, false, false)
BINARY_EXPRESSION(ge, >=, false, false, false, false)
BINARY_EXPRESSION(lt, <, false, false, false, false)
BINARY_EXPRESSION(gt, >, false, false, false, false)
BINARY_EXPRESSION(bitwise_and, &, true, true, false, true)
BINARY_EXPRESSION(bitwise_xor, ^, true, true, false, true)
BINARY_EXPRESSION(bitwise_or, |, true, true, false, true)
BINARY_EXPRESSION(logical_and, &&, false, false, false, true)
BINARY_EXPRESSION(logical_or, ||, false, false, false, true)

// A trinary expression.

class Trinary_expression : public Expression
{
 public:
  Trinary_expression(Expression* arg1, Expression* arg2, Expression* arg3)
    : arg1_(arg1), arg2_(arg2), arg3_(arg3)
  { }

  ~Trinary_expression()
  {
    delete this->arg1_;
    delete this->arg2_;
    delete this->arg3_;
  }

 protected:
  uint64_t
  arg1_value(const Expression_eval_info* eei,
	     Output_section** section_pointer) const
  {
    return this->arg1_->eval_maybe_dot(eei->symtab, eei->layout,
				       eei->check_assertions,
				       eei->is_dot_available,
				       eei->dot_value,
				       eei->dot_section,
				       section_pointer,
				       NULL,
				       NULL,
				       NULL,
				       NULL,
				       false,
				       eei->is_valid_pointer);
  }

  uint64_t
  arg2_value(const Expression_eval_info* eei,
	     Output_section** section_pointer,
	     uint64_t* alignment_pointer) const
  {
    return this->arg1_->eval_maybe_dot(eei->symtab, eei->layout,
				       eei->check_assertions,
				       eei->is_dot_available,
				       eei->dot_value,
				       eei->dot_section,
				       section_pointer,
				       alignment_pointer,
				       NULL,
				       NULL,
				       NULL,
				       false,
				       eei->is_valid_pointer);
  }

  uint64_t
  arg3_value(const Expression_eval_info* eei,
	     Output_section** section_pointer,
	     uint64_t* alignment_pointer) const
  {
    return this->arg1_->eval_maybe_dot(eei->symtab, eei->layout,
				       eei->check_assertions,
				       eei->is_dot_available,
				       eei->dot_value,
				       eei->dot_section,
				       section_pointer,
				       alignment_pointer,
				       NULL,
				       NULL,
				       NULL,
				       false,
				       eei->is_valid_pointer);
  }

  void
  arg1_print(FILE* f) const
  { this->arg1_->print(f); }

  void
  arg2_print(FILE* f) const
  { this->arg2_->print(f); }

  void
  arg3_print(FILE* f) const
  { this->arg3_->print(f); }

 private:
  Expression* arg1_;
  Expression* arg2_;
  Expression* arg3_;
};

// The conditional operator.

class Trinary_cond : public Trinary_expression
{
 public:
  Trinary_cond(Expression* arg1, Expression* arg2, Expression* arg3)
    : Trinary_expression(arg1, arg2, arg3)
  { }

  uint64_t
  value(const Expression_eval_info* eei)
  {
    Output_section* arg1_section;
    uint64_t arg1 = this->arg1_value(eei, &arg1_section);
    return (arg1
	    ? this->arg2_value(eei, eei->result_section_pointer,
			       eei->result_alignment_pointer)
	    : this->arg3_value(eei, eei->result_section_pointer,
			       eei->result_alignment_pointer));
  }

  void
  print(FILE* f) const
  {
    fprintf(f, "(");
    this->arg1_print(f);
    fprintf(f, " ? ");
    this->arg2_print(f);
    fprintf(f, " : ");
    this->arg3_print(f);
    fprintf(f, ")");
  }
};

extern "C" Expression*
script_exp_trinary_cond(Expression* arg1, Expression* arg2, Expression* arg3)
{
  return new Trinary_cond(arg1, arg2, arg3);
}

// Max function.

class Max_expression : public Binary_expression
{
 public:
  Max_expression(Expression* left, Expression* right)
    : Binary_expression(left, right)
  { }

  uint64_t
  value(const Expression_eval_info* eei)
  {
    Output_section* left_section;
    uint64_t left_alignment;
    uint64_t left = this->left_value(eei, &left_section, &left_alignment);
    Output_section* right_section;
    uint64_t right_alignment;
    uint64_t right = this->right_value(eei, &right_section, &right_alignment);
    if (left_section == right_section)
      {
	if (eei->result_section_pointer != NULL)
	  *eei->result_section_pointer = left_section;
      }
    else if ((left_section != NULL || right_section != NULL)
	     && parameters->options().relocatable())
      gold_warning(_("max applied to section relative value"));
    if (eei->result_alignment_pointer != NULL)
      {
	uint64_t ra = *eei->result_alignment_pointer;
	if (left > right)
	  ra = std::max(ra, left_alignment);
	else if (right > left)
	  ra = std::max(ra, right_alignment);
	else
	  ra = std::max(ra, std::max(left_alignment, right_alignment));
	*eei->result_alignment_pointer = ra;
      }
    return std::max(left, right);
  }

  void
  print(FILE* f) const
  { this->print_function(f, "MAX"); }
};

extern "C" Expression*
script_exp_function_max(Expression* left, Expression* right)
{
  return new Max_expression(left, right);
}

// Min function.

class Min_expression : public Binary_expression
{
 public:
  Min_expression(Expression* left, Expression* right)
    : Binary_expression(left, right)
  { }

  uint64_t
  value(const Expression_eval_info* eei)
  {
    Output_section* left_section;
    uint64_t left_alignment;
    uint64_t left = this->left_value(eei, &left_section, &left_alignment);
    Output_section* right_section;
    uint64_t right_alignment;
    uint64_t right = this->right_value(eei, &right_section, &right_alignment);
    if (left_section == right_section)
      {
	if (eei->result_section_pointer != NULL)
	  *eei->result_section_pointer = left_section;
      }
    else if ((left_section != NULL || right_section != NULL)
	     && parameters->options().relocatable())
      gold_warning(_("min applied to section relative value"));
    if (eei->result_alignment_pointer != NULL)
      {
	uint64_t ra = *eei->result_alignment_pointer;
	if (left < right)
	  ra = std::max(ra, left_alignment);
	else if (right < left)
	  ra = std::max(ra, right_alignment);
	else
	  ra = std::max(ra, std::max(left_alignment, right_alignment));
	*eei->result_alignment_pointer = ra;
      }
    return std::min(left, right);
  }

  void
  print(FILE* f) const
  { this->print_function(f, "MIN"); }
};

extern "C" Expression*
script_exp_function_min(Expression* left, Expression* right)
{
  return new Min_expression(left, right);
}

// Class Section_expression.  This is a parent class used for
// functions which take the name of an output section.

class Section_expression : public Expression
{
 public:
  Section_expression(const char* section_name, size_t section_name_len)
    : section_name_(section_name, section_name_len)
  { }

  uint64_t
  value(const Expression_eval_info*);

  void
  print(FILE* f) const
  { fprintf(f, "%s(%s)", this->function_name(), this->section_name_.c_str()); }

 protected:
  // The child class must implement this.
  virtual uint64_t
  value_from_output_section(const Expression_eval_info*,
			    Output_section*) = 0;

  // The child class must implement this.
  virtual uint64_t
  value_from_script_output_section(uint64_t address, uint64_t load_address,
                                   uint64_t addralign, uint64_t size) = 0;

  // The child class must implement this.
  virtual const char*
  function_name() const = 0;

 private:
  std::string section_name_;
};

uint64_t
Section_expression::value(const Expression_eval_info* eei)
{
  const char* section_name = this->section_name_.c_str();
  Output_section* os = eei->layout->find_output_section(section_name);
  if (os != NULL)
    return this->value_from_output_section(eei, os);

  uint64_t address;
  uint64_t load_address;
  uint64_t addralign;
  uint64_t size;
  const Script_options* ss = eei->layout->script_options();
  if (ss->saw_sections_clause())
    {
      if (ss->script_sections()->get_output_section_info(section_name,
                                                         &address,
                                                         &load_address,
                                                         &addralign,
                                                         &size))
        return this->value_from_script_output_section(address, load_address,
                                                      addralign, size);
    }

  gold_error("%s called on nonexistent output section '%s'",
             this->function_name(), section_name);
  return 0;
}

// ABSOLUTE function.

class Absolute_expression : public Unary_expression
{
 public:
  Absolute_expression(Expression* arg)
    : Unary_expression(arg)
  { }

  uint64_t
  value(const Expression_eval_info* eei)
  {
    uint64_t ret = this->arg_value(eei, NULL);
    // Force the value to be absolute.
    if (eei->result_section_pointer != NULL)
      *eei->result_section_pointer = NULL;
    return ret;
  }

  void
  print(FILE* f) const
  {
    fprintf(f, "ABSOLUTE(");
    this->arg_print(f);
    fprintf(f, ")");
  }
};

extern "C" Expression*
script_exp_function_absolute(Expression* arg)
{
  return new Absolute_expression(arg);
}

// ALIGN function.

class Align_expression : public Binary_expression
{
 public:
  Align_expression(Expression* left, Expression* right)
    : Binary_expression(left, right)
  { }

  uint64_t
  value(const Expression_eval_info* eei)
  {
    Output_section* align_section;
    uint64_t align = this->right_value(eei, &align_section, NULL);
    if (align_section != NULL
	&& parameters->options().relocatable())
      gold_warning(_("aligning to section relative value"));

    if (eei->result_alignment_pointer != NULL
	&& align > *eei->result_alignment_pointer)
      {
	uint64_t a = align;
	while ((a & (a - 1)) != 0)
	  a &= a - 1;
	*eei->result_alignment_pointer = a;
      }

    uint64_t value = this->left_value(eei, eei->result_section_pointer, NULL);
    if (align <= 1)
      return value;
    return ((value + align - 1) / align) * align;
  }

  void
  print(FILE* f) const
  { this->print_function(f, "ALIGN"); }
};

extern "C" Expression*
script_exp_function_align(Expression* left, Expression* right)
{
  return new Align_expression(left, right);
}

// ASSERT function.

class Assert_expression : public Unary_expression
{
 public:
  Assert_expression(Expression* arg, const char* message, size_t length)
    : Unary_expression(arg), message_(message, length)
  { }

  uint64_t
  value(const Expression_eval_info* eei)
  {
    uint64_t value = this->arg_value(eei, eei->result_section_pointer);
    if (!value && eei->check_assertions)
      gold_error("%s", this->message_.c_str());
    return value;
  }

  void
  print(FILE* f) const
  {
    fprintf(f, "ASSERT(");
    this->arg_print(f);
    fprintf(f, ", %s)", this->message_.c_str());
  }

 private:
  std::string message_;
};

extern "C" Expression*
script_exp_function_assert(Expression* expr, const char* message,
			   size_t length)
{
  return new Assert_expression(expr, message, length);
}

// ADDR function.

class Addr_expression : public Section_expression
{
 public:
  Addr_expression(const char* section_name, size_t section_name_len)
    : Section_expression(section_name, section_name_len)
  { }

 protected:
  uint64_t
  value_from_output_section(const Expression_eval_info* eei,
			    Output_section* os)
  {
    if (eei->result_section_pointer != NULL)
      *eei->result_section_pointer = os;
    if (os->is_address_valid())
      return os->address();
    *eei->is_valid_pointer = false;
    return 0;
  }

  uint64_t
  value_from_script_output_section(uint64_t address, uint64_t, uint64_t,
                                   uint64_t)
  { return address; }

  const char*
  function_name() const
  { return "ADDR"; }
};

extern "C" Expression*
script_exp_function_addr(const char* section_name, size_t section_name_len)
{
  return new Addr_expression(section_name, section_name_len);
}

// ALIGNOF.

class Alignof_expression : public Section_expression
{
 public:
  Alignof_expression(const char* section_name, size_t section_name_len)
    : Section_expression(section_name, section_name_len)
  { }

 protected:
  uint64_t
  value_from_output_section(const Expression_eval_info*,
			    Output_section* os)
  { return os->addralign(); }

  uint64_t
  value_from_script_output_section(uint64_t, uint64_t, uint64_t addralign,
                                   uint64_t)
  { return addralign; }

  const char*
  function_name() const
  { return "ALIGNOF"; }
};

extern "C" Expression*
script_exp_function_alignof(const char* section_name, size_t section_name_len)
{
  return new Alignof_expression(section_name, section_name_len);
}

// CONSTANT.  It would be nice if we could simply evaluate this
// immediately and return an Integer_expression, but unfortunately we
// don't know the target.

class Constant_expression : public Expression
{
 public:
  Constant_expression(const char* name, size_t length);

  uint64_t
  value(const Expression_eval_info*);

  void
  print(FILE* f) const;

 private:
  enum Constant_function
  {
    CONSTANT_MAXPAGESIZE,
    CONSTANT_COMMONPAGESIZE
  };

  Constant_function function_;
};

Constant_expression::Constant_expression(const char* name, size_t length)
{
  if (length == 11 && strncmp(name, "MAXPAGESIZE", length) == 0)
    this->function_ = CONSTANT_MAXPAGESIZE;
  else if (length == 14 && strncmp(name, "COMMONPAGESIZE", length) == 0)
    this->function_ = CONSTANT_COMMONPAGESIZE;
  else
    {
      std::string s(name, length);
      gold_error(_("unknown constant %s"), s.c_str());
      this->function_ = CONSTANT_MAXPAGESIZE;
    }
}

uint64_t
Constant_expression::value(const Expression_eval_info*)
{
  switch (this->function_)
    {
    case CONSTANT_MAXPAGESIZE:
      return parameters->target().abi_pagesize();
    case CONSTANT_COMMONPAGESIZE:
      return parameters->target().common_pagesize();
    default:
      gold_unreachable();
    }
}

void
Constant_expression::print(FILE* f) const
{
  const char* name;
  switch (this->function_)
    {
    case CONSTANT_MAXPAGESIZE:
      name = "MAXPAGESIZE";
      break;
    case CONSTANT_COMMONPAGESIZE:
      name = "COMMONPAGESIZE";
      break;
    default:
      gold_unreachable();
    }
  fprintf(f, "CONSTANT(%s)", name);
}
  
extern "C" Expression*
script_exp_function_constant(const char* name, size_t length)
{
  return new Constant_expression(name, length);
}

// DATA_SEGMENT_ALIGN.  FIXME: we don't implement this; we always fall
// back to the general case.

extern "C" Expression*
script_exp_function_data_segment_align(Expression* left, Expression*)
{
  Expression* e1 = script_exp_function_align(script_exp_string(".", 1), left);
  Expression* e2 = script_exp_binary_sub(left, script_exp_integer(1));
  Expression* e3 = script_exp_binary_bitwise_and(script_exp_string(".", 1),
						 e2);
  return script_exp_binary_add(e1, e3);
}

// DATA_SEGMENT_RELRO.  FIXME: This is not implemented.

extern "C" Expression*
script_exp_function_data_segment_relro_end(Expression*, Expression* right)
{
  return right;
}

// DATA_SEGMENT_END.  FIXME: This is not implemented.

extern "C" Expression*
script_exp_function_data_segment_end(Expression* val)
{
  return val;
}

// DEFINED function.

class Defined_expression : public Expression
{
 public:
  Defined_expression(const char* symbol_name, size_t symbol_name_len)
    : symbol_name_(symbol_name, symbol_name_len)
  { }

  uint64_t
  value(const Expression_eval_info* eei)
  {
    Symbol* sym = eei->symtab->lookup(this->symbol_name_.c_str());
    return sym != NULL && sym->is_defined();
  }

  void
  print(FILE* f) const
  { fprintf(f, "DEFINED(%s)", this->symbol_name_.c_str()); }

 private:
  std::string symbol_name_;
};

extern "C" Expression*
script_exp_function_defined(const char* symbol_name, size_t symbol_name_len)
{
  return new Defined_expression(symbol_name, symbol_name_len);
}

// LOADADDR function

class Loadaddr_expression : public Section_expression
{
 public:
  Loadaddr_expression(const char* section_name, size_t section_name_len)
    : Section_expression(section_name, section_name_len)
  { }

 protected:
  uint64_t
  value_from_output_section(const Expression_eval_info* eei,
			    Output_section* os)
  {
    if (os->has_load_address())
      return os->load_address();
    else
      {
	if (eei->result_section_pointer != NULL)
	  *eei->result_section_pointer = os;
	return os->address();
      }
  }

  uint64_t
  value_from_script_output_section(uint64_t, uint64_t load_address, uint64_t,
                                   uint64_t)
  { return load_address; }

  const char*
  function_name() const
  { return "LOADADDR"; }
};

extern "C" Expression*
script_exp_function_loadaddr(const char* section_name, size_t section_name_len)
{
  return new Loadaddr_expression(section_name, section_name_len);
}

// SIZEOF function

class Sizeof_expression : public Section_expression
{
 public:
  Sizeof_expression(const char* section_name, size_t section_name_len)
    : Section_expression(section_name, section_name_len)
  { }

 protected:
  uint64_t
  value_from_output_section(const Expression_eval_info*,
			    Output_section* os)
  {
    // We can not use data_size here, as the size of the section may
    // not have been finalized.  Instead we get whatever the current
    // size is.  This will work correctly for backward references in
    // linker scripts.
    return os->current_data_size();
  }

  uint64_t
  value_from_script_output_section(uint64_t, uint64_t, uint64_t,
                                   uint64_t size)
  { return size; }

  const char*
  function_name() const
  { return "SIZEOF"; }
};

extern "C" Expression*
script_exp_function_sizeof(const char* section_name, size_t section_name_len)
{
  return new Sizeof_expression(section_name, section_name_len);
}

// SIZEOF_HEADERS.

class Sizeof_headers_expression : public Expression
{
 public:
  Sizeof_headers_expression()
  { }

  uint64_t
  value(const Expression_eval_info*);

  void
  print(FILE* f) const
  { fprintf(f, "SIZEOF_HEADERS"); }
};

uint64_t
Sizeof_headers_expression::value(const Expression_eval_info* eei)
{
  unsigned int ehdr_size;
  unsigned int phdr_size;
  if (parameters->target().get_size() == 32)
    {
      ehdr_size = elfcpp::Elf_sizes<32>::ehdr_size;
      phdr_size = elfcpp::Elf_sizes<32>::phdr_size;
    }
  else if (parameters->target().get_size() == 64)
    {
      ehdr_size = elfcpp::Elf_sizes<64>::ehdr_size;
      phdr_size = elfcpp::Elf_sizes<64>::phdr_size;
    }
  else
    gold_unreachable();

  return ehdr_size + phdr_size * eei->layout->expected_segment_count();
}

extern "C" Expression*
script_exp_function_sizeof_headers()
{
  return new Sizeof_headers_expression();
}

// SEGMENT_START.

class Segment_start_expression : public Unary_expression
{
 public:
  Segment_start_expression(const char* segment_name, size_t segment_name_len,
			   Expression* default_value)
    : Unary_expression(default_value),
      segment_name_(segment_name, segment_name_len)
  { }

  uint64_t
  value(const Expression_eval_info*);

  void
  print(FILE* f) const
  {
    fprintf(f, "SEGMENT_START(\"%s\", ", this->segment_name_.c_str());
    this->arg_print(f);
    fprintf(f, ")");
  }

 private:
  std::string segment_name_;
};

uint64_t
Segment_start_expression::value(const Expression_eval_info* eei)
{
  // Check for command line overrides.
  if (parameters->options().user_set_Ttext()
      && this->segment_name_ == ".text")
    return parameters->options().Ttext();
  else if (parameters->options().user_set_Tdata()
	   && this->segment_name_ == ".data")
    return parameters->options().Tdata();
  else if (parameters->options().user_set_Tbss()
	   && this->segment_name_ == ".bss")
    return parameters->options().Tbss();
  else
    {
      uint64_t ret = this->arg_value(eei, NULL);
      // Force the value to be absolute.
      if (eei->result_section_pointer != NULL)
        *eei->result_section_pointer = NULL;
      return ret;
    }
}

extern "C" Expression*
script_exp_function_segment_start(const char* segment_name,
				  size_t segment_name_len,
				  Expression* default_value)
{
  return new Segment_start_expression(segment_name, segment_name_len,
				      default_value);
}

} // End namespace gold.
