btrace: uppercase btrace_read_type
[deliverable/binutils-gdb.git] / gdb / auto-load.c
index b314ad65b97d8ca5b3d456464c4ff3191fb5351f..46d063c9dd3890b407f21ac9884043b588914418 100644 (file)
@@ -1,6 +1,6 @@
 /* GDB routines for supporting auto-loaded scripts.
 
-   Copyright (C) 2012 Free Software Foundation, Inc.
+   Copyright (C) 2012-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "exceptions.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 "gdb_vecs.h"
 #include "readline/tilde.h"
 #include "completer.h"
-#include "observer.h"
 #include "fnmatch.h"
+#include "top.h"
+#include "filestuff.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 suffix of per-objfile scripts to auto-load as non-Python command files.
    E.g. When the program loads libfoo.so, look for libfoo-gdb.gdb.  */
@@ -77,6 +87,14 @@ show_auto_load_gdb_scripts (struct ui_file *file, int from_tty,
                    value);
 }
 
+/* Return non-zero if auto-loading gdb scripts is enabled.  */
+
+static int
+auto_load_gdb_scripts_enabled (void)
+{
+  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.
@@ -177,7 +195,6 @@ auto_load_expand_dir_vars (const char *string)
 static void
 auto_load_safe_path_vec_update (void)
 {
-  VEC (char_ptr) *dir_vec = NULL;
   unsigned len;
   int ix;
 
@@ -441,6 +458,7 @@ file_is_auto_load_safe (const char *filename, const char *debug_fmt, ...)
 {
   char *filename_real = NULL;
   struct cleanup *back_to;
+  static int advice_printed = 0;
 
   if (debug_auto_load)
     {
@@ -470,37 +488,50 @@ file_is_auto_load_safe (const char *filename, const char *debug_fmt, ...)
             "`auto-load safe-path' set to \"%s\"."),
           filename_real, auto_load_safe_path);
 
+  if (!advice_printed)
+    {
+      const char *homedir = getenv ("HOME");
+      char *homeinit;
+
+      if (homedir == NULL)
+       homedir = "$HOME";
+      homeinit = xstrprintf ("%s/%s", homedir, gdbinit);
+      make_cleanup (xfree, homeinit);
+
+      printf_filtered (_("\
+To enable execution of this file add\n\
+\tadd-auto-load-safe-path %s\n\
+line to your configuration file \"%s\".\n\
+To completely disable this security protection add\n\
+\tset auto-load safe-path /\n\
+line to your configuration file \"%s\".\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, homeinit, homeinit);
+      advice_printed = 1;
+    }
+
   do_cleanups (back_to);
   return 0;
 }
 
 /* Definition of script language for GDB canned sequences of commands.  */
 
-static const struct script_language script_language_gdb
-  = { GDB_AUTO_FILE_NAME, source_gdb_script_for_objfile };
+static const struct script_language script_language_gdb =
+{
+  "gdb",
+  GDB_AUTO_FILE_NAME,
+  auto_load_gdb_scripts_enabled,
+  source_gdb_script_for_objfile
+};
 
 static void
 source_gdb_script_for_objfile (struct objfile *objfile, FILE *file,
                               const char *filename)
 {
-  int is_safe;
-  struct auto_load_pspace_info *pspace_info;
   volatile struct gdb_exception e;
 
-  is_safe = file_is_auto_load_safe (filename, _("auto-load: Loading canned "
-                                               "sequences of commands script "
-                                               "\"%s\" for objfile \"%s\".\n"),
-                                   filename, objfile->name);
-
-  /* Add this script to the hash table too so "info auto-load gdb-scripts"
-     can print it.  */
-  pspace_info = get_auto_load_pspace_data_for_loading (current_program_space);
-  maybe_add_script (pspace_info, is_safe, filename, filename,
-                   &script_language_gdb);
-
-  if (!is_safe)
-    return;
-
   TRY_CATCH (e, RETURN_MASK_ALL)
     {
       script_from_file (file, filename);
@@ -546,15 +577,11 @@ static const struct program_space_data *auto_load_pspace_data;
 static void
 auto_load_pspace_data_cleanup (struct program_space *pspace, void *arg)
 {
-  struct auto_load_pspace_info *info;
+  struct auto_load_pspace_info *info = arg;
 
-  info = program_space_data (pspace, auto_load_pspace_data);
-  if (info != NULL)
-    {
-      if (info->loaded_scripts)
-       htab_delete (info->loaded_scripts);
-      xfree (info);
-    }
+  if (info->loaded_scripts)
+    htab_delete (info->loaded_scripts);
+  xfree (info);
 }
 
 /* Get the current autoload data.  If none is found yet, add it now.  This
@@ -568,7 +595,7 @@ get_auto_load_pspace_data (struct program_space *pspace)
   info = program_space_data (pspace, auto_load_pspace_data);
   if (info == NULL)
     {
-      info = XZALLOC (struct auto_load_pspace_info);
+      info = XCNEW (struct auto_load_pspace_info);
       set_program_space_data (pspace, auto_load_pspace_data, info);
     }
 
@@ -713,7 +740,7 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
 
   cleanups = make_cleanup (xfree, filename);
 
-  input = fopen (filename, "r");
+  input = gdb_fopen_cloexec (filename, "r");
   debugfile = filename;
   if (debug_auto_load)
     fprintf_unfiltered (gdb_stdlog, _("auto-load: Attempted file \"%s\" %s.\n"),
@@ -745,7 +772,7 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
          strcat (debugfile, filename);
 
          make_cleanup (xfree, debugfile);
-         input = fopen (debugfile, "r");
+         input = gdb_fopen_cloexec (debugfile, "r");
          if (debug_auto_load)
            fprintf_unfiltered (gdb_stdlog, _("auto-load: Attempted file "
                                              "\"%s\" %s.\n"),
@@ -758,14 +785,31 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
 
   if (input)
     {
+      int is_safe;
+      struct auto_load_pspace_info *pspace_info;
+
       make_cleanup_fclose (input);
 
+      is_safe
+       = file_is_auto_load_safe (filename,
+                                 _("auto-load: Loading %s script \"%s\""
+                                   " by extension for objfile \"%s\".\n"),
+                                 language->name, filename,
+                                 objfile_name (objfile));
+
+      /* 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 (pspace_info, is_safe, filename, filename, 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.  */
-      language->source_script_for_objfile (objfile, input, debugfile);
+      if (is_safe)
+       language->source_script_for_objfile (objfile, input, debugfile);
 
       retval = 1;
     }
@@ -779,12 +823,21 @@ auto_load_objfile_script_1 (struct objfile *objfile, const char *realname,
 /* Look for the auto-load script in LANGUAGE associated with OBJFILE and load
    it.  */
 
-void
+static void
 auto_load_objfile_script (struct objfile *objfile,
                          const struct script_language *language)
 {
-  char *realname = gdb_realpath (objfile->name);
-  struct cleanup *cleanups = make_cleanup (xfree, realname);
+  char *realname;
+  struct cleanup *cleanups;
+
+  /* Skip this script if support has not been compiled in or
+     auto-loading it has been disabled.  */
+  if (language == NULL
+      || !language->auto_load_enabled ())
+    return;
+
+  realname = gdb_realpath (objfile_name (objfile));
+  cleanups = make_cleanup (xfree, realname);
 
   if (!auto_load_objfile_script_1 (objfile, realname, language))
     {
@@ -809,18 +862,170 @@ auto_load_objfile_script (struct objfile *objfile,
   do_cleanups (cleanups);
 }
 
+/* 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 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.
+   Each path is null-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 *file;
+      FILE *stream;
+      char *full_path;
+      int opened, in_hash_table;
+      struct cleanup *back_to;
+      /* At the moment we only support python scripts in .debug_gdb_scripts,
+        but that can change.  */
+      const struct script_language *language = gdbpy_script_language_defn ();
+
+      if (*p != 1)
+       {
+         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.  */
+         break;
+       }
+      file = ++p;
+
+      while (p < end && *p != '\0')
+       ++p;
+      if (p == end)
+       {
+         char *buf = alloca (p - file + 1);
+
+         memcpy (buf, file, p - file);
+         buf[p - file] = '\0';
+         warning (_("Non-null-terminated path in %s: %s"),
+                  section_name, buf);
+         /* Don't load it.  */
+         break;
+       }
+      if (p == file)
+       {
+         warning (_("Empty path in %s"), section_name);
+         continue;
+       }
+
+      /* Skip this script if support has not been compiled in or
+        auto-loading it has been disabled.  */
+      if (language == NULL
+         || !language->auto_load_enabled ())
+       {
+         /* No message is printed, just skip it.  */
+         continue;
+       }
+
+      opened = find_and_open_script (file, 1 /*search_path*/,
+                                    &stream, &full_path);
+
+      back_to = make_cleanup (null_cleanup, NULL);
+      if (opened)
+       {
+         make_cleanup_fclose (stream);
+         make_cleanup (xfree, full_path);
+
+         if (!file_is_auto_load_safe (full_path,
+                                      _("auto-load: Loading %s script "
+                                        "\"%s\" from section \"%s\" of "
+                                        "objfile \"%s\".\n"),
+                                      language->name, full_path, section_name,
+                                      objfile_name (objfile)))
+           opened = 0;
+       }
+      else
+       {
+         full_path = NULL;
+
+         /* 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.  */
+
+         if (script_not_found_warning_print (pspace_info))
+           warning (_("Missing auto-load scripts referenced in section %s\n\
+of file %s\n\
+Use `info auto-load %s-scripts [REGEXP]' to list them."),
+                    section_name, objfile_name (objfile), language->name);
+       }
+
+      in_hash_table = maybe_add_script (pspace_info, opened, file, full_path,
+                                       language);
+
+      /* If this file is not currently loaded, load it.  */
+      if (opened && !in_hash_table)
+       {
+         gdb_assert (language->source_script_for_objfile != NULL);
+         language->source_script_for_objfile (objfile, stream, full_path);
+       }
+
+      do_cleanups (back_to);
+    }
+}
+
+/* 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)
+    return;
+
+  if (!bfd_get_full_section_contents (abfd, scripts_sect, &data))
+    warning (_("Couldn't read %s section of %s"),
+            section_name, bfd_get_filename (abfd));
+  else
+    {
+      struct cleanup *cleanups;
+      char *p = (char *) data;
+
+      cleanups = make_cleanup (xfree, p);
+      source_section_scripts (objfile, section_name, p,
+                             p + bfd_get_section_size (scripts_sect));
+      do_cleanups (cleanups);
+    }
+}
+
 /* Load any auto-loaded scripts for OBJFILE.  */
 
 void
 load_auto_scripts_for_objfile (struct objfile *objfile)
 {
-  if (!global_auto_load)
+  /* Return immediately if auto-loading has been globally disabled.
+     This is to handle sequencing of operations during gdb startup.
+     Also return immediately if OBJFILE is not actually a file.  */
+  if (!global_auto_load || (objfile->flags & OBJF_NOT_FILENAME) != 0)
     return;
 
-  if (auto_load_gdb_scripts)
-    auto_load_objfile_script (objfile, &script_language_gdb);
+  /* Load any scripts for this objfile. e.g. foo-gdb.gdb, foo-gdb.py.  */
+  auto_load_objfile_script (objfile, &script_language_gdb);
+  auto_load_objfile_script (objfile, gdbpy_script_language_defn ());
 
-  gdbpy_load_auto_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.
@@ -1164,6 +1369,7 @@ void
 _initialize_auto_load (void)
 {
   struct cmd_list_element *cmd;
+  char *scripts_directory_help;
 
   auto_load_pspace_data
     = register_program_space_data_with_cleanup (NULL,
@@ -1207,30 +1413,50 @@ Usage: info auto-load local-gdbinit"),
           auto_load_info_cmdlist_get ());
 
   auto_load_dir = xstrdup (AUTO_LOAD_DIR);
+  scripts_directory_help = xstrprintf (
+#ifdef HAVE_PYTHON
+                                      _("\
+Automatically loaded Python scripts (named OBJFILE%s) and GDB scripts\n\
+(named OBJFILE%s) are located in one of the directories listed by this\n\
+option.\n\
+%s"),
+                                      GDBPY_AUTO_FILE_NAME,
+#else
+                                      _("\
+Automatically loaded GDB scripts (named OBJFILE%s) are located in one\n\
+of the directories listed by this option.\n\
+%s"),
+#endif
+                                      GDB_AUTO_FILE_NAME,
+                                      _("\
+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."));
   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."), _("\
-Automatically loaded Python scripts and GDB scripts are located in one of the\n\
-directories listed by this option.  This option is ignored for the kinds of\n\
-scripts having 'set auto-load ... off'.  Directories listed here need to be\n\
-present also in the 'set auto-load safe-path' option."),
+Show the list of directories from which to load auto-loaded scripts."),
+                                    scripts_directory_help,
                                     set_auto_load_dir, show_auto_load_dir,
                                     auto_load_set_cmdlist_get (),
                                     auto_load_show_cmdlist_get ());
+  xfree (scripts_directory_help);
 
   auto_load_safe_path = xstrdup (AUTO_LOAD_SAFE_PATH);
   auto_load_safe_path_vec_update ();
   add_setshow_optional_filename_cmd ("safe-path", class_support,
                                     &auto_load_safe_path, _("\
-Set the list of directories from which it is safe to auto-load files."), _("\
-Show the list of directories from which it is safe to auto-load files."), _("\
+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 directory can be also shell\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 options has security implications for untrusted inferiors."),
This page took 0.029449 seconds and 4 git commands to generate.