/* Handle shared libraries for GDB, the GNU Debugger.
- Copyright (C) 1990-2017 Free Software Foundation, Inc.
+ Copyright (C) 1990-2018 Free Software Foundation, Inc.
This file is part of GDB.
#include "filenames.h" /* for DOSish file names */
#include "exec.h"
#include "solist.h"
-#include "observer.h"
+#include "observable.h"
#include "readline/readline.h"
#include "remote.h"
#include "solib.h"
#include "filesystem.h"
#include "gdb_bfd.h"
#include "filestuff.h"
+#include "source.h"
/* Architecture-specific operations. */
# define DOS_BASED_FILE_SYSTEM 0
#endif
-/* Return the full pathname of a binary file (the main executable
- or a shared library file), or NULL if not found. The returned
- pathname is malloc'ed and must be freed by the caller. If FD
- is non-NULL, *FD is set to either -1 or an open file handle for
- the binary file.
+/* Return the full pathname of a binary file (the main executable or a
+ shared library file), or NULL if not found. If FD is non-NULL, *FD
+ is set to either -1 or an open file handle for the binary file.
Global variable GDB_SYSROOT is used as a prefix directory
to search for binary files if they have an absolute path.
* machines since a sysroot will almost always be set.
*/
-static char *
+static gdb::unique_xmalloc_ptr<char>
solib_find_1 (const char *in_pathname, int *fd, int is_solib)
{
const struct target_so_ops *ops = solib_ops (target_gdbarch ());
int found_file = -1;
- char *temp_pathname = NULL;
+ gdb::unique_xmalloc_ptr<char> temp_pathname;
const char *fskind = effective_target_file_system_kind ();
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
- char *sysroot = gdb_sysroot;
+ const char *sysroot = gdb_sysroot;
int prefix_len, orig_prefix_len;
/* If the absolute prefix starts with "target:" but the filesystem
while (prefix_len > 0 && IS_DIR_SEPARATOR (sysroot[prefix_len - 1]))
prefix_len--;
+ std::string sysroot_holder;
if (prefix_len == 0)
sysroot = NULL;
else if (prefix_len != orig_prefix_len)
{
- sysroot = savestring (sysroot, prefix_len);
- make_cleanup (xfree, sysroot);
+ sysroot_holder = std::string (sysroot, prefix_len);
+ sysroot = sysroot_holder.c_str ();
}
/* If we're on a non-DOS-based system, backslashes won't be
*/
if (!IS_TARGET_ABSOLUTE_PATH (fskind, in_pathname) || sysroot == NULL)
- temp_pathname = xstrdup (in_pathname);
+ temp_pathname.reset (xstrdup (in_pathname));
else
{
int need_dir_separator;
|| strcmp (TARGET_SYSROOT_PREFIX, sysroot) == 0);
/* Cat the prefixed pathname together. */
- temp_pathname = concat (sysroot,
- need_dir_separator ? SLASH_STRING : "",
- in_pathname, (char *) NULL);
+ temp_pathname.reset (concat (sysroot,
+ need_dir_separator ? SLASH_STRING : "",
+ in_pathname, (char *) NULL));
}
/* Handle files to be accessed via the target. */
- if (is_target_filename (temp_pathname))
+ if (is_target_filename (temp_pathname.get ()))
{
if (fd != NULL)
*fd = -1;
- do_cleanups (old_chain);
return temp_pathname;
}
/* Now see if we can open it. */
- found_file = gdb_open_cloexec (temp_pathname, O_RDONLY | O_BINARY, 0);
- if (found_file < 0)
- xfree (temp_pathname);
+ found_file = gdb_open_cloexec (temp_pathname.get (), O_RDONLY | O_BINARY, 0);
/* If the search in gdb_sysroot failed, and the path name has a
drive spec (e.g, c:/foo), try stripping ':' from the drive spec,
&& HAS_TARGET_DRIVE_SPEC (fskind, in_pathname))
{
int need_dir_separator = !IS_DIR_SEPARATOR (in_pathname[2]);
- char *drive = savestring (in_pathname, 1);
+ char drive[2] = { in_pathname[0], '\0' };
- temp_pathname = concat (sysroot,
- SLASH_STRING,
- drive,
- need_dir_separator ? SLASH_STRING : "",
- in_pathname + 2, (char *) NULL);
- xfree (drive);
+ temp_pathname.reset (concat (sysroot,
+ SLASH_STRING,
+ drive,
+ need_dir_separator ? SLASH_STRING : "",
+ in_pathname + 2, (char *) NULL));
- found_file = gdb_open_cloexec (temp_pathname, O_RDONLY | O_BINARY, 0);
+ found_file = gdb_open_cloexec (temp_pathname.get (),
+ O_RDONLY | O_BINARY, 0);
if (found_file < 0)
{
- xfree (temp_pathname);
-
/* If the search in gdb_sysroot still failed, try fully
stripping the drive spec, and trying once more in the
sysroot before giving up.
c:/foo/bar.dll ==> /sysroot/foo/bar.dll. */
- temp_pathname = concat (sysroot,
- need_dir_separator ? SLASH_STRING : "",
- in_pathname + 2, (char *) NULL);
+ temp_pathname.reset (concat (sysroot,
+ need_dir_separator ? SLASH_STRING : "",
+ in_pathname + 2, (char *) NULL));
- found_file = gdb_open_cloexec (temp_pathname, O_RDONLY | O_BINARY, 0);
- if (found_file < 0)
- xfree (temp_pathname);
+ found_file = gdb_open_cloexec (temp_pathname.get (),
+ O_RDONLY | O_BINARY, 0);
}
}
- do_cleanups (old_chain);
-
/* We try to find the library in various ways. After each attempt,
either found_file >= 0 and temp_pathname is a malloc'd string, or
found_file < 0 and temp_pathname does not point to storage that
needs to be freed. */
if (found_file < 0)
- temp_pathname = NULL;
+ temp_pathname.reset (NULL);
/* If the search in gdb_sysroot failed, and the path name is
absolute at this point, make it relative. (openp will try and open the
}
/* Return the full pathname of the main executable, or NULL if not
- found. The returned pathname is malloc'ed and must be freed by
- the caller. If FD is non-NULL, *FD is set to either -1 or an open
- file handle for the main executable. */
+ found. If FD is non-NULL, *FD is set to either -1 or an open file
+ handle for the main executable. */
-char *
+gdb::unique_xmalloc_ptr<char>
exec_file_find (const char *in_pathname, int *fd)
{
- char *result;
+ gdb::unique_xmalloc_ptr<char> result;
const char *fskind = effective_target_file_system_kind ();
if (in_pathname == NULL)
filename. Not much more we can do...) */
if (!source_full_path_of (in_pathname, &result))
- result = xstrdup (in_pathname);
+ result.reset (xstrdup (in_pathname));
if (fd != NULL)
*fd = -1;
}
}
/* Return the full pathname of a shared library file, or NULL if not
- found. The returned pathname is malloc'ed and must be freed by
- the caller. If FD is non-NULL, *FD is set to either -1 or an open
- file handle for the shared library.
+ found. If FD is non-NULL, *FD is set to either -1 or an open file
+ handle for the shared library.
The search algorithm used is described in solib_find_1's comment
above. */
-char *
+gdb::unique_xmalloc_ptr<char>
solib_find (const char *in_pathname, int *fd)
{
const char *solib_symbols_extension
it is used as file handle to open the file. Throws an error if the file
could not be opened. Handles both local and remote file access.
- PATHNAME must be malloc'ed by the caller. It will be freed by this
- function. If unsuccessful, the FD will be closed (unless FD was
- -1). */
+ If unsuccessful, the FD will be closed (unless FD was -1). */
gdb_bfd_ref_ptr
-solib_bfd_fopen (char *pathname, int fd)
+solib_bfd_fopen (const char *pathname, int fd)
{
gdb_bfd_ref_ptr abfd (gdb_bfd_open (pathname, gnutarget, fd));
if (abfd == NULL)
{
- make_cleanup (xfree, pathname);
+ /* Arrange to free PATHNAME when the error is thrown. */
error (_("Could not open `%s' as an executable file: %s"),
pathname, bfd_errmsg (bfd_get_error ()));
}
- xfree (pathname);
-
return abfd;
}
/* Find shared library PATHNAME and open a BFD for it. */
gdb_bfd_ref_ptr
-solib_bfd_open (char *pathname)
+solib_bfd_open (const char *pathname)
{
- char *found_pathname;
int found_file;
const struct bfd_arch_info *b;
/* Search for shared library file. */
- found_pathname = solib_find (pathname, &found_file);
+ gdb::unique_xmalloc_ptr<char> found_pathname
+ = solib_find (pathname, &found_file);
if (found_pathname == NULL)
{
/* Return failure if the file could not be found, so that we can
}
/* Open bfd for shared library. */
- gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname, found_file));
+ gdb_bfd_ref_ptr abfd (solib_bfd_fopen (found_pathname.get (), found_file));
/* Check bfd format. */
if (!bfd_check_format (abfd.get (), bfd_object))
solib_map_sections (struct so_list *so)
{
const struct target_so_ops *ops = solib_ops (target_gdbarch ());
- char *filename;
struct target_section *p;
- struct cleanup *old_chain;
- filename = tilde_expand (so->so_name);
- old_chain = make_cleanup (xfree, filename);
- gdb_bfd_ref_ptr abfd (ops->bfd_open (filename));
- do_cleanups (old_chain);
+ gdb::unique_xmalloc_ptr<char> filename (tilde_expand (so->so_name));
+ gdb_bfd_ref_ptr abfd (ops->bfd_open (filename.get ()));
if (abfd == NULL)
return 0;
TRY
{
- struct section_addr_info *sap;
-
/* Have we already loaded this shared object? */
ALL_OBJFILES (so->objfile)
{
}
if (so->objfile == NULL)
{
- sap = build_section_addr_info_from_section_table (so->sections,
- so->sections_end);
+ section_addr_info sap
+ = build_section_addr_info_from_section_table (so->sections,
+ so->sections_end);
so->objfile = symbol_file_add_from_bfd (so->abfd, so->so_name,
- flags, sap, OBJF_SHARED,
- NULL);
+ flags, &sap,
+ OBJF_SHARED, NULL);
so->objfile->addr_low = so->addr_low;
- free_section_addr_info (sap);
}
so->symbols_loaded = 1;
have not opened a symbol file, we may be able to get its
symbols now! */
if (inf->attach_flag && symfile_objfile == NULL)
- catch_errors (ops->open_symbol_file_object, &from_tty,
- "Error reading attached process's symbol file.\n",
- RETURN_MASK_ALL);
+ {
+ TRY
+ {
+ ops->open_symbol_file_object (from_tty);
+ }
+ CATCH (ex, RETURN_MASK_ALL)
+ {
+ exception_fprintf (gdb_stderr, ex,
+ "Error reading attached "
+ "process's symbol file.\n");
+ }
+ END_CATCH
+ }
}
/* GDB and the inferior's dynamic linker each maintain their own
{
/* Notify any observer that the shared object has been
unloaded before we remove it from GDB's tables. */
- observer_notify_solib_unloaded (gdb);
+ gdb::observers::solib_unloaded.notify (gdb);
- VEC_safe_push (char_ptr, current_program_space->deleted_solibs,
- xstrdup (gdb->so_name));
+ current_program_space->deleted_solibs.push_back (gdb->so_name);
*gdb_link = gdb->next;
/* Unless the user loaded it explicitly, free SO's objfile. */
if (gdb->objfile && ! (gdb->objfile->flags & OBJF_USERLOADED)
&& !solib_used (gdb))
- free_objfile (gdb->objfile);
+ delete gdb->objfile;
/* Some targets' section tables might be referring to
sections from so->abfd; remove them. */
{
i->pspace = current_program_space;
- VEC_safe_push (so_list_ptr, current_program_space->added_solibs, i);
+ current_program_space->added_solibs.push_back (i);
TRY
{
/* Notify any observer that the shared object has been
loaded now that we've added it to GDB's tables. */
- observer_notify_solib_loaded (i);
+ gdb::observers::solib_loaded.notify (i);
}
/* If a library was not found, issue an appropriate warning
all. */
static void
-info_sharedlibrary_command (char *pattern, int from_tty)
+info_sharedlibrary_command (const char *pattern, int from_tty)
{
struct so_list *so = NULL; /* link map state variable */
int so_missing_debug_info = 0;
int addr_width;
int nr_libs;
- struct cleanup *table_cleanup;
struct gdbarch *gdbarch = target_gdbarch ();
struct ui_out *uiout = current_uiout;
update_solib_list (from_tty);
- /* make_cleanup_ui_out_table_begin_end needs to know the number of
- rows, so we need to make two passes over the libs. */
+ /* ui_out_emit_table table_emitter needs to know the number of rows,
+ so we need to make two passes over the libs. */
for (nr_libs = 0, so = so_list_head; so; so = so->next)
{
}
}
- table_cleanup =
- make_cleanup_ui_out_table_begin_end (uiout, 4, nr_libs,
- "SharedLibraryTable");
-
- /* The "- 1" is because ui_out adds one space between columns. */
- uiout->table_header (addr_width - 1, ui_left, "from", "From");
- uiout->table_header (addr_width - 1, ui_left, "to", "To");
- uiout->table_header (12 - 1, ui_left, "syms-read", "Syms Read");
- uiout->table_header (0, ui_noalign, "name", "Shared Object Library");
-
- uiout->table_body ();
-
- ALL_SO_LIBS (so)
- {
- if (! so->so_name[0])
- continue;
- if (pattern && ! re_exec (so->so_name))
- continue;
-
- ui_out_emit_tuple tuple_emitter (uiout, "lib");
-
- if (so->addr_high != 0)
- {
- uiout->field_core_addr ("from", gdbarch, so->addr_low);
- uiout->field_core_addr ("to", gdbarch, so->addr_high);
- }
- else
- {
- uiout->field_skip ("from");
- uiout->field_skip ("to");
- }
-
- if (! interp_ui_out (top_level_interpreter ())->is_mi_like_p ()
- && so->symbols_loaded
- && !objfile_has_symbols (so->objfile))
- {
- so_missing_debug_info = 1;
- uiout->field_string ("syms-read", "Yes (*)");
- }
- else
- uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No");
+ {
+ ui_out_emit_table table_emitter (uiout, 4, nr_libs, "SharedLibraryTable");
- uiout->field_string ("name", so->so_name);
+ /* The "- 1" is because ui_out adds one space between columns. */
+ uiout->table_header (addr_width - 1, ui_left, "from", "From");
+ uiout->table_header (addr_width - 1, ui_left, "to", "To");
+ uiout->table_header (12 - 1, ui_left, "syms-read", "Syms Read");
+ uiout->table_header (0, ui_noalign, "name", "Shared Object Library");
- uiout->text ("\n");
- }
+ uiout->table_body ();
- do_cleanups (table_cleanup);
+ ALL_SO_LIBS (so)
+ {
+ if (! so->so_name[0])
+ continue;
+ if (pattern && ! re_exec (so->so_name))
+ continue;
+
+ ui_out_emit_tuple tuple_emitter (uiout, "lib");
+
+ if (so->addr_high != 0)
+ {
+ uiout->field_core_addr ("from", gdbarch, so->addr_low);
+ uiout->field_core_addr ("to", gdbarch, so->addr_high);
+ }
+ else
+ {
+ uiout->field_skip ("from");
+ uiout->field_skip ("to");
+ }
+
+ if (! top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ()
+ && so->symbols_loaded
+ && !objfile_has_symbols (so->objfile))
+ {
+ so_missing_debug_info = 1;
+ uiout->field_string ("syms-read", "Yes (*)");
+ }
+ else
+ uiout->field_string ("syms-read", so->symbols_loaded ? "Yes" : "No");
+
+ uiout->field_string ("name", so->so_name);
+
+ uiout->text ("\n");
+ }
+ }
if (nr_libs == 0)
{
struct so_list *so = so_list_head;
so_list_head = so->next;
- observer_notify_solib_unloaded (so);
+ gdb::observers::solib_unloaded.notify (so);
remove_target_sections (so);
free_so (so);
}
/* Implements the "sharedlibrary" command. */
static void
-sharedlibrary_command (char *args, int from_tty)
+sharedlibrary_command (const char *args, int from_tty)
{
dont_repeat ();
solib_add (args, from_tty, 1);
are not discarded. Also called from remote.c. */
void
-no_shared_libraries (char *ignored, int from_tty)
+no_shared_libraries (const char *ignored, int from_tty)
{
/* The order of the two routines below is important: clear_solib notifies
the solib_unloaded observers, and some of these observers might need
/* Check for any newly added shared libraries if we're supposed to
be adding them automatically. Switch terminal for any messages
produced by breakpoint_re_set. */
- target_terminal_ours_for_output ();
+ target_terminal::ours_for_output ();
solib_add (NULL, 0, auto_solib_add);
- target_terminal_inferior ();
+ target_terminal::inferior ();
}
/* Reload shared libraries, but avoid reloading the same symbol file
reload_shared_libraries_1 (int from_tty)
{
struct so_list *so;
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
if (print_symbol_loading_p (from_tty, 0, 0))
printf_unfiltered (_("Loading symbols for shared libraries.\n"));
for (so = so_list_head; so != NULL; so = so->next)
{
- char *filename, *found_pathname = NULL;
+ char *found_pathname = NULL;
int was_loaded = so->symbols_loaded;
symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET;
if (from_tty)
add_flags |= SYMFILE_VERBOSE;
- filename = tilde_expand (so->so_original_name);
- make_cleanup (xfree, filename);
- gdb_bfd_ref_ptr abfd (solib_bfd_open (filename));
+ gdb::unique_xmalloc_ptr<char> filename
+ (tilde_expand (so->so_original_name));
+ gdb_bfd_ref_ptr abfd (solib_bfd_open (filename.get ()));
if (abfd != NULL)
- {
- found_pathname = xstrdup (bfd_get_filename (abfd.get ()));
- make_cleanup (xfree, found_pathname);
- }
+ found_pathname = bfd_get_filename (abfd.get ());
/* If this shared library is no longer associated with its previous
symbol file, close that. */
{
if (so->objfile && ! (so->objfile->flags & OBJF_USERLOADED)
&& !solib_used (so))
- free_objfile (so->objfile);
+ delete so->objfile;
remove_target_sections (so);
clear_so (so);
}
solib_read_symbols (so, add_flags);
}
}
-
- do_cleanups (old_chain);
}
static void
-reload_shared_libraries (char *ignored, int from_tty,
+reload_shared_libraries (const char *ignored, int from_tty,
struct cmd_list_element *e)
{
const struct target_so_ops *ops;
at the start of gdb_sysroot with "target:". */
static void
-gdb_sysroot_changed (char *ignored, int from_tty,
+gdb_sysroot_changed (const char *ignored, int from_tty,
struct cmd_list_element *e)
{
const char *old_prefix = "remote:";
{
unsigned int i;
- asymbol **symbol_table = (asymbol **) xmalloc (storage_needed);
- struct cleanup *back_to = make_cleanup (xfree, symbol_table);
+ gdb::def_vector<asymbol *> storage (storage_needed / sizeof (asymbol *));
+ asymbol **symbol_table = storage.data ();
unsigned int number_of_symbols =
bfd_canonicalize_symtab (abfd, symbol_table);
break;
}
}
- do_cleanups (back_to);
}
return symaddr;
if (storage_needed > 0)
{
unsigned int i;
- asymbol **symbol_table = (asymbol **) xmalloc (storage_needed);
- struct cleanup *back_to = make_cleanup (xfree, symbol_table);
+ gdb::def_vector<asymbol *> storage (storage_needed / sizeof (asymbol *));
+ asymbol **symbol_table = storage.data ();
unsigned int number_of_symbols =
bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
break;
}
}
- do_cleanups (back_to);
}
return symaddr;
}
}
}
-extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
-
void
_initialize_solib (void)
{
solib_data = gdbarch_data_register_pre_init (solib_init);
- observer_attach_free_objfile (remove_user_added_objfile);
+ gdb::observers::free_objfile.attach (remove_user_added_objfile);
add_com ("sharedlibrary", class_files, sharedlibrary_command,
_("Load shared object library symbols for files matching REGEXP."));