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

// Copyright 2006, 2007, 2008 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;
};

// Evaluate an expression.

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

// 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)
{
  return this->eval_maybe_dot(symtab, layout, check_assertions, true,
			      dot_value, dot_section, result_section_pointer);
}

// 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)
{
  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.
  *result_section_pointer = NULL;
  eei.result_section_pointer = result_section_pointer;

  return this->value(&eei);
}

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

  *eei->result_section_pointer = sym->output_section();

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

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

  uint64_t
  right_value(const Expression_eval_info* eei,
	      Output_section** section_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);
  }

  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 = this->left_value(eei, &left_section);		\
      Output_section* right_section;					\
      uint64_t right = this->right_value(eei, &right_section);		\
      if (KEEP_RIGHT && left_section == NULL && right_section != NULL)	\
	*eei->result_section_pointer = right_section;			\
      else if (KEEP_LEFT						\
	       && left_section != NULL					\
	       && right_section == NULL)				\
	*eei->result_section_pointer = left_section;			\
      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);
  }

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

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

  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)
	    : this->arg3_value(eei, eei->result_section_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 = this->left_value(eei, &left_section);
    Output_section* right_section;
    uint64_t right = this->right_value(eei, &right_section);
    if (left_section == right_section)
      *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"));
    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 = this->left_value(eei, &left_section);
    Output_section* right_section;
    uint64_t right = this->right_value(eei, &right_section);
    if (left_section == right_section)
      *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"));
    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)
  {
    Output_section* dummy;
    uint64_t ret = this->arg_value(eei, &dummy);
    // Force the value to be absolute.
    *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);
    if (align_section != NULL
	&& parameters->options().relocatable())
      gold_warning(_("aligning to section relative value"));

    uint64_t value = this->left_value(eei, eei->result_section_pointer);
    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)
  {
    *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
      {
	*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();
}

// In the GNU linker SEGMENT_START basically returns the value for
// -Ttext, -Tdata, or -Tbss.  We could implement this by copying the
// values from General_options to Parameters.  But I doubt that
// anybody actually uses it.  The point of it for the GNU linker was
// because -Ttext set the address of the .text section rather than the
// text segment.  In gold -Ttext sets the text segment address anyhow.

extern "C" Expression*
script_exp_function_segment_start(const char*, size_t, Expression*)
{
  gold_fatal(_("SEGMENT_START not implemented"));
}

// Functions for memory regions.  These can not be implemented unless
// and until we implement memory regions.

extern "C" Expression*
script_exp_function_origin(const char*, size_t)
{
  gold_fatal(_("ORIGIN not implemented"));
}

extern "C" Expression*
script_exp_function_length(const char*, size_t)
{
  gold_fatal(_("LENGTH not implemented"));
}

} // End namespace gold.
