/* GDB routines for supporting auto-loaded scripts.

   Copyright (C) 2012-2022 Free Software Foundation, Inc.

   This file is part of GDB.

   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, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include <ctype.h>
#include "auto-load.h"
#include "progspace.h"
#include "gdbsupport/gdb_regex.h"
#include "ui-out.h"
#include "filenames.h"
#include "command.h"
#include "observable.h"
#include "objfiles.h"
#include "cli/cli-script.h"
#include "gdbcmd.h"
#include "cli/cli-cmds.h"
#include "cli/cli-decode.h"
#include "cli/cli-setshow.h"
#include "readline/tilde.h"
#include "completer.h"
#include "fnmatch.h"
#include "top.h"
#include "gdbsupport/filestuff.h"
#include "extension.h"
#include "gdb/section-scripts.h"
#include <algorithm>
#include "gdbsupport/pathstuff.h"
#include "cli/cli-style.h"

/* The section to look in for auto-loaded scripts (in file formats that
   support sections).
   Each entry in this section is a record that begins with a leading byte
   identifying the record type.
   At the moment we only support one record type: A leading byte of 1,
   followed by the path of a python script to load.  */
#define AUTO_SECTION_NAME ".debug_gdb_scripts"

/* The section to look in for the name of a separate debug file.  */
#define DEBUGLINK_SECTION_NAME ".gnu_debuglink"

static void maybe_print_unsupported_script_warning
  (struct auto_load_pspace_info *, struct objfile *objfile,
   const struct extension_language_defn *language,
   const char *section_name, unsigned offset);

static void maybe_print_script_not_found_warning
  (struct auto_load_pspace_info *, struct objfile *objfile,
   const struct extension_language_defn *language,
   const char *section_name, unsigned offset);

/* See auto-load.h.  */

bool debug_auto_load = false;

/* "show" command for the debug_auto_load configuration variable.  */

static void
show_debug_auto_load (struct ui_file *file, int from_tty,
		      struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Debugging output for files "
		      "of 'set auto-load ...' is %s.\n"),
	      value);
}

/* User-settable option to enable/disable auto-loading of GDB_AUTO_FILE_NAME
   scripts:
   set auto-load gdb-scripts on|off
   This is true if we should auto-load associated scripts when an objfile
   is opened, false otherwise.  */
static bool auto_load_gdb_scripts = true;

/* "show" command for the auto_load_gdb_scripts configuration variable.  */

static void
show_auto_load_gdb_scripts (struct ui_file *file, int from_tty,
			    struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Auto-loading of canned sequences of commands "
		      "scripts is %s.\n"),
	      value);
}

/* See auto-load.h.  */

bool
auto_load_gdb_scripts_enabled (const struct extension_language_defn *extlang)
{
  return auto_load_gdb_scripts;
}

/* Internal-use flag to enable/disable auto-loading.
   This is true if we should auto-load python code when an objfile is opened,
   false otherwise.

   Both auto_load_scripts && global_auto_load must be true to enable
   auto-loading.

   This flag exists to facilitate deferring auto-loading during start-up
   until after ./.gdbinit has been read; it may augment the search directories
   used to find the scripts.  */
bool global_auto_load = true;

/* Auto-load .gdbinit file from the current directory?  */
bool auto_load_local_gdbinit = true;

/* Absolute pathname to the current directory .gdbinit, if it exists.  */
char *auto_load_local_gdbinit_pathname = NULL;

/* if AUTO_LOAD_LOCAL_GDBINIT_PATHNAME has been loaded.  */
bool auto_load_local_gdbinit_loaded = false;

/* "show" command for the auto_load_local_gdbinit configuration variable.  */

static void
show_auto_load_local_gdbinit (struct ui_file *file, int from_tty,
			      struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Auto-loading of .gdbinit script from current "
		      "directory is %s.\n"),
	      value);
}

/* Directory list from which to load auto-loaded scripts.  It is not checked
   for absolute paths but they are strongly recommended.  It is initialized by
   _initialize_auto_load.  */
static std::string auto_load_dir = AUTO_LOAD_DIR;

/* "set" command for the auto_load_dir configuration variable.  */

static void
set_auto_load_dir (const char *args, int from_tty, struct cmd_list_element *c)
{
  /* Setting the variable to "" resets it to the compile time defaults.  */
  if (auto_load_dir.empty ())
    auto_load_dir = AUTO_LOAD_DIR;
}

/* "show" command for the auto_load_dir configuration variable.  */

static void
show_auto_load_dir (struct ui_file *file, int from_tty,
		    struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("List of directories from which to load "
		      "auto-loaded scripts is %s.\n"),
	      value);
}

/* Directory list safe to hold auto-loaded files.  It is not checked for
   absolute paths but they are strongly recommended.  It is initialized by
   _initialize_auto_load.  */
static std::string auto_load_safe_path = AUTO_LOAD_SAFE_PATH;

/* Vector of directory elements of AUTO_LOAD_SAFE_PATH with each one normalized
   by tilde_expand and possibly each entries has added its gdb_realpath
   counterpart.  */
static std::vector<gdb::unique_xmalloc_ptr<char>> auto_load_safe_path_vec;

/* Expand $datadir and $debugdir in STRING according to the rules of
   substitute_path_component.  */

static std::vector<gdb::unique_xmalloc_ptr<char>>
auto_load_expand_dir_vars (const char *string)
{
  char *s = xstrdup (string);
  substitute_path_component (&s, "$datadir", gdb_datadir.c_str ());
  substitute_path_component (&s, "$debugdir", debug_file_directory.c_str ());

  if (debug_auto_load && strcmp (s, string) != 0)
    auto_load_debug_printf ("Expanded $-variables to \"%s\".", s);

  std::vector<gdb::unique_xmalloc_ptr<char>> dir_vec
    = dirnames_to_char_ptr_vec (s);
  xfree(s);

  return dir_vec;
}

/* Update auto_load_safe_path_vec from current AUTO_LOAD_SAFE_PATH.  */

static void
auto_load_safe_path_vec_update (void)
{
  auto_load_debug_printf ("Updating directories of \"%s\".",
			  auto_load_safe_path.c_str ());

  auto_load_safe_path_vec
    = auto_load_expand_dir_vars (auto_load_safe_path.c_str ());
  size_t len = auto_load_safe_path_vec.size ();

  /* Apply tilde_expand and gdb_realpath to each AUTO_LOAD_SAFE_PATH_VEC
     element.  */
  for (size_t i = 0; i < len; i++)
    {
      gdb::unique_xmalloc_ptr<char> &in_vec = auto_load_safe_path_vec[i];
      gdb::unique_xmalloc_ptr<char> expanded (tilde_expand (in_vec.get ()));
      gdb::unique_xmalloc_ptr<char> real_path = gdb_realpath (expanded.get ());

      /* Ensure the current entry is at least tilde_expand-ed.  ORIGINAL makes
	 sure we free the original string.  */
      gdb::unique_xmalloc_ptr<char> original = std::move (in_vec);
      in_vec = std::move (expanded);

      if (debug_auto_load)
	{
	  if (strcmp (in_vec.get (), original.get ()) == 0)
	    auto_load_debug_printf ("Using directory \"%s\".",
				    in_vec.get ());
	  else
	    auto_load_debug_printf ("Resolved directory \"%s\" as \"%s\".",
				    original.get (), in_vec.get ());
	}

      /* If gdb_realpath returns a different content, append it.  */
      if (strcmp (real_path.get (), in_vec.get ()) != 0)
	{
	  auto_load_debug_printf ("And canonicalized as \"%s\".",
				  real_path.get ());

	  auto_load_safe_path_vec.push_back (std::move (real_path));
	}
    }
}

/* Variable gdb_datadir has been set.  Update content depending on $datadir.  */

static void
auto_load_gdb_datadir_changed (void)
{
  auto_load_safe_path_vec_update ();
}

/* "set" command for the auto_load_safe_path configuration variable.  */

static void
set_auto_load_safe_path (const char *args,
			 int from_tty, struct cmd_list_element *c)
{
  /* Setting the variable to "" resets it to the compile time defaults.  */
  if (auto_load_safe_path.empty ())
    auto_load_safe_path = AUTO_LOAD_SAFE_PATH;

  auto_load_safe_path_vec_update ();
}

/* "show" command for the auto_load_safe_path configuration variable.  */

static void
show_auto_load_safe_path (struct ui_file *file, int from_tty,
			  struct cmd_list_element *c, const char *value)
{
  const char *cs;

  /* Check if user has entered either "/" or for example ":".
     But while more complicate content like ":/foo" would still also
     permit any location do not hide those.  */

  for (cs = value; *cs && (*cs == DIRNAME_SEPARATOR || IS_DIR_SEPARATOR (*cs));
       cs++);
  if (*cs == 0)
    gdb_printf (file, _("Auto-load files are safe to load from any "
			"directory.\n"));
  else
    gdb_printf (file, _("List of directories from which it is safe to "
			"auto-load files is %s.\n"),
		value);
}

/* "add-auto-load-safe-path" command for the auto_load_safe_path configuration
   variable.  */

static void
add_auto_load_safe_path (const char *args, int from_tty)
{
  if (args == NULL || *args == 0)
    error (_("\
Directory argument required.\n\
Use 'set auto-load safe-path /' for disabling the auto-load safe-path security.\
"));

  auto_load_safe_path = string_printf ("%s%c%s", auto_load_safe_path.c_str (),
				       DIRNAME_SEPARATOR, args);

  auto_load_safe_path_vec_update ();
}

/* "add-auto-load-scripts-directory" command for the auto_load_dir configuration
   variable.  */

static void
add_auto_load_dir (const char *args, int from_tty)
{
  if (args == NULL || *args == 0)
    error (_("Directory argument required."));

  auto_load_dir = string_printf ("%s%c%s", auto_load_dir.c_str (),
				 DIRNAME_SEPARATOR, args);
}

/* Implementation for filename_is_in_pattern overwriting the caller's FILENAME
   and PATTERN.  */

static int
filename_is_in_pattern_1 (char *filename, char *pattern)
{
  size_t pattern_len = strlen (pattern);
  size_t filename_len = strlen (filename);

  auto_load_debug_printf ("Matching file \"%s\" to pattern \"%s\"",
			  filename, pattern);

  /* Trim trailing slashes ("/") from PATTERN.  Even for "d:\" paths as
     trailing slashes are trimmed also from FILENAME it still matches
     correctly.  */
  while (pattern_len && IS_DIR_SEPARATOR (pattern[pattern_len - 1]))
    pattern_len--;
  pattern[pattern_len] = '\0';

  /* Ensure auto_load_safe_path "/" matches any FILENAME.  On MS-Windows
     platform FILENAME even after gdb_realpath does not have to start with
     IS_DIR_SEPARATOR character, such as the 'C:\x.exe' filename.  */
  if (pattern_len == 0)
    {
      auto_load_debug_printf ("Matched - empty pattern");
      return 1;
    }

  for (;;)
    {
      /* Trim trailing slashes ("/").  PATTERN also has slashes trimmed the
	 same way so they will match.  */
      while (filename_len && IS_DIR_SEPARATOR (filename[filename_len - 1]))
	filename_len--;
      filename[filename_len] = '\0';
      if (filename_len == 0)
	{
	  auto_load_debug_printf ("Not matched - pattern \"%s\".", pattern);
	  return 0;
	}

      if (gdb_filename_fnmatch (pattern, filename, FNM_FILE_NAME | FNM_NOESCAPE)
	  == 0)
	{
	  auto_load_debug_printf ("Matched - file \"%s\" to pattern \"%s\".",
				  filename, pattern);
	  return 1;
	}

      /* Trim trailing FILENAME component.  */
      while (filename_len > 0 && !IS_DIR_SEPARATOR (filename[filename_len - 1]))
	filename_len--;
    }
}

/* Return 1 if FILENAME matches PATTERN or if FILENAME resides in
   a subdirectory of a directory that matches PATTERN.  Return 0 otherwise.
   gdb_realpath normalization is never done here.  */

static ATTRIBUTE_PURE int
filename_is_in_pattern (const char *filename, const char *pattern)
{
  char *filename_copy, *pattern_copy;

  filename_copy = (char *) alloca (strlen (filename) + 1);
  strcpy (filename_copy, filename);
  pattern_copy = (char *) alloca (strlen (pattern) + 1);
  strcpy (pattern_copy, pattern);

  return filename_is_in_pattern_1 (filename_copy, pattern_copy);
}

/* Return 1 if FILENAME belongs to one of directory components of
   AUTO_LOAD_SAFE_PATH_VEC.  Return 0 otherwise.
   auto_load_safe_path_vec_update is never called.
   *FILENAME_REALP may be updated by gdb_realpath of FILENAME.  */

static int
filename_is_in_auto_load_safe_path_vec (const char *filename,
					gdb::unique_xmalloc_ptr<char> *filename_realp)
{
  const char *pattern = NULL;

  for (const gdb::unique_xmalloc_ptr<char> &p : auto_load_safe_path_vec)
    if (*filename_realp == NULL && filename_is_in_pattern (filename, p.get ()))
      {
	pattern = p.get ();
	break;
      }
  
  if (pattern == NULL)
    {
      if (*filename_realp == NULL)
	{
	  *filename_realp = gdb_realpath (filename);
	  if (debug_auto_load && strcmp (filename_realp->get (), filename) != 0)
	    auto_load_debug_printf ("Resolved file \"%s\" as \"%s\".",
				    filename, filename_realp->get ());
	}

      if (strcmp (filename_realp->get (), filename) != 0)
	for (const gdb::unique_xmalloc_ptr<char> &p : auto_load_safe_path_vec)
	  if (filename_is_in_pattern (filename_realp->get (), p.get ()))
	    {
	      pattern = p.get ();
	      break;
	    }
    }

  if (pattern != NULL)
    {
      auto_load_debug_printf ("File \"%s\" matches directory \"%s\".",
			      filename, pattern);
      return 1;
    }

  return 0;
}

/* See auto-load.h.  */

bool
file_is_auto_load_safe (const char *filename)
{
  gdb::unique_xmalloc_ptr<char> filename_real;
  static bool advice_printed = false;

  if (filename_is_in_auto_load_safe_path_vec (filename, &filename_real))
    return true;

  auto_load_safe_path_vec_update ();
  if (filename_is_in_auto_load_safe_path_vec (filename, &filename_real))
    return true;

  warning (_("File \"%ps\" auto-loading has been declined by your "
	     "`auto-load safe-path' set to \"%s\"."),
	   styled_string (file_name_style.style (), filename_real.get ()),
	   auto_load_safe_path.c_str ());

  if (!advice_printed)
    {
      /* Find the existing home directory config file.  */
      struct stat buf;
      std::string home_config = find_gdb_home_config_file (GDBINIT, &buf);
      if (home_config.empty ())
	{
	  /* The user doesn't have an existing home directory config file,
	     so we should suggest a suitable path for them to use.  */
	  std::string config_dir_file
	    = get_standard_config_filename (GDBINIT);
	  if (!config_dir_file.empty ())
	    home_config = config_dir_file;
	  else
	    {
	      const char *homedir = getenv ("HOME");
	      if (homedir == nullptr)
		homedir = "$HOME";
	      home_config = (std::string (homedir) + SLASH_STRING
			     + std::string (GDBINIT));
	    }
	}

      gdb_printf (_("\
To enable execution of this file add\n\
\tadd-auto-load-safe-path %s\n\
line to your configuration file \"%ps\".\n\
To completely disable this security protection add\n\
\tset auto-load safe-path /\n\
line to your configuration file \"%ps\".\n\
For more information about this security protection see the\n\
\"Auto-loading safe path\" section in the GDB manual.  E.g., run from the shell:\n\
\tinfo \"(gdb)Auto-loading safe path\"\n"),
		       filename_real.get (),
		       styled_string (file_name_style.style (),
				      home_config.c_str ()),
		       styled_string (file_name_style.style (),
				      home_config.c_str ()));
      advice_printed = true;
    }

  return false;
}

/* For scripts specified in .debug_gdb_scripts, multiple objfiles may load
   the same script.  There's no point in loading the script multiple times,
   and there can be a lot of objfiles and scripts, so we keep track of scripts
   loaded this way.  */

struct auto_load_pspace_info
{
  /* For each program space we keep track of loaded scripts, both when
     specified as file names and as scripts to be executed directly.  */
  htab_up loaded_script_files;
  htab_up loaded_script_texts;

  /* Non-zero if we've issued the warning about an auto-load script not being
     supported.  We only want to issue this warning once.  */
  bool unsupported_script_warning_printed = false;

  /* Non-zero if we've issued the warning about an auto-load script not being
     found.  We only want to issue this warning once.  */
  bool script_not_found_warning_printed = false;
};

/* Objects of this type are stored in the loaded_script hash table.  */

struct loaded_script
{
  /* Name as provided by the objfile.  */
  const char *name;

  /* Full path name or NULL if script wasn't found (or was otherwise
     inaccessible), or NULL for loaded_script_texts.  */
  const char *full_path;

  /* True if this script has been loaded.  */
  bool loaded;

  const struct extension_language_defn *language;
};

/* Per-program-space data key.  */
static const struct program_space_key<struct auto_load_pspace_info>
  auto_load_pspace_data;

/* Get the current autoload data.  If none is found yet, add it now.  This
   function always returns a valid object.  */

static struct auto_load_pspace_info *
get_auto_load_pspace_data (struct program_space *pspace)
{
  struct auto_load_pspace_info *info;

  info = auto_load_pspace_data.get (pspace);
  if (info == NULL)
    info = auto_load_pspace_data.emplace (pspace);

  return info;
}

/* Hash function for the loaded script hash.  */

static hashval_t
hash_loaded_script_entry (const void *data)
{
  const struct loaded_script *e = (const struct loaded_script *) data;

  return htab_hash_string (e->name) ^ htab_hash_pointer (e->language);
}

/* Equality function for the loaded script hash.  */

static int
eq_loaded_script_entry (const void *a, const void *b)
{
  const struct loaded_script *ea = (const struct loaded_script *) a;
  const struct loaded_script *eb = (const struct loaded_script *) b;

  return strcmp (ea->name, eb->name) == 0 && ea->language == eb->language;
}

/* Initialize the table to track loaded scripts.
   Each entry is hashed by the full path name.  */

static void
init_loaded_scripts_info (struct auto_load_pspace_info *pspace_info)
{
  /* Choose 31 as the starting size of the hash table, somewhat arbitrarily.
     Space for each entry is obtained with one malloc so we can free them
     easily.  */

  pspace_info->loaded_script_files.reset
    (htab_create (31,
		  hash_loaded_script_entry,
		  eq_loaded_script_entry,
		  xfree));
  pspace_info->loaded_script_texts.reset
    (htab_create (31,
		  hash_loaded_script_entry,
		  eq_loaded_script_entry,
		  xfree));

  pspace_info->unsupported_script_warning_printed = false;
  pspace_info->script_not_found_warning_printed = false;
}

/* Wrapper on get_auto_load_pspace_data to also allocate the hash table
   for loading scripts.  */

struct auto_load_pspace_info *
get_auto_load_pspace_data_for_loading (struct program_space *pspace)
{
  struct auto_load_pspace_info *info;

  info = get_auto_load_pspace_data (pspace);
  if (info->loaded_script_files == NULL)
    init_loaded_scripts_info (info);

  return info;
}

/* Add script file NAME in LANGUAGE to hash table of PSPACE_INFO.
   LOADED is true if the script has been (is going to) be loaded, false
   otherwise (such as if it has not been found).
   FULL_PATH is NULL if the script wasn't found.

   The result is true if the script was already in the hash table.  */

static bool
maybe_add_script_file (struct auto_load_pspace_info *pspace_info, bool loaded,
		       const char *name, const char *full_path,
		       const struct extension_language_defn *language)
{
  struct htab *htab = pspace_info->loaded_script_files.get ();
  struct loaded_script **slot, entry;

  entry.name = name;
  entry.language = language;
  slot = (struct loaded_script **) htab_find_slot (htab, &entry, INSERT);
  bool in_hash_table = *slot != NULL;

  /* If this script is not in the hash table, add it.  */

  if (!in_hash_table)
    {
      char *p;

      /* Allocate all space in one chunk so it's easier to free.  */
      *slot = ((struct loaded_script *)
	       xmalloc (sizeof (**slot)
			+ strlen (name) + 1
			+ (full_path != NULL ? (strlen (full_path) + 1) : 0)));
      p = ((char*) *slot) + sizeof (**slot);
      strcpy (p, name);
      (*slot)->name = p;
      if (full_path != NULL)
	{
	  p += strlen (p) + 1;
	  strcpy (p, full_path);
	  (*slot)->full_path = p;
	}
      else
	(*slot)->full_path = NULL;
      (*slot)->loaded = loaded;
      (*slot)->language = language;
    }

  return in_hash_table;
}

/* Add script contents NAME in LANGUAGE to hash table of PSPACE_INFO.
   LOADED is true if the script has been (is going to) be loaded, false
   otherwise (such as if it has not been found).

   The result is true if the script was already in the hash table.  */

static bool
maybe_add_script_text (struct auto_load_pspace_info *pspace_info,
		       bool loaded, const char *name,
		       const struct extension_language_defn *language)
{
  struct htab *htab = pspace_info->loaded_script_texts.get ();
  struct loaded_script **slot, entry;

  entry.name = name;
  entry.language = language;
  slot = (struct loaded_script **) htab_find_slot (htab, &entry, INSERT);
  bool in_hash_table = *slot != NULL;

  /* If this script is not in the hash table, add it.  */

  if (!in_hash_table)
    {
      char *p;

      /* Allocate all space in one chunk so it's easier to free.  */
      *slot = ((struct loaded_script *)
	       xmalloc (sizeof (**slot) + strlen (name) + 1));
      p = ((char*) *slot) + sizeof (**slot);
      strcpy (p, name);
      (*slot)->name = p;
      (*slot)->full_path = NULL;
      (*slot)->loaded = loaded;
      (*slot)->language = language;
    }

  return in_hash_table;
}

/* Clear the table of loaded section scripts.  */

static void
clear_section_scripts (void)
{
  struct program_space *pspace = current_program_space;
  struct auto_load_pspace_info *info;

  info = auto_load_pspace_data.get (pspace);
  if (info != NULL && info->loaded_script_files != NULL)
    auto_load_pspace_data.clear (pspace);
}

/* Look for the auto-load script in LANGUAGE associated with OBJFILE where
   OBJFILE's gdb_realpath is REALNAME and load it.  Return 1 if we found any
   matching script, return 0 otherwise.  */

static int
auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
			    const struct extension_language_defn *language)
{
  const char *debugfile;
  int retval;
  const char *suffix = ext_lang_auto_load_suffix (language);

  std::string filename = std::string (realname) + suffix;

  gdb_file_up input = gdb_fopen_cloexec (filename.c_str (), "r");
  debugfile = filename.c_str ();

  auto_load_debug_printf ("Attempted file \"%ps\" %s.",
			  styled_string (file_name_style.style (), debugfile),
			  input != nullptr ? "exists" : "does not exist");

  std::string debugfile_holder;
  if (!input)
    {
      /* Also try the same file in a subdirectory of gdb's data
	 directory.  */

      std::vector<gdb::unique_xmalloc_ptr<char>> vec
	= auto_load_expand_dir_vars (auto_load_dir.c_str ());

      auto_load_debug_printf
	("Searching 'set auto-load scripts-directory' path \"%s\".",
	 auto_load_dir.c_str ());

      /* Convert Windows file name from c:/dir/file to /c/dir/file.  */
      if (HAS_DRIVE_SPEC (debugfile))
	filename = (std::string("\\") + debugfile[0]
		    + STRIP_DRIVE_SPEC (debugfile));

      for (const gdb::unique_xmalloc_ptr<char> &dir : vec)
	{
	  /* FILENAME is absolute, so we don't need a "/" here.  */
	  debugfile_holder = dir.get () + filename;
	  debugfile = debugfile_holder.c_str ();

	  input = gdb_fopen_cloexec (debugfile, "r");

	  auto_load_debug_printf ("Attempted file \"%ps\" %s.",
				  styled_string (file_name_style.style (),
						 debugfile),
				  (input != nullptr
				   ? "exists"
				   : "does not exist"));

	  if (input != NULL)
	    break;
	}
    }

  if (input)
    {
      struct auto_load_pspace_info *pspace_info;

      auto_load_debug_printf
	("Loading %s script \"%s\" by extension for objfile \"%s\".",
	 ext_lang_name (language), debugfile, objfile_name (objfile));

      bool is_safe = file_is_auto_load_safe (debugfile);

      /* Add this script to the hash table too so
	 "info auto-load ${lang}-scripts" can print it.  */
      pspace_info
	= get_auto_load_pspace_data_for_loading (current_program_space);
      maybe_add_script_file (pspace_info, is_safe, debugfile, debugfile,
			     language);

      /* To preserve existing behaviour we don't check for whether the
	 script was already in the table, and always load it.
	 It's highly unlikely that we'd ever load it twice,
	 and these scripts are required to be idempotent under multiple
	 loads anyway.  */
      if (is_safe)
	{
	  objfile_script_sourcer_func *sourcer
	    = ext_lang_objfile_script_sourcer (language);

	  /* We shouldn't get here if support for the language isn't
	     compiled in.  And the extension language is required to implement
	     this function.  */
	  gdb_assert (sourcer != NULL);
	  sourcer (language, objfile, input.get (), debugfile);
	}

      retval = 1;
    }
  else
    retval = 0;

  return retval;
}

/* Look for the auto-load script in LANGUAGE associated with OBJFILE and load
   it.  */

void
auto_load_objfile_script (struct objfile *objfile,
			  const struct extension_language_defn *language)
{
  gdb::unique_xmalloc_ptr<char> realname
    = gdb_realpath (objfile_name (objfile));

  if (auto_load_objfile_script_1 (objfile, realname.get (), language))
    return;

  /* For Windows/DOS .exe executables, strip the .exe suffix, so that
     FOO-gdb.gdb could be used for FOO.exe, and try again.  */

  size_t len = strlen (realname.get ());
  const size_t lexe = sizeof (".exe") - 1;

  if (len > lexe && strcasecmp (realname.get () + len - lexe, ".exe") == 0)
    {
      len -= lexe;
      realname.get ()[len] = '\0';

      auto_load_debug_printf
	("Stripped .exe suffix, retrying with \"%s\".", realname.get ());

      auto_load_objfile_script_1 (objfile, realname.get (), language);
      return;
    }

  /* If OBJFILE is a separate debug file and its name does not match
     the name given in the parent's .gnu_debuglink section, try to
     find the auto-load script using the parent's path and the
     debuglink name.  */

  struct objfile *parent = objfile->separate_debug_objfile_backlink;
  if (parent != nullptr)
    {
      unsigned long crc32;
      gdb::unique_xmalloc_ptr<char> debuglink
	(bfd_get_debug_link_info (parent->obfd, &crc32));

      if (debuglink.get () != nullptr
	  && strcmp (debuglink.get (), lbasename (realname.get ())) != 0)
	{
	  /* Replace the last component of the parent's path with the
	     debuglink name.  */

	  std::string p_realname = gdb_realpath (objfile_name (parent)).get ();
	  size_t last = p_realname.find_last_of ('/');

	  if (last != std::string::npos)
	    {
	      p_realname.replace (last + 1, std::string::npos,
				  debuglink.get ());

	      auto_load_debug_printf
		("Debug filename mismatch, retrying with \"%s\".",
		 p_realname.c_str ());

	      auto_load_objfile_script_1 (objfile,
					  p_realname.c_str (), language);
	    }
	}
    }
}

/* Subroutine of source_section_scripts to simplify it.
   Load FILE as a script in extension language LANGUAGE.
   The script is from section SECTION_NAME in OBJFILE at offset OFFSET.  */

static void
source_script_file (struct auto_load_pspace_info *pspace_info,
		    struct objfile *objfile,
		    const struct extension_language_defn *language,
		    const char *section_name, unsigned int offset,
		    const char *file)
{
  objfile_script_sourcer_func *sourcer;

  /* Skip this script if support is not compiled in.  */
  sourcer = ext_lang_objfile_script_sourcer (language);
  if (sourcer == NULL)
    {
      /* We don't throw an error, the program is still debuggable.  */
      maybe_print_unsupported_script_warning (pspace_info, objfile, language,
					      section_name, offset);
      /* We *could* still try to open it, but there's no point.  */
      maybe_add_script_file (pspace_info, 0, file, NULL, language);
      return;
    }

  /* Skip this script if auto-loading it has been disabled.  */
  if (!ext_lang_auto_load_enabled (language))
    {
      /* No message is printed, just skip it.  */
      return;
    }

  gdb::optional<open_script> opened = find_and_open_script (file,
							    1 /*search_path*/);

  if (opened)
    {
      auto_load_debug_printf
	("Loading %s script \"%s\" from section \"%s\" of objfile \"%s\".",
	 ext_lang_name (language), opened->full_path.get (),
	 section_name, objfile_name (objfile));

      if (!file_is_auto_load_safe (opened->full_path.get ()))
	opened.reset ();
    }
  else
    {
      /* If one script isn't found it's not uncommon for more to not be
	 found either.  We don't want to print a message for each script,
	 too much noise.  Instead, we print the warning once and tell the
	 user how to find the list of scripts that weren't loaded.
	 We don't throw an error, the program is still debuggable.

	 IWBN if complaints.c were more general-purpose.  */

      maybe_print_script_not_found_warning (pspace_info, objfile, language,
					    section_name, offset);
    }

  bool in_hash_table
    = maybe_add_script_file (pspace_info, bool (opened), file,
			     (opened ? opened->full_path.get (): NULL),
			     language);

  /* If this file is not currently loaded, load it.  */
  if (opened && !in_hash_table)
    sourcer (language, objfile, opened->stream.get (),
	     opened->full_path.get ());
}

/* Subroutine of source_section_scripts to simplify it.
   Execute SCRIPT as a script in extension language LANG.
   The script is from section SECTION_NAME in OBJFILE at offset OFFSET.  */

static void
execute_script_contents (struct auto_load_pspace_info *pspace_info,
			 struct objfile *objfile,
			 const struct extension_language_defn *language,
			 const char *section_name, unsigned int offset,
			 const char *script)
{
  objfile_script_executor_func *executor;
  const char *newline, *script_text;
  const char *name;

  /* The first line of the script is the name of the script.
     It must not contain any kind of space character.  */
  name = NULL;
  newline = strchr (script, '\n');
  std::string name_holder;
  if (newline != NULL)
    {
      const char *buf, *p;

      /* Put the name in a buffer and validate it.  */
      name_holder = std::string (script, newline - script);
      buf = name_holder.c_str ();
      for (p = buf; *p != '\0'; ++p)
	{
	  if (isspace (*p))
	    break;
	}
      /* We don't allow nameless scripts, they're not helpful to the user.  */
      if (p != buf && *p == '\0')
	name = buf;
    }
  if (name == NULL)
    {
      /* We don't throw an error, the program is still debuggable.  */
      warning (_("\
Missing/bad script name in entry at offset %u in section %s\n\
of file %ps."),
	       offset, section_name,
	       styled_string (file_name_style.style (),
			      objfile_name (objfile)));
      return;
    }
  script_text = newline + 1;

  /* Skip this script if support is not compiled in.  */
  executor = ext_lang_objfile_script_executor (language);
  if (executor == NULL)
    {
      /* We don't throw an error, the program is still debuggable.  */
      maybe_print_unsupported_script_warning (pspace_info, objfile, language,
					      section_name, offset);
      maybe_add_script_text (pspace_info, 0, name, language);
      return;
    }

  /* Skip this script if auto-loading it has been disabled.  */
  if (!ext_lang_auto_load_enabled (language))
    {
      /* No message is printed, just skip it.  */
      return;
    }

  auto_load_debug_printf
    ("Loading %s script \"%s\" from section \"%s\" of objfile \"%s\".",
     ext_lang_name (language), name, section_name, objfile_name (objfile));

  bool is_safe = file_is_auto_load_safe (objfile_name (objfile));

  bool in_hash_table
    = maybe_add_script_text (pspace_info, is_safe, name, language);

  /* If this file is not currently loaded, load it.  */
  if (is_safe && !in_hash_table)
    executor (language, objfile, name, script_text);
}

/* Load scripts specified in OBJFILE.
   START,END delimit a buffer containing a list of nul-terminated
   file names.
   SECTION_NAME is used in error messages.

   Scripts specified as file names are found per normal "source -s" command
   processing.  First the script is looked for in $cwd.  If not found there
   the source search path is used.

   The section contains a list of path names of script files to load or
   actual script contents.  Each entry is nul-terminated.  */

static void
source_section_scripts (struct objfile *objfile, const char *section_name,
			const char *start, const char *end)
{
  const char *p;
  struct auto_load_pspace_info *pspace_info;

  pspace_info = get_auto_load_pspace_data_for_loading (current_program_space);

  for (p = start; p < end; ++p)
    {
      const char *entry;
      const struct extension_language_defn *language;
      unsigned int offset = p - start;
      int code = *p;

      switch (code)
	{
	case SECTION_SCRIPT_ID_PYTHON_FILE:
	case SECTION_SCRIPT_ID_PYTHON_TEXT:
	  language = get_ext_lang_defn (EXT_LANG_PYTHON);
	  break;
	case SECTION_SCRIPT_ID_SCHEME_FILE:
	case SECTION_SCRIPT_ID_SCHEME_TEXT:
	  language = get_ext_lang_defn (EXT_LANG_GUILE);
	  break;
	default:
	  warning (_("Invalid entry in %s section"), section_name);
	  /* We could try various heuristics to find the next valid entry,
	     but it's safer to just punt.  */
	  return;
	}
      entry = ++p;

      while (p < end && *p != '\0')
	++p;
      if (p == end)
	{
	  warning (_("Non-nul-terminated entry in %s at offset %u"),
		   section_name, offset);
	  /* Don't load/execute it.  */
	  break;
	}

      switch (code)
	{
	case SECTION_SCRIPT_ID_PYTHON_FILE:
	case SECTION_SCRIPT_ID_SCHEME_FILE:
	  if (p == entry)
	    {
	      warning (_("Empty entry in %s at offset %u"),
		       section_name, offset);
	      continue;
	    }
	  source_script_file (pspace_info, objfile, language,
			      section_name, offset, entry);
	  break;
	case SECTION_SCRIPT_ID_PYTHON_TEXT:
	case SECTION_SCRIPT_ID_SCHEME_TEXT:
	  execute_script_contents (pspace_info, objfile, language,
				   section_name, offset, entry);
	  break;
	}
    }
}

/* Load scripts specified in section SECTION_NAME of OBJFILE.  */

static void
auto_load_section_scripts (struct objfile *objfile, const char *section_name)
{
  bfd *abfd = objfile->obfd;
  asection *scripts_sect;
  bfd_byte *data = NULL;

  scripts_sect = bfd_get_section_by_name (abfd, section_name);
  if (scripts_sect == NULL
      || (bfd_section_flags (scripts_sect) & SEC_HAS_CONTENTS) == 0)
    return;

  if (!bfd_get_full_section_contents (abfd, scripts_sect, &data))
    warning (_("Couldn't read %s section of %ps"),
	     section_name,
	     styled_string (file_name_style.style (),
			    bfd_get_filename (abfd)));
  else
    {
      gdb::unique_xmalloc_ptr<bfd_byte> data_holder (data);

      char *p = (char *) data;
      source_section_scripts (objfile, section_name, p,
			      p + bfd_section_size (scripts_sect));
    }
}

/* Load any auto-loaded scripts for OBJFILE.  */

void
load_auto_scripts_for_objfile (struct objfile *objfile)
{
  /* Return immediately if auto-loading has been globally disabled.
     This is to handle sequencing of operations during gdb startup.
     Also return immediately if OBJFILE was not created from a file
     on the local filesystem.  */
  if (!global_auto_load
      || (objfile->flags & OBJF_NOT_FILENAME) != 0
      || is_target_filename (objfile->original_name))
    return;

  /* Load any extension language scripts for this objfile.
     E.g., foo-gdb.gdb, foo-gdb.py.  */
  auto_load_ext_lang_scripts_for_objfile (objfile);

  /* Load any scripts mentioned in AUTO_SECTION_NAME (.debug_gdb_scripts).  */
  auto_load_section_scripts (objfile, AUTO_SECTION_NAME);
}

/* This is a new_objfile observer callback to auto-load scripts.

   Two flavors of auto-loaded scripts are supported.
   1) based on the path to the objfile
   2) from .debug_gdb_scripts section  */

static void
auto_load_new_objfile (struct objfile *objfile)
{
  if (!objfile)
    {
      /* OBJFILE is NULL when loading a new "main" symbol-file.  */
      clear_section_scripts ();
      return;
    }

  load_auto_scripts_for_objfile (objfile);
}

/* Collect scripts to be printed in a vec.  */

struct collect_matching_scripts_data
{
  collect_matching_scripts_data (std::vector<loaded_script *> *scripts_p_,
				 const extension_language_defn *language_)
  : scripts_p (scripts_p_), language (language_)
  {}

  std::vector<loaded_script *> *scripts_p;
  const struct extension_language_defn *language;
};

/* Traversal function for htab_traverse.
   Collect the entry if it matches the regexp.  */

static int
collect_matching_scripts (void **slot, void *info)
{
  struct loaded_script *script = (struct loaded_script *) *slot;
  struct collect_matching_scripts_data *data
    = (struct collect_matching_scripts_data *) info;

  if (script->language == data->language && re_exec (script->name))
    data->scripts_p->push_back (script);

  return 1;
}

/* Print SCRIPT.  */

static void
print_script (struct loaded_script *script)
{
  struct ui_out *uiout = current_uiout;

  ui_out_emit_tuple tuple_emitter (uiout, NULL);

  uiout->field_string ("loaded", script->loaded ? "Yes" : "No");
  uiout->field_string ("script", script->name);
  uiout->text ("\n");

  /* If the name isn't the full path, print it too.  */
  if (script->full_path != NULL
      && strcmp (script->name, script->full_path) != 0)
    {
      uiout->text ("\tfull name: ");
      uiout->field_string ("full_path", script->full_path);
      uiout->text ("\n");
    }
}

/* Helper for info_auto_load_scripts to sort the scripts by name.  */

static bool
sort_scripts_by_name (loaded_script *a, loaded_script *b)
{
  return FILENAME_CMP (a->name, b->name) < 0;
}

/* Special internal GDB value of auto_load_info_scripts's PATTERN identify
   the "info auto-load XXX" command has been executed through the general
   "info auto-load" invocation.  Extra newline will be printed if needed.  */
char auto_load_info_scripts_pattern_nl[] = "";

/* Subroutine of auto_load_info_scripts to simplify it.
   Print SCRIPTS.  */

static void
print_scripts (const std::vector<loaded_script *> &scripts)
{
  for (loaded_script *script : scripts)
    print_script (script);
}

/* Implementation for "info auto-load gdb-scripts"
   (and "info auto-load python-scripts").  List scripts in LANGUAGE matching
   PATTERN.  FROM_TTY is the usual GDB boolean for user interactivity.  */

void
auto_load_info_scripts (const char *pattern, int from_tty,
			const struct extension_language_defn *language)
{
  struct ui_out *uiout = current_uiout;
  struct auto_load_pspace_info *pspace_info;

  dont_repeat ();

  pspace_info = get_auto_load_pspace_data (current_program_space);

  if (pattern && *pattern)
    {
      char *re_err = re_comp (pattern);

      if (re_err)
	error (_("Invalid regexp: %s"), re_err);
    }
  else
    {
      re_comp ("");
    }

  /* We need to know the number of rows before we build the table.
     Plus we want to sort the scripts by name.
     So first traverse the hash table collecting the matching scripts.  */

  std::vector<loaded_script *> script_files, script_texts;

  if (pspace_info != NULL && pspace_info->loaded_script_files != NULL)
    {
      collect_matching_scripts_data data (&script_files, language);

      /* Pass a pointer to scripts as VEC_safe_push can realloc space.  */
      htab_traverse_noresize (pspace_info->loaded_script_files.get (),
			      collect_matching_scripts, &data);

      std::sort (script_files.begin (), script_files.end (),
		 sort_scripts_by_name);
    }

  if (pspace_info != NULL && pspace_info->loaded_script_texts != NULL)
    {
      collect_matching_scripts_data data (&script_texts, language);

      /* Pass a pointer to scripts as VEC_safe_push can realloc space.  */
      htab_traverse_noresize (pspace_info->loaded_script_texts.get (),
			      collect_matching_scripts, &data);

      std::sort (script_texts.begin (), script_texts.end (),
		 sort_scripts_by_name);
    }

  int nr_scripts = script_files.size () + script_texts.size ();

  /* Table header shifted right by preceding "gdb-scripts:  " would not match
     its columns.  */
  if (nr_scripts > 0 && pattern == auto_load_info_scripts_pattern_nl)
    uiout->text ("\n");

  {
    ui_out_emit_table table_emitter (uiout, 2, nr_scripts,
				     "AutoLoadedScriptsTable");

    uiout->table_header (7, ui_left, "loaded", "Loaded");
    uiout->table_header (70, ui_left, "script", "Script");
    uiout->table_body ();

    print_scripts (script_files);
    print_scripts (script_texts);
  }

  if (nr_scripts == 0)
    {
      if (pattern && *pattern)
	uiout->message ("No auto-load scripts matching %s.\n", pattern);
      else
	uiout->message ("No auto-load scripts.\n");
    }
}

/* Wrapper for "info auto-load gdb-scripts".  */

static void
info_auto_load_gdb_scripts (const char *pattern, int from_tty)
{
  auto_load_info_scripts (pattern, from_tty, &extension_language_gdb);
}

/* Implement 'info auto-load local-gdbinit'.  */

static void
info_auto_load_local_gdbinit (const char *args, int from_tty)
{
  if (auto_load_local_gdbinit_pathname == NULL)
    gdb_printf (_("Local .gdbinit file was not found.\n"));
  else if (auto_load_local_gdbinit_loaded)
    gdb_printf (_("Local .gdbinit file \"%ps\" has been loaded.\n"),
		styled_string (file_name_style.style (),
			       auto_load_local_gdbinit_pathname));
  else
    gdb_printf (_("Local .gdbinit file \"%ps\" has not been loaded.\n"),
		styled_string (file_name_style.style (),
			       auto_load_local_gdbinit_pathname));
}

/* Print an "unsupported script" warning if it has not already been printed.
   The script is in language LANGUAGE at offset OFFSET in section SECTION_NAME
   of OBJFILE.  */

static void
maybe_print_unsupported_script_warning
  (struct auto_load_pspace_info *pspace_info,
   struct objfile *objfile, const struct extension_language_defn *language,
   const char *section_name, unsigned offset)
{
  if (!pspace_info->unsupported_script_warning_printed)
    {
      warning (_("\
Unsupported auto-load script at offset %u in section %s\n\
of file %ps.\n\
Use `info auto-load %s-scripts [REGEXP]' to list them."),
	       offset, section_name,
	       styled_string (file_name_style.style (),
			      objfile_name (objfile)),
	       ext_lang_name (language));
      pspace_info->unsupported_script_warning_printed = true;
    }
}

/* Return non-zero if SCRIPT_NOT_FOUND_WARNING_PRINTED of PSPACE_INFO was unset
   before calling this function.  Always set SCRIPT_NOT_FOUND_WARNING_PRINTED
   of PSPACE_INFO.  */

static void
maybe_print_script_not_found_warning
  (struct auto_load_pspace_info *pspace_info,
   struct objfile *objfile, const struct extension_language_defn *language,
   const char *section_name, unsigned offset)
{
  if (!pspace_info->script_not_found_warning_printed)
    {
      warning (_("\
Missing auto-load script at offset %u in section %s\n\
of file %ps.\n\
Use `info auto-load %s-scripts [REGEXP]' to list them."),
	       offset, section_name,
	       styled_string (file_name_style.style (),
			      objfile_name (objfile)),
	       ext_lang_name (language));
      pspace_info->script_not_found_warning_printed = true;
    }
}

/* The only valid "set auto-load" argument is off|0|no|disable.  */

static void
set_auto_load_cmd (const char *args, int from_tty)
{
  struct cmd_list_element *list;
  size_t length;

  /* See parse_binary_operation in use by the sub-commands.  */

  length = args ? strlen (args) : 0;

  while (length > 0 && (args[length - 1] == ' ' || args[length - 1] == '\t'))
    length--;

  if (length == 0 || (strncmp (args, "off", length) != 0
		      && strncmp (args, "0", length) != 0
		      && strncmp (args, "no", length) != 0
		      && strncmp (args, "disable", length) != 0))
    error (_("Valid is only global 'set auto-load no'; "
	     "otherwise check the auto-load sub-commands."));

  for (list = *auto_load_set_cmdlist_get (); list != NULL; list = list->next)
    if (list->var->type () == var_boolean)
      {
	gdb_assert (list->type == set_cmd);
	do_set_command (args, from_tty, list);
      }
}

/* Initialize "set auto-load " commands prefix and return it.  */

struct cmd_list_element **
auto_load_set_cmdlist_get (void)
{
  static struct cmd_list_element *retval;

  if (retval == NULL)
    add_prefix_cmd ("auto-load", class_maintenance, set_auto_load_cmd, _("\
Auto-loading specific settings.\n\
Configure various auto-load-specific variables such as\n\
automatic loading of Python scripts."),
		    &retval, 1/*allow-unknown*/, &setlist);

  return &retval;
}

/* Initialize "show auto-load " commands prefix and return it.  */

struct cmd_list_element **
auto_load_show_cmdlist_get (void)
{
  static struct cmd_list_element *retval;

  if (retval == NULL)
    add_show_prefix_cmd ("auto-load", class_maintenance, _("\
Show auto-loading specific settings.\n\
Show configuration of various auto-load-specific variables such as\n\
automatic loading of Python scripts."),
			 &retval, 0/*allow-unknown*/, &showlist);

  return &retval;
}

/* Command "info auto-load" displays whether the various auto-load files have
   been loaded.  This is reimplementation of cmd_show_list which inserts
   newlines at proper places.  */

static void
info_auto_load_cmd (const char *args, int from_tty)
{
  struct cmd_list_element *list;
  struct ui_out *uiout = current_uiout;

  ui_out_emit_tuple tuple_emitter (uiout, "infolist");

  for (list = *auto_load_info_cmdlist_get (); list != NULL; list = list->next)
    {
      ui_out_emit_tuple option_emitter (uiout, "option");

      gdb_assert (!list->is_prefix ());
      gdb_assert (list->type == not_set_cmd);

      uiout->field_string ("name", list->name);
      uiout->text (":  ");
      cmd_func (list, auto_load_info_scripts_pattern_nl, from_tty);
    }
}

/* Initialize "info auto-load " commands prefix and return it.  */

struct cmd_list_element **
auto_load_info_cmdlist_get (void)
{
  static struct cmd_list_element *retval;

  if (retval == NULL)
    add_prefix_cmd ("auto-load", class_info, info_auto_load_cmd, _("\
Print current status of auto-loaded files.\n\
Print whether various files like Python scripts or .gdbinit files have been\n\
found and/or loaded."),
		    &retval, 0/*allow-unknown*/, &infolist);

  return &retval;
}

/* See auto-load.h.  */

gdb::observers::token auto_load_new_objfile_observer_token;

void _initialize_auto_load ();
void
_initialize_auto_load ()
{
  struct cmd_list_element *cmd;
  gdb::unique_xmalloc_ptr<char> scripts_directory_help, gdb_name_help,
    python_name_help, guile_name_help;
  const char *suffix;

  gdb::observers::new_objfile.attach (auto_load_new_objfile,
                                      auto_load_new_objfile_observer_token,
                                      "auto-load");
  add_setshow_boolean_cmd ("gdb-scripts", class_support,
			   &auto_load_gdb_scripts, _("\
Enable or disable auto-loading of canned sequences of commands scripts."), _("\
Show whether auto-loading of canned sequences of commands scripts is enabled."),
			   _("\
If enabled, canned sequences of commands are loaded when the debugger reads\n\
an executable or shared library.\n\
This option has security implications for untrusted inferiors."),
			   NULL, show_auto_load_gdb_scripts,
			   auto_load_set_cmdlist_get (),
			   auto_load_show_cmdlist_get ());

  add_cmd ("gdb-scripts", class_info, info_auto_load_gdb_scripts,
	   _("Print the list of automatically loaded sequences of commands.\n\
Usage: info auto-load gdb-scripts [REGEXP]"),
	   auto_load_info_cmdlist_get ());

  add_setshow_boolean_cmd ("local-gdbinit", class_support,
			   &auto_load_local_gdbinit, _("\
Enable or disable auto-loading of .gdbinit script in current directory."), _("\
Show whether auto-loading .gdbinit script in current directory is enabled."),
			   _("\
If enabled, canned sequences of commands are loaded when debugger starts\n\
from .gdbinit file in current directory.  Such files are deprecated,\n\
use a script associated with inferior executable file instead.\n\
This option has security implications for untrusted inferiors."),
			   NULL, show_auto_load_local_gdbinit,
			   auto_load_set_cmdlist_get (),
			   auto_load_show_cmdlist_get ());

  add_cmd ("local-gdbinit", class_info, info_auto_load_local_gdbinit,
	   _("Print whether current directory .gdbinit file has been loaded.\n\
Usage: info auto-load local-gdbinit"),
	   auto_load_info_cmdlist_get ());

  suffix = ext_lang_auto_load_suffix (get_ext_lang_defn (EXT_LANG_GDB));
  gdb_name_help
    = xstrprintf (_("\
GDB scripts:    OBJFILE%s\n"),
		  suffix);
  python_name_help = NULL;
#ifdef HAVE_PYTHON
  suffix = ext_lang_auto_load_suffix (get_ext_lang_defn (EXT_LANG_PYTHON));
  python_name_help
    = xstrprintf (_("\
Python scripts: OBJFILE%s\n"),
		  suffix);
#endif
  guile_name_help = NULL;
#ifdef HAVE_GUILE
  suffix = ext_lang_auto_load_suffix (get_ext_lang_defn (EXT_LANG_GUILE));
  guile_name_help
    = xstrprintf (_("\
Guile scripts:  OBJFILE%s\n"),
		  suffix);
#endif
  scripts_directory_help
    = xstrprintf (_("\
Automatically loaded scripts are located in one of the directories listed\n\
by this option.\n\
\n\
Script names:\n\
%s%s%s\
\n\
This option is ignored for the kinds of scripts \
having 'set auto-load ... off'.\n\
Directories listed here need to be present also \
in the 'set auto-load safe-path'\n\
option."),
		  gdb_name_help.get (),
		  python_name_help.get () ? python_name_help.get () : "",
		  guile_name_help.get () ? guile_name_help.get () : "");

  add_setshow_optional_filename_cmd ("scripts-directory", class_support,
				     &auto_load_dir, _("\
Set the list of directories from which to load auto-loaded scripts."), _("\
Show the list of directories from which to load auto-loaded scripts."),
				     scripts_directory_help.get (),
				     set_auto_load_dir, show_auto_load_dir,
				     auto_load_set_cmdlist_get (),
				     auto_load_show_cmdlist_get ());
  auto_load_safe_path_vec_update ();
  add_setshow_optional_filename_cmd ("safe-path", class_support,
				     &auto_load_safe_path, _("\
Set the list of files and directories that are safe for auto-loading."), _("\
Show the list of files and directories that are safe for auto-loading."), _("\
Various files loaded automatically for the 'set auto-load ...' options must\n\
be located in one of the directories listed by this option.  Warning will be\n\
printed and file will not be used otherwise.\n\
You can mix both directory and filename entries.\n\
Setting this parameter to an empty list resets it to its default value.\n\
Setting this parameter to '/' (without the quotes) allows any file\n\
for the 'set auto-load ...' options.  Each path entry can be also shell\n\
wildcard pattern; '*' does not match directory separator.\n\
This option is ignored for the kinds of files having 'set auto-load ... off'.\n\
This option has security implications for untrusted inferiors."),
				     set_auto_load_safe_path,
				     show_auto_load_safe_path,
				     auto_load_set_cmdlist_get (),
				     auto_load_show_cmdlist_get ());
  gdb::observers::gdb_datadir_changed.attach (auto_load_gdb_datadir_changed,
					      "auto-load");

  cmd = add_cmd ("add-auto-load-safe-path", class_support,
		 add_auto_load_safe_path,
		 _("Add entries to the list of directories from which it is safe "
		   "to auto-load files.\n\
See the commands 'set auto-load safe-path' and 'show auto-load safe-path' to\n\
access the current full list setting."),
		 &cmdlist);
  set_cmd_completer (cmd, filename_completer);

  cmd = add_cmd ("add-auto-load-scripts-directory", class_support,
		 add_auto_load_dir,
		 _("Add entries to the list of directories from which to load "
		   "auto-loaded scripts.\n\
See the commands 'set auto-load scripts-directory' and\n\
'show auto-load scripts-directory' to access the current full list setting."),
		 &cmdlist);
  set_cmd_completer (cmd, filename_completer);

  add_setshow_boolean_cmd ("auto-load", class_maintenance,
			   &debug_auto_load, _("\
Set auto-load verifications debugging."), _("\
Show auto-load verifications debugging."), _("\
When non-zero, debugging output for files of 'set auto-load ...'\n\
is displayed."),
			    NULL, show_debug_auto_load,
			    &setdebuglist, &showdebuglist);
}
