/* GDB routines for supporting auto-loaded scripts.
- Copyright (C) 2012-2021 Free Software Foundation, Inc.
+ Copyright (C) 2012-2022 Free Software Foundation, Inc.
This file is part of GDB.
#include <ctype.h>
#include "auto-load.h"
#include "progspace.h"
-#include "gdb_regex.h"
+#include "gdbsupport/gdb_regex.h"
#include "ui-out.h"
#include "filenames.h"
#include "command.h"
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,
show_debug_auto_load (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file, _("Debugging output for files "
- "of 'set auto-load ...' is %s.\n"),
- 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
show_auto_load_gdb_scripts (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file, _("Auto-loading of canned sequences of commands "
- "scripts is %s.\n"),
- value);
+ gdb_printf (file, _("Auto-loading of canned sequences of commands "
+ "scripts is %s.\n"),
+ value);
}
/* See auto-load.h. */
show_auto_load_local_gdbinit (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file, _("Auto-loading of .gdbinit script from current "
- "directory is %s.\n"),
- 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
show_auto_load_dir (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
- fprintf_filtered (file, _("List of directories from which to load "
- "auto-loaded scripts is %s.\n"),
- 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
for (cs = value; *cs && (*cs == DIRNAME_SEPARATOR || IS_DIR_SEPARATOR (*cs));
cs++);
if (*cs == 0)
- fprintf_filtered (file, _("Auto-load files are safe to load from any "
- "directory.\n"));
+ gdb_printf (file, _("Auto-load files are safe to load from any "
+ "directory.\n"));
else
- fprintf_filtered (file, _("List of directories from which it is safe to "
- "auto-load files is %s.\n"),
- value);
+ 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
}
}
- printf_filtered (_("\
+ gdb_printf (_("\
To enable execution of this file add\n\
\tadd-auto-load-safe-path %s\n\
-line to your configuration file \"%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 \"%s\".\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 (),
- home_config.c_str (), home_config.c_str ());
+ styled_string (file_name_style.style (),
+ home_config.c_str ()),
+ styled_string (file_name_style.style (),
+ home_config.c_str ()));
advice_printed = true;
}
gdb::unique_xmalloc_ptr<char> realname
= gdb_realpath (objfile_name (objfile));
- if (!auto_load_objfile_script_1 (objfile, realname.get (), language))
+ 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)
{
- /* For Windows/DOS .exe executables, strip the .exe suffix, so that
- FOO-gdb.gdb could be used for FOO.exe, and try again. */
+ len -= lexe;
+ realname.get ()[len] = '\0';
- size_t len = strlen (realname.get ());
- const size_t lexe = sizeof (".exe") - 1;
+ auto_load_debug_printf
+ ("Stripped .exe suffix, retrying with \"%s\".", realname.get ());
+
+ auto_load_objfile_script_1 (objfile, realname.get (), language);
+ return;
+ }
- if (len > lexe && strcasecmp (realname.get () + len - lexe, ".exe") == 0)
+ /* 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)
{
- len -= lexe;
- realname.get ()[len] = '\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 ('/');
- auto_load_debug_printf
- ("auto-load: Stripped .exe suffix, retrying with \"%s\".",
- realname.get ());
+ 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, realname.get (), language);
+ auto_load_objfile_script_1 (objfile,
+ p_realname.c_str (), language);
+ }
}
}
}
info_auto_load_local_gdbinit (const char *args, int from_tty)
{
if (auto_load_local_gdbinit_pathname == NULL)
- printf_filtered (_("Local .gdbinit file was not found.\n"));
+ gdb_printf (_("Local .gdbinit file was not found.\n"));
else if (auto_load_local_gdbinit_loaded)
- printf_filtered (_("Local .gdbinit file \"%ps\" has been loaded.\n"),
- styled_string (file_name_style.style (),
- auto_load_local_gdbinit_pathname));
+ gdb_printf (_("Local .gdbinit file \"%ps\" has been loaded.\n"),
+ styled_string (file_name_style.style (),
+ auto_load_local_gdbinit_pathname));
else
- printf_filtered (_("Local .gdbinit file \"%ps\" has not been loaded.\n"),
- styled_string (file_name_style.style (),
- auto_load_local_gdbinit_pathname));
+ 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.
_initialize_auto_load ()
{
struct cmd_list_element *cmd;
- char *scripts_directory_help, *gdb_name_help, *python_name_help;
- char *guile_name_help;
+ 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,
Directories listed here need to be present also \
in the 'set auto-load safe-path'\n\
option."),
- gdb_name_help,
- python_name_help ? python_name_help : "",
- guile_name_help ? guile_name_help : "");
+ 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,
+ scripts_directory_help.get (),
set_auto_load_dir, show_auto_load_dir,
auto_load_set_cmdlist_get (),
auto_load_show_cmdlist_get ());
- xfree (scripts_directory_help);
- xfree (python_name_help);
- xfree (gdb_name_help);
- xfree (guile_name_help);
-
auto_load_safe_path_vec_update ();
add_setshow_optional_filename_cmd ("safe-path", class_support,
&auto_load_safe_path, _("\