#include "hashtab.h"
#include "readline/readline.h"
#include "block.h"
-#include "observer.h"
+#include "observable.h"
#include "exec.h"
#include "parser-defs.h"
#include "varobj.h"
#include <sys/stat.h>
#include <ctype.h>
#include <chrono>
+#include <algorithm>
#include "psymtab.h"
*lowest = sect;
}
-/* Create a new section_addr_info, with room for NUM_SECTIONS. The
- new object's 'num_sections' field is set to 0; it must be updated
- by the caller. */
-
-struct section_addr_info *
-alloc_section_addr_info (size_t num_sections)
-{
- struct section_addr_info *sap;
- size_t size;
-
- size = (sizeof (struct section_addr_info)
- + sizeof (struct other_sections) * (num_sections - 1));
- sap = (struct section_addr_info *) xmalloc (size);
- memset (sap, 0, size);
-
- return sap;
-}
-
/* Build (allocate and populate) a section_addr_info struct from
an existing section table. */
-extern struct section_addr_info *
+section_addr_info
build_section_addr_info_from_section_table (const struct target_section *start,
const struct target_section *end)
{
- struct section_addr_info *sap;
const struct target_section *stp;
- int oidx;
- sap = alloc_section_addr_info (end - start);
+ section_addr_info sap;
- for (stp = start, oidx = 0; stp != end; stp++)
+ for (stp = start; stp != end; stp++)
{
struct bfd_section *asect = stp->the_bfd_section;
bfd *abfd = asect->owner;
if (bfd_get_section_flags (abfd, asect) & (SEC_ALLOC | SEC_LOAD)
- && oidx < end - start)
- {
- sap->other[oidx].addr = stp->addr;
- sap->other[oidx].name = xstrdup (bfd_section_name (abfd, asect));
- sap->other[oidx].sectindex = gdb_bfd_section_index (abfd, asect);
- oidx++;
- }
+ && sap.size () < end - start)
+ sap.emplace_back (stp->addr,
+ bfd_section_name (abfd, asect),
+ gdb_bfd_section_index (abfd, asect));
}
- sap->num_sections = oidx;
-
return sap;
}
/* Create a section_addr_info from section offsets in ABFD. */
-static struct section_addr_info *
+static section_addr_info
build_section_addr_info_from_bfd (bfd *abfd)
{
- struct section_addr_info *sap;
- int i;
struct bfd_section *sec;
- sap = alloc_section_addr_info (bfd_count_sections (abfd));
- for (i = 0, sec = abfd->sections; sec != NULL; sec = sec->next)
+ section_addr_info sap;
+ for (sec = abfd->sections; sec != NULL; sec = sec->next)
if (bfd_get_section_flags (abfd, sec) & (SEC_ALLOC | SEC_LOAD))
- {
- sap->other[i].addr = bfd_get_section_vma (abfd, sec);
- sap->other[i].name = xstrdup (bfd_get_section_name (abfd, sec));
- sap->other[i].sectindex = gdb_bfd_section_index (abfd, sec);
- i++;
- }
-
- sap->num_sections = i;
+ sap.emplace_back (bfd_get_section_vma (abfd, sec),
+ bfd_get_section_name (abfd, sec),
+ gdb_bfd_section_index (abfd, sec));
return sap;
}
/* Create a section_addr_info from section offsets in OBJFILE. */
-struct section_addr_info *
+section_addr_info
build_section_addr_info_from_objfile (const struct objfile *objfile)
{
- struct section_addr_info *sap;
int i;
/* Before reread_symbols gets rewritten it is not safe to call:
gdb_assert (objfile->num_sections == bfd_count_sections (objfile->obfd));
*/
- sap = build_section_addr_info_from_bfd (objfile->obfd);
- for (i = 0; i < sap->num_sections; i++)
+ section_addr_info sap = build_section_addr_info_from_bfd (objfile->obfd);
+ for (i = 0; i < sap.size (); i++)
{
- int sectindex = sap->other[i].sectindex;
+ int sectindex = sap[i].sectindex;
- sap->other[i].addr += objfile->section_offsets->offsets[sectindex];
+ sap[i].addr += objfile->section_offsets->offsets[sectindex];
}
return sap;
}
-/* Free all memory allocated by build_section_addr_info_from_section_table. */
-
-extern void
-free_section_addr_info (struct section_addr_info *sap)
-{
- int idx;
-
- for (idx = 0; idx < sap->num_sections; idx++)
- xfree (sap->other[idx].name);
- xfree (sap);
-}
-
/* Initialize OBJFILE's sect_index_* members. */
static void
arg->lowest = start_addr + bfd_get_section_size (sect);
}
-/* Store struct section_addr_info as prepared (made relative and with SECTINDEX
+/* Store section_addr_info as prepared (made relative and with SECTINDEX
filled-in) by addr_info_make_relative into SECTION_OFFSETS of NUM_SECTIONS
entries. */
void
relative_addr_info_to_section_offsets (struct section_offsets *section_offsets,
int num_sections,
- const struct section_addr_info *addrs)
+ const section_addr_info &addrs)
{
int i;
memset (section_offsets, 0, SIZEOF_N_SECTION_OFFSETS (num_sections));
/* Now calculate offsets for section that were specified by the caller. */
- for (i = 0; i < addrs->num_sections; i++)
+ for (i = 0; i < addrs.size (); i++)
{
const struct other_sections *osp;
- osp = &addrs->other[i];
+ osp = &addrs[i];
if (osp->sectindex == -1)
continue;
return s;
}
-/* qsort comparator for addrs_section_sort. Sort entries in ascending order by
- their (name, sectindex) pair. sectindex makes the sort by name stable. */
+/* std::sort comparator for addrs_section_sort. Sort entries in
+ ascending order by their (name, sectindex) pair. sectindex makes
+ the sort by name stable. */
-static int
-addrs_section_compar (const void *ap, const void *bp)
+static bool
+addrs_section_compar (const struct other_sections *a,
+ const struct other_sections *b)
{
- const struct other_sections *a = *((struct other_sections **) ap);
- const struct other_sections *b = *((struct other_sections **) bp);
int retval;
- retval = strcmp (addr_section_name (a->name), addr_section_name (b->name));
- if (retval)
- return retval;
+ retval = strcmp (addr_section_name (a->name.c_str ()),
+ addr_section_name (b->name.c_str ()));
+ if (retval != 0)
+ return retval < 0;
- return a->sectindex - b->sectindex;
+ return a->sectindex < b->sectindex;
}
-/* Provide sorted array of pointers to sections of ADDRS. The array is
- terminated by NULL. Caller is responsible to call xfree for it. */
+/* Provide sorted array of pointers to sections of ADDRS. */
-static struct other_sections **
-addrs_section_sort (struct section_addr_info *addrs)
+static std::vector<const struct other_sections *>
+addrs_section_sort (const section_addr_info &addrs)
{
- struct other_sections **array;
int i;
- /* `+ 1' for the NULL terminator. */
- array = XNEWVEC (struct other_sections *, addrs->num_sections + 1);
- for (i = 0; i < addrs->num_sections; i++)
- array[i] = &addrs->other[i];
- array[i] = NULL;
+ std::vector<const struct other_sections *> array (addrs.size ());
+ for (i = 0; i < addrs.size (); i++)
+ array[i] = &addrs[i];
- qsort (array, i, sizeof (*array), addrs_section_compar);
+ std::sort (array.begin (), array.end (), addrs_section_compar);
return array;
}
rebase ADDRS to start referencing different BFD than before. */
void
-addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
+addr_info_make_relative (section_addr_info *addrs, bfd *abfd)
{
asection *lower_sect;
CORE_ADDR lower_offset;
int i;
- struct cleanup *my_cleanup;
- struct section_addr_info *abfd_addrs;
- struct other_sections **addrs_sorted, **abfd_addrs_sorted;
- struct other_sections **addrs_to_abfd_addrs;
/* Find lowest loadable section to be used as starting point for
continguous sections. */
Use stable sort by name for the sections in both files. Then linearly
scan both lists matching as most of the entries as possible. */
- addrs_sorted = addrs_section_sort (addrs);
- my_cleanup = make_cleanup (xfree, addrs_sorted);
+ std::vector<const struct other_sections *> addrs_sorted
+ = addrs_section_sort (*addrs);
- abfd_addrs = build_section_addr_info_from_bfd (abfd);
- make_cleanup_free_section_addr_info (abfd_addrs);
- abfd_addrs_sorted = addrs_section_sort (abfd_addrs);
- make_cleanup (xfree, abfd_addrs_sorted);
+ section_addr_info abfd_addrs = build_section_addr_info_from_bfd (abfd);
+ std::vector<const struct other_sections *> abfd_addrs_sorted
+ = addrs_section_sort (abfd_addrs);
/* Now create ADDRS_TO_ABFD_ADDRS from ADDRS_SORTED and
ABFD_ADDRS_SORTED. */
- addrs_to_abfd_addrs = XCNEWVEC (struct other_sections *, addrs->num_sections);
- make_cleanup (xfree, addrs_to_abfd_addrs);
+ std::vector<const struct other_sections *>
+ addrs_to_abfd_addrs (addrs->size (), nullptr);
- while (*addrs_sorted)
+ std::vector<const struct other_sections *>::iterator abfd_sorted_iter
+ = abfd_addrs_sorted.begin ();
+ for (const struct other_sections *sect : addrs_sorted)
{
- const char *sect_name = addr_section_name ((*addrs_sorted)->name);
+ const char *sect_name = addr_section_name (sect->name.c_str ());
- while (*abfd_addrs_sorted
- && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
+ while (abfd_sorted_iter != abfd_addrs_sorted.end ()
+ && strcmp (addr_section_name ((*abfd_sorted_iter)->name.c_str ()),
sect_name) < 0)
- abfd_addrs_sorted++;
+ abfd_sorted_iter++;
- if (*abfd_addrs_sorted
- && strcmp (addr_section_name ((*abfd_addrs_sorted)->name),
+ if (abfd_sorted_iter != abfd_addrs_sorted.end ()
+ && strcmp (addr_section_name ((*abfd_sorted_iter)->name.c_str ()),
sect_name) == 0)
{
int index_in_addrs;
/* Make the found item directly addressable from ADDRS. */
- index_in_addrs = *addrs_sorted - addrs->other;
+ index_in_addrs = sect - addrs->data ();
gdb_assert (addrs_to_abfd_addrs[index_in_addrs] == NULL);
- addrs_to_abfd_addrs[index_in_addrs] = *abfd_addrs_sorted;
+ addrs_to_abfd_addrs[index_in_addrs] = *abfd_sorted_iter;
/* Never use the same ABFD entry twice. */
- abfd_addrs_sorted++;
+ abfd_sorted_iter++;
}
-
- addrs_sorted++;
}
/* Calculate offsets for the loadable sections.
(the loadable section directly below it in memory).
this_offset = lower_offset = lower_addr - lower_orig_addr */
- for (i = 0; i < addrs->num_sections; i++)
+ for (i = 0; i < addrs->size (); i++)
{
- struct other_sections *sect = addrs_to_abfd_addrs[i];
+ const struct other_sections *sect = addrs_to_abfd_addrs[i];
if (sect)
{
/* This is the index used by BFD. */
- addrs->other[i].sectindex = sect->sectindex;
+ (*addrs)[i].sectindex = sect->sectindex;
- if (addrs->other[i].addr != 0)
+ if ((*addrs)[i].addr != 0)
{
- addrs->other[i].addr -= sect->addr;
- lower_offset = addrs->other[i].addr;
+ (*addrs)[i].addr -= sect->addr;
+ lower_offset = (*addrs)[i].addr;
}
else
- addrs->other[i].addr = lower_offset;
+ (*addrs)[i].addr = lower_offset;
}
else
{
/* addr_section_name transformation is not used for SECT_NAME. */
- const char *sect_name = addrs->other[i].name;
+ const std::string §_name = (*addrs)[i].name;
/* This section does not exist in ABFD, which is normally
unexpected and we want to issue a warning.
For the sections `.bss' and `.sbss' see addr_section_name. */
- if (!(strcmp (sect_name, ".gnu.liblist") == 0
- || strcmp (sect_name, ".gnu.conflict") == 0
- || (strcmp (sect_name, ".bss") == 0
+ if (!(sect_name == ".gnu.liblist"
+ || sect_name == ".gnu.conflict"
+ || (sect_name == ".bss"
&& i > 0
- && strcmp (addrs->other[i - 1].name, ".dynbss") == 0
+ && (*addrs)[i - 1].name == ".dynbss"
&& addrs_to_abfd_addrs[i - 1] != NULL)
- || (strcmp (sect_name, ".sbss") == 0
+ || (sect_name == ".sbss"
&& i > 0
- && strcmp (addrs->other[i - 1].name, ".sdynbss") == 0
+ && (*addrs)[i - 1].name == ".sdynbss"
&& addrs_to_abfd_addrs[i - 1] != NULL)))
- warning (_("section %s not found in %s"), sect_name,
+ warning (_("section %s not found in %s"), sect_name.c_str (),
bfd_get_filename (abfd));
- addrs->other[i].addr = 0;
- addrs->other[i].sectindex = -1;
+ (*addrs)[i].addr = 0;
+ (*addrs)[i].sectindex = -1;
}
}
-
- do_cleanups (my_cleanup);
}
/* Parse the user's idea of an offset for dynamic linking, into our idea
void
default_symfile_offsets (struct objfile *objfile,
- const struct section_addr_info *addrs)
+ const section_addr_info &addrs)
{
objfile->num_sections = gdb_bfd_count_sections (objfile->obfd);
objfile->section_offsets = (struct section_offsets *)
virtual section-as-bfd like the bfd filename containing the
section. Therefore use also non-canonical name form for the same
file containing the section. */
- symbol_file_add_separate (abfd.get (), objfile->original_name,
- add_flags, objfile);
+ symbol_file_add_separate (abfd.get (),
+ bfd_get_filename (abfd.get ()),
+ add_flags | SYMFILE_NOT_FILENAME, objfile);
}
}
if ((add_flags & SYMFILE_NO_READ) == 0)
entry_point
= gdbarch_convert_from_func_ptr_addr (get_objfile_arch (objfile),
entry_point,
- ¤t_target);
+ target_stack);
/* Remove any ISA markers, so that this matches entries in the
symbol table. */
static void
syms_from_objfile_1 (struct objfile *objfile,
- struct section_addr_info *addrs,
+ section_addr_info *addrs,
symfile_add_flags add_flags)
{
- struct section_addr_info *local_addr = NULL;
+ section_addr_info local_addr;
struct cleanup *old_chain;
const int mainline = add_flags & SYMFILE_MAINLINE;
We now establish the convention that an addr of zero means
no load address was specified. */
if (! addrs)
- {
- local_addr = alloc_section_addr_info (1);
- make_cleanup (xfree, local_addr);
- addrs = local_addr;
- }
+ addrs = &local_addr;
if (mainline)
{
We no longer warn if the lowest section is not a text segment (as
happens for the PA64 port. */
- if (addrs->num_sections > 0)
+ if (addrs->size () > 0)
addr_info_make_relative (addrs, objfile->obfd);
/* Initialize symbol reading routines for this objfile, allow complaints to
(*objfile->sf->sym_init) (objfile);
clear_complaints (&symfile_complaints, 1, add_flags & SYMFILE_VERBOSE);
- (*objfile->sf->sym_offsets) (objfile, addrs);
+ (*objfile->sf->sym_offsets) (objfile, *addrs);
read_symbols (objfile, add_flags);
objfile_holder.release ();
discard_cleanups (old_chain);
- xfree (local_addr);
}
/* Same as syms_from_objfile_1, but also initializes the objfile
static void
syms_from_objfile (struct objfile *objfile,
- struct section_addr_info *addrs,
+ section_addr_info *addrs,
symfile_add_flags add_flags)
{
syms_from_objfile_1 (objfile, addrs, add_flags);
static struct objfile *
symbol_file_add_with_addrs (bfd *abfd, const char *name,
symfile_add_flags add_flags,
- struct section_addr_info *addrs,
+ section_addr_info *addrs,
objfile_flags flags, struct objfile *parent)
{
struct objfile *objfile;
flags |= OBJF_READNEVER;
add_flags |= SYMFILE_NO_READ;
}
+ if ((add_flags & SYMFILE_NOT_FILENAME) != 0)
+ flags |= OBJF_NOT_FILENAME;
/* Give user a chance to burp if we'd be
interactively wiping out any existing symbols. */
if (objfile->sf == NULL)
{
- observer_notify_new_objfile (objfile);
+ gdb::observers::new_objfile.notify (objfile);
return objfile; /* No symbols. */
}
finish_new_objfile (objfile, add_flags);
- observer_notify_new_objfile (objfile);
+ gdb::observers::new_objfile.notify (objfile);
bfd_cache_close_all ();
return (objfile);
symfile_add_flags symfile_flags,
struct objfile *objfile)
{
- struct section_addr_info *sap;
- struct cleanup *my_cleanup;
-
/* Create section_addr_info. We can't directly use offsets from OBJFILE
because sections of BFD may not match sections of OBJFILE and because
vma may have been modified by tools such as prelink. */
- sap = build_section_addr_info_from_objfile (objfile);
- my_cleanup = make_cleanup_free_section_addr_info (sap);
+ section_addr_info sap = build_section_addr_info_from_objfile (objfile);
symbol_file_add_with_addrs
- (bfd, name, symfile_flags, sap,
+ (bfd, name, symfile_flags, &sap,
objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
| OBJF_USERLOADED),
objfile);
-
- do_cleanups (my_cleanup);
}
/* Process the symbol file ABFD, as either the main file or as a
struct objfile *
symbol_file_add_from_bfd (bfd *abfd, const char *name,
symfile_add_flags add_flags,
- struct section_addr_info *addrs,
+ section_addr_info *addrs,
objfile_flags flags, struct objfile *parent)
{
return symbol_file_add_with_addrs (abfd, name, add_flags, addrs, flags,
struct objfile *
symbol_file_add (const char *name, symfile_add_flags add_flags,
- struct section_addr_info *addrs, objfile_flags flags)
+ section_addr_info *addrs, objfile_flags flags)
{
gdb_bfd_ref_ptr bfd (symfile_bfd_open (name));
int separate_debug_file_debug = 0;
static int
-separate_debug_file_exists (const char *name, unsigned long crc,
+separate_debug_file_exists (const std::string &name, unsigned long crc,
struct objfile *parent_objfile)
{
unsigned long file_crc;
".debug" suffix as "/usr/lib/debug/path/to/file" is a separate tree where
the separate debug infos with the same basename can exist. */
- if (filename_cmp (name, objfile_name (parent_objfile)) == 0)
+ if (filename_cmp (name.c_str (), objfile_name (parent_objfile)) == 0)
return 0;
if (separate_debug_file_debug)
- printf_unfiltered (_(" Trying %s\n"), name);
+ printf_unfiltered (_(" Trying %s\n"), name.c_str ());
- gdb_bfd_ref_ptr abfd (gdb_bfd_open (name, gnutarget, -1));
+ gdb_bfd_ref_ptr abfd (gdb_bfd_open (name.c_str (), gnutarget, -1));
if (abfd == NULL)
return 0;
if (verified_as_different || parent_crc != file_crc)
warning (_("the debug information found in \"%s\""
" does not match \"%s\" (CRC mismatch).\n"),
- name, objfile_name (parent_objfile));
+ name.c_str (), objfile_name (parent_objfile));
return 0;
}
dirname(objfile->name) due to symlinks), and DEBUGLINK as the file we are
looking for. CANON_DIR is the "realpath" form of DIR.
DIR must contain a trailing '/'.
- Returns the path of the file with separate debug info, of NULL. */
+ Returns the path of the file with separate debug info, or an empty
+ string. */
-static char *
+static std::string
find_separate_debug_file (const char *dir,
const char *canon_dir,
const char *debuglink,
unsigned long crc32, struct objfile *objfile)
{
- char *debugdir;
- char *debugfile;
- int i;
- VEC (char_ptr) *debugdir_vec;
- struct cleanup *back_to;
- int ix;
-
if (separate_debug_file_debug)
printf_unfiltered (_("\nLooking for separate debug info (debug link) for "
"%s\n"), objfile_name (objfile));
- /* Set I to std::max (strlen (canon_dir), strlen (dir)). */
- i = strlen (dir);
- if (canon_dir != NULL && strlen (canon_dir) > i)
- i = strlen (canon_dir);
-
- debugfile
- = (char *) xmalloc (strlen (debug_file_directory) + 1
- + i
- + strlen (DEBUG_SUBDIRECTORY)
- + strlen ("/")
- + strlen (debuglink)
- + 1);
-
/* First try in the same directory as the original file. */
- strcpy (debugfile, dir);
- strcat (debugfile, debuglink);
+ std::string debugfile = dir;
+ debugfile += debuglink;
if (separate_debug_file_exists (debugfile, crc32, objfile))
return debugfile;
/* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */
- strcpy (debugfile, dir);
- strcat (debugfile, DEBUG_SUBDIRECTORY);
- strcat (debugfile, "/");
- strcat (debugfile, debuglink);
+ debugfile = dir;
+ debugfile += DEBUG_SUBDIRECTORY;
+ debugfile += "/";
+ debugfile += debuglink;
if (separate_debug_file_exists (debugfile, crc32, objfile))
return debugfile;
Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
cause "/..." lookups. */
- debugdir_vec = dirnames_to_char_ptr_vec (debug_file_directory);
- back_to = make_cleanup_free_char_ptr_vec (debugdir_vec);
+ std::vector<gdb::unique_xmalloc_ptr<char>> debugdir_vec
+ = dirnames_to_char_ptr_vec (debug_file_directory);
- for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix)
+ for (const gdb::unique_xmalloc_ptr<char> &debugdir : debugdir_vec)
{
- strcpy (debugfile, debugdir);
- strcat (debugfile, "/");
- strcat (debugfile, dir);
- strcat (debugfile, debuglink);
+ debugfile = debugdir.get ();
+ debugfile += "/";
+ debugfile += dir;
+ debugfile += debuglink;
if (separate_debug_file_exists (debugfile, crc32, objfile))
- {
- do_cleanups (back_to);
- return debugfile;
- }
+ return debugfile;
/* If the file is in the sysroot, try using its base path in the
global debugfile directory. */
strlen (gdb_sysroot)) == 0
&& IS_DIR_SEPARATOR (canon_dir[strlen (gdb_sysroot)]))
{
- strcpy (debugfile, debugdir);
- strcat (debugfile, canon_dir + strlen (gdb_sysroot));
- strcat (debugfile, "/");
- strcat (debugfile, debuglink);
+ debugfile = debugdir.get ();
+ debugfile += (canon_dir + strlen (gdb_sysroot));
+ debugfile += "/";
+ debugfile += debuglink;
if (separate_debug_file_exists (debugfile, crc32, objfile))
- {
- do_cleanups (back_to);
- return debugfile;
- }
+ return debugfile;
}
}
- do_cleanups (back_to);
- xfree (debugfile);
- return NULL;
+ return std::string ();
}
/* Modify PATH to contain only "[/]directory/" part of PATH.
}
/* Find separate debuginfo for OBJFILE (using .gnu_debuglink section).
- Returns pathname, or NULL. */
+ Returns pathname, or an empty string. */
-char *
+std::string
find_separate_debug_file_by_debuglink (struct objfile *objfile)
{
- char *debugfile;
unsigned long crc32;
gdb::unique_xmalloc_ptr<char> debuglink
{
/* There's no separate debug info, hence there's no way we could
load it => no warning. */
- return NULL;
+ return std::string ();
}
std::string dir = objfile_name (objfile);
terminate_after_last_dir_separator (&dir[0]);
gdb::unique_xmalloc_ptr<char> canon_dir (lrealpath (dir.c_str ()));
- debugfile = find_separate_debug_file (dir.c_str (), canon_dir.get (),
- debuglink.get (), crc32, objfile);
+ std::string debugfile
+ = find_separate_debug_file (dir.c_str (), canon_dir.get (),
+ debuglink.get (), crc32, objfile);
- if (debugfile == NULL)
+ if (debugfile.empty ())
{
/* For PR gdb/9538, try again with realpath (if different from the
original). */
symfile_bfd_open (const char *name)
{
int desc = -1;
- struct cleanup *back_to = make_cleanup (null_cleanup, 0);
+ gdb::unique_xmalloc_ptr<char> absolute_name;
if (!is_target_filename (name))
{
- char *absolute_name;
-
gdb::unique_xmalloc_ptr<char> expanded_name (tilde_expand (name));
/* Look down path for it, allocate 2nd new malloc'd copy. */
if (desc < 0)
perror_with_name (expanded_name.get ());
- make_cleanup (xfree, absolute_name);
- name = absolute_name;
+ name = absolute_name.get ();
}
gdb_bfd_ref_ptr sym_bfd (gdb_bfd_open (name, gnutarget, desc));
error (_("`%s': can't read symbols: %s."), name,
bfd_errmsg (bfd_get_error ()));
- do_cleanups (back_to);
-
return sym_bfd;
}
static void
load_command (const char *arg, int from_tty)
{
- struct cleanup *cleanup = make_cleanup (null_cleanup, NULL);
-
dont_repeat ();
/* The user might be reloading because the binary has changed. Take
reopen_exec_file ();
reread_symbols ();
+ std::string temp;
if (arg == NULL)
{
- const char *parg;
- int count = 0;
+ const char *parg, *prev;
- parg = arg = get_exec_file (1);
+ arg = get_exec_file (1);
- /* Count how many \ " ' tab space there are in the name. */
+ /* We may need to quote this string so buildargv can pull it
+ apart. */
+ prev = parg = arg;
while ((parg = strpbrk (parg, "\\\"'\t ")))
{
- parg++;
- count++;
+ temp.append (prev, parg - prev);
+ prev = parg++;
+ temp.push_back ('\\');
}
-
- if (count)
+ /* If we have not copied anything yet, then we didn't see a
+ character to quote, and we can just leave ARG unchanged. */
+ if (!temp.empty ())
{
- /* We need to quote this string so buildargv can pull it apart. */
- char *temp = (char *) xmalloc (strlen (arg) + count + 1 );
- char *ptemp = temp;
- const char *prev;
-
- make_cleanup (xfree, temp);
-
- prev = parg = arg;
- while ((parg = strpbrk (parg, "\\\"'\t ")))
- {
- strncpy (ptemp, prev, parg - prev);
- ptemp += parg - prev;
- prev = parg++;
- *ptemp++ = '\\';
- }
- strcpy (ptemp, prev);
-
- arg = temp;
+ temp.append (prev);
+ arg = temp.c_str ();
}
}
/* After re-loading the executable, we don't really know which
overlays are mapped any more. */
overlay_cache_invalid = 1;
-
- do_cleanups (cleanup);
}
/* This version of "load" should be usable for any target. Currently
*sum += bfd_get_section_size (asec);
}
-/* Opaque data for load_section_callback. */
-struct load_section_data {
- CORE_ADDR load_offset;
- struct load_progress_data *progress_data;
- VEC(memory_write_request_s) *requests;
-};
-
/* Opaque data for load_progress. */
-struct load_progress_data {
+struct load_progress_data
+{
/* Cumulative data. */
- unsigned long write_count;
- unsigned long data_count;
- bfd_size_type total_size;
+ unsigned long write_count = 0;
+ unsigned long data_count = 0;
+ bfd_size_type total_size = 0;
};
/* Opaque data for load_progress for a single section. */
-struct load_progress_section_data {
+struct load_progress_section_data
+{
+ load_progress_section_data (load_progress_data *cumulative_,
+ const char *section_name_, ULONGEST section_size_,
+ CORE_ADDR lma_, gdb_byte *buffer_)
+ : cumulative (cumulative_), section_name (section_name_),
+ section_size (section_size_), lma (lma_), buffer (buffer_)
+ {}
+
struct load_progress_data *cumulative;
/* Per-section data. */
const char *section_name;
- ULONGEST section_sent;
+ ULONGEST section_sent = 0;
ULONGEST section_size;
CORE_ADDR lma;
gdb_byte *buffer;
};
+/* Opaque data for load_section_callback. */
+struct load_section_data
+{
+ load_section_data (load_progress_data *progress_data_)
+ : progress_data (progress_data_)
+ {}
+
+ ~load_section_data ()
+ {
+ for (auto &&request : requests)
+ {
+ xfree (request.data);
+ delete ((load_progress_section_data *) request.baton);
+ }
+ }
+
+ CORE_ADDR load_offset = 0;
+ struct load_progress_data *progress_data;
+ std::vector<struct memory_write_request> requests;
+};
+
/* Target write callback routine for progress reporting. */
static void
static void
load_section_callback (bfd *abfd, asection *asec, void *data)
{
- struct memory_write_request *new_request;
struct load_section_data *args = (struct load_section_data *) data;
- struct load_progress_section_data *section_data;
bfd_size_type size = bfd_get_section_size (asec);
- gdb_byte *buffer;
const char *sect_name = bfd_get_section_name (abfd, asec);
if ((bfd_get_section_flags (abfd, asec) & SEC_LOAD) == 0)
if (size == 0)
return;
- new_request = VEC_safe_push (memory_write_request_s,
- args->requests, NULL);
- memset (new_request, 0, sizeof (struct memory_write_request));
- section_data = XCNEW (struct load_progress_section_data);
- new_request->begin = bfd_section_lma (abfd, asec) + args->load_offset;
- new_request->end = new_request->begin + size; /* FIXME Should size
- be in instead? */
- new_request->data = (gdb_byte *) xmalloc (size);
- new_request->baton = section_data;
-
- buffer = new_request->data;
-
- section_data->cumulative = args->progress_data;
- section_data->section_name = sect_name;
- section_data->section_size = size;
- section_data->lma = new_request->begin;
- section_data->buffer = buffer;
-
+ ULONGEST begin = bfd_section_lma (abfd, asec) + args->load_offset;
+ ULONGEST end = begin + size;
+ gdb_byte *buffer = (gdb_byte *) xmalloc (size);
bfd_get_section_contents (abfd, asec, buffer, 0, size);
-}
-/* Clean up an entire memory request vector, including load
- data and progress records. */
+ load_progress_section_data *section_data
+ = new load_progress_section_data (args->progress_data, sect_name, size,
+ begin, buffer);
-static void
-clear_memory_write_data (void *arg)
-{
- VEC(memory_write_request_s) **vec_p = (VEC(memory_write_request_s) **) arg;
- VEC(memory_write_request_s) *vec = *vec_p;
- int i;
- struct memory_write_request *mr;
-
- for (i = 0; VEC_iterate (memory_write_request_s, vec, i, mr); ++i)
- {
- xfree (mr->data);
- xfree (mr->baton);
- }
- VEC_free (memory_write_request_s, vec);
+ args->requests.emplace_back (begin, end, buffer, section_data);
}
static void print_transfer_performance (struct ui_file *stream,
void
generic_load (const char *args, int from_tty)
{
- struct cleanup *old_cleanups;
- struct load_section_data cbdata;
struct load_progress_data total_progress;
+ struct load_section_data cbdata (&total_progress);
struct ui_out *uiout = current_uiout;
- CORE_ADDR entry;
-
- memset (&cbdata, 0, sizeof (cbdata));
- memset (&total_progress, 0, sizeof (total_progress));
- cbdata.progress_data = &total_progress;
-
- old_cleanups = make_cleanup (clear_memory_write_data, &cbdata.requests);
-
if (args == NULL)
error_no_arg (_("file to load"));
steady_clock::time_point end_time = steady_clock::now ();
- entry = bfd_get_start_address (loadfile_bfd.get ());
+ CORE_ADDR entry = bfd_get_start_address (loadfile_bfd.get ());
entry = gdbarch_addr_bits_remove (target_gdbarch (), entry);
uiout->text ("Start address ");
uiout->field_fmt ("address", "%s", paddress (target_gdbarch (), entry));
print_transfer_performance (gdb_stdout, total_progress.data_count,
total_progress.write_count,
end_time - start_time);
-
- do_cleanups (old_cleanups);
}
/* Report on STREAM the performance of a memory transfer operation,
gdb::unique_xmalloc_ptr<char> filename;
char *arg;
int argcnt = 0;
- int sec_num = 0;
struct objfile *objf;
objfile_flags flags = OBJF_USERLOADED | OBJF_SHARED;
symfile_add_flags add_flags = 0;
const char *value;
};
- struct section_addr_info *section_addrs;
std::vector<sect_opt> sect_opts = { { ".text", NULL } };
bool stop_processing_options = false;
- struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
dont_repeat ();
printf_unfiltered (_("add symbol table from file \"%s\" at\n"),
filename.get ());
- section_addrs = alloc_section_addr_info (sect_opts.size ());
- make_cleanup (xfree, section_addrs);
+ section_addr_info section_addrs;
for (sect_opt § : sect_opts)
{
CORE_ADDR addr;
/* Here we store the section offsets in the order they were
entered on the command line. */
- section_addrs->other[sec_num].name = (char *) sec;
- section_addrs->other[sec_num].addr = addr;
+ section_addrs.emplace_back (addr, sec, 0);
printf_unfiltered ("\t%s_addr = %s\n", sec,
paddress (gdbarch, addr));
- sec_num++;
/* The object's sections are initialized when a
call is made to build_objfile_section_table (objfile).
At this point, we don't know what file type this is,
so we can't determine what section names are valid. */
}
- section_addrs->num_sections = sec_num;
if (from_tty && (!query ("%s", "")))
error (_("Not confirmed."));
- objf = symbol_file_add (filename.get (), add_flags, section_addrs, flags);
+ objf = symbol_file_add (filename.get (), add_flags, §ion_addrs,
+ flags);
add_target_sections_of_objfile (objf);
/* Getting new symbols may change our opinion about what is
frameless. */
reinit_frame_cache ();
- do_cleanups (my_cleanups);
}
\f
clear_symtab_users (0);
/* clear_objfile_data for each objfile was called before freeing it and
- observer_notify_new_objfile (NULL) has been called by
+ gdb::observers::new_objfile.notify (NULL) has been called by
clear_symtab_users above. Notify the new files now. */
for (auto iter : new_objfiles)
- observer_notify_new_objfile (iter);
+ gdb::observers::new_objfile.notify (objfile);
/* At least one objfile has changed, so we can consider that
the executable we're debugging has changed too. */
- observer_notify_executable_changed ();
+ gdb::observers::executable_changed.notify ();
}
}
\f
clear_displays ();
clear_last_displayed_sal ();
clear_pc_function_cache ();
- observer_notify_new_objfile (NULL);
+ gdb::observers::new_objfile.notify (NULL);
/* Clear globals which might have pointed into a removed objfile.
FIXME: It's not clear which of these are supposed to persist
between expressions and which ought to be reset each time. */
expression_context_block = NULL;
- innermost_block = NULL;
+ innermost_block.reset ();
/* Varobj may refer to old symbols, perform a cleanup. */
varobj_invalidate ();
if (osect->ovly_mapped == -1)
gdbarch_overlay_update (gdbarch, osect);
}
- /* fall thru to manual case */
+ /* fall thru */
case ovly_on: /* overlay debugging manual */
return osect->ovly_mapped == 1;
}
{
struct cmd_list_element *c;
- observer_attach_free_objfile (symfile_free_objfile);
+ gdb::observers::free_objfile.attach (symfile_free_objfile);
#define READNOW_READNEVER_HELP \
"The '-readnow' option will cause GDB to read the entire symbol file\n\