// script.cc -- handle 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 <cstdio>
#include <cstdlib>
#include <cstring>
#include <fnmatch.h>
#include <string>
#include <vector>
#include "filenames.h"

#include "elfcpp.h"
#include "demangle.h"
#include "dirsearch.h"
#include "options.h"
#include "fileread.h"
#include "workqueue.h"
#include "readsyms.h"
#include "parameters.h"
#include "layout.h"
#include "symtab.h"
#include "target-select.h"
#include "script.h"
#include "script-c.h"
#include "incremental.h"

namespace gold
{

// A token read from a script file.  We don't implement keywords here;
// all keywords are simply represented as a string.

class Token
{
 public:
  // Token classification.
  enum Classification
  {
    // Token is invalid.
    TOKEN_INVALID,
    // Token indicates end of input.
    TOKEN_EOF,
    // Token is a string of characters.
    TOKEN_STRING,
    // Token is a quoted string of characters.
    TOKEN_QUOTED_STRING,
    // Token is an operator.
    TOKEN_OPERATOR,
    // Token is a number (an integer).
    TOKEN_INTEGER
  };

  // We need an empty constructor so that we can put this STL objects.
  Token()
    : classification_(TOKEN_INVALID), value_(NULL), value_length_(0),
      opcode_(0), lineno_(0), charpos_(0)
  { }

  // A general token with no value.
  Token(Classification classification, int lineno, int charpos)
    : classification_(classification), value_(NULL), value_length_(0),
      opcode_(0), lineno_(lineno), charpos_(charpos)
  {
    gold_assert(classification == TOKEN_INVALID
		|| classification == TOKEN_EOF);
  }

  // A general token with a value.
  Token(Classification classification, const char* value, size_t length,
	int lineno, int charpos)
    : classification_(classification), value_(value), value_length_(length),
      opcode_(0), lineno_(lineno), charpos_(charpos)
  {
    gold_assert(classification != TOKEN_INVALID
		&& classification != TOKEN_EOF);
  }

  // A token representing an operator.
  Token(int opcode, int lineno, int charpos)
    : classification_(TOKEN_OPERATOR), value_(NULL), value_length_(0),
      opcode_(opcode), lineno_(lineno), charpos_(charpos)
  { }

  // Return whether the token is invalid.
  bool
  is_invalid() const
  { return this->classification_ == TOKEN_INVALID; }

  // Return whether this is an EOF token.
  bool
  is_eof() const
  { return this->classification_ == TOKEN_EOF; }

  // Return the token classification.
  Classification
  classification() const
  { return this->classification_; }

  // Return the line number at which the token starts.
  int
  lineno() const
  { return this->lineno_; }

  // Return the character position at this the token starts.
  int
  charpos() const
  { return this->charpos_; }

  // Get the value of a token.

  const char*
  string_value(size_t* length) const
  {
    gold_assert(this->classification_ == TOKEN_STRING
		|| this->classification_ == TOKEN_QUOTED_STRING);
    *length = this->value_length_;
    return this->value_;
  }

  int
  operator_value() const
  {
    gold_assert(this->classification_ == TOKEN_OPERATOR);
    return this->opcode_;
  }

  uint64_t
  integer_value() const;

 private:
  // The token classification.
  Classification classification_;
  // The token value, for TOKEN_STRING or TOKEN_QUOTED_STRING or
  // TOKEN_INTEGER.
  const char* value_;
  // The length of the token value.
  size_t value_length_;
  // The token value, for TOKEN_OPERATOR.
  int opcode_;
  // The line number where this token started (one based).
  int lineno_;
  // The character position within the line where this token started
  // (one based).
  int charpos_;
};

// Return the value of a TOKEN_INTEGER.

uint64_t
Token::integer_value() const
{
  gold_assert(this->classification_ == TOKEN_INTEGER);

  size_t len = this->value_length_;

  uint64_t multiplier = 1;
  char last = this->value_[len - 1];
  if (last == 'm' || last == 'M')
    {
      multiplier = 1024 * 1024;
      --len;
    }
  else if (last == 'k' || last == 'K')
    {
      multiplier = 1024;
      --len;
    }

  char *end;
  uint64_t ret = strtoull(this->value_, &end, 0);
  gold_assert(static_cast<size_t>(end - this->value_) == len);

  return ret * multiplier;
}

// This class handles lexing a file into a sequence of tokens.

class Lex
{
 public:
  // We unfortunately have to support different lexing modes, because
  // when reading different parts of a linker script we need to parse
  // things differently.
  enum Mode
  {
    // Reading an ordinary linker script.
    LINKER_SCRIPT,
    // Reading an expression in a linker script.
    EXPRESSION,
    // Reading a version script.
    VERSION_SCRIPT,
    // Reading a --dynamic-list file.
    DYNAMIC_LIST
  };

  Lex(const char* input_string, size_t input_length, int parsing_token)
    : input_string_(input_string), input_length_(input_length),
      current_(input_string), mode_(LINKER_SCRIPT),
      first_token_(parsing_token), token_(),
      lineno_(1), linestart_(input_string)
  { }

  // Read a file into a string.
  static void
  read_file(Input_file*, std::string*);

  // Return the next token.
  const Token*
  next_token();

  // Return the current lexing mode.
  Lex::Mode
  mode() const
  { return this->mode_; }

  // Set the lexing mode.
  void
  set_mode(Mode mode)
  { this->mode_ = mode; }

 private:
  Lex(const Lex&);
  Lex& operator=(const Lex&);

  // Make a general token with no value at the current location.
  Token
  make_token(Token::Classification c, const char* start) const
  { return Token(c, this->lineno_, start - this->linestart_ + 1); }

  // Make a general token with a value at the current location.
  Token
  make_token(Token::Classification c, const char* v, size_t len,
	     const char* start)
    const
  { return Token(c, v, len, this->lineno_, start - this->linestart_ + 1); }

  // Make an operator token at the current location.
  Token
  make_token(int opcode, const char* start) const
  { return Token(opcode, this->lineno_, start - this->linestart_ + 1); }

  // Make an invalid token at the current location.
  Token
  make_invalid_token(const char* start)
  { return this->make_token(Token::TOKEN_INVALID, start); }

  // Make an EOF token at the current location.
  Token
  make_eof_token(const char* start)
  { return this->make_token(Token::TOKEN_EOF, start); }

  // Return whether C can be the first character in a name.  C2 is the
  // next character, since we sometimes need that.
  inline bool
  can_start_name(char c, char c2);

  // If C can appear in a name which has already started, return a
  // pointer to a character later in the token or just past
  // it. Otherwise, return NULL.
  inline const char*
  can_continue_name(const char* c);

  // Return whether C, C2, C3 can start a hex number.
  inline bool
  can_start_hex(char c, char c2, char c3);

  // If C can appear in a hex number which has already started, return
  // a pointer to a character later in the token or just past
  // it. Otherwise, return NULL.
  inline const char*
  can_continue_hex(const char* c);

  // Return whether C can start a non-hex number.
  static inline bool
  can_start_number(char c);

  // If C can appear in a decimal number which has already started,
  // return a pointer to a character later in the token or just past
  // it. Otherwise, return NULL.
  inline const char*
  can_continue_number(const char* c)
  { return Lex::can_start_number(*c) ? c + 1 : NULL; }

  // If C1 C2 C3 form a valid three character operator, return the
  // opcode.  Otherwise return 0.
  static inline int
  three_char_operator(char c1, char c2, char c3);

  // If C1 C2 form a valid two character operator, return the opcode.
  // Otherwise return 0.
  static inline int
  two_char_operator(char c1, char c2);

  // If C1 is a valid one character operator, return the opcode.
  // Otherwise return 0.
  static inline int
  one_char_operator(char c1);

  // Read the next token.
  Token
  get_token(const char**);

  // Skip a C style /* */ comment.  Return false if the comment did
  // not end.
  bool
  skip_c_comment(const char**);

  // Skip a line # comment.  Return false if there was no newline.
  bool
  skip_line_comment(const char**);

  // Build a token CLASSIFICATION from all characters that match
  // CAN_CONTINUE_FN.  The token starts at START.  Start matching from
  // MATCH.  Set *PP to the character following the token.
  inline Token
  gather_token(Token::Classification,
	       const char* (Lex::*can_continue_fn)(const char*),
	       const char* start, const char* match, const char** pp);

  // Build a token from a quoted string.
  Token
  gather_quoted_string(const char** pp);

  // The string we are tokenizing.
  const char* input_string_;
  // The length of the string.
  size_t input_length_;
  // The current offset into the string.
  const char* current_;
  // The current lexing mode.
  Mode mode_;
  // The code to use for the first token.  This is set to 0 after it
  // is used.
  int first_token_;
  // The current token.
  Token token_;
  // The current line number.
  int lineno_;
  // The start of the current line in the string.
  const char* linestart_;
};

// Read the whole file into memory.  We don't expect linker scripts to
// be large, so we just use a std::string as a buffer.  We ignore the
// data we've already read, so that we read aligned buffers.

void
Lex::read_file(Input_file* input_file, std::string* contents)
{
  off_t filesize = input_file->file().filesize();
  contents->clear();
  contents->reserve(filesize);

  off_t off = 0;
  unsigned char buf[BUFSIZ];
  while (off < filesize)
    {
      off_t get = BUFSIZ;
      if (get > filesize - off)
	get = filesize - off;
      input_file->file().read(off, get, buf);
      contents->append(reinterpret_cast<char*>(&buf[0]), get);
      off += get;
    }
}

// Return whether C can be the start of a name, if the next character
// is C2.  A name can being with a letter, underscore, period, or
// dollar sign.  Because a name can be a file name, we also permit
// forward slash, backslash, and tilde.  Tilde is the tricky case
// here; GNU ld also uses it as a bitwise not operator.  It is only
// recognized as the operator if it is not immediately followed by
// some character which can appear in a symbol.  That is, when we
// don't know that we are looking at an expression, "~0" is a file
// name, and "~ 0" is an expression using bitwise not.  We are
// compatible.

inline bool
Lex::can_start_name(char c, char c2)
{
  switch (c)
    {
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
    case 'M': case 'N': case 'O': case 'Q': case 'P': case 'R':
    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
    case 'Y': case 'Z':
    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
    case 'm': case 'n': case 'o': case 'q': case 'p': case 'r':
    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
    case 'y': case 'z':
    case '_': case '.': case '$':
      return true;

    case '/': case '\\':
      return this->mode_ == LINKER_SCRIPT;

    case '~':
      return this->mode_ == LINKER_SCRIPT && can_continue_name(&c2);

    case '*': case '[':
      return (this->mode_ == VERSION_SCRIPT
              || this->mode_ == DYNAMIC_LIST
	      || (this->mode_ == LINKER_SCRIPT
		  && can_continue_name(&c2)));

    default:
      return false;
    }
}

// Return whether C can continue a name which has already started.
// Subsequent characters in a name are the same as the leading
// characters, plus digits and "=+-:[],?*".  So in general the linker
// script language requires spaces around operators, unless we know
// that we are parsing an expression.

inline const char*
Lex::can_continue_name(const char* c)
{
  switch (*c)
    {
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
    case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
    case 'M': case 'N': case 'O': case 'Q': case 'P': case 'R':
    case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
    case 'Y': case 'Z':
    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
    case 'm': case 'n': case 'o': case 'q': case 'p': case 'r':
    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
    case 'y': case 'z':
    case '_': case '.': case '$':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      return c + 1;

    // TODO(csilvers): why not allow ~ in names for version-scripts?
    case '/': case '\\': case '~':
    case '=': case '+':
    case ',':
      if (this->mode_ == LINKER_SCRIPT)
        return c + 1;
      return NULL;

    case '[': case ']': case '*': case '?': case '-':
      if (this->mode_ == LINKER_SCRIPT || this->mode_ == VERSION_SCRIPT
          || this->mode_ == DYNAMIC_LIST)
        return c + 1;
      return NULL;

    // TODO(csilvers): why allow this?  ^ is meaningless in version scripts.
    case '^':
      if (this->mode_ == VERSION_SCRIPT || this->mode_ == DYNAMIC_LIST)
        return c + 1;
      return NULL;

    case ':':
      if (this->mode_ == LINKER_SCRIPT)
        return c + 1;
      else if ((this->mode_ == VERSION_SCRIPT || this->mode_ == DYNAMIC_LIST)
               && (c[1] == ':'))
        {
          // A name can have '::' in it, as that's a c++ namespace
          // separator. But a single colon is not part of a name.
          return c + 2;
        }
      return NULL;

    default:
      return NULL;
    }
}

// For a number we accept 0x followed by hex digits, or any sequence
// of digits.  The old linker accepts leading '$' for hex, and
// trailing HXBOD.  Those are for MRI compatibility and we don't
// accept them.

// Return whether C1 C2 C3 can start a hex number.

inline bool
Lex::can_start_hex(char c1, char c2, char c3)
{
  if (c1 == '0' && (c2 == 'x' || c2 == 'X'))
    return this->can_continue_hex(&c3);
  return false;
}

// Return whether C can appear in a hex number.

inline const char*
Lex::can_continue_hex(const char* c)
{
  switch (*c)
    {
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
      return c + 1;

    default:
      return NULL;
    }
}

// Return whether C can start a non-hex number.

inline bool
Lex::can_start_number(char c)
{
  switch (c)
    {
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
      return true;

    default:
      return false;
    }
}

// If C1 C2 C3 form a valid three character operator, return the
// opcode (defined in the yyscript.h file generated from yyscript.y).
// Otherwise return 0.

inline int
Lex::three_char_operator(char c1, char c2, char c3)
{
  switch (c1)
    {
    case '<':
      if (c2 == '<' && c3 == '=')
	return LSHIFTEQ;
      break;
    case '>':
      if (c2 == '>' && c3 == '=')
	return RSHIFTEQ;
      break;
    default:
      break;
    }
  return 0;
}

// If C1 C2 form a valid two character operator, return the opcode
// (defined in the yyscript.h file generated from yyscript.y).
// Otherwise return 0.

inline int
Lex::two_char_operator(char c1, char c2)
{
  switch (c1)
    {
    case '=':
      if (c2 == '=')
	return EQ;
      break;
    case '!':
      if (c2 == '=')
	return NE;
      break;
    case '+':
      if (c2 == '=')
	return PLUSEQ;
      break;
    case '-':
      if (c2 == '=')
	return MINUSEQ;
      break;
    case '*':
      if (c2 == '=')
	return MULTEQ;
      break;
    case '/':
      if (c2 == '=')
	return DIVEQ;
      break;
    case '|':
      if (c2 == '=')
	return OREQ;
      if (c2 == '|')
	return OROR;
      break;
    case '&':
      if (c2 == '=')
	return ANDEQ;
      if (c2 == '&')
	return ANDAND;
      break;
    case '>':
      if (c2 == '=')
	return GE;
      if (c2 == '>')
	return RSHIFT;
      break;
    case '<':
      if (c2 == '=')
	return LE;
      if (c2 == '<')
	return LSHIFT;
      break;
    default:
      break;
    }
  return 0;
}

// If C1 is a valid operator, return the opcode.  Otherwise return 0.

inline int
Lex::one_char_operator(char c1)
{
  switch (c1)
    {
    case '+':
    case '-':
    case '*':
    case '/':
    case '%':
    case '!':
    case '&':
    case '|':
    case '^':
    case '~':
    case '<':
    case '>':
    case '=':
    case '?':
    case ',':
    case '(':
    case ')':
    case '{':
    case '}':
    case '[':
    case ']':
    case ':':
    case ';':
      return c1;
    default:
      return 0;
    }
}

// Skip a C style comment.  *PP points to just after the "/*".  Return
// false if the comment did not end.

bool
Lex::skip_c_comment(const char** pp)
{
  const char* p = *pp;
  while (p[0] != '*' || p[1] != '/')
    {
      if (*p == '\0')
	{
	  *pp = p;
	  return false;
	}

      if (*p == '\n')
	{
	  ++this->lineno_;
	  this->linestart_ = p + 1;
	}
      ++p;
    }

  *pp = p + 2;
  return true;
}

// Skip a line # comment.  Return false if there was no newline.

bool
Lex::skip_line_comment(const char** pp)
{
  const char* p = *pp;
  size_t skip = strcspn(p, "\n");
  if (p[skip] == '\0')
    {
      *pp = p + skip;
      return false;
    }

  p += skip + 1;
  ++this->lineno_;
  this->linestart_ = p;
  *pp = p;

  return true;
}

// Build a token CLASSIFICATION from all characters that match
// CAN_CONTINUE_FN.  Update *PP.

inline Token
Lex::gather_token(Token::Classification classification,
		  const char* (Lex::*can_continue_fn)(const char*),
		  const char* start,
		  const char* match,
		  const char** pp)
{
  const char* new_match = NULL;
  while ((new_match = (this->*can_continue_fn)(match)) != NULL)
    match = new_match;

  // A special case: integers may be followed by a single M or K,
  // case-insensitive.
  if (classification == Token::TOKEN_INTEGER
      && (*match == 'm' || *match == 'M' || *match == 'k' || *match == 'K'))
    ++match;

  *pp = match;
  return this->make_token(classification, start, match - start, start);
}

// Build a token from a quoted string.

Token
Lex::gather_quoted_string(const char** pp)
{
  const char* start = *pp;
  const char* p = start;
  ++p;
  size_t skip = strcspn(p, "\"\n");
  if (p[skip] != '"')
    return this->make_invalid_token(start);
  *pp = p + skip + 1;
  return this->make_token(Token::TOKEN_QUOTED_STRING, p, skip, start);
}

// Return the next token at *PP.  Update *PP.  General guideline: we
// require linker scripts to be simple ASCII.  No unicode linker
// scripts.  In particular we can assume that any '\0' is the end of
// the input.

Token
Lex::get_token(const char** pp)
{
  const char* p = *pp;

  while (true)
    {
      if (*p == '\0')
	{
	  *pp = p;
	  return this->make_eof_token(p);
	}

      // Skip whitespace quickly.
      while (*p == ' ' || *p == '\t' || *p == '\r')
	++p;

      if (*p == '\n')
	{
	  ++p;
	  ++this->lineno_;
	  this->linestart_ = p;
	  continue;
	}

      // Skip C style comments.
      if (p[0] == '/' && p[1] == '*')
	{
	  int lineno = this->lineno_;
	  int charpos = p - this->linestart_ + 1;

	  *pp = p + 2;
	  if (!this->skip_c_comment(pp))
	    return Token(Token::TOKEN_INVALID, lineno, charpos);
	  p = *pp;

	  continue;
	}

      // Skip line comments.
      if (*p == '#')
	{
	  *pp = p + 1;
	  if (!this->skip_line_comment(pp))
	    return this->make_eof_token(p);
	  p = *pp;
	  continue;
	}

      // Check for a name.
      if (this->can_start_name(p[0], p[1]))
	return this->gather_token(Token::TOKEN_STRING,
				  &Lex::can_continue_name,
				  p, p + 1, pp);

      // We accept any arbitrary name in double quotes, as long as it
      // does not cross a line boundary.
      if (*p == '"')
	{
	  *pp = p;
	  return this->gather_quoted_string(pp);
	}

      // Check for a number.

      if (this->can_start_hex(p[0], p[1], p[2]))
	return this->gather_token(Token::TOKEN_INTEGER,
				  &Lex::can_continue_hex,
				  p, p + 3, pp);

      if (Lex::can_start_number(p[0]))
	return this->gather_token(Token::TOKEN_INTEGER,
				  &Lex::can_continue_number,
				  p, p + 1, pp);

      // Check for operators.

      int opcode = Lex::three_char_operator(p[0], p[1], p[2]);
      if (opcode != 0)
	{
	  *pp = p + 3;
	  return this->make_token(opcode, p);
	}

      opcode = Lex::two_char_operator(p[0], p[1]);
      if (opcode != 0)
	{
	  *pp = p + 2;
	  return this->make_token(opcode, p);
	}

      opcode = Lex::one_char_operator(p[0]);
      if (opcode != 0)
	{
	  *pp = p + 1;
	  return this->make_token(opcode, p);
	}

      return this->make_token(Token::TOKEN_INVALID, p);
    }
}

// Return the next token.

const Token*
Lex::next_token()
{
  // The first token is special.
  if (this->first_token_ != 0)
    {
      this->token_ = Token(this->first_token_, 0, 0);
      this->first_token_ = 0;
      return &this->token_;
    }

  this->token_ = this->get_token(&this->current_);

  // Don't let an early null byte fool us into thinking that we've
  // reached the end of the file.
  if (this->token_.is_eof()
      && (static_cast<size_t>(this->current_ - this->input_string_)
	  < this->input_length_))
    this->token_ = this->make_invalid_token(this->current_);

  return &this->token_;
}

// class Symbol_assignment.

// Add the symbol to the symbol table.  This makes sure the symbol is
// there and defined.  The actual value is stored later.  We can't
// determine the actual value at this point, because we can't
// necessarily evaluate the expression until all ordinary symbols have
// been finalized.

// The GNU linker lets symbol assignments in the linker script
// silently override defined symbols in object files.  We are
// compatible.  FIXME: Should we issue a warning?

void
Symbol_assignment::add_to_table(Symbol_table* symtab)
{
  elfcpp::STV vis = this->hidden_ ? elfcpp::STV_HIDDEN : elfcpp::STV_DEFAULT;
  this->sym_ = symtab->define_as_constant(this->name_.c_str(),
					  NULL, // version
					  (this->is_defsym_
					   ? Symbol_table::DEFSYM
					   : Symbol_table::SCRIPT),
					  0, // value
					  0, // size
					  elfcpp::STT_NOTYPE,
					  elfcpp::STB_GLOBAL,
					  vis,
					  0, // nonvis
					  this->provide_,
                                          true); // force_override
}

// Finalize a symbol value.

void
Symbol_assignment::finalize(Symbol_table* symtab, const Layout* layout)
{
  this->finalize_maybe_dot(symtab, layout, false, 0, NULL);
}

// Finalize a symbol value which can refer to the dot symbol.

void
Symbol_assignment::finalize_with_dot(Symbol_table* symtab,
				     const Layout* layout,
				     uint64_t dot_value,
				     Output_section* dot_section)
{
  this->finalize_maybe_dot(symtab, layout, true, dot_value, dot_section);
}

// Finalize a symbol value, internal version.

void
Symbol_assignment::finalize_maybe_dot(Symbol_table* symtab,
				      const Layout* layout,
				      bool is_dot_available,
				      uint64_t dot_value,
				      Output_section* dot_section)
{
  // If we were only supposed to provide this symbol, the sym_ field
  // will be NULL if the symbol was not referenced.
  if (this->sym_ == NULL)
    {
      gold_assert(this->provide_);
      return;
    }

  if (parameters->target().get_size() == 32)
    {
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
      this->sized_finalize<32>(symtab, layout, is_dot_available, dot_value,
			       dot_section);
#else
      gold_unreachable();
#endif
    }
  else if (parameters->target().get_size() == 64)
    {
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
      this->sized_finalize<64>(symtab, layout, is_dot_available, dot_value,
			       dot_section);
#else
      gold_unreachable();
#endif
    }
  else
    gold_unreachable();
}

template<int size>
void
Symbol_assignment::sized_finalize(Symbol_table* symtab, const Layout* layout,
				  bool is_dot_available, uint64_t dot_value,
				  Output_section* dot_section)
{
  Output_section* section;
  elfcpp::STT type = elfcpp::STT_NOTYPE;
  elfcpp::STV vis = elfcpp::STV_DEFAULT;
  unsigned char nonvis = 0;
  uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout, true,
						  is_dot_available,
						  dot_value, dot_section,
						  &section, NULL, &type,
						  &vis, &nonvis, false, NULL);
  Sized_symbol<size>* ssym = symtab->get_sized_symbol<size>(this->sym_);
  ssym->set_value(final_val);
  ssym->set_type(type);
  ssym->set_visibility(vis);
  ssym->set_nonvis(nonvis);
  if (section != NULL)
    ssym->set_output_section(section);
}

// Set the symbol value if the expression yields an absolute value or
// a value relative to DOT_SECTION.

void
Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout,
				   bool is_dot_available, uint64_t dot_value,
				   Output_section* dot_section)
{
  if (this->sym_ == NULL)
    return;

  Output_section* val_section;
  bool is_valid;
  uint64_t val = this->val_->eval_maybe_dot(symtab, layout, false,
					    is_dot_available, dot_value,
					    dot_section, &val_section, NULL,
					    NULL, NULL, NULL, false, &is_valid);
  if (!is_valid || (val_section != NULL && val_section != dot_section))
    return;

  if (parameters->target().get_size() == 32)
    {
#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_32_BIG)
      Sized_symbol<32>* ssym = symtab->get_sized_symbol<32>(this->sym_);
      ssym->set_value(val);
#else
      gold_unreachable();
#endif
    }
  else if (parameters->target().get_size() == 64)
    {
#if defined(HAVE_TARGET_64_LITTLE) || defined(HAVE_TARGET_64_BIG)
      Sized_symbol<64>* ssym = symtab->get_sized_symbol<64>(this->sym_);
      ssym->set_value(val);
#else
      gold_unreachable();
#endif
    }
  else
    gold_unreachable();
  if (val_section != NULL)
    this->sym_->set_output_section(val_section);
}

// Print for debugging.

void
Symbol_assignment::print(FILE* f) const
{
  if (this->provide_ && this->hidden_)
    fprintf(f, "PROVIDE_HIDDEN(");
  else if (this->provide_)
    fprintf(f, "PROVIDE(");
  else if (this->hidden_)
    gold_unreachable();

  fprintf(f, "%s = ", this->name_.c_str());
  this->val_->print(f);

  if (this->provide_ || this->hidden_)
    fprintf(f, ")");

  fprintf(f, "\n");
}

// Class Script_assertion.

// Check the assertion.

void
Script_assertion::check(const Symbol_table* symtab, const Layout* layout)
{
  if (!this->check_->eval(symtab, layout, true))
    gold_error("%s", this->message_.c_str());
}

// Print for debugging.

void
Script_assertion::print(FILE* f) const
{
  fprintf(f, "ASSERT(");
  this->check_->print(f);
  fprintf(f, ", \"%s\")\n", this->message_.c_str());
}

// Class Script_options.

Script_options::Script_options()
  : entry_(), symbol_assignments_(), symbol_definitions_(),
    symbol_references_(), version_script_info_(), script_sections_()
{
}

// Returns true if NAME is on the list of symbol assignments waiting
// to be processed.

bool
Script_options::is_pending_assignment(const char* name)
{
  for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
       p != this->symbol_assignments_.end();
       ++p)
    if ((*p)->name() == name)
      return true;
  return false;
}

// Add a symbol to be defined.

void
Script_options::add_symbol_assignment(const char* name, size_t length,
				      bool is_defsym, Expression* value,
				      bool provide, bool hidden)
{
  if (length != 1 || name[0] != '.')
    {
      if (this->script_sections_.in_sections_clause())
	{
	  gold_assert(!is_defsym);
	  this->script_sections_.add_symbol_assignment(name, length, value,
						       provide, hidden);
	}
      else
	{
	  Symbol_assignment* p = new Symbol_assignment(name, length, is_defsym,
						       value, provide, hidden);
	  this->symbol_assignments_.push_back(p);
	}

      if (!provide)
	{
	  std::string n(name, length);
	  this->symbol_definitions_.insert(n);
	  this->symbol_references_.erase(n);
	}
    }
  else
    {
      if (provide || hidden)
	gold_error(_("invalid use of PROVIDE for dot symbol"));

      // The GNU linker permits assignments to dot outside of SECTIONS
      // clauses and treats them as occurring inside, so we don't
      // check in_sections_clause here.
      this->script_sections_.add_dot_assignment(value);
    }
}

// Add a reference to a symbol.

void
Script_options::add_symbol_reference(const char* name, size_t length)
{
  if (length != 1 || name[0] != '.')
    {
      std::string n(name, length);
      if (this->symbol_definitions_.find(n) == this->symbol_definitions_.end())
	this->symbol_references_.insert(n);
    }
}

// Add an assertion.

void
Script_options::add_assertion(Expression* check, const char* message,
			      size_t messagelen)
{
  if (this->script_sections_.in_sections_clause())
    this->script_sections_.add_assertion(check, message, messagelen);
  else
    {
      Script_assertion* p = new Script_assertion(check, message, messagelen);
      this->assertions_.push_back(p);
    }
}

// Create sections required by any linker scripts.

void
Script_options::create_script_sections(Layout* layout)
{
  if (this->saw_sections_clause())
    this->script_sections_.create_sections(layout);
}

// Add any symbols we are defining to the symbol table.

void
Script_options::add_symbols_to_table(Symbol_table* symtab)
{
  for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
       p != this->symbol_assignments_.end();
       ++p)
    (*p)->add_to_table(symtab);
  this->script_sections_.add_symbols_to_table(symtab);
}

// Finalize symbol values.  Also check assertions.

void
Script_options::finalize_symbols(Symbol_table* symtab, const Layout* layout)
{
  // We finalize the symbols defined in SECTIONS first, because they
  // are the ones which may have changed.  This way if symbol outside
  // SECTIONS are defined in terms of symbols inside SECTIONS, they
  // will get the right value.
  this->script_sections_.finalize_symbols(symtab, layout);

  for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
       p != this->symbol_assignments_.end();
       ++p)
    (*p)->finalize(symtab, layout);

  for (Assertions::iterator p = this->assertions_.begin();
       p != this->assertions_.end();
       ++p)
    (*p)->check(symtab, layout);
}

// Set section addresses.  We set all the symbols which have absolute
// values.  Then we let the SECTIONS clause do its thing.  This
// returns the segment which holds the file header and segment
// headers, if any.

Output_segment*
Script_options::set_section_addresses(Symbol_table* symtab, Layout* layout)
{
  for (Symbol_assignments::iterator p = this->symbol_assignments_.begin();
       p != this->symbol_assignments_.end();
       ++p)
    (*p)->set_if_absolute(symtab, layout, false, 0, NULL);

  return this->script_sections_.set_section_addresses(symtab, layout);
}

// This class holds data passed through the parser to the lexer and to
// the parser support functions.  This avoids global variables.  We
// can't use global variables because we need not be called by a
// singleton thread.

class Parser_closure
{
 public:
  Parser_closure(const char* filename,
		 const Position_dependent_options& posdep_options,
		 bool parsing_defsym, bool in_group, bool is_in_sysroot,
                 Command_line* command_line,
		 Script_options* script_options,
		 Lex* lex,
		 bool skip_on_incompatible_target,
		 Script_info* script_info)
    : filename_(filename), posdep_options_(posdep_options),
      parsing_defsym_(parsing_defsym), in_group_(in_group),
      is_in_sysroot_(is_in_sysroot),
      skip_on_incompatible_target_(skip_on_incompatible_target),
      found_incompatible_target_(false),
      command_line_(command_line), script_options_(script_options),
      version_script_info_(script_options->version_script_info()),
      lex_(lex), lineno_(0), charpos_(0), lex_mode_stack_(), inputs_(NULL),
      script_info_(script_info)
  {
    // We start out processing C symbols in the default lex mode.
    this->language_stack_.push_back(Version_script_info::LANGUAGE_C);
    this->lex_mode_stack_.push_back(lex->mode());
  }

  // Return the file name.
  const char*
  filename() const
  { return this->filename_; }

  // Return the position dependent options.  The caller may modify
  // this.
  Position_dependent_options&
  position_dependent_options()
  { return this->posdep_options_; }

  // Whether we are parsing a --defsym.
  bool
  parsing_defsym() const
  { return this->parsing_defsym_; }

  // Return whether this script is being run in a group.
  bool
  in_group() const
  { return this->in_group_; }

  // Return whether this script was found using a directory in the
  // sysroot.
  bool
  is_in_sysroot() const
  { return this->is_in_sysroot_; }

  // Whether to skip to the next file with the same name if we find an
  // incompatible target in an OUTPUT_FORMAT statement.
  bool
  skip_on_incompatible_target() const
  { return this->skip_on_incompatible_target_; }

  // Stop skipping to the next file on an incompatible target.  This
  // is called when we make some unrevocable change to the data
  // structures.
  void
  clear_skip_on_incompatible_target()
  { this->skip_on_incompatible_target_ = false; }

  // Whether we found an incompatible target in an OUTPUT_FORMAT
  // statement.
  bool
  found_incompatible_target() const
  { return this->found_incompatible_target_; }

  // Note that we found an incompatible target.
  void
  set_found_incompatible_target()
  { this->found_incompatible_target_ = true; }

  // Returns the Command_line structure passed in at constructor time.
  // This value may be NULL.  The caller may modify this, which modifies
  // the passed-in Command_line object (not a copy).
  Command_line*
  command_line()
  { return this->command_line_; }

  // Return the options which may be set by a script.
  Script_options*
  script_options()
  { return this->script_options_; }

  // Return the object in which version script information should be stored.
  Version_script_info*
  version_script()
  { return this->version_script_info_; }

  // Return the next token, and advance.
  const Token*
  next_token()
  {
    const Token* token = this->lex_->next_token();
    this->lineno_ = token->lineno();
    this->charpos_ = token->charpos();
    return token;
  }

  // Set a new lexer mode, pushing the current one.
  void
  push_lex_mode(Lex::Mode mode)
  {
    this->lex_mode_stack_.push_back(this->lex_->mode());
    this->lex_->set_mode(mode);
  }

  // Pop the lexer mode.
  void
  pop_lex_mode()
  {
    gold_assert(!this->lex_mode_stack_.empty());
    this->lex_->set_mode(this->lex_mode_stack_.back());
    this->lex_mode_stack_.pop_back();
  }

  // Return the current lexer mode.
  Lex::Mode
  lex_mode() const
  { return this->lex_mode_stack_.back(); }

  // Return the line number of the last token.
  int
  lineno() const
  { return this->lineno_; }

  // Return the character position in the line of the last token.
  int
  charpos() const
  { return this->charpos_; }

  // Return the list of input files, creating it if necessary.  This
  // is a space leak--we never free the INPUTS_ pointer.
  Input_arguments*
  inputs()
  {
    if (this->inputs_ == NULL)
      this->inputs_ = new Input_arguments();
    return this->inputs_;
  }

  // Return whether we saw any input files.
  bool
  saw_inputs() const
  { return this->inputs_ != NULL && !this->inputs_->empty(); }

  // Return the current language being processed in a version script
  // (eg, "C++").  The empty string represents unmangled C names.
  Version_script_info::Language
  get_current_language() const
  { return this->language_stack_.back(); }

  // Push a language onto the stack when entering an extern block.
  void
  push_language(Version_script_info::Language lang)
  { this->language_stack_.push_back(lang); }

  // Pop a language off of the stack when exiting an extern block.
  void
  pop_language()
  {
    gold_assert(!this->language_stack_.empty());
    this->language_stack_.pop_back();
  }

  // Return a pointer to the incremental info.
  Script_info*
  script_info()
  { return this->script_info_; }

 private:
  // The name of the file we are reading.
  const char* filename_;
  // The position dependent options.
  Position_dependent_options posdep_options_;
  // True if we are parsing a --defsym.
  bool parsing_defsym_;
  // Whether we are currently in a --start-group/--end-group.
  bool in_group_;
  // Whether the script was found in a sysrooted directory.
  bool is_in_sysroot_;
  // If this is true, then if we find an OUTPUT_FORMAT with an
  // incompatible target, then we tell the parser to abort so that we
  // can search for the next file with the same name.
  bool skip_on_incompatible_target_;
  // True if we found an OUTPUT_FORMAT with an incompatible target.
  bool found_incompatible_target_;
  // May be NULL if the user chooses not to pass one in.
  Command_line* command_line_;
  // Options which may be set from any linker script.
  Script_options* script_options_;
  // Information parsed from a version script.
  Version_script_info* version_script_info_;
  // The lexer.
  Lex* lex_;
  // The line number of the last token returned by next_token.
  int lineno_;
  // The column number of the last token returned by next_token.
  int charpos_;
  // A stack of lexer modes.
  std::vector<Lex::Mode> lex_mode_stack_;
  // A stack of which extern/language block we're inside. Can be C++,
  // java, or empty for C.
  std::vector<Version_script_info::Language> language_stack_;
  // New input files found to add to the link.
  Input_arguments* inputs_;
  // Pointer to incremental linking info.
  Script_info* script_info_;
};

// FILE was found as an argument on the command line.  Try to read it
// as a script.  Return true if the file was handled.

bool
read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout,
		  Dirsearch* dirsearch, int dirindex,
		  Input_objects* input_objects, Mapfile* mapfile,
		  Input_group* input_group,
		  const Input_argument* input_argument,
		  Input_file* input_file, Task_token* next_blocker,
		  bool* used_next_blocker)
{
  *used_next_blocker = false;

  std::string input_string;
  Lex::read_file(input_file, &input_string);

  Lex lex(input_string.c_str(), input_string.length(), PARSING_LINKER_SCRIPT);

  Script_info* script_info = NULL;
  if (layout->incremental_inputs() != NULL)
    {
      const std::string& filename = input_file->filename();
      Timespec mtime = input_file->file().get_mtime();
      unsigned int arg_serial = input_argument->file().arg_serial();
      script_info = new Script_info(filename);
      layout->incremental_inputs()->report_script(script_info, arg_serial,
						  mtime);
    }

  Parser_closure closure(input_file->filename().c_str(),
			 input_argument->file().options(),
			 false,
			 input_group != NULL,
			 input_file->is_in_sysroot(),
                         NULL,
			 layout->script_options(),
			 &lex,
			 input_file->will_search_for(),
			 script_info);

  bool old_saw_sections_clause =
    layout->script_options()->saw_sections_clause();

  if (yyparse(&closure) != 0)
    {
      if (closure.found_incompatible_target())
	{
	  Read_symbols::incompatible_warning(input_argument, input_file);
	  Read_symbols::requeue(workqueue, input_objects, symtab, layout,
				dirsearch, dirindex, mapfile, input_argument,
				input_group, next_blocker);
	  return true;
	}
      return false;
    }

  if (!old_saw_sections_clause
      && layout->script_options()->saw_sections_clause()
      && layout->have_added_input_section())
    gold_error(_("%s: SECTIONS seen after other input files; try -T/--script"),
	       input_file->filename().c_str());

  if (!closure.saw_inputs())
    return true;

  Task_token* this_blocker = NULL;
  for (Input_arguments::const_iterator p = closure.inputs()->begin();
       p != closure.inputs()->end();
       ++p)
    {
      Task_token* nb;
      if (p + 1 == closure.inputs()->end())
	nb = next_blocker;
      else
	{
	  nb = new Task_token(true);
	  nb->add_blocker();
	}
      workqueue->queue_soon(new Read_symbols(input_objects, symtab,
					     layout, dirsearch, 0, mapfile, &*p,
					     input_group, NULL, this_blocker, nb));
      this_blocker = nb;
    }

  *used_next_blocker = true;

  return true;
}

// Helper function for read_version_script(), read_commandline_script() and
// script_include_directive().  Processes the given file in the mode indicated
// by first_token and lex_mode.

static bool
read_script_file(const char* filename, Command_line* cmdline,
                 Script_options* script_options,
                 int first_token, Lex::Mode lex_mode)
{
  Dirsearch dirsearch;
  std::string name = filename;

  // If filename is a relative filename, search for it manually using "." +
  // cmdline->options()->library_path() -- not dirsearch.
  if (!IS_ABSOLUTE_PATH(filename))
    {
      const General_options::Dir_list& search_path =
          cmdline->options().library_path();
      name = Dirsearch::find_file_in_dir_list(name, search_path, ".");
    }

  // The file locking code wants to record a Task, but we haven't
  // started the workqueue yet.  This is only for debugging purposes,
  // so we invent a fake value.
  const Task* task = reinterpret_cast<const Task*>(-1);

  // We don't want this file to be opened in binary mode.
  Position_dependent_options posdep = cmdline->position_dependent_options();
  if (posdep.format_enum() == General_options::OBJECT_FORMAT_BINARY)
    posdep.set_format_enum(General_options::OBJECT_FORMAT_ELF);
  Input_file_argument input_argument(name.c_str(),
				     Input_file_argument::INPUT_FILE_TYPE_FILE,
				     "", false, posdep);
  Input_file input_file(&input_argument);
  int dummy = 0;
  if (!input_file.open(dirsearch, task, &dummy))
    return false;

  std::string input_string;
  Lex::read_file(&input_file, &input_string);

  Lex lex(input_string.c_str(), input_string.length(), first_token);
  lex.set_mode(lex_mode);

  Parser_closure closure(filename,
			 cmdline->position_dependent_options(),
			 first_token == Lex::DYNAMIC_LIST,
			 false,
			 input_file.is_in_sysroot(),
                         cmdline,
			 script_options,
			 &lex,
			 false,
			 NULL);
  if (yyparse(&closure) != 0)
    {
      input_file.file().unlock(task);
      return false;
    }

  input_file.file().unlock(task);

  gold_assert(!closure.saw_inputs());

  return true;
}

// FILENAME was found as an argument to --script (-T).
// Read it as a script, and execute its contents immediately.

bool
read_commandline_script(const char* filename, Command_line* cmdline)
{
  return read_script_file(filename, cmdline, &cmdline->script_options(),
                          PARSING_LINKER_SCRIPT, Lex::LINKER_SCRIPT);
}

// FILENAME was found as an argument to --version-script.  Read it as
// a version script, and store its contents in
// cmdline->script_options()->version_script_info().

bool
read_version_script(const char* filename, Command_line* cmdline)
{
  return read_script_file(filename, cmdline, &cmdline->script_options(),
                          PARSING_VERSION_SCRIPT, Lex::VERSION_SCRIPT);
}

// FILENAME was found as an argument to --dynamic-list.  Read it as a
// list of symbols, and store its contents in DYNAMIC_LIST.

bool
read_dynamic_list(const char* filename, Command_line* cmdline,
                  Script_options* dynamic_list)
{
  return read_script_file(filename, cmdline, dynamic_list,
                          PARSING_DYNAMIC_LIST, Lex::DYNAMIC_LIST);
}

// Implement the --defsym option on the command line.  Return true if
// all is well.

bool
Script_options::define_symbol(const char* definition)
{
  Lex lex(definition, strlen(definition), PARSING_DEFSYM);
  lex.set_mode(Lex::EXPRESSION);

  // Dummy value.
  Position_dependent_options posdep_options;

  Parser_closure closure("command line", posdep_options, true,
			 false, false, NULL, this, &lex, false, NULL);

  if (yyparse(&closure) != 0)
    return false;

  gold_assert(!closure.saw_inputs());

  return true;
}

// Print the script to F for debugging.

void
Script_options::print(FILE* f) const
{
  fprintf(f, "%s: Dumping linker script\n", program_name);

  if (!this->entry_.empty())
    fprintf(f, "ENTRY(%s)\n", this->entry_.c_str());

  for (Symbol_assignments::const_iterator p =
	 this->symbol_assignments_.begin();
       p != this->symbol_assignments_.end();
       ++p)
    (*p)->print(f);

  for (Assertions::const_iterator p = this->assertions_.begin();
       p != this->assertions_.end();
       ++p)
    (*p)->print(f);

  this->script_sections_.print(f);

  this->version_script_info_.print(f);
}

// Manage mapping from keywords to the codes expected by the bison
// parser.  We construct one global object for each lex mode with
// keywords.

class Keyword_to_parsecode
{
 public:
  // The structure which maps keywords to parsecodes.
  struct Keyword_parsecode
  {
    // Keyword.
    const char* keyword;
    // Corresponding parsecode.
    int parsecode;
  };

  Keyword_to_parsecode(const Keyword_parsecode* keywords,
                       int keyword_count)
      : keyword_parsecodes_(keywords), keyword_count_(keyword_count)
  { }

  // Return the parsecode corresponding KEYWORD, or 0 if it is not a
  // keyword.
  int
  keyword_to_parsecode(const char* keyword, size_t len) const;

 private:
  const Keyword_parsecode* keyword_parsecodes_;
  const int keyword_count_;
};

// Mapping from keyword string to keyword parsecode.  This array must
// be kept in sorted order.  Parsecodes are looked up using bsearch.
// This array must correspond to the list of parsecodes in yyscript.y.

static const Keyword_to_parsecode::Keyword_parsecode
script_keyword_parsecodes[] =
{
  { "ABSOLUTE", ABSOLUTE },
  { "ADDR", ADDR },
  { "ALIGN", ALIGN_K },
  { "ALIGNOF", ALIGNOF },
  { "ASSERT", ASSERT_K },
  { "AS_NEEDED", AS_NEEDED },
  { "AT", AT },
  { "BIND", BIND },
  { "BLOCK", BLOCK },
  { "BYTE", BYTE },
  { "CONSTANT", CONSTANT },
  { "CONSTRUCTORS", CONSTRUCTORS },
  { "COPY", COPY },
  { "CREATE_OBJECT_SYMBOLS", CREATE_OBJECT_SYMBOLS },
  { "DATA_SEGMENT_ALIGN", DATA_SEGMENT_ALIGN },
  { "DATA_SEGMENT_END", DATA_SEGMENT_END },
  { "DATA_SEGMENT_RELRO_END", DATA_SEGMENT_RELRO_END },
  { "DEFINED", DEFINED },
  { "DSECT", DSECT },
  { "ENTRY", ENTRY },
  { "EXCLUDE_FILE", EXCLUDE_FILE },
  { "EXTERN", EXTERN },
  { "FILL", FILL },
  { "FLOAT", FLOAT },
  { "FORCE_COMMON_ALLOCATION", FORCE_COMMON_ALLOCATION },
  { "GROUP", GROUP },
  { "HIDDEN", HIDDEN },
  { "HLL", HLL },
  { "INCLUDE", INCLUDE },
  { "INFO", INFO },
  { "INHIBIT_COMMON_ALLOCATION", INHIBIT_COMMON_ALLOCATION },
  { "INPUT", INPUT },
  { "KEEP", KEEP },
  { "LENGTH", LENGTH },
  { "LOADADDR", LOADADDR },
  { "LONG", LONG },
  { "MAP", MAP },
  { "MAX", MAX_K },
  { "MEMORY", MEMORY },
  { "MIN", MIN_K },
  { "NEXT", NEXT },
  { "NOCROSSREFS", NOCROSSREFS },
  { "NOFLOAT", NOFLOAT },
  { "NOLOAD", NOLOAD },
  { "ONLY_IF_RO", ONLY_IF_RO },
  { "ONLY_IF_RW", ONLY_IF_RW },
  { "OPTION", OPTION },
  { "ORIGIN", ORIGIN },
  { "OUTPUT", OUTPUT },
  { "OUTPUT_ARCH", OUTPUT_ARCH },
  { "OUTPUT_FORMAT", OUTPUT_FORMAT },
  { "OVERLAY", OVERLAY },
  { "PHDRS", PHDRS },
  { "PROVIDE", PROVIDE },
  { "PROVIDE_HIDDEN", PROVIDE_HIDDEN },
  { "QUAD", QUAD },
  { "SEARCH_DIR", SEARCH_DIR },
  { "SECTIONS", SECTIONS },
  { "SEGMENT_START", SEGMENT_START },
  { "SHORT", SHORT },
  { "SIZEOF", SIZEOF },
  { "SIZEOF_HEADERS", SIZEOF_HEADERS },
  { "SORT", SORT_BY_NAME },
  { "SORT_BY_ALIGNMENT", SORT_BY_ALIGNMENT },
  { "SORT_BY_INIT_PRIORITY", SORT_BY_INIT_PRIORITY },
  { "SORT_BY_NAME", SORT_BY_NAME },
  { "SPECIAL", SPECIAL },
  { "SQUAD", SQUAD },
  { "STARTUP", STARTUP },
  { "SUBALIGN", SUBALIGN },
  { "SYSLIB", SYSLIB },
  { "TARGET", TARGET_K },
  { "TRUNCATE", TRUNCATE },
  { "VERSION", VERSIONK },
  { "global", GLOBAL },
  { "l", LENGTH },
  { "len", LENGTH },
  { "local", LOCAL },
  { "o", ORIGIN },
  { "org", ORIGIN },
  { "sizeof_headers", SIZEOF_HEADERS },
};

static const Keyword_to_parsecode
script_keywords(&script_keyword_parsecodes[0],
                (sizeof(script_keyword_parsecodes)
                 / sizeof(script_keyword_parsecodes[0])));

static const Keyword_to_parsecode::Keyword_parsecode
version_script_keyword_parsecodes[] =
{
  { "extern", EXTERN },
  { "global", GLOBAL },
  { "local", LOCAL },
};

static const Keyword_to_parsecode
version_script_keywords(&version_script_keyword_parsecodes[0],
                        (sizeof(version_script_keyword_parsecodes)
                         / sizeof(version_script_keyword_parsecodes[0])));

static const Keyword_to_parsecode::Keyword_parsecode
dynamic_list_keyword_parsecodes[] =
{
  { "extern", EXTERN },
};

static const Keyword_to_parsecode
dynamic_list_keywords(&dynamic_list_keyword_parsecodes[0],
                      (sizeof(dynamic_list_keyword_parsecodes)
                       / sizeof(dynamic_list_keyword_parsecodes[0])));



// Comparison function passed to bsearch.

extern "C"
{

struct Ktt_key
{
  const char* str;
  size_t len;
};

static int
ktt_compare(const void* keyv, const void* kttv)
{
  const Ktt_key* key = static_cast<const Ktt_key*>(keyv);
  const Keyword_to_parsecode::Keyword_parsecode* ktt =
    static_cast<const Keyword_to_parsecode::Keyword_parsecode*>(kttv);
  int i = strncmp(key->str, ktt->keyword, key->len);
  if (i != 0)
    return i;
  if (ktt->keyword[key->len] != '\0')
    return -1;
  return 0;
}

} // End extern "C".

int
Keyword_to_parsecode::keyword_to_parsecode(const char* keyword,
                                           size_t len) const
{
  Ktt_key key;
  key.str = keyword;
  key.len = len;
  void* kttv = bsearch(&key,
                       this->keyword_parsecodes_,
                       this->keyword_count_,
                       sizeof(this->keyword_parsecodes_[0]),
                       ktt_compare);
  if (kttv == NULL)
    return 0;
  Keyword_parsecode* ktt = static_cast<Keyword_parsecode*>(kttv);
  return ktt->parsecode;
}

// The following structs are used within the VersionInfo class as well
// as in the bison helper functions.  They store the information
// parsed from the version script.

// A single version expression.
// For example, pattern="std::map*" and language="C++".
struct Version_expression
{
  Version_expression(const std::string& a_pattern,
		     Version_script_info::Language a_language,
                     bool a_exact_match)
    : pattern(a_pattern), language(a_language), exact_match(a_exact_match),
      was_matched_by_symbol(false)
  { }

  std::string pattern;
  Version_script_info::Language language;
  // If false, we use glob() to match pattern.  If true, we use strcmp().
  bool exact_match;
  // True if --no-undefined-version is in effect and we found this
  // version in get_symbol_version.  We use mutable because this
  // struct is generally not modifiable after it has been created.
  mutable bool was_matched_by_symbol;
};

// A list of expressions.
struct Version_expression_list
{
  std::vector<struct Version_expression> expressions;
};

// A list of which versions upon which another version depends.
// Strings should be from the Stringpool.
struct Version_dependency_list
{
  std::vector<std::string> dependencies;
};

// The total definition of a version.  It includes the tag for the
// version, its global and local expressions, and any dependencies.
struct Version_tree
{
  Version_tree()
      : tag(), global(NULL), local(NULL), dependencies(NULL)
  { }

  std::string tag;
  const struct Version_expression_list* global;
  const struct Version_expression_list* local;
  const struct Version_dependency_list* dependencies;
};

// Helper class that calls cplus_demangle when needed and takes care of freeing
// the result.

class Lazy_demangler
{
 public:
  Lazy_demangler(const char* symbol, int options)
    : symbol_(symbol), options_(options), demangled_(NULL), did_demangle_(false)
  { }

  ~Lazy_demangler()
  { free(this->demangled_); }

  // Return the demangled name. The actual demangling happens on the first call,
  // and the result is later cached.
  inline char*
  get();

 private:
  // The symbol to demangle.
  const char* symbol_;
  // Option flags to pass to cplus_demagle.
  const int options_;
  // The cached demangled value, or NULL if demangling didn't happen yet or
  // failed.
  char* demangled_;
  // Whether we already called cplus_demangle
  bool did_demangle_;
};

// Return the demangled name. The actual demangling happens on the first call,
// and the result is later cached. Returns NULL if the symbol cannot be
// demangled.

inline char*
Lazy_demangler::get()
{
  if (!this->did_demangle_)
    {
      this->demangled_ = cplus_demangle(this->symbol_, this->options_);
      this->did_demangle_ = true;
    }
  return this->demangled_;
}

// Class Version_script_info.

Version_script_info::Version_script_info()
  : dependency_lists_(), expression_lists_(), version_trees_(), globs_(),
    default_version_(NULL), default_is_global_(false), is_finalized_(false)
{
  for (int i = 0; i < LANGUAGE_COUNT; ++i)
    this->exact_[i] = NULL;
}

Version_script_info::~Version_script_info()
{
}

// Forget all the known version script information.

void
Version_script_info::clear()
{
  for (size_t k = 0; k < this->dependency_lists_.size(); ++k)
    delete this->dependency_lists_[k];
  this->dependency_lists_.clear();
  for (size_t k = 0; k < this->version_trees_.size(); ++k)
    delete this->version_trees_[k];
  this->version_trees_.clear();
  for (size_t k = 0; k < this->expression_lists_.size(); ++k)
    delete this->expression_lists_[k];
  this->expression_lists_.clear();
}

// Finalize the version script information.

void
Version_script_info::finalize()
{
  if (!this->is_finalized_)
    {
      this->build_lookup_tables();
      this->is_finalized_ = true;
    }
}

// Return all the versions.

std::vector<std::string>
Version_script_info::get_versions() const
{
  std::vector<std::string> ret;
  for (size_t j = 0; j < this->version_trees_.size(); ++j)
    if (!this->version_trees_[j]->tag.empty())
      ret.push_back(this->version_trees_[j]->tag);
  return ret;
}

// Return the dependencies of VERSION.

std::vector<std::string>
Version_script_info::get_dependencies(const char* version) const
{
  std::vector<std::string> ret;
  for (size_t j = 0; j < this->version_trees_.size(); ++j)
    if (this->version_trees_[j]->tag == version)
      {
        const struct Version_dependency_list* deps =
          this->version_trees_[j]->dependencies;
        if (deps != NULL)
          for (size_t k = 0; k < deps->dependencies.size(); ++k)
            ret.push_back(deps->dependencies[k]);
        return ret;
      }
  return ret;
}

// A version script essentially maps a symbol name to a version tag
// and an indication of whether symbol is global or local within that
// version tag.  Each symbol maps to at most one version tag.
// Unfortunately, in practice, version scripts are ambiguous, and list
// symbols multiple times.  Thus, we have to document the matching
// process.

// This is a description of what the GNU linker does as of 2010-01-11.
// It walks through the version tags in the order in which they appear
// in the version script.  For each tag, it first walks through the
// global patterns for that tag, then the local patterns.  When
// looking at a single pattern, it first applies any language specific
// demangling as specified for the pattern, and then matches the
// resulting symbol name to the pattern.  If it finds an exact match
// for a literal pattern (a pattern enclosed in quotes or with no
// wildcard characters), then that is the match that it uses.  If
// finds a match with a wildcard pattern, then it saves it and
// continues searching.  Wildcard patterns that are exactly "*" are
// saved separately.

// If no exact match with a literal pattern is ever found, then if a
// wildcard match with a global pattern was found it is used,
// otherwise if a wildcard match with a local pattern was found it is
// used.

// This is the result:
//   * If there is an exact match, then we use the first tag in the
//     version script where it matches.
//     + If the exact match in that tag is global, it is used.
//     + Otherwise the exact match in that tag is local, and is used.
//   * Otherwise, if there is any match with a global wildcard pattern:
//     + If there is any match with a wildcard pattern which is not
//       "*", then we use the tag in which the *last* such pattern
//       appears.
//     + Otherwise, we matched "*".  If there is no match with a local
//       wildcard pattern which is not "*", then we use the *last*
//       match with a global "*".  Otherwise, continue.
//   * Otherwise, if there is any match with a local wildcard pattern:
//     + If there is any match with a wildcard pattern which is not
//       "*", then we use the tag in which the *last* such pattern
//       appears.
//     + Otherwise, we matched "*", and we use the tag in which the
//       *last* such match occurred.

// There is an additional wrinkle.  When the GNU linker finds a symbol
// with a version defined in an object file due to a .symver
// directive, it looks up that symbol name in that version tag.  If it
// finds it, it matches the symbol name against the patterns for that
// version.  If there is no match with a global pattern, but there is
// a match with a local pattern, then the GNU linker marks the symbol
// as local.

// We want gold to be generally compatible, but we also want gold to
// be fast.  These are the rules that gold implements:
//   * If there is an exact match for the mangled name, we use it.
//     + If there is more than one exact match, we give a warning, and
//       we use the first tag in the script which matches.
//     + If a symbol has an exact match as both global and local for
//       the same version tag, we give an error.
//   * Otherwise, we look for an extern C++ or an extern Java exact
//     match.  If we find an exact match, we use it.
//     + If there is more than one exact match, we give a warning, and
//       we use the first tag in the script which matches.
//     + If a symbol has an exact match as both global and local for
//       the same version tag, we give an error.
//   * Otherwise, we look through the wildcard patterns, ignoring "*"
//     patterns.  We look through the version tags in reverse order.
//     For each version tag, we look through the global patterns and
//     then the local patterns.  We use the first match we find (i.e.,
//     the last matching version tag in the file).
//   * Otherwise, we use the "*" pattern if there is one.  We give an
//     error if there are multiple "*" patterns.

// At least for now, gold does not look up the version tag for a
// symbol version found in an object file to see if it should be
// forced local.  There are other ways to force a symbol to be local,
// and I don't understand why this one is useful.

// Build a set of fast lookup tables for a version script.

void
Version_script_info::build_lookup_tables()
{
  size_t size = this->version_trees_.size();
  for (size_t j = 0; j < size; ++j)
    {
      const Version_tree* v = this->version_trees_[j];
      this->build_expression_list_lookup(v->local, v, false);
      this->build_expression_list_lookup(v->global, v, true);
    }
}

// If a pattern has backlashes but no unquoted wildcard characters,
// then we apply backslash unquoting and look for an exact match.
// Otherwise we treat it as a wildcard pattern.  This function returns
// true for a wildcard pattern.  Otherwise, it does backslash
// unquoting on *PATTERN and returns false.  If this returns true,
// *PATTERN may have been partially unquoted.

bool
Version_script_info::unquote(std::string* pattern) const
{
  bool saw_backslash = false;
  size_t len = pattern->length();
  size_t j = 0;
  for (size_t i = 0; i < len; ++i)
    {
      if (saw_backslash)
	saw_backslash = false;
      else
	{
	  switch ((*pattern)[i])
	    {
	    case '?': case '[': case '*':
	      return true;
	    case '\\':
	      saw_backslash = true;
	      continue;
	    default:
	      break;
	    }
	}

      if (i != j)
	(*pattern)[j] = (*pattern)[i];
      ++j;
    }
  return false;
}

// Add an exact match for MATCH to *PE.  The result of the match is
// V/IS_GLOBAL.

void
Version_script_info::add_exact_match(const std::string& match,
				     const Version_tree* v, bool is_global,
				     const Version_expression* ve,
				     Exact* pe)
{
  std::pair<Exact::iterator, bool> ins =
    pe->insert(std::make_pair(match, Version_tree_match(v, is_global, ve)));
  if (ins.second)
    {
      // This is the first time we have seen this match.
      return;
    }

  Version_tree_match& vtm(ins.first->second);
  if (vtm.real->tag != v->tag)
    {
      // This is an ambiguous match.  We still return the
      // first version that we found in the script, but we
      // record the new version to issue a warning if we
      // wind up looking up this symbol.
      if (vtm.ambiguous == NULL)
	vtm.ambiguous = v;
    }
  else if (is_global != vtm.is_global)
    {
      // We have a match for both the global and local entries for a
      // version tag.  That's got to be wrong.
      gold_error(_("'%s' appears as both a global and a local symbol "
		   "for version '%s' in script"),
		 match.c_str(), v->tag.c_str());
    }
}

// Build fast lookup information for EXPLIST and store it in LOOKUP.
// All matches go to V, and IS_GLOBAL is true if they are global
// matches.

void
Version_script_info::build_expression_list_lookup(
    const Version_expression_list* explist,
    const Version_tree* v,
    bool is_global)
{
  if (explist == NULL)
    return;
  size_t size = explist->expressions.size();
  for (size_t i = 0; i < size; ++i)
    {
      const Version_expression& exp(explist->expressions[i]);

      if (exp.pattern.length() == 1 && exp.pattern[0] == '*')
	{
	  if (this->default_version_ != NULL
	      && this->default_version_->tag != v->tag)
	    gold_warning(_("wildcard match appears in both version '%s' "
			   "and '%s' in script"),
			 this->default_version_->tag.c_str(), v->tag.c_str());
	  else if (this->default_version_ != NULL
		   && this->default_is_global_ != is_global)
	    gold_error(_("wildcard match appears as both global and local "
			 "in version '%s' in script"),
		       v->tag.c_str());
	  this->default_version_ = v;
	  this->default_is_global_ = is_global;
	  continue;
	}

      std::string pattern = exp.pattern;
      if (!exp.exact_match)
	{
	  if (this->unquote(&pattern))
	    {
	      this->globs_.push_back(Glob(&exp, v, is_global));
	      continue;
	    }
	}

      if (this->exact_[exp.language] == NULL)
	this->exact_[exp.language] = new Exact();
      this->add_exact_match(pattern, v, is_global, &exp,
			    this->exact_[exp.language]);
    }
}

// Return the name to match given a name, a language code, and two
// lazy demanglers.

const char*
Version_script_info::get_name_to_match(const char* name,
				       int language,
				       Lazy_demangler* cpp_demangler,
				       Lazy_demangler* java_demangler) const
{
  switch (language)
    {
    case LANGUAGE_C:
      return name;
    case LANGUAGE_CXX:
      return cpp_demangler->get();
    case LANGUAGE_JAVA:
      return java_demangler->get();
    default:
      gold_unreachable();
    }
}

// Look up SYMBOL_NAME in the list of versions.  Return true if the
// symbol is found, false if not.  If the symbol is found, then if
// PVERSION is not NULL, set *PVERSION to the version tag, and if
// P_IS_GLOBAL is not NULL, set *P_IS_GLOBAL according to whether the
// symbol is global or not.

bool
Version_script_info::get_symbol_version(const char* symbol_name,
					std::string* pversion,
					bool* p_is_global) const
{
  Lazy_demangler cpp_demangled_name(symbol_name, DMGL_ANSI | DMGL_PARAMS);
  Lazy_demangler java_demangled_name(symbol_name,
				     DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);

  gold_assert(this->is_finalized_);
  for (int i = 0; i < LANGUAGE_COUNT; ++i)
    {
      Exact* exact = this->exact_[i];
      if (exact == NULL)
	continue;

      const char* name_to_match = this->get_name_to_match(symbol_name, i,
							  &cpp_demangled_name,
							  &java_demangled_name);
      if (name_to_match == NULL)
	{
	  // If the name can not be demangled, the GNU linker goes
	  // ahead and tries to match it anyhow.  That does not
	  // make sense to me and I have not implemented it.
	  continue;
	}

      Exact::const_iterator pe = exact->find(name_to_match);
      if (pe != exact->end())
	{
	  const Version_tree_match& vtm(pe->second);
	  if (vtm.ambiguous != NULL)
	    gold_warning(_("using '%s' as version for '%s' which is also "
			   "named in version '%s' in script"),
			 vtm.real->tag.c_str(), name_to_match,
			 vtm.ambiguous->tag.c_str());

	  if (pversion != NULL)
	    *pversion = vtm.real->tag;
	  if (p_is_global != NULL)
	    *p_is_global = vtm.is_global;

	  // If we are using --no-undefined-version, and this is a
	  // global symbol, we have to record that we have found this
	  // symbol, so that we don't warn about it.  We have to do
	  // this now, because otherwise we have no way to get from a
	  // non-C language back to the demangled name that we
	  // matched.
	  if (p_is_global != NULL && vtm.is_global)
	    vtm.expression->was_matched_by_symbol = true;

	  return true;
	}
    }

  // Look through the glob patterns in reverse order.

  for (Globs::const_reverse_iterator p = this->globs_.rbegin();
       p != this->globs_.rend();
       ++p)
    {
      int language = p->expression->language;
      const char* name_to_match = this->get_name_to_match(symbol_name,
							  language,
							  &cpp_demangled_name,
							  &java_demangled_name);
      if (name_to_match == NULL)
	continue;

      if (fnmatch(p->expression->pattern.c_str(), name_to_match,
		  FNM_NOESCAPE) == 0)
	{
	  if (pversion != NULL)
	    *pversion = p->version->tag;
	  if (p_is_global != NULL)
	    *p_is_global = p->is_global;
	  return true;
	}
    }

  // Finally, there may be a wildcard.
  if (this->default_version_ != NULL)
    {
      if (pversion != NULL)
	*pversion = this->default_version_->tag;
      if (p_is_global != NULL)
	*p_is_global = this->default_is_global_;
      return true;
    }

  return false;
}

// Give an error if any exact symbol names (not wildcards) appear in a
// version script, but there is no such symbol.

void
Version_script_info::check_unmatched_names(const Symbol_table* symtab) const
{
  for (size_t i = 0; i < this->version_trees_.size(); ++i)
    {
      const Version_tree* vt = this->version_trees_[i];
      if (vt->global == NULL)
	continue;
      for (size_t j = 0; j < vt->global->expressions.size(); ++j)
	{
	  const Version_expression& expression(vt->global->expressions[j]);

	  // Ignore cases where we used the version because we saw a
	  // symbol that we looked up.  Note that
	  // WAS_MATCHED_BY_SYMBOL will be true even if the symbol was
	  // not a definition.  That's OK as in that case we most
	  // likely gave an undefined symbol error anyhow.
	  if (expression.was_matched_by_symbol)
	    continue;

	  // Just ignore names which are in languages other than C.
	  // We have no way to look them up in the symbol table.
	  if (expression.language != LANGUAGE_C)
	    continue;

	  // Remove backslash quoting, and ignore wildcard patterns.
	  std::string pattern = expression.pattern;
	  if (!expression.exact_match)
	    {
	      if (this->unquote(&pattern))
		continue;
	    }

	  if (symtab->lookup(pattern.c_str(), vt->tag.c_str()) == NULL)
	    gold_error(_("version script assignment of %s to symbol %s "
			 "failed: symbol not defined"),
		       vt->tag.c_str(), pattern.c_str());
	}
    }
}

struct Version_dependency_list*
Version_script_info::allocate_dependency_list()
{
  dependency_lists_.push_back(new Version_dependency_list);
  return dependency_lists_.back();
}

struct Version_expression_list*
Version_script_info::allocate_expression_list()
{
  expression_lists_.push_back(new Version_expression_list);
  return expression_lists_.back();
}

struct Version_tree*
Version_script_info::allocate_version_tree()
{
  version_trees_.push_back(new Version_tree);
  return version_trees_.back();
}

// Print for debugging.

void
Version_script_info::print(FILE* f) const
{
  if (this->empty())
    return;

  fprintf(f, "VERSION {");

  for (size_t i = 0; i < this->version_trees_.size(); ++i)
    {
      const Version_tree* vt = this->version_trees_[i];

      if (vt->tag.empty())
	fprintf(f, "  {\n");
      else
	fprintf(f, "  %s {\n", vt->tag.c_str());

      if (vt->global != NULL)
	{
	  fprintf(f, "    global :\n");
	  this->print_expression_list(f, vt->global);
	}

      if (vt->local != NULL)
	{
	  fprintf(f, "    local :\n");
	  this->print_expression_list(f, vt->local);
	}

      fprintf(f, "  }");
      if (vt->dependencies != NULL)
	{
	  const Version_dependency_list* deps = vt->dependencies;
	  for (size_t j = 0; j < deps->dependencies.size(); ++j)
	    {
	      if (j < deps->dependencies.size() - 1)
		fprintf(f, "\n");
	      fprintf(f, "    %s", deps->dependencies[j].c_str());
	    }
	}
      fprintf(f, ";\n");
    }

  fprintf(f, "}\n");
}

void
Version_script_info::print_expression_list(
    FILE* f,
    const Version_expression_list* vel) const
{
  Version_script_info::Language current_language = LANGUAGE_C;
  for (size_t i = 0; i < vel->expressions.size(); ++i)
    {
      const Version_expression& ve(vel->expressions[i]);

      if (ve.language != current_language)
	{
	  if (current_language != LANGUAGE_C)
	    fprintf(f, "      }\n");
	  switch (ve.language)
	    {
	    case LANGUAGE_C:
	      break;
	    case LANGUAGE_CXX:
	      fprintf(f, "      extern \"C++\" {\n");
	      break;
	    case LANGUAGE_JAVA:
	      fprintf(f, "      extern \"Java\" {\n");
	      break;
	    default:
	      gold_unreachable();
	    }
	  current_language = ve.language;
	}

      fprintf(f, "      ");
      if (current_language != LANGUAGE_C)
	fprintf(f, "  ");

      if (ve.exact_match)
	fprintf(f, "\"");
      fprintf(f, "%s", ve.pattern.c_str());
      if (ve.exact_match)
	fprintf(f, "\"");

      fprintf(f, "\n");
    }

  if (current_language != LANGUAGE_C)
    fprintf(f, "      }\n");
}

} // End namespace gold.

// The remaining functions are extern "C", so it's clearer to not put
// them in namespace gold.

using namespace gold;

// This function is called by the bison parser to return the next
// token.

extern "C" int
yylex(YYSTYPE* lvalp, void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  const Token* token = closure->next_token();
  switch (token->classification())
    {
    default:
      gold_unreachable();

    case Token::TOKEN_INVALID:
      yyerror(closurev, "invalid character");
      return 0;

    case Token::TOKEN_EOF:
      return 0;

    case Token::TOKEN_STRING:
      {
	// This is either a keyword or a STRING.
	size_t len;
	const char* str = token->string_value(&len);
	int parsecode = 0;
        switch (closure->lex_mode())
          {
          case Lex::LINKER_SCRIPT:
            parsecode = script_keywords.keyword_to_parsecode(str, len);
            break;
          case Lex::VERSION_SCRIPT:
            parsecode = version_script_keywords.keyword_to_parsecode(str, len);
            break;
          case Lex::DYNAMIC_LIST:
            parsecode = dynamic_list_keywords.keyword_to_parsecode(str, len);
            break;
          default:
            break;
          }
	if (parsecode != 0)
	  return parsecode;
	lvalp->string.value = str;
	lvalp->string.length = len;
	return STRING;
      }

    case Token::TOKEN_QUOTED_STRING:
      lvalp->string.value = token->string_value(&lvalp->string.length);
      return QUOTED_STRING;

    case Token::TOKEN_OPERATOR:
      return token->operator_value();

    case Token::TOKEN_INTEGER:
      lvalp->integer = token->integer_value();
      return INTEGER;
    }
}

// This function is called by the bison parser to report an error.

extern "C" void
yyerror(void* closurev, const char* message)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  gold_error(_("%s:%d:%d: %s"), closure->filename(), closure->lineno(),
	     closure->charpos(), message);
}

// Called by the bison parser to add an external symbol to the link.

extern "C" void
script_add_extern(void* closurev, const char* name, size_t length)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->script_options()->add_symbol_reference(name, length);
}

// Called by the bison parser to add a file to the link.

extern "C" void
script_add_file(void* closurev, const char* name, size_t length)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);

  // If this is an absolute path, and we found the script in the
  // sysroot, then we want to prepend the sysroot to the file name.
  // For example, this is how we handle a cross link to the x86_64
  // libc.so, which refers to /lib/libc.so.6.
  std::string name_string(name, length);
  const char* extra_search_path = ".";
  std::string script_directory;
  if (IS_ABSOLUTE_PATH(name_string.c_str()))
    {
      if (closure->is_in_sysroot())
	{
	  const std::string& sysroot(parameters->options().sysroot());
	  gold_assert(!sysroot.empty());
	  name_string = sysroot + name_string;
	}
    }
  else
    {
      // In addition to checking the normal library search path, we
      // also want to check in the script-directory.
      const char* slash = strrchr(closure->filename(), '/');
      if (slash != NULL)
	{
	  script_directory.assign(closure->filename(),
				  slash - closure->filename() + 1);
	  extra_search_path = script_directory.c_str();
	}
    }

  Input_file_argument file(name_string.c_str(),
			   Input_file_argument::INPUT_FILE_TYPE_FILE,
			   extra_search_path, false,
			   closure->position_dependent_options());
  Input_argument& arg = closure->inputs()->add_file(file);
  arg.set_script_info(closure->script_info());
}

// Called by the bison parser to add a library to the link.

extern "C" void
script_add_library(void* closurev, const char* name, size_t length)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  std::string name_string(name, length);

  if (name_string[0] != 'l')
    gold_error(_("library name must be prefixed with -l"));

  Input_file_argument file(name_string.c_str() + 1,
			   Input_file_argument::INPUT_FILE_TYPE_LIBRARY,
			   "", false,
			   closure->position_dependent_options());
  Input_argument& arg = closure->inputs()->add_file(file);
  arg.set_script_info(closure->script_info());
}

// Called by the bison parser to start a group.  If we are already in
// a group, that means that this script was invoked within a
// --start-group --end-group sequence on the command line, or that
// this script was found in a GROUP of another script.  In that case,
// we simply continue the existing group, rather than starting a new
// one.  It is possible to construct a case in which this will do
// something other than what would happen if we did a recursive group,
// but it's hard to imagine why the different behaviour would be
// useful for a real program.  Avoiding recursive groups is simpler
// and more efficient.

extern "C" void
script_start_group(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (!closure->in_group())
    closure->inputs()->start_group();
}

// Called by the bison parser at the end of a group.

extern "C" void
script_end_group(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (!closure->in_group())
    closure->inputs()->end_group();
}

// Called by the bison parser to start an AS_NEEDED list.

extern "C" void
script_start_as_needed(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->position_dependent_options().set_as_needed(true);
}

// Called by the bison parser at the end of an AS_NEEDED list.

extern "C" void
script_end_as_needed(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->position_dependent_options().set_as_needed(false);
}

// Called by the bison parser to set the entry symbol.

extern "C" void
script_set_entry(void* closurev, const char* entry, size_t length)
{
  // We'll parse this exactly the same as --entry=ENTRY on the commandline
  // TODO(csilvers): FIXME -- call set_entry directly.
  std::string arg("--entry=");
  arg.append(entry, length);
  script_parse_option(closurev, arg.c_str(), arg.size());
}

// Called by the bison parser to set whether to define common symbols.

extern "C" void
script_set_common_allocation(void* closurev, int set)
{
  const char* arg = set != 0 ? "--define-common" : "--no-define-common";
  script_parse_option(closurev, arg, strlen(arg));
}

// Called by the bison parser to refer to a symbol.

extern "C" Expression*
script_symbol(void* closurev, const char* name, size_t length)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (length != 1 || name[0] != '.')
    closure->script_options()->add_symbol_reference(name, length);
  return script_exp_string(name, length);
}

// Called by the bison parser to define a symbol.

extern "C" void
script_set_symbol(void* closurev, const char* name, size_t length,
		  Expression* value, int providei, int hiddeni)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  const bool provide = providei != 0;
  const bool hidden = hiddeni != 0;
  closure->script_options()->add_symbol_assignment(name, length,
						   closure->parsing_defsym(),
						   value, provide, hidden);
  closure->clear_skip_on_incompatible_target();
}

// Called by the bison parser to add an assertion.

extern "C" void
script_add_assertion(void* closurev, Expression* check, const char* message,
		     size_t messagelen)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->script_options()->add_assertion(check, message, messagelen);
  closure->clear_skip_on_incompatible_target();
}

// Called by the bison parser to parse an OPTION.

extern "C" void
script_parse_option(void* closurev, const char* option, size_t length)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  // We treat the option as a single command-line option, even if
  // it has internal whitespace.
  if (closure->command_line() == NULL)
    {
      // There are some options that we could handle here--e.g.,
      // -lLIBRARY.  Should we bother?
      gold_warning(_("%s:%d:%d: ignoring command OPTION; OPTION is only valid"
		     " for scripts specified via -T/--script"),
		   closure->filename(), closure->lineno(), closure->charpos());
    }
  else
    {
      bool past_a_double_dash_option = false;
      const char* mutable_option = strndup(option, length);
      gold_assert(mutable_option != NULL);
      closure->command_line()->process_one_option(1, &mutable_option, 0,
                                                  &past_a_double_dash_option);
      // The General_options class will quite possibly store a pointer
      // into mutable_option, so we can't free it.  In cases the class
      // does not store such a pointer, this is a memory leak.  Alas. :(
    }
  closure->clear_skip_on_incompatible_target();
}

// Called by the bison parser to handle OUTPUT_FORMAT.  OUTPUT_FORMAT
// takes either one or three arguments.  In the three argument case,
// the format depends on the endianness option, which we don't
// currently support (FIXME).  If we see an OUTPUT_FORMAT for the
// wrong format, then we want to search for a new file.  Returning 0
// here will cause the parser to immediately abort.

extern "C" int
script_check_output_format(void* closurev,
			   const char* default_name, size_t default_length,
			   const char*, size_t, const char*, size_t)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  std::string name(default_name, default_length);
  Target* target = select_target_by_bfd_name(name.c_str());
  if (target == NULL || !parameters->is_compatible_target(target))
    {
      if (closure->skip_on_incompatible_target())
	{
	  closure->set_found_incompatible_target();
	  return 0;
	}
      // FIXME: Should we warn about the unknown target?
    }
  return 1;
}

// Called by the bison parser to handle TARGET.

extern "C" void
script_set_target(void* closurev, const char* target, size_t len)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  std::string s(target, len);
  General_options::Object_format format_enum;
  format_enum = General_options::string_to_object_format(s.c_str());
  closure->position_dependent_options().set_format_enum(format_enum);
}

// Called by the bison parser to handle SEARCH_DIR.  This is handled
// exactly like a -L option.

extern "C" void
script_add_search_dir(void* closurev, const char* option, size_t length)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (closure->command_line() == NULL)
    gold_warning(_("%s:%d:%d: ignoring SEARCH_DIR; SEARCH_DIR is only valid"
		   " for scripts specified via -T/--script"),
		 closure->filename(), closure->lineno(), closure->charpos());
  else if (!closure->command_line()->options().nostdlib())
    {
      std::string s = "-L" + std::string(option, length);
      script_parse_option(closurev, s.c_str(), s.size());
    }
}

/* Called by the bison parser to push the lexer into expression
   mode.  */

extern "C" void
script_push_lex_into_expression_mode(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->push_lex_mode(Lex::EXPRESSION);
}

/* Called by the bison parser to push the lexer into version
   mode.  */

extern "C" void
script_push_lex_into_version_mode(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (closure->version_script()->is_finalized())
    gold_error(_("%s:%d:%d: invalid use of VERSION in input file"),
	       closure->filename(), closure->lineno(), closure->charpos());
  closure->push_lex_mode(Lex::VERSION_SCRIPT);
}

/* Called by the bison parser to pop the lexer mode.  */

extern "C" void
script_pop_lex_mode(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->pop_lex_mode();
}

// Register an entire version node. For example:
//
// GLIBC_2.1 {
//   global: foo;
// } GLIBC_2.0;
//
// - tag is "GLIBC_2.1"
// - tree contains the information "global: foo"
// - deps contains "GLIBC_2.0"

extern "C" void
script_register_vers_node(void*,
			  const char* tag,
			  int taglen,
			  struct Version_tree* tree,
			  struct Version_dependency_list* deps)
{
  gold_assert(tree != NULL);
  tree->dependencies = deps;
  if (tag != NULL)
    tree->tag = std::string(tag, taglen);
}

// Add a dependencies to the list of existing dependencies, if any,
// and return the expanded list.

extern "C" struct Version_dependency_list*
script_add_vers_depend(void* closurev,
		       struct Version_dependency_list* all_deps,
		       const char* depend_to_add, int deplen)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (all_deps == NULL)
    all_deps = closure->version_script()->allocate_dependency_list();
  all_deps->dependencies.push_back(std::string(depend_to_add, deplen));
  return all_deps;
}

// Add a pattern expression to an existing list of expressions, if any.

extern "C" struct Version_expression_list*
script_new_vers_pattern(void* closurev,
			struct Version_expression_list* expressions,
			const char* pattern, int patlen, int exact_match)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (expressions == NULL)
    expressions = closure->version_script()->allocate_expression_list();
  expressions->expressions.push_back(
      Version_expression(std::string(pattern, patlen),
                         closure->get_current_language(),
                         static_cast<bool>(exact_match)));
  return expressions;
}

// Attaches b to the end of a, and clears b.  So a = a + b and b = {}.

extern "C" struct Version_expression_list*
script_merge_expressions(struct Version_expression_list* a,
                         struct Version_expression_list* b)
{
  a->expressions.insert(a->expressions.end(),
                        b->expressions.begin(), b->expressions.end());
  // We could delete b and remove it from expressions_lists_, but
  // that's a lot of work.  This works just as well.
  b->expressions.clear();
  return a;
}

// Combine the global and local expressions into a a Version_tree.

extern "C" struct Version_tree*
script_new_vers_node(void* closurev,
		     struct Version_expression_list* global,
		     struct Version_expression_list* local)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  Version_tree* tree = closure->version_script()->allocate_version_tree();
  tree->global = global;
  tree->local = local;
  return tree;
}

// Handle a transition in language, such as at the
// start or end of 'extern "C++"'

extern "C" void
version_script_push_lang(void* closurev, const char* lang, int langlen)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  std::string language(lang, langlen);
  Version_script_info::Language code;
  if (language.empty() || language == "C")
    code = Version_script_info::LANGUAGE_C;
  else if (language == "C++")
    code = Version_script_info::LANGUAGE_CXX;
  else if (language == "Java")
    code = Version_script_info::LANGUAGE_JAVA;
  else
    {
      char* buf = new char[langlen + 100];
      snprintf(buf, langlen + 100,
	       _("unrecognized version script language '%s'"),
	       language.c_str());
      yyerror(closurev, buf);
      delete[] buf;
      code = Version_script_info::LANGUAGE_C;
    }
  closure->push_language(code);
}

extern "C" void
version_script_pop_lang(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->pop_language();
}

// Called by the bison parser to start a SECTIONS clause.

extern "C" void
script_start_sections(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->script_options()->script_sections()->start_sections();
  closure->clear_skip_on_incompatible_target();
}

// Called by the bison parser to finish a SECTIONS clause.

extern "C" void
script_finish_sections(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->script_options()->script_sections()->finish_sections();
}

// Start processing entries for an output section.

extern "C" void
script_start_output_section(void* closurev, const char* name, size_t namelen,
			    const struct Parser_output_section_header* header)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->script_options()->script_sections()->start_output_section(name,
								     namelen,
								     header);
}

// Finish processing entries for an output section.

extern "C" void
script_finish_output_section(void* closurev,
			     const struct Parser_output_section_trailer* trail)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->script_options()->script_sections()->finish_output_section(trail);
}

// Add a data item (e.g., "WORD (0)") to the current output section.

extern "C" void
script_add_data(void* closurev, int data_token, Expression* val)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  int size;
  bool is_signed = true;
  switch (data_token)
    {
    case QUAD:
      size = 8;
      is_signed = false;
      break;
    case SQUAD:
      size = 8;
      break;
    case LONG:
      size = 4;
      break;
    case SHORT:
      size = 2;
      break;
    case BYTE:
      size = 1;
      break;
    default:
      gold_unreachable();
    }
  closure->script_options()->script_sections()->add_data(size, is_signed, val);
}

// Add a clause setting the fill value to the current output section.

extern "C" void
script_add_fill(void* closurev, Expression* val)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  closure->script_options()->script_sections()->add_fill(val);
}

// Add a new input section specification to the current output
// section.

extern "C" void
script_add_input_section(void* closurev,
			 const struct Input_section_spec* spec,
			 int keepi)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  bool keep = keepi != 0;
  closure->script_options()->script_sections()->add_input_section(spec, keep);
}

// When we see DATA_SEGMENT_ALIGN we record that following output
// sections may be relro.

extern "C" void
script_data_segment_align(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (!closure->script_options()->saw_sections_clause())
    gold_error(_("%s:%d:%d: DATA_SEGMENT_ALIGN not in SECTIONS clause"),
	       closure->filename(), closure->lineno(), closure->charpos());
  else
    closure->script_options()->script_sections()->data_segment_align();
}

// When we see DATA_SEGMENT_RELRO_END we know that all output sections
// since DATA_SEGMENT_ALIGN should be relro.

extern "C" void
script_data_segment_relro_end(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (!closure->script_options()->saw_sections_clause())
    gold_error(_("%s:%d:%d: DATA_SEGMENT_ALIGN not in SECTIONS clause"),
	       closure->filename(), closure->lineno(), closure->charpos());
  else
    closure->script_options()->script_sections()->data_segment_relro_end();
}

// Create a new list of string/sort pairs.

extern "C" String_sort_list_ptr
script_new_string_sort_list(const struct Wildcard_section* string_sort)
{
  return new String_sort_list(1, *string_sort);
}

// Add an entry to a list of string/sort pairs.  The way the parser
// works permits us to simply modify the first parameter, rather than
// copy the vector.

extern "C" String_sort_list_ptr
script_string_sort_list_add(String_sort_list_ptr pv,
			    const struct Wildcard_section* string_sort)
{
  if (pv == NULL)
    return script_new_string_sort_list(string_sort);
  else
    {
      pv->push_back(*string_sort);
      return pv;
    }
}

// Create a new list of strings.

extern "C" String_list_ptr
script_new_string_list(const char* str, size_t len)
{
  return new String_list(1, std::string(str, len));
}

// Add an element to a list of strings.  The way the parser works
// permits us to simply modify the first parameter, rather than copy
// the vector.

extern "C" String_list_ptr
script_string_list_push_back(String_list_ptr pv, const char* str, size_t len)
{
  if (pv == NULL)
    return script_new_string_list(str, len);
  else
    {
      pv->push_back(std::string(str, len));
      return pv;
    }
}

// Concatenate two string lists.  Either or both may be NULL.  The way
// the parser works permits us to modify the parameters, rather than
// copy the vector.

extern "C" String_list_ptr
script_string_list_append(String_list_ptr pv1, String_list_ptr pv2)
{
  if (pv1 == NULL)
    return pv2;
  if (pv2 == NULL)
    return pv1;
  pv1->insert(pv1->end(), pv2->begin(), pv2->end());
  return pv1;
}

// Add a new program header.

extern "C" void
script_add_phdr(void* closurev, const char* name, size_t namelen,
		unsigned int type, const Phdr_info* info)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  bool includes_filehdr = info->includes_filehdr != 0;
  bool includes_phdrs = info->includes_phdrs != 0;
  bool is_flags_valid = info->is_flags_valid != 0;
  Script_sections* ss = closure->script_options()->script_sections();
  ss->add_phdr(name, namelen, type, includes_filehdr, includes_phdrs,
	       is_flags_valid, info->flags, info->load_address);
  closure->clear_skip_on_incompatible_target();
}

// Convert a program header string to a type.

#define PHDR_TYPE(NAME) { #NAME, sizeof(#NAME) - 1, elfcpp::NAME }

static struct
{
  const char* name;
  size_t namelen;
  unsigned int val;
} phdr_type_names[] =
{
  PHDR_TYPE(PT_NULL),
  PHDR_TYPE(PT_LOAD),
  PHDR_TYPE(PT_DYNAMIC),
  PHDR_TYPE(PT_INTERP),
  PHDR_TYPE(PT_NOTE),
  PHDR_TYPE(PT_SHLIB),
  PHDR_TYPE(PT_PHDR),
  PHDR_TYPE(PT_TLS),
  PHDR_TYPE(PT_GNU_EH_FRAME),
  PHDR_TYPE(PT_GNU_STACK),
  PHDR_TYPE(PT_GNU_RELRO)
};

extern "C" unsigned int
script_phdr_string_to_type(void* closurev, const char* name, size_t namelen)
{
  for (unsigned int i = 0;
       i < sizeof(phdr_type_names) / sizeof(phdr_type_names[0]);
       ++i)
    if (namelen == phdr_type_names[i].namelen
	&& strncmp(name, phdr_type_names[i].name, namelen) == 0)
      return phdr_type_names[i].val;
  yyerror(closurev, _("unknown PHDR type (try integer)"));
  return elfcpp::PT_NULL;
}

extern "C" void
script_saw_segment_start_expression(void* closurev)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  Script_sections* ss = closure->script_options()->script_sections();
  ss->set_saw_segment_start_expression(true);
}

extern "C" void
script_set_section_region(void* closurev, const char* name, size_t namelen,
			  int set_vma)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  if (!closure->script_options()->saw_sections_clause())
    {
      gold_error(_("%s:%d:%d: MEMORY region '%.*s' referred to outside of "
		   "SECTIONS clause"),
		 closure->filename(), closure->lineno(), closure->charpos(),
		 static_cast<int>(namelen), name);
      return;
    }

  Script_sections* ss = closure->script_options()->script_sections();
  Memory_region* mr = ss->find_memory_region(name, namelen);
  if (mr == NULL)
    {
      gold_error(_("%s:%d:%d: MEMORY region '%.*s' not declared"),
		 closure->filename(), closure->lineno(), closure->charpos(),
		 static_cast<int>(namelen), name);
      return;
    }

  ss->set_memory_region(mr, set_vma);
}

extern "C" void
script_add_memory(void* closurev, const char* name, size_t namelen,
		  unsigned int attrs, Expression* origin, Expression* length)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  Script_sections* ss = closure->script_options()->script_sections();
  ss->add_memory_region(name, namelen, attrs, origin, length);
}

extern "C" unsigned int
script_parse_memory_attr(void* closurev, const char* attrs, size_t attrlen,
			 int invert)
{
  int attributes = 0;

  while (attrlen--)
    switch (*attrs++)
      {
      case 'R':
      case 'r':
	attributes |= MEM_READABLE; break;
      case 'W':
      case 'w':
	attributes |= MEM_READABLE | MEM_WRITEABLE; break;
      case 'X':
      case 'x':
	attributes |= MEM_EXECUTABLE; break;
      case 'A':
      case 'a':
	attributes |= MEM_ALLOCATABLE; break;
      case 'I':
      case 'i':
      case 'L':
      case 'l':
	attributes |= MEM_INITIALIZED; break;
      default:
	yyerror(closurev, _("unknown MEMORY attribute"));
      }

  if (invert)
    attributes = (~ attributes) & MEM_ATTR_MASK;

  return attributes;
}

extern "C" void
script_include_directive(int first_token, void* closurev,
			 const char* filename, size_t length)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  std::string name(filename, length);
  Command_line* cmdline = closure->command_line();
  read_script_file(name.c_str(), cmdline, &cmdline->script_options(),
                   first_token, Lex::LINKER_SCRIPT);
}

// Functions for memory regions.

extern "C" Expression*
script_exp_function_origin(void* closurev, const char* name, size_t namelen)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  Script_sections* ss = closure->script_options()->script_sections();
  Expression* origin = ss->find_memory_region_origin(name, namelen);

  if (origin == NULL)
    {
      gold_error(_("undefined memory region '%s' referenced "
		   "in ORIGIN expression"),
		 name);
      // Create a dummy expression to prevent crashes later on.
      origin = script_exp_integer(0);
    }

  return origin;
}

extern "C" Expression*
script_exp_function_length(void* closurev, const char* name, size_t namelen)
{
  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
  Script_sections* ss = closure->script_options()->script_sections();
  Expression* length = ss->find_memory_region_length(name, namelen);

  if (length == NULL)
    {
      gold_error(_("undefined memory region '%s' referenced "
		   "in LENGTH expression"),
		 name);
      // Create a dummy expression to prevent crashes later on.
      length = script_exp_integer(0);
    }

  return length;
}
