// options.c -- handle command line options for gold

// Copyright 2006, 2007, 2008, 2009, 2010, 2011 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 <cerrno>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <vector>
#include <iostream>
#include <sys/stat.h>
#include "filenames.h"
#include "libiberty.h"
#include "demangle.h"
#include "../bfd/bfdver.h"

#include "debug.h"
#include "script.h"
#include "target-select.h"
#include "options.h"
#include "plugin.h"

namespace gold
{

General_options
Position_dependent_options::default_options_;

namespace options
{

// This flag is TRUE if we should register the command-line options as they
// are constructed.  It is set after construction of the options within
// class Position_dependent_options.
static bool ready_to_register = false;

// This global variable is set up as General_options is constructed.
static std::vector<const One_option*> registered_options;

// These are set up at the same time -- the variables that accept one
// dash, two, or require -z.  A single variable may be in more than
// one of these data structures.
typedef Unordered_map<std::string, One_option*> Option_map;
static Option_map* long_options = NULL;
static One_option* short_options[128];

void
One_option::register_option()
{
  if (!ready_to_register)
    return;

  registered_options.push_back(this);

  // We can't make long_options a static Option_map because we can't
  // guarantee that will be initialized before register_option() is
  // first called.
  if (long_options == NULL)
    long_options = new Option_map;

  // TWO_DASHES means that two dashes are preferred, but one is ok too.
  if (!this->longname.empty())
    (*long_options)[this->longname] = this;

  const int shortname_as_int = static_cast<int>(this->shortname);
  gold_assert(shortname_as_int >= 0 && shortname_as_int < 128);
  if (this->shortname != '\0')
    {
      gold_assert(short_options[shortname_as_int] == NULL);
      short_options[shortname_as_int] = this;
    }
}

void
One_option::print() const
{
  bool comma = false;
  printf("  ");
  int len = 2;
  if (this->shortname != '\0')
    {
      len += printf("-%c", this->shortname);
      if (this->helparg)
        {
          // -z takes long-names only.
          gold_assert(this->dashes != DASH_Z);
          len += printf(" %s", gettext(this->helparg));
        }
      comma = true;
    }
  if (!this->longname.empty()
      && !(this->longname[0] == this->shortname
	   && this->longname[1] == '\0'))
    {
      if (comma)
        len += printf(", ");
      switch (this->dashes)
        {
        case options::ONE_DASH: case options::EXACTLY_ONE_DASH:
          len += printf("-");
          break;
        case options::TWO_DASHES: case options::EXACTLY_TWO_DASHES:
          len += printf("--");
          break;
        case options::DASH_Z:
          len += printf("-z ");
          break;
        default:
          gold_unreachable();
        }
      len += printf("%s", this->longname.c_str());
      if (this->helparg)
        {
          // For most options, we print "--frob FOO".  But for -z
          // we print "-z frob=FOO".
          len += printf("%c%s", this->dashes == options::DASH_Z ? '=' : ' ',
                        gettext(this->helparg));
        }
    }

  if (len >= 30)
    {
      printf("\n");
      len = 0;
    }
  for (; len < 30; ++len)
    std::putchar(' ');

  // TODO: if we're boolean, add " (default)" when appropriate.
  printf("%s\n", gettext(this->helpstring));
}

void
help()
{
  printf(_("Usage: %s [options] file...\nOptions:\n"), gold::program_name);

  std::vector<const One_option*>::const_iterator it;
  for (it = registered_options.begin(); it != registered_options.end(); ++it)
    (*it)->print();

  // config.guess and libtool.m4 look in ld --help output for the
  // string "supported targets".
  printf(_("%s: supported targets:"), gold::program_name);
  std::vector<const char*> supported_names;
  gold::supported_target_names(&supported_names);
  for (std::vector<const char*>::const_iterator p = supported_names.begin();
       p != supported_names.end();
       ++p)
    printf(" %s", *p);
  printf("\n");

  printf(_("%s: supported emulations:"), gold::program_name);
  supported_names.clear();
  gold::supported_emulation_names(&supported_names);
  for (std::vector<const char*>::const_iterator p = supported_names.begin();
       p != supported_names.end();
       ++p)
    printf(" %s", *p);
  printf("\n");

  // REPORT_BUGS_TO is defined in bfd/bfdver.h.
  const char* report = REPORT_BUGS_TO;
  if (*report != '\0')
    printf(_("Report bugs to %s\n"), report);
}

// For bool, arg will be NULL (boolean options take no argument);
// we always just set to true.
void
parse_bool(const char*, const char*, bool* retval)
{
  *retval = true;
}

void
parse_uint(const char* option_name, const char* arg, int* retval)
{
  char* endptr;
  *retval = strtol(arg, &endptr, 0);
  if (*endptr != '\0' || *retval < 0)
    gold_fatal(_("%s: invalid option value (expected an integer): %s"),
               option_name, arg);
}

void
parse_int(const char* option_name, const char* arg, int* retval)
{
  char* endptr;
  *retval = strtol(arg, &endptr, 0);
  if (*endptr != '\0')
    gold_fatal(_("%s: invalid option value (expected an integer): %s"),
               option_name, arg);
}

void
parse_uint64(const char* option_name, const char* arg, uint64_t* retval)
{
  char* endptr;
  *retval = strtoull(arg, &endptr, 0);
  if (*endptr != '\0')
    gold_fatal(_("%s: invalid option value (expected an integer): %s"),
               option_name, arg);
}

void
parse_double(const char* option_name, const char* arg, double* retval)
{
  char* endptr;
  *retval = strtod(arg, &endptr);
  if (*endptr != '\0')
    gold_fatal(_("%s: invalid option value "
		 "(expected a floating point number): %s"),
	       option_name, arg);
}

void
parse_percent(const char* option_name, const char* arg, double* retval)
{
  char* endptr;
  *retval = strtod(arg, &endptr) / 100.0;
  if (*endptr != '\0')
    gold_fatal(_("%s: invalid option value "
		 "(expected a floating point number): %s"),
	       option_name, arg);
}

void
parse_string(const char* option_name, const char* arg, const char** retval)
{
  if (*arg == '\0')
    gold_fatal(_("%s: must take a non-empty argument"), option_name);
  *retval = arg;
}

void
parse_optional_string(const char*, const char* arg, const char** retval)
{
  *retval = arg;
}

void
parse_dirlist(const char*, const char* arg, Dir_list* retval)
{
  retval->push_back(Search_directory(arg, false));
}

void
parse_set(const char*, const char* arg, String_set* retval)
{
  retval->insert(std::string(arg));
}

void
parse_choices(const char* option_name, const char* arg, const char** retval,
              const char* choices[], int num_choices)
{
  for (int i = 0; i < num_choices; i++)
    if (strcmp(choices[i], arg) == 0)
      {
        *retval = arg;
        return;
      }

  // If we get here, the user did not enter a valid choice, so we die.
  std::string choices_list;
  for (int i = 0; i < num_choices; i++)
    {
      choices_list += choices[i];
      if (i != num_choices - 1)
        choices_list += ", ";
    }
  gold_fatal(_("%s: must take one of the following arguments: %s"),
             option_name, choices_list.c_str());
}

} // End namespace options.

// Define the handler for "special" options (set via DEFINE_special).

void
General_options::parse_help(const char*, const char*, Command_line*)
{
  options::help();
  ::exit(EXIT_SUCCESS);
}

void
General_options::parse_version(const char* opt, const char*, Command_line*)
{
  bool print_short = (opt[0] == '-' && opt[1] == 'v');
  gold::print_version(print_short);
  this->printed_version_ = true;
  if (!print_short)
    ::exit(EXIT_SUCCESS);
}

void
General_options::parse_V(const char*, const char*, Command_line*)
{
  gold::print_version(true);
  this->printed_version_ = true;

  printf(_("  Supported targets:\n"));
  std::vector<const char*> supported_names;
  gold::supported_target_names(&supported_names);
  for (std::vector<const char*>::const_iterator p = supported_names.begin();
       p != supported_names.end();
       ++p)
    printf("   %s\n", *p);

  printf(_("  Supported emulations:\n"));
  supported_names.clear();
  gold::supported_emulation_names(&supported_names);
  for (std::vector<const char*>::const_iterator p = supported_names.begin();
       p != supported_names.end();
       ++p)
    printf("   %s\n", *p);
}

void
General_options::parse_defsym(const char*, const char* arg,
                              Command_line* cmdline)
{
  cmdline->script_options().define_symbol(arg);
}

void
General_options::parse_incremental(const char*, const char*,
                                   Command_line*)
{
  this->incremental_mode_ = INCREMENTAL_AUTO;
}

void
General_options::parse_no_incremental(const char*, const char*,
                                      Command_line*)
{
  this->incremental_mode_ = INCREMENTAL_OFF;
}

void
General_options::parse_incremental_full(const char*, const char*,
					Command_line*)
{
  this->incremental_mode_ = INCREMENTAL_FULL;
}

void
General_options::parse_incremental_update(const char*, const char*,
					  Command_line*)
{
  this->incremental_mode_ = INCREMENTAL_UPDATE;
}

void
General_options::parse_incremental_changed(const char*, const char*,
                                           Command_line*)
{
  this->implicit_incremental_ = true;
  this->incremental_disposition_ = INCREMENTAL_CHANGED;
}

void
General_options::parse_incremental_unchanged(const char*, const char*,
                                             Command_line*)
{
  this->implicit_incremental_ = true;
  this->incremental_disposition_ = INCREMENTAL_UNCHANGED;
}

void
General_options::parse_incremental_unknown(const char*, const char*,
                                           Command_line*)
{
  this->implicit_incremental_ = true;
  this->incremental_disposition_ = INCREMENTAL_CHECK;
}

void
General_options::parse_incremental_startup_unchanged(const char*, const char*,
						     Command_line*)
{
  this->implicit_incremental_ = true;
  this->incremental_startup_disposition_ = INCREMENTAL_UNCHANGED;
}

void
General_options::parse_library(const char*, const char* arg,
                               Command_line* cmdline)
{
  Input_file_argument::Input_file_type type;
  const char* name;
  if (arg[0] == ':')
    {
      type = Input_file_argument::INPUT_FILE_TYPE_SEARCHED_FILE;
      name = arg + 1;
    }
  else
    {
      type = Input_file_argument::INPUT_FILE_TYPE_LIBRARY;
      name = arg;
    }
  Input_file_argument file(name, type, "", false, *this);
  cmdline->inputs().add_file(file);
}

#ifdef ENABLE_PLUGINS
void
General_options::parse_plugin(const char*, const char* arg,
                              Command_line*)
{
  this->add_plugin(arg);
}

// Parse --plugin-opt.

void
General_options::parse_plugin_opt(const char*, const char* arg,
                                  Command_line*)
{
  this->add_plugin_option(arg);
}
#endif // ENABLE_PLUGINS

void
General_options::parse_R(const char* option, const char* arg,
                         Command_line* cmdline)
{
  struct stat s;
  if (::stat(arg, &s) != 0 || S_ISDIR(s.st_mode))
    this->add_to_rpath(arg);
  else
    this->parse_just_symbols(option, arg, cmdline);
}

void
General_options::parse_just_symbols(const char*, const char* arg,
                                    Command_line* cmdline)
{
  Input_file_argument file(arg, Input_file_argument::INPUT_FILE_TYPE_FILE,
			   "", true, *this);
  cmdline->inputs().add_file(file);
}

// Handle --section-start.

void
General_options::parse_section_start(const char*, const char* arg,
				     Command_line*)
{
  const char* eq = strchr(arg, '=');
  if (eq == NULL)
    {
      gold_error(_("invalid argument to --section-start; "
		   "must be SECTION=ADDRESS"));
      return;
    }

  std::string section_name(arg, eq - arg);

  ++eq;
  const char* val_start = eq;
  if (eq[0] == '0' && (eq[1] == 'x' || eq[1] == 'X'))
    eq += 2;
  if (*eq == '\0')
    {
      gold_error(_("--section-start address missing"));
      return;
    }
  uint64_t addr = 0;
  hex_init();
  for (; *eq != '\0'; ++eq)
    {
      if (!hex_p(*eq))
	{
	  gold_error(_("--section-start argument %s is not a valid hex number"),
		     val_start);
	  return;
	}
      addr <<= 4;
      addr += hex_value(*eq);
    }

  this->section_starts_[section_name] = addr;
}

// Look up a --section-start value.

bool
General_options::section_start(const char* secname, uint64_t* paddr) const
{
  if (this->section_starts_.empty())
    return false;
  std::map<std::string, uint64_t>::const_iterator p =
    this->section_starts_.find(secname);
  if (p == this->section_starts_.end())
    return false;
  *paddr = p->second;
  return true;
}

void
General_options::parse_static(const char*, const char*, Command_line*)
{
  this->set_static(true);
}

void
General_options::parse_script(const char*, const char* arg,
                              Command_line* cmdline)
{
  if (!read_commandline_script(arg, cmdline))
    gold::gold_fatal(_("unable to parse script file %s"), arg);
}

void
General_options::parse_version_script(const char*, const char* arg,
                                      Command_line* cmdline)
{
  if (!read_version_script(arg, cmdline))
    gold::gold_fatal(_("unable to parse version script file %s"), arg);
}

void
General_options::parse_dynamic_list(const char*, const char* arg,
                                    Command_line* cmdline)
{
  if (!read_dynamic_list(arg, cmdline, &this->dynamic_list_))
    gold::gold_fatal(_("unable to parse dynamic-list script file %s"), arg);
}

void
General_options::parse_start_group(const char*, const char*,
                                   Command_line* cmdline)
{
  cmdline->inputs().start_group();
}

void
General_options::parse_end_group(const char*, const char*,
                                 Command_line* cmdline)
{
  cmdline->inputs().end_group();
}

void
General_options::parse_start_lib(const char*, const char*,
                                 Command_line* cmdline)
{
  cmdline->inputs().start_lib(cmdline->position_dependent_options());
}

void
General_options::parse_end_lib(const char*, const char*,
                               Command_line* cmdline)
{
  cmdline->inputs().end_lib();
}

// The function add_excluded_libs() in ld/ldlang.c of GNU ld breaks up a list
// of names separated by commas or colons and puts them in a linked list.
// We implement the same parsing of names here but store names in an unordered
// map to speed up searching of names.

void
General_options::parse_exclude_libs(const char*, const char* arg,
                                    Command_line*)
{
  const char* p = arg;

  while (*p != '\0')
    {
      size_t length = strcspn(p, ",:");
      this->excluded_libs_.insert(std::string(p, length));
      p += (p[length] ? length + 1 : length);
    }
}

// The checking logic is based on the function check_excluded_libs() in
// ld/ldlang.c of GNU ld but our implementation is different because we use
// an unordered map instead of a linked list, which is what GNU ld uses.  GNU
// ld searches sequentially in the excluded libs list.  For a given archive,
// a match is found if the archive's name matches exactly one of the list
// entry or if the archive's name is of the form FOO.a and FOO matches exactly
// one of the list entry.  An entry "ALL" in the list is considered as a
// wild-card and matches any given name.

bool
General_options::check_excluded_libs(const std::string &name) const
{
  Unordered_set<std::string>::const_iterator p;

  // Exit early for the most common case.
  if (excluded_libs_.empty())
    return false;

  // If we see "ALL", all archives are excluded from automatic export.
  p = excluded_libs_.find(std::string("ALL"));
  if (p != excluded_libs_.end())
    return true;

  // First strip off any directories in name.
  const char* basename = lbasename(name.c_str());

  // Try finding an exact match.
  p = excluded_libs_.find(std::string(basename));
  if (p != excluded_libs_.end())
    return true;

  // Try matching NAME without ".a" at the end.
  size_t length = strlen(basename);
  if ((length >= 2)
      && (basename[length - 2] == '.')
      && (basename[length - 1] == 'a'))
    {
      p = excluded_libs_.find(std::string(basename, length - 2));
      if (p != excluded_libs_.end())
	return true;
    }

  return false;
}

// Recognize input and output target names.  The GNU linker accepts
// these with --format and --oformat.  This code is intended to be
// minimally compatible.  In practice for an ELF target this would be
// the same target as the input files; that name always start with
// "elf".  Non-ELF targets would be "srec", "symbolsrec", "tekhex",
// "binary", "ihex".

General_options::Object_format
General_options::string_to_object_format(const char* arg)
{
  if (strncmp(arg, "elf", 3) == 0)
    return gold::General_options::OBJECT_FORMAT_ELF;
  else if (strcmp(arg, "binary") == 0)
    return gold::General_options::OBJECT_FORMAT_BINARY;
  else
    {
      gold::gold_error(_("format '%s' not supported; treating as elf "
                         "(supported formats: elf, binary)"),
                       arg);
      return gold::General_options::OBJECT_FORMAT_ELF;
    }
}

void
General_options::parse_fix_v4bx(const char*, const char*,
                                Command_line*)
{
  this->fix_v4bx_ = FIX_V4BX_REPLACE;
}

void
General_options::parse_fix_v4bx_interworking(const char*, const char*,
					     Command_line*)
{
  this->fix_v4bx_ = FIX_V4BX_INTERWORKING;
}

void
General_options::parse_EB(const char*, const char*, Command_line*)
{
  this->endianness_ = ENDIANNESS_BIG;
}

void
General_options::parse_EL(const char*, const char*, Command_line*)
{
  this->endianness_ = ENDIANNESS_LITTLE;
}

} // End namespace gold.

namespace
{

void
usage()
{
  fprintf(stderr,
          _("%s: use the --help option for usage information\n"),
          gold::program_name);
  ::exit(EXIT_FAILURE);
}

void
usage(const char* msg, const char* opt)
{
  fprintf(stderr,
          _("%s: %s: %s\n"),
          gold::program_name, opt, msg);
  usage();
}

// If the default sysroot is relocatable, try relocating it based on
// the prefix FROM.

static char*
get_relative_sysroot(const char* from)
{
  char* path = make_relative_prefix(gold::program_name, from,
                                    TARGET_SYSTEM_ROOT);
  if (path != NULL)
    {
      struct stat s;
      if (::stat(path, &s) == 0 && S_ISDIR(s.st_mode))
        return path;
      free(path);
    }

  return NULL;
}

// Return the default sysroot.  This is set by the --with-sysroot
// option to configure.  Note we do not free the return value of
// get_relative_sysroot, which is a small memory leak, but is
// necessary since we store this pointer directly in General_options.

static const char*
get_default_sysroot()
{
  const char* sysroot = TARGET_SYSTEM_ROOT;
  if (*sysroot == '\0')
    return NULL;

  if (TARGET_SYSTEM_ROOT_RELOCATABLE)
    {
      char* path = get_relative_sysroot(BINDIR);
      if (path == NULL)
        path = get_relative_sysroot(TOOLBINDIR);
      if (path != NULL)
        return path;
    }

  return sysroot;
}

// Parse a long option.  Such options have the form
// <-|--><option>[=arg].  If "=arg" is not present but the option
// takes an argument, the next word is taken to the be the argument.
// If equals_only is set, then only the <option>=<arg> form is
// accepted, not the <option><space><arg> form.  Returns a One_option
// struct or NULL if argv[i] cannot be parsed as a long option.  In
// the not-NULL case, *arg is set to the option's argument (NULL if
// the option takes no argument), and *i is advanced past this option.
// NOTE: it is safe for argv and arg to point to the same place.
gold::options::One_option*
parse_long_option(int argc, const char** argv, bool equals_only,
                  const char** arg, int* i)
{
  const char* const this_argv = argv[*i];

  const char* equals = strchr(this_argv, '=');
  const char* option_start = this_argv + strspn(this_argv, "-");
  std::string option(option_start,
                     equals ? equals - option_start : strlen(option_start));

  gold::options::Option_map::iterator it
      = gold::options::long_options->find(option);
  if (it == gold::options::long_options->end())
    return NULL;

  gold::options::One_option* retval = it->second;

  // If the dash-count doesn't match, we fail.
  if (this_argv[0] != '-')  // no dashes at all: had better be "-z <longopt>"
    {
      if (retval->dashes != gold::options::DASH_Z)
        return NULL;
    }
  else if (this_argv[1] != '-')   // one dash
    {
      if (retval->dashes != gold::options::ONE_DASH
          && retval->dashes != gold::options::EXACTLY_ONE_DASH
          && retval->dashes != gold::options::TWO_DASHES)
        return NULL;
    }
  else                            // two dashes (or more!)
    {
      if (retval->dashes != gold::options::TWO_DASHES
          && retval->dashes != gold::options::EXACTLY_TWO_DASHES
          && retval->dashes != gold::options::ONE_DASH)
        return NULL;
    }

  // Now that we know the option is good (or else bad in a way that
  // will cause us to die), increment i to point past this argv.
  ++(*i);

  // Figure out the option's argument, if any.
  if (!retval->takes_argument())
    {
      if (equals)
        usage(_("unexpected argument"), this_argv);
      else
        *arg = NULL;
    }
  else
    {
      if (equals)
        *arg = equals + 1;
      else if (retval->takes_optional_argument())
	*arg = retval->default_value;
      else if (*i < argc && !equals_only)
        *arg = argv[(*i)++];
      else
        usage(_("missing argument"), this_argv);
    }

  return retval;
}

// Parse a short option.  Such options have the form -<option>[arg].
// If "arg" is not present but the option takes an argument, the next
// word is taken to the be the argument.  If the option does not take
// an argument, it may be followed by another short option.  Returns a
// One_option struct or NULL if argv[i] cannot be parsed as a short
// option.  In the not-NULL case, *arg is set to the option's argument
// (NULL if the option takes no argument), and *i is advanced past
// this option.  This function keeps *i the same if we parsed a short
// option that does not take an argument, that looks to be followed by
// another short option in the same word.
gold::options::One_option*
parse_short_option(int argc, const char** argv, int pos_in_argv_i,
                   const char** arg, int* i)
{
  const char* const this_argv = argv[*i];

  if (this_argv[0] != '-')
    return NULL;

  // We handle -z as a special case.
  static gold::options::One_option dash_z("", gold::options::DASH_Z,
                                          'z', "", NULL, "Z-OPTION", false,
					  NULL);
  gold::options::One_option* retval = NULL;
  if (this_argv[pos_in_argv_i] == 'z')
    retval = &dash_z;
  else
    {
      const int char_as_int = static_cast<int>(this_argv[pos_in_argv_i]);
      if (char_as_int > 0 && char_as_int < 128)
        retval = gold::options::short_options[char_as_int];
    }

  if (retval == NULL)
    return NULL;

  // Figure out the option's argument, if any.
  if (!retval->takes_argument())
    {
      *arg = NULL;
      // We only advance past this argument if it's the only one in argv.
      if (this_argv[pos_in_argv_i + 1] == '\0')
        ++(*i);
    }
  else
    {
      // If we take an argument, we'll eat up this entire argv entry.
      ++(*i);
      if (this_argv[pos_in_argv_i + 1] != '\0')
        *arg = this_argv + pos_in_argv_i + 1;
      else if (retval->takes_optional_argument())
	*arg = retval->default_value;
      else if (*i < argc)
        *arg = argv[(*i)++];
      else
        usage(_("missing argument"), this_argv);
    }

  // If we're a -z option, we need to parse our argument as a
  // long-option, e.g. "-z stacksize=8192".
  if (retval == &dash_z)
    {
      int dummy_i = 0;
      const char* dash_z_arg = *arg;
      retval = parse_long_option(1, arg, true, arg, &dummy_i);
      if (retval == NULL)
        usage(_("unknown -z option"), dash_z_arg);
    }

  return retval;
}

} // End anonymous namespace.

namespace gold
{

General_options::General_options()
  : printed_version_(false),
    execstack_status_(EXECSTACK_FROM_INPUT),
    icf_status_(ICF_NONE),
    static_(false),
    do_demangle_(false),
    plugins_(NULL),
    dynamic_list_(),
    incremental_mode_(INCREMENTAL_OFF),
    incremental_disposition_(INCREMENTAL_STARTUP),
    incremental_startup_disposition_(INCREMENTAL_CHECK),
    implicit_incremental_(false),
    excluded_libs_(),
    symbols_to_retain_(),
    section_starts_(),
    fix_v4bx_(FIX_V4BX_NONE),
    endianness_(ENDIANNESS_NOT_SET)
{
  // Turn off option registration once construction is complete.
  gold::options::ready_to_register = false;
}

General_options::Object_format
General_options::format_enum() const
{
  return General_options::string_to_object_format(this->format());
}

General_options::Object_format
General_options::oformat_enum() const
{
  return General_options::string_to_object_format(this->oformat());
}

// Add the sysroot, if any, to the search paths.

void
General_options::add_sysroot()
{
  if (this->sysroot() == NULL || this->sysroot()[0] == '\0')
    {
      this->set_sysroot(get_default_sysroot());
      if (this->sysroot() == NULL || this->sysroot()[0] == '\0')
        return;
    }

  char* canonical_sysroot = lrealpath(this->sysroot());

  for (Dir_list::iterator p = this->library_path_.value.begin();
       p != this->library_path_.value.end();
       ++p)
    p->add_sysroot(this->sysroot(), canonical_sysroot);

  free(canonical_sysroot);
}

// Return whether FILENAME is in a system directory.

bool
General_options::is_in_system_directory(const std::string& filename) const
{
  for (Dir_list::const_iterator p = this->library_path_.value.begin();
       p != this->library_path_.value.end();
       ++p)
    {
      // We use a straight string comparison rather than calling
      // FILENAME_CMP because we are only interested in the cases
      // where we found the file in a system directory, which means
      // that we used the directory name as a prefix for a -L search.
      if (p->is_system_directory()
	  && filename.compare(0, p->name().size(), p->name()) == 0)
	return true;
    }
  return false;
}

// Add a plugin to the list of plugins.

void
General_options::add_plugin(const char* filename)
{
  if (this->plugins_ == NULL)
    this->plugins_ = new Plugin_manager(*this);
  this->plugins_->add_plugin(filename);
}

// Add a plugin option to a plugin.

void
General_options::add_plugin_option(const char* arg)
{
  if (this->plugins_ == NULL)
    gold_fatal("--plugin-opt requires --plugin.");
  this->plugins_->add_plugin_option(arg);
}

// Set up variables and other state that isn't set up automatically by
// the parse routine, and ensure options don't contradict each other
// and are otherwise kosher.

void
General_options::finalize()
{
  // Normalize the strip modifiers.  They have a total order:
  // strip_all > strip_debug > strip_non_line > strip_debug_gdb.
  // If one is true, set all beneath it to true as well.
  if (this->strip_all())
    this->set_strip_debug(true);
  if (this->strip_debug())
    this->set_strip_debug_non_line(true);
  if (this->strip_debug_non_line())
    this->set_strip_debug_gdb(true);

  if (this->Bshareable())
    this->set_shared(true);

  // If the user specifies both -s and -r, convert the -s to -S.
  // -r requires us to keep externally visible symbols!
  if (this->strip_all() && this->relocatable())
    {
      this->set_strip_all(false);
      gold_assert(this->strip_debug());
    }

  // For us, -dc and -dp are synonyms for --define-common.
  if (this->dc())
    this->set_define_common(true);
  if (this->dp())
    this->set_define_common(true);

  // We also set --define-common if we're not relocatable, as long as
  // the user didn't explicitly ask for something different.
  if (!this->user_set_define_common())
    this->set_define_common(!this->relocatable());

  // execstack_status_ is a three-state variable; update it based on
  // -z [no]execstack.
  if (this->execstack())
    this->set_execstack_status(EXECSTACK_YES);
  else if (this->noexecstack())
    this->set_execstack_status(EXECSTACK_NO);

  // icf_status_ is a three-state variable; update it based on the
  // value of this->icf().
  if (strcmp(this->icf(), "none") == 0)
    this->set_icf_status(ICF_NONE);
  else if (strcmp(this->icf(), "safe") == 0)
    this->set_icf_status(ICF_SAFE);
  else
    this->set_icf_status(ICF_ALL);

  // Handle the optional argument for --demangle.
  if (this->user_set_demangle())
    {
      this->set_do_demangle(true);
      const char* style = this->demangle();
      if (*style != '\0')
	{
	  enum demangling_styles style_code;

	  style_code = cplus_demangle_name_to_style(style);
	  if (style_code == unknown_demangling)
	    gold_fatal("unknown demangling style '%s'", style);
	  cplus_demangle_set_style(style_code);
	}
    }
  else if (this->user_set_no_demangle())
    this->set_do_demangle(false);
  else
    {
      // Testing COLLECT_NO_DEMANGLE makes our default demangling
      // behaviour identical to that of gcc's linker wrapper.
      this->set_do_demangle(getenv("COLLECT_NO_DEMANGLE") == NULL);
    }

  // -M is equivalent to "-Map -".
  if (this->print_map() && !this->user_set_Map())
    {
      this->set_Map("-");
      this->set_user_set_Map();
    }

  // Using -n or -N implies -static.
  if (this->nmagic() || this->omagic())
    this->set_static(true);

  // If --thread_count is specified, it applies to
  // --thread-count-{initial,middle,final}, though it doesn't override
  // them.
  if (this->thread_count() > 0 && this->thread_count_initial() == 0)
    this->set_thread_count_initial(this->thread_count());
  if (this->thread_count() > 0 && this->thread_count_middle() == 0)
    this->set_thread_count_middle(this->thread_count());
  if (this->thread_count() > 0 && this->thread_count_final() == 0)
    this->set_thread_count_final(this->thread_count());

  // Let's warn if you set the thread-count but we're going to ignore it.
#ifndef ENABLE_THREADS
  if (this->threads())
    {
      gold_warning(_("ignoring --threads: "
		     "%s was compiled without thread support"),
		   program_name);
      this->set_threads(false);
    }
  if (this->thread_count() > 0 || this->thread_count_initial() > 0
      || this->thread_count_middle() > 0 || this->thread_count_final() > 0)
    gold_warning(_("ignoring --thread-count: "
                   "%s was compiled without thread support"),
                 program_name);
#endif

  std::string libpath;
  if (this->user_set_Y())
    {
      libpath = this->Y();
      if (libpath.compare(0, 2, "P,") == 0)
	libpath.erase(0, 2);
    }
  else if (!this->nostdlib())
    {
#ifndef NATIVE_LINKER
#define NATIVE_LINKER 0
#endif
      const char* p = LIB_PATH;
      if (strcmp(p, "::DEFAULT::") != 0)
	libpath = p;
      else if (NATIVE_LINKER
	       || this->user_set_sysroot()
	       || *TARGET_SYSTEM_ROOT != '\0')
	{
	  this->add_to_library_path_with_sysroot("/lib");
	  this->add_to_library_path_with_sysroot("/usr/lib");
	}
      else
	this->add_to_library_path_with_sysroot(TOOLLIBDIR);
    }

  if (!libpath.empty())
    {
      size_t pos = 0;
      size_t next_pos;
      do
	{
	  next_pos = libpath.find(':', pos);
	  size_t len = (next_pos == std::string::npos
			? next_pos
			: next_pos - pos);
	  if (len != 0)
	    this->add_to_library_path_with_sysroot(libpath.substr(pos, len));
	  pos = next_pos + 1;
	}
      while (next_pos != std::string::npos);
    }

  // Parse the contents of -retain-symbols-file into a set.
  if (this->retain_symbols_file())
    {
      std::ifstream in;
      in.open(this->retain_symbols_file());
      if (!in)
        gold_fatal(_("unable to open -retain-symbols-file file %s: %s"),
                   this->retain_symbols_file(), strerror(errno));
      std::string line;
      std::getline(in, line);   // this chops off the trailing \n, if any
      while (in)
        {
          if (!line.empty() && line[line.length() - 1] == '\r')   // Windows
            line.resize(line.length() - 1);
          this->symbols_to_retain_.insert(line);
          std::getline(in, line);
        }
    }

  // -Bgroup implies --unresolved-symbols=report-all.
  if (this->Bgroup() && !this->user_set_unresolved_symbols())
    this->set_unresolved_symbols("report-all");

  // -shared implies --allow-shlib-undefined.  Currently
  // ---allow-shlib-undefined controls warnings issued based on the
  // -symbol table.  --unresolved-symbols controls warnings issued
  // -based on relocations.
  if (this->shared() && !this->user_set_allow_shlib_undefined())
    this->set_allow_shlib_undefined(true);

  // Normalize library_path() by adding the sysroot to all directories
  // in the path, as appropriate.
  this->add_sysroot();

  // Now that we've normalized the options, check for contradictory ones.
  if (this->shared() && this->is_static())
    gold_fatal(_("-shared and -static are incompatible"));
  if (this->shared() && this->pie())
    gold_fatal(_("-shared and -pie are incompatible"));
  if (this->pie() && this->is_static())
    gold_fatal(_("-pie and -static are incompatible"));

  if (this->shared() && this->relocatable())
    gold_fatal(_("-shared and -r are incompatible"));
  if (this->pie() && this->relocatable())
    gold_fatal(_("-pie and -r are incompatible"));

  if (!this->shared())
    {
      if (this->filter() != NULL)
	gold_fatal(_("-F/--filter may not used without -shared"));
      if (this->any_auxiliary())
	gold_fatal(_("-f/--auxiliary may not be used without -shared"));
    }

  // TODO: implement support for -retain-symbols-file with -r, if needed.
  if (this->relocatable() && this->retain_symbols_file())
    gold_fatal(_("-retain-symbols-file does not yet work with -r"));

  if (this->oformat_enum() != General_options::OBJECT_FORMAT_ELF
      && (this->shared()
	  || this->pie()
	  || this->relocatable()))
    gold_fatal(_("binary output format not compatible "
		 "with -shared or -pie or -r"));

  if (this->user_set_hash_bucket_empty_fraction()
      && (this->hash_bucket_empty_fraction() < 0.0
	  || this->hash_bucket_empty_fraction() >= 1.0))
    gold_fatal(_("--hash-bucket-empty-fraction value %g out of range "
		 "[0.0, 1.0)"),
	       this->hash_bucket_empty_fraction());

  if (this->implicit_incremental_ && this->incremental_mode_ == INCREMENTAL_OFF)
    gold_fatal(_("Options --incremental-changed, --incremental-unchanged, "
                 "--incremental-unknown require the use of --incremental"));

  // Check for options that are not compatible with incremental linking.
  // Where an option can be disabled without seriously changing the semantics
  // of the link, we turn the option off; otherwise, we issue a fatal error.

  if (this->incremental_mode_ != INCREMENTAL_OFF)
    {
      if (this->relocatable())
	gold_fatal(_("incremental linking is not compatible with -r"));
      if (this->emit_relocs())
	gold_fatal(_("incremental linking is not compatible with "
		     "--emit-relocs"));
      if (this->has_plugins())
	gold_fatal(_("incremental linking is not compatible with --plugin"));
      if (this->gc_sections())
	{
	  gold_warning(_("ignoring --gc-sections for an incremental link"));
	  this->set_gc_sections(false);
	}
      if (this->icf_enabled())
	{
	  gold_warning(_("ignoring --icf for an incremental link"));
	  this->set_icf_status(ICF_NONE);
	}
      if (strcmp(this->compress_debug_sections(), "none") != 0)
	{
	  gold_warning(_("ignoring --compress-debug-sections for an "
			 "incremental link"));
	  this->set_compress_debug_sections("none");
	}
    }

  // FIXME: we can/should be doing a lot more sanity checking here.
}

// Search_directory methods.

// This is called if we have a sysroot.  Apply the sysroot if
// appropriate.  Record whether the directory is in the sysroot.

void
Search_directory::add_sysroot(const char* sysroot,
                              const char* canonical_sysroot)
{
  gold_assert(*sysroot != '\0');
  if (this->put_in_sysroot_)
    {
      if (!IS_DIR_SEPARATOR(this->name_[0])
          && !IS_DIR_SEPARATOR(sysroot[strlen(sysroot) - 1]))
        this->name_ = '/' + this->name_;
      this->name_ = sysroot + this->name_;
      this->is_in_sysroot_ = true;
    }
  else
    {
      // Check whether this entry is in the sysroot.  To do this
      // correctly, we need to use canonical names.  Otherwise we will
      // get confused by the ../../.. paths that gcc tends to use.
      char* canonical_name = lrealpath(this->name_.c_str());
      int canonical_name_len = strlen(canonical_name);
      int canonical_sysroot_len = strlen(canonical_sysroot);
      if (canonical_name_len > canonical_sysroot_len
          && IS_DIR_SEPARATOR(canonical_name[canonical_sysroot_len]))
        {
          canonical_name[canonical_sysroot_len] = '\0';
          if (FILENAME_CMP(canonical_name, canonical_sysroot) == 0)
            this->is_in_sysroot_ = true;
        }
      free(canonical_name);
    }
}

// Input_arguments methods.

// Add a file to the list.

Input_argument&
Input_arguments::add_file(Input_file_argument& file)
{
  file.set_arg_serial(++this->file_count_);
  if (this->in_group_)
    {
      gold_assert(!this->input_argument_list_.empty());
      gold_assert(this->input_argument_list_.back().is_group());
      return this->input_argument_list_.back().group()->add_file(file);
    }
  if (this->in_lib_)
    {
      gold_assert(!this->input_argument_list_.empty());
      gold_assert(this->input_argument_list_.back().is_lib());
      return this->input_argument_list_.back().lib()->add_file(file);
    }
  this->input_argument_list_.push_back(Input_argument(file));
  return this->input_argument_list_.back();
}

// Start a group.

void
Input_arguments::start_group()
{
  if (this->in_group_)
    gold_fatal(_("May not nest groups"));
  if (this->in_lib_)
    gold_fatal(_("may not nest groups in libraries"));
  Input_file_group* group = new Input_file_group();
  this->input_argument_list_.push_back(Input_argument(group));
  this->in_group_ = true;
}

// End a group.

void
Input_arguments::end_group()
{
  if (!this->in_group_)
    gold_fatal(_("Group end without group start"));
  this->in_group_ = false;
}

// Start a lib.

void
Input_arguments::start_lib(const Position_dependent_options& options)
{
  if (this->in_lib_)
    gold_fatal(_("may not nest libraries"));
  if (this->in_group_)
    gold_fatal(_("may not nest libraries in groups"));
  Input_file_lib* lib = new Input_file_lib(options);
  this->input_argument_list_.push_back(Input_argument(lib));
  this->in_lib_ = true;
}

// End a lib.

void
Input_arguments::end_lib()
{
  if (!this->in_lib_)
    gold_fatal(_("lib end without lib start"));
  this->in_lib_ = false;
}

// Command_line options.

Command_line::Command_line()
{
}

// Pre_options is the hook that sets the ready_to_register flag.

Command_line::Pre_options::Pre_options()
{
  gold::options::ready_to_register = true;
}

// Process the command line options.  For process_one_option, i is the
// index of argv to process next, and must be an option (that is,
// start with a dash).  The return value is the index of the next
// option to process (i+1 or i+2, or argc to indicate processing is
// done).  no_more_options is set to true if (and when) "--" is seen
// as an option.

int
Command_line::process_one_option(int argc, const char** argv, int i,
                                 bool* no_more_options)
{
  gold_assert(argv[i][0] == '-' && !(*no_more_options));

  // If we are reading "--", then just set no_more_options and return.
  if (argv[i][1] == '-' && argv[i][2] == '\0')
    {
      *no_more_options = true;
      return i + 1;
    }

  int new_i = i;
  options::One_option* option = NULL;
  const char* arg = NULL;

  // First, try to process argv as a long option.
  option = parse_long_option(argc, argv, false, &arg, &new_i);
  if (option)
    {
      option->reader->parse_to_value(argv[i], arg, this, &this->options_);
      return new_i;
    }

  // Now, try to process argv as a short option.  Since several short
  // options can be combined in one argv, we may have to parse a lot
  // until we're done reading this argv.
  int pos_in_argv_i = 1;
  while (new_i == i)
    {
      option = parse_short_option(argc, argv, pos_in_argv_i, &arg, &new_i);
      if (!option)
        break;
      option->reader->parse_to_value(argv[i], arg, this, &this->options_);
      ++pos_in_argv_i;
    }
  if (option)
    return new_i;

  // I guess it's neither a long option nor a short option.
  usage(_("unknown option"), argv[i]);
  return argc;
}


void
Command_line::process(int argc, const char** argv)
{
  bool no_more_options = false;
  int i = 0;
  while (i < argc)
    {
      this->position_options_.copy_from_options(this->options());
      if (no_more_options || argv[i][0] != '-')
        {
	  Input_file_argument file(argv[i],
				   Input_file_argument::INPUT_FILE_TYPE_FILE,
				   "", false, this->position_options_);
          this->inputs_.add_file(file);
          ++i;
        }
      else
        i = process_one_option(argc, argv, i, &no_more_options);
    }

  if (this->inputs_.in_group())
    {
      fprintf(stderr, _("%s: missing group end\n"), program_name);
      usage();
    }

  // Normalize the options and ensure they don't contradict each other.
  this->options_.finalize();
}

// Finalize the version script options and return them.

const Version_script_info&
Command_line::version_script()
{
  this->options_.finalize_dynamic_list();
  Version_script_info* vsi = this->script_options_.version_script_info();
  vsi->finalize();
  return *vsi;
}

} // End namespace gold.
