/* GDB routines for supporting auto-loaded scripts.
- Copyright (C) 2012-2017 Free Software Foundation, Inc.
+ Copyright (C) 2012-2019 Free Software Foundation, Inc.
This file is part of GDB.
#include "ui-out.h"
#include "filenames.h"
#include "command.h"
-#include "observer.h"
+#include "observable.h"
#include "objfiles.h"
#include "cli/cli-script.h"
#include "gdbcmd.h"
#include "completer.h"
#include "fnmatch.h"
#include "top.h"
-#include "filestuff.h"
+#include "common/filestuff.h"
#include "extension.h"
#include "gdb/section-scripts.h"
#include <algorithm>
+#include "common/pathstuff.h"
/* The section to look in for auto-loaded scripts (in file formats that
support sections).
/* "set" command for the auto_load_dir configuration variable. */
static void
-set_auto_load_dir (char *args, int from_tty, struct cmd_list_element *c)
+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[0] == '\0')
/* 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 VEC (char_ptr) *auto_load_safe_path_vec;
+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. Return vector from dirnames_to_char_ptr_vec,
- this vector must be freed by free_char_ptr_vec by the caller. */
+ substitute_path_component. */
-static VEC (char_ptr) *
+static std::vector<gdb::unique_xmalloc_ptr<char>>
auto_load_expand_dir_vars (const char *string)
{
- VEC (char_ptr) *dir_vec;
- char *s;
-
- s = xstrdup (string);
+ char *s = xstrdup (string);
substitute_path_component (&s, "$datadir", gdb_datadir);
substitute_path_component (&s, "$debugdir", debug_file_directory);
fprintf_unfiltered (gdb_stdlog,
_("auto-load: Expanded $-variables to \"%s\".\n"), s);
- dir_vec = dirnames_to_char_ptr_vec (s);
+ std::vector<gdb::unique_xmalloc_ptr<char>> dir_vec
+ = dirnames_to_char_ptr_vec (s);
xfree(s);
return dir_vec;
static void
auto_load_safe_path_vec_update (void)
{
- unsigned len;
- int ix;
-
if (debug_auto_load)
fprintf_unfiltered (gdb_stdlog,
_("auto-load: Updating directories of \"%s\".\n"),
auto_load_safe_path);
- free_char_ptr_vec (auto_load_safe_path_vec);
-
auto_load_safe_path_vec = auto_load_expand_dir_vars (auto_load_safe_path);
- len = VEC_length (char_ptr, auto_load_safe_path_vec);
+ size_t len = auto_load_safe_path_vec.size ();
/* Apply tilde_expand and gdb_realpath to each AUTO_LOAD_SAFE_PATH_VEC
element. */
- for (ix = 0; ix < len; ix++)
+ for (size_t i = 0; i < len; i++)
{
- char *dir = VEC_index (char_ptr, auto_load_safe_path_vec, ix);
- char *expanded = tilde_expand (dir);
- gdb::unique_xmalloc_ptr<char> real_path = gdb_realpath (expanded);
+ 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. */
- VEC_replace (char_ptr, auto_load_safe_path_vec, ix, expanded);
+ /* 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 (expanded, dir) == 0)
+ if (strcmp (in_vec.get (), original.get ()) == 0)
fprintf_unfiltered (gdb_stdlog,
_("auto-load: Using directory \"%s\".\n"),
- expanded);
+ in_vec.get ());
else
fprintf_unfiltered (gdb_stdlog,
_("auto-load: Resolved directory \"%s\" "
"as \"%s\".\n"),
- dir, expanded);
+ original.get (), in_vec.get ());
}
- xfree (dir);
/* If gdb_realpath returns a different content, append it. */
- if (strcmp (real_path.get (), expanded) != 0)
+ if (strcmp (real_path.get (), in_vec.get ()) != 0)
{
if (debug_auto_load)
fprintf_unfiltered (gdb_stdlog,
_("auto-load: And canonicalized as \"%s\".\n"),
real_path.get ());
- VEC_safe_push (char_ptr, auto_load_safe_path_vec,
- real_path.release ());
+ auto_load_safe_path_vec.push_back (std::move (real_path));
}
}
}
/* "set" command for the auto_load_safe_path configuration variable. */
static void
-set_auto_load_safe_path (char *args, int from_tty, struct cmd_list_element *c)
+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[0] == '\0')
variable. */
static void
-add_auto_load_safe_path (char *args, int from_tty)
+add_auto_load_safe_path (const char *args, int from_tty)
{
char *s;
variable. */
static void
-add_auto_load_dir (char *args, int from_tty)
+add_auto_load_dir (const char *args, int from_tty)
{
char *s;
filename_is_in_auto_load_safe_path_vec (const char *filename,
gdb::unique_xmalloc_ptr<char> *filename_realp)
{
- char *pattern;
- int ix;
+ const char *pattern = NULL;
- for (ix = 0; VEC_iterate (char_ptr, auto_load_safe_path_vec, ix, pattern);
- ++ix)
- if (*filename_realp == NULL && filename_is_in_pattern (filename, pattern))
- break;
+ 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 (strcmp (filename_realp->get (), filename) != 0)
- for (ix = 0;
- VEC_iterate (char_ptr, auto_load_safe_path_vec, ix, pattern); ++ix)
- if (filename_is_in_pattern (filename_realp->get (), pattern))
- break;
+ 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_objfile_script_1 (struct objfile *objfile, const char *realname,
const struct extension_language_defn *language)
{
- char *filename, *debugfile;
- int len, retval;
- struct cleanup *cleanups;
+ const char *debugfile;
+ int retval;
const char *suffix = ext_lang_auto_load_suffix (language);
- len = strlen (realname);
- filename = (char *) xmalloc (len + strlen (suffix) + 1);
- memcpy (filename, realname, len);
- strcpy (filename + len, suffix);
+ std::string filename = std::string (realname) + suffix;
- cleanups = make_cleanup (xfree, filename);
-
- gdb_file_up input = gdb_fopen_cloexec (filename, "r");
- debugfile = filename;
+ gdb_file_up input = gdb_fopen_cloexec (filename.c_str (), "r");
+ debugfile = filename.c_str ();
if (debug_auto_load)
fprintf_unfiltered (gdb_stdlog, _("auto-load: Attempted file \"%s\" %s.\n"),
debugfile, input ? _("exists") : _("does not exist"));
+ std::string debugfile_holder;
if (!input)
{
- VEC (char_ptr) *vec;
- int ix;
- char *dir;
-
/* Also try the same file in a subdirectory of gdb's data
directory. */
- vec = auto_load_expand_dir_vars (auto_load_dir);
- make_cleanup_free_char_ptr_vec (vec);
+ std::vector<gdb::unique_xmalloc_ptr<char>> vec
+ = auto_load_expand_dir_vars (auto_load_dir);
if (debug_auto_load)
fprintf_unfiltered (gdb_stdlog, _("auto-load: Searching 'set auto-load "
"scripts-directory' path \"%s\".\n"),
auto_load_dir);
- for (ix = 0; VEC_iterate (char_ptr, vec, ix, dir); ++ix)
+ for (const gdb::unique_xmalloc_ptr<char> &dir : vec)
{
- debugfile = (char *) xmalloc (strlen (dir) + strlen (filename) + 1);
- strcpy (debugfile, dir);
-
/* FILENAME is absolute, so we don't need a "/" here. */
- strcat (debugfile, filename);
+ debugfile_holder = dir.get () + filename;
+ debugfile = debugfile_holder.c_str ();
- make_cleanup (xfree, debugfile);
input = gdb_fopen_cloexec (debugfile, "r");
if (debug_auto_load)
fprintf_unfiltered (gdb_stdlog, _("auto-load: Attempted file "
else
retval = 0;
- do_cleanups (cleanups);
return retval;
}
{
objfile_script_executor_func *executor;
const char *newline, *script_text;
- char *name;
+ const char *name;
int is_safe, in_hash_table;
- struct cleanup *cleanups;
-
- cleanups = make_cleanup (null_cleanup, NULL);
/* 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)
{
- char *buf, *p;
+ const char *buf, *p;
/* Put the name in a buffer and validate it. */
- buf = xstrndup (script, newline - script);
- make_cleanup (xfree, buf);
+ name_holder = std::string (script, newline - script);
+ buf = name_holder.c_str ();
for (p = buf; *p != '\0'; ++p)
{
if (isspace (*p))
Missing/bad script name in entry at offset %u in section %s\n\
of file %s."),
offset, section_name, objfile_name (objfile));
- do_cleanups (cleanups);
return;
}
script_text = newline + 1;
maybe_print_unsupported_script_warning (pspace_info, objfile, language,
section_name, offset);
maybe_add_script_text (pspace_info, 0, name, language);
- do_cleanups (cleanups);
return;
}
if (!ext_lang_auto_load_enabled (language))
{
/* No message is printed, just skip it. */
- do_cleanups (cleanups);
return;
}
/* If this file is not currently loaded, load it. */
if (is_safe && !in_hash_table)
executor (language, objfile, name, script_text);
-
- do_cleanups (cleanups);
}
/* Load scripts specified in OBJFILE.
section_name, bfd_get_filename (abfd));
else
{
- struct cleanup *cleanups;
- char *p = (char *) data;
+ gdb::unique_xmalloc_ptr<bfd_byte> data_holder (data);
- cleanups = make_cleanup (xfree, p);
+ char *p = (char *) data;
source_section_scripts (objfile, section_name, p,
p + bfd_get_section_size (scripts_sect));
- do_cleanups (cleanups);
}
}
PATTERN. FROM_TTY is the usual GDB boolean for user interactivity. */
void
-auto_load_info_scripts (char *pattern, int from_tty,
+auto_load_info_scripts (const char *pattern, int from_tty,
const struct extension_language_defn *language)
{
struct ui_out *uiout = current_uiout;
/* Wrapper for "info auto-load gdb-scripts". */
static void
-info_auto_load_gdb_scripts (char *pattern, int from_tty)
+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 (char *args, int from_tty)
+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"));
info_auto_load_cmd (const char *args, int from_tty)
{
struct cmd_list_element *list;
- struct cleanup *infolist_chain;
struct ui_out *uiout = current_uiout;
ui_out_emit_tuple tuple_emitter (uiout, "infolist");
= register_program_space_data_with_cleanup (NULL,
auto_load_pspace_data_cleanup);
- observer_attach_new_objfile (auto_load_new_objfile);
+ gdb::observers::new_objfile.attach (auto_load_new_objfile);
add_setshow_boolean_cmd ("gdb-scripts", class_support,
&auto_load_gdb_scripts, _("\
_("\
If enabled, canned sequences of commands are loaded when the debugger reads\n\
an executable or shared library.\n\
-This options has security implications for untrusted inferiors."),
+This option has security implications for untrusted inferiors."),
NULL, show_auto_load_gdb_scripts,
auto_load_set_cmdlist_get (),
auto_load_show_cmdlist_get ());
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 options has security implications for untrusted inferiors."),
+This option has security implications for untrusted inferiors."),
NULL, show_auto_load_local_gdbinit,
auto_load_set_cmdlist_get (),
auto_load_show_cmdlist_get ());
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 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 ());
- observer_attach_gdb_datadir_changed (auto_load_gdb_datadir_changed);
+ gdb::observers::gdb_datadir_changed.attach (auto_load_gdb_datadir_changed);
cmd = add_cmd ("add-auto-load-safe-path", class_support,
add_auto_load_safe_path,