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

// Copyright (C) 2006-2015 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;
};

// 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);
}

// 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);
}

// 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)
{
  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;

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

  // 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);
  }

  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);
  }

  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);
  }

  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);
  }

  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);
  }

  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);
  }

  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;
    return os->address();
  }

  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.
