| Index: gdb/symfile.c
|
| diff --git a/gdb/symfile.c b/gdb/symfile.c
|
| index 175d61c2a8860c282f65a4d91ad0879c7649397f..71f6b3e8c77fd0671d17c7f52963d2b158066793 100644
|
| --- a/gdb/symfile.c
|
| +++ b/gdb/symfile.c
|
| @@ -1,6 +1,6 @@
|
| /* Generic symbol file reading for the GNU debugger, GDB.
|
|
|
| - Copyright (C) 1990-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 1990-2013 Free Software Foundation, Inc.
|
|
|
| Contributed by Cygnus Support, using pieces from other GDB modules.
|
|
|
| @@ -55,11 +55,14 @@
|
| #include "solib.h"
|
| #include "remote.h"
|
| #include "stack.h"
|
| +#include "gdb_bfd.h"
|
| +#include "cli/cli-utils.h"
|
| +#include "target.h"
|
|
|
| #include <sys/types.h>
|
| #include <fcntl.h>
|
| -#include "gdb_string.h"
|
| -#include "gdb_stat.h"
|
| +#include <string.h>
|
| +#include <sys/stat.h>
|
| #include <ctype.h>
|
| #include <time.h>
|
| #include <sys/time.h>
|
| @@ -81,34 +84,20 @@ static void clear_symtab_users_cleanup (void *ignore);
|
| /* Global variables owned by this file. */
|
| int readnow_symbol_files; /* Read full symbols immediately. */
|
|
|
| -/* External variables and functions referenced. */
|
| -
|
| -extern void report_transfer_performance (unsigned long, time_t, time_t);
|
| -
|
| /* Functions this file defines. */
|
|
|
| static void load_command (char *, int);
|
|
|
| -static void symbol_file_add_main_1 (char *args, int from_tty, int flags);
|
| +static void symbol_file_add_main_1 (const char *args, int from_tty, int flags);
|
|
|
| static void add_symbol_file_command (char *, int);
|
|
|
| -bfd *symfile_bfd_open (char *);
|
| -
|
| -int get_section_index (struct objfile *, char *);
|
| -
|
| static const struct sym_fns *find_sym_fns (bfd *);
|
|
|
| static void decrement_reading_symtab (void *);
|
|
|
| static void overlay_invalidate_all (void);
|
|
|
| -void list_overlays_command (char *, int);
|
| -
|
| -void map_overlay_command (char *, int);
|
| -
|
| -void unmap_overlay_command (char *, int);
|
| -
|
| static void overlay_auto_command (char *, int);
|
|
|
| static void overlay_manual_command (char *, int);
|
| @@ -142,10 +131,18 @@ void _initialize_symfile (void);
|
| calls add_symtab_fns() to register information on each format it is
|
| prepared to read. */
|
|
|
| -typedef const struct sym_fns *sym_fns_ptr;
|
| -DEF_VEC_P (sym_fns_ptr);
|
| +typedef struct
|
| +{
|
| + /* BFD flavour that we handle. */
|
| + enum bfd_flavour sym_flavour;
|
| +
|
| + /* The "vtable" of symbol functions. */
|
| + const struct sym_fns *sym_fns;
|
| +} registered_sym_fns;
|
| +
|
| +DEF_VEC_O (registered_sym_fns);
|
|
|
| -static VEC (sym_fns_ptr) *symtab_fns = NULL;
|
| +static VEC (registered_sym_fns) *symtab_fns = NULL;
|
|
|
| /* If non-zero, shared library symbols will be added automatically
|
| when the inferior is created, new libraries are loaded, or when
|
| @@ -160,56 +157,6 @@ static VEC (sym_fns_ptr) *symtab_fns = NULL;
|
| int auto_solib_add = 1;
|
|
|
|
|
| -/* Make a null terminated copy of the string at PTR with SIZE characters in
|
| - the obstack pointed to by OBSTACKP . Returns the address of the copy.
|
| - Note that the string at PTR does not have to be null terminated, I.e. it
|
| - may be part of a larger string and we are only saving a substring. */
|
| -
|
| -char *
|
| -obsavestring (const char *ptr, int size, struct obstack *obstackp)
|
| -{
|
| - char *p = (char *) obstack_alloc (obstackp, size + 1);
|
| - /* Open-coded memcpy--saves function call time. These strings are usually
|
| - short. FIXME: Is this really still true with a compiler that can
|
| - inline memcpy? */
|
| - {
|
| - const char *p1 = ptr;
|
| - char *p2 = p;
|
| - const char *end = ptr + size;
|
| -
|
| - while (p1 != end)
|
| - *p2++ = *p1++;
|
| - }
|
| - p[size] = 0;
|
| - return p;
|
| -}
|
| -
|
| -/* Concatenate NULL terminated variable argument list of `const char *'
|
| - strings; return the new string. Space is found in the OBSTACKP.
|
| - Argument list must be terminated by a sentinel expression `(char *)
|
| - NULL'. */
|
| -
|
| -char *
|
| -obconcat (struct obstack *obstackp, ...)
|
| -{
|
| - va_list ap;
|
| -
|
| - va_start (ap, obstackp);
|
| - for (;;)
|
| - {
|
| - const char *s = va_arg (ap, const char *);
|
| -
|
| - if (s == NULL)
|
| - break;
|
| -
|
| - obstack_grow_str (obstackp, s);
|
| - }
|
| - va_end (ap);
|
| - obstack_1grow (obstackp, 0);
|
| -
|
| - return obstack_finish (obstackp);
|
| -}
|
| -
|
| /* True if we are reading a symbol table. */
|
|
|
| int currently_reading_symtab = 0;
|
| @@ -218,14 +165,17 @@ static void
|
| decrement_reading_symtab (void *dummy)
|
| {
|
| currently_reading_symtab--;
|
| + gdb_assert (currently_reading_symtab >= 0);
|
| }
|
|
|
| /* Increment currently_reading_symtab and return a cleanup that can be
|
| used to decrement it. */
|
| +
|
| struct cleanup *
|
| increment_reading_symtab (void)
|
| {
|
| ++currently_reading_symtab;
|
| + gdb_assert (currently_reading_symtab > 0);
|
| return make_cleanup (decrement_reading_symtab, NULL);
|
| }
|
|
|
| @@ -255,7 +205,9 @@ find_lowest_section (bfd *abfd, asection *sect, void *obj)
|
| *lowest = sect;
|
| }
|
|
|
| -/* Create a new section_addr_info, with room for NUM_SECTIONS. */
|
| +/* 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)
|
| @@ -267,7 +219,6 @@ alloc_section_addr_info (size_t num_sections)
|
| + sizeof (struct other_sections) * (num_sections - 1));
|
| sap = (struct section_addr_info *) xmalloc (size);
|
| memset (sap, 0, size);
|
| - sap->num_sections = num_sections;
|
|
|
| return sap;
|
| }
|
| @@ -287,18 +238,21 @@ build_section_addr_info_from_section_table (const struct target_section *start,
|
|
|
| for (stp = start, oidx = 0; stp != end; stp++)
|
| {
|
| - if (bfd_get_section_flags (stp->bfd,
|
| - stp->the_bfd_section) & (SEC_ALLOC | SEC_LOAD)
|
| + 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 (stp->bfd, stp->the_bfd_section));
|
| - sap->other[oidx].sectindex = stp->the_bfd_section->index;
|
| + sap->other[oidx].name = xstrdup (bfd_section_name (abfd, asect));
|
| + sap->other[oidx].sectindex = gdb_bfd_section_index (abfd, asect);
|
| oidx++;
|
| }
|
| }
|
|
|
| + sap->num_sections = oidx;
|
| +
|
| return sap;
|
| }
|
|
|
| @@ -317,9 +271,12 @@ build_section_addr_info_from_bfd (bfd *abfd)
|
| {
|
| 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 = sec->index;
|
| + sap->other[i].sectindex = gdb_bfd_section_index (abfd, sec);
|
| i++;
|
| }
|
| +
|
| + sap->num_sections = i;
|
| +
|
| return sap;
|
| }
|
|
|
| @@ -335,7 +292,7 @@ build_section_addr_info_from_objfile (const struct objfile *objfile)
|
| 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 && sap->other[i].name; i++)
|
| + for (i = 0; i < sap->num_sections; i++)
|
| {
|
| int sectindex = sap->other[i].sectindex;
|
|
|
| @@ -352,13 +309,12 @@ free_section_addr_info (struct section_addr_info *sap)
|
| int idx;
|
|
|
| for (idx = 0; idx < sap->num_sections; idx++)
|
| - if (sap->other[idx].name)
|
| - xfree (sap->other[idx].name);
|
| + xfree (sap->other[idx].name);
|
| xfree (sap);
|
| }
|
|
|
| -
|
| /* Initialize OBJFILE's sect_index_* members. */
|
| +
|
| static void
|
| init_objfile_sect_indices (struct objfile *objfile)
|
| {
|
| @@ -442,7 +398,7 @@ place_section (bfd *abfd, asection *sect, void *obj)
|
| return;
|
|
|
| /* If the user specified an offset, honor it. */
|
| - if (offsets[sect->index] != 0)
|
| + if (offsets[gdb_bfd_section_index (abfd, sect)] != 0)
|
| return;
|
|
|
| /* Otherwise, let's try to find a place for the section. */
|
| @@ -486,7 +442,7 @@ place_section (bfd *abfd, asection *sect, void *obj)
|
| }
|
| while (!done);
|
|
|
| - offsets[sect->index] = start_addr;
|
| + offsets[gdb_bfd_section_index (abfd, sect)] = start_addr;
|
| arg->lowest = start_addr + bfd_get_section_size (sect);
|
| }
|
|
|
| @@ -497,16 +453,16 @@ place_section (bfd *abfd, asection *sect, void *obj)
|
| void
|
| relative_addr_info_to_section_offsets (struct section_offsets *section_offsets,
|
| int num_sections,
|
| - struct section_addr_info *addrs)
|
| + const struct 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 && addrs->other[i].name; i++)
|
| + for (i = 0; i < addrs->num_sections; i++)
|
| {
|
| - struct other_sections *osp;
|
| + const struct other_sections *osp;
|
|
|
| osp = &addrs->other[i];
|
| if (osp->sectindex == -1)
|
| @@ -564,7 +520,7 @@ addrs_section_sort (struct section_addr_info *addrs)
|
|
|
| /* `+ 1' for the NULL terminator. */
|
| array = xmalloc (sizeof (*array) * (addrs->num_sections + 1));
|
| - for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
|
| + for (i = 0; i < addrs->num_sections; i++)
|
| array[i] = &addrs->other[i];
|
| array[i] = NULL;
|
|
|
| @@ -663,7 +619,7 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
|
| (the loadable section directly below it in memory).
|
| this_offset = lower_offset = lower_addr - lower_orig_addr */
|
|
|
| - for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
|
| + for (i = 0; i < addrs->num_sections; i++)
|
| {
|
| struct other_sections *sect = addrs_to_abfd_addrs[i];
|
|
|
| @@ -728,9 +684,9 @@ addr_info_make_relative (struct section_addr_info *addrs, bfd *abfd)
|
|
|
| void
|
| default_symfile_offsets (struct objfile *objfile,
|
| - struct section_addr_info *addrs)
|
| + const struct section_addr_info *addrs)
|
| {
|
| - objfile->num_sections = bfd_count_sections (objfile->obfd);
|
| + objfile->num_sections = gdb_bfd_count_sections (objfile->obfd);
|
| objfile->section_offsets = (struct section_offsets *)
|
| obstack_alloc (&objfile->objfile_obstack,
|
| SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
|
| @@ -810,7 +766,6 @@ default_symfile_offsets (struct objfile *objfile,
|
| init_objfile_sect_indices (objfile);
|
| }
|
|
|
| -
|
| /* Divide the file into segments, which are individual relocatable units.
|
| This is the default version of the sym_fns.sym_segments function for
|
| symbol readers that do not have an explicit representation of segments.
|
| @@ -875,9 +830,92 @@ default_symfile_segments (bfd *abfd)
|
| return data;
|
| }
|
|
|
| +/* This is a convenience function to call sym_read for OBJFILE and
|
| + possibly force the partial symbols to be read. */
|
| +
|
| +static void
|
| +read_symbols (struct objfile *objfile, int add_flags)
|
| +{
|
| + (*objfile->sf->sym_read) (objfile, add_flags);
|
| +
|
| + /* find_separate_debug_file_in_section should be called only if there is
|
| + single binary with no existing separate debug info file. */
|
| + if (!objfile_has_partial_symbols (objfile)
|
| + && objfile->separate_debug_objfile == NULL
|
| + && objfile->separate_debug_objfile_backlink == NULL)
|
| + {
|
| + bfd *abfd = find_separate_debug_file_in_section (objfile);
|
| + struct cleanup *cleanup = make_cleanup_bfd_unref (abfd);
|
| +
|
| + if (abfd != NULL)
|
| + {
|
| + /* find_separate_debug_file_in_section uses the same filename for the
|
| + 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, objfile->original_name, add_flags,
|
| + objfile);
|
| + }
|
| +
|
| + do_cleanups (cleanup);
|
| + }
|
| + if ((add_flags & SYMFILE_NO_READ) == 0)
|
| + require_partial_symbols (objfile, 0);
|
| +}
|
| +
|
| +/* Initialize entry point information for this objfile. */
|
| +
|
| +static void
|
| +init_entry_point_info (struct objfile *objfile)
|
| +{
|
| + /* Save startup file's range of PC addresses to help blockframe.c
|
| + decide where the bottom of the stack is. */
|
| +
|
| + if (bfd_get_file_flags (objfile->obfd) & EXEC_P)
|
| + {
|
| + /* Executable file -- record its entry point so we'll recognize
|
| + the startup file because it contains the entry point. */
|
| + objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
|
| + objfile->ei.entry_point_p = 1;
|
| + }
|
| + else if (bfd_get_file_flags (objfile->obfd) & DYNAMIC
|
| + && bfd_get_start_address (objfile->obfd) != 0)
|
| + {
|
| + /* Some shared libraries may have entry points set and be
|
| + runnable. There's no clear way to indicate this, so just check
|
| + for values other than zero. */
|
| + objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
|
| + objfile->ei.entry_point_p = 1;
|
| + }
|
| + else
|
| + {
|
| + /* Examination of non-executable.o files. Short-circuit this stuff. */
|
| + objfile->ei.entry_point_p = 0;
|
| + }
|
| +
|
| + if (objfile->ei.entry_point_p)
|
| + {
|
| + CORE_ADDR entry_point = objfile->ei.entry_point;
|
| +
|
| + /* Make certain that the address points at real code, and not a
|
| + function descriptor. */
|
| + entry_point
|
| + = gdbarch_convert_from_func_ptr_addr (get_objfile_arch (objfile),
|
| + entry_point,
|
| + ¤t_target);
|
| +
|
| + /* Remove any ISA markers, so that this matches entries in the
|
| + symbol table. */
|
| + objfile->ei.entry_point
|
| + = gdbarch_addr_bits_remove (get_objfile_arch (objfile), entry_point);
|
| + }
|
| +}
|
| +
|
| /* Process a symbol file, as either the main file or as a dynamically
|
| loaded file.
|
|
|
| + This function does not set the OBJFILE's entry-point info.
|
| +
|
| OBJFILE is where the symbols are to be read from.
|
|
|
| ADDRS is the list of section load addresses. If the user has given
|
| @@ -889,58 +927,50 @@ default_symfile_segments (bfd *abfd)
|
| into an offset from the section VMA's as it appears in the object
|
| file, and then call the file's sym_offsets function to convert this
|
| into a format-specific offset table --- a `struct section_offsets'.
|
| - If ADDRS is non-zero, OFFSETS must be zero.
|
| -
|
| - OFFSETS is a table of section offsets already in the right
|
| - format-specific representation. NUM_OFFSETS is the number of
|
| - elements present in OFFSETS->offsets. If OFFSETS is non-zero, we
|
| - assume this is the proper table the call to sym_offsets described
|
| - above would produce. Instead of calling sym_offsets, we just dump
|
| - it right into objfile->section_offsets. (When we're re-reading
|
| - symbols from an objfile, we don't have the original load address
|
| - list any more; all we have is the section offset table.) If
|
| - OFFSETS is non-zero, ADDRS must be zero.
|
|
|
| ADD_FLAGS encodes verbosity level, whether this is main symbol or
|
| an extra symbol file such as dynamically loaded code, and wether
|
| breakpoint reset should be deferred. */
|
|
|
| -void
|
| -syms_from_objfile (struct objfile *objfile,
|
| - struct section_addr_info *addrs,
|
| - struct section_offsets *offsets,
|
| - int num_offsets,
|
| - int add_flags)
|
| +static void
|
| +syms_from_objfile_1 (struct objfile *objfile,
|
| + struct section_addr_info *addrs,
|
| + int add_flags)
|
| {
|
| struct section_addr_info *local_addr = NULL;
|
| struct cleanup *old_chain;
|
| const int mainline = add_flags & SYMFILE_MAINLINE;
|
|
|
| - gdb_assert (! (addrs && offsets));
|
| -
|
| - init_entry_point_info (objfile);
|
| - objfile->sf = find_sym_fns (objfile->obfd);
|
| + objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd));
|
|
|
| if (objfile->sf == NULL)
|
| - return; /* No symbols. */
|
| + {
|
| + /* No symbols to load, but we still need to make sure
|
| + that the section_offsets table is allocated. */
|
| + int num_sections = gdb_bfd_count_sections (objfile->obfd);
|
| + size_t size = SIZEOF_N_SECTION_OFFSETS (num_sections);
|
| +
|
| + objfile->num_sections = num_sections;
|
| + objfile->section_offsets
|
| + = obstack_alloc (&objfile->objfile_obstack, size);
|
| + memset (objfile->section_offsets, 0, size);
|
| + return;
|
| + }
|
|
|
| /* Make sure that partially constructed symbol tables will be cleaned up
|
| if an error occurs during symbol reading. */
|
| old_chain = make_cleanup_free_objfile (objfile);
|
|
|
| - /* If ADDRS and OFFSETS are both NULL, put together a dummy address
|
| - list. We now establish the convention that an addr of zero means
|
| + /* If ADDRS is NULL, put together a dummy address list.
|
| + We now establish the convention that an addr of zero means
|
| no load address was specified. */
|
| - if (! addrs && ! offsets)
|
| + if (! addrs)
|
| {
|
| - local_addr
|
| - = alloc_section_addr_info (bfd_count_sections (objfile->obfd));
|
| + local_addr = alloc_section_addr_info (1);
|
| make_cleanup (xfree, local_addr);
|
| addrs = local_addr;
|
| }
|
|
|
| - /* Now either addrs or offsets is non-zero. */
|
| -
|
| if (mainline)
|
| {
|
| /* We will modify the main symbol table, make sure that all its users
|
| @@ -969,7 +999,7 @@ syms_from_objfile (struct objfile *objfile,
|
|
|
| We no longer warn if the lowest section is not a text segment (as
|
| happens for the PA64 port. */
|
| - if (addrs && addrs->other[0].name)
|
| + if (addrs->num_sections > 0)
|
| addr_info_make_relative (addrs, objfile->obfd);
|
|
|
| /* Initialize symbol reading routines for this objfile, allow complaints to
|
| @@ -979,26 +1009,9 @@ syms_from_objfile (struct objfile *objfile,
|
| (*objfile->sf->sym_init) (objfile);
|
| clear_complaints (&symfile_complaints, 1, add_flags & SYMFILE_VERBOSE);
|
|
|
| - if (addrs)
|
| - (*objfile->sf->sym_offsets) (objfile, addrs);
|
| - else
|
| - {
|
| - size_t size = SIZEOF_N_SECTION_OFFSETS (num_offsets);
|
| -
|
| - /* Just copy in the offset table directly as given to us. */
|
| - objfile->num_sections = num_offsets;
|
| - objfile->section_offsets
|
| - = ((struct section_offsets *)
|
| - obstack_alloc (&objfile->objfile_obstack, size));
|
| - memcpy (objfile->section_offsets, offsets, size);
|
| -
|
| - init_objfile_sect_indices (objfile);
|
| - }
|
| -
|
| - (*objfile->sf->sym_read) (objfile, add_flags);
|
| + (*objfile->sf->sym_offsets) (objfile, addrs);
|
|
|
| - if ((add_flags & SYMFILE_NO_READ) == 0)
|
| - require_partial_symbols (objfile, 0);
|
| + read_symbols (objfile, add_flags);
|
|
|
| /* Discard cleanups as symbol reading was successful. */
|
|
|
| @@ -1006,6 +1019,18 @@ syms_from_objfile (struct objfile *objfile,
|
| xfree (local_addr);
|
| }
|
|
|
| +/* Same as syms_from_objfile_1, but also initializes the objfile
|
| + entry-point info. */
|
| +
|
| +static void
|
| +syms_from_objfile (struct objfile *objfile,
|
| + struct section_addr_info *addrs,
|
| + int add_flags)
|
| +{
|
| + syms_from_objfile_1 (objfile, addrs, add_flags);
|
| + init_entry_point_info (objfile);
|
| +}
|
| +
|
| /* Perform required actions after either reading in the initial
|
| symbols for a new objfile, or mapping in the symbols from a reusable
|
| objfile. ADD_FLAGS is a bitmask of enum symfile_add_flags. */
|
| @@ -1036,13 +1061,14 @@ new_symfile_objfile (struct objfile *objfile, int add_flags)
|
| loaded file.
|
|
|
| ABFD is a BFD already open on the file, as from symfile_bfd_open.
|
| - This BFD will be closed on error, and is always consumed by this function.
|
| + A new reference is acquired by this function.
|
| +
|
| + For NAME description see allocate_objfile's definition.
|
|
|
| ADD_FLAGS encodes verbosity, whether this is main symbol file or
|
| extra, such as dynamically loaded code, and what to do with breakpoins.
|
|
|
| - ADDRS, OFFSETS, and NUM_OFFSETS are as described for
|
| - syms_from_objfile, above.
|
| + ADDRS is as described for syms_from_objfile_1, above.
|
| ADDRS is ignored when SYMFILE_MAINLINE bit is set in ADD_FLAGS.
|
|
|
| PARENT is the original objfile if ABFD is a separate debug info file.
|
| @@ -1052,16 +1078,11 @@ new_symfile_objfile (struct objfile *objfile, int add_flags)
|
| Upon failure, jumps back to command level (never returns). */
|
|
|
| static struct objfile *
|
| -symbol_file_add_with_addrs_or_offsets (bfd *abfd,
|
| - int add_flags,
|
| - struct section_addr_info *addrs,
|
| - struct section_offsets *offsets,
|
| - int num_offsets,
|
| - int flags, struct objfile *parent)
|
| +symbol_file_add_with_addrs (bfd *abfd, const char *name, int add_flags,
|
| + struct section_addr_info *addrs,
|
| + int flags, struct objfile *parent)
|
| {
|
| struct objfile *objfile;
|
| - struct cleanup *my_cleanups;
|
| - const char *name = bfd_get_filename (abfd);
|
| const int from_tty = add_flags & SYMFILE_VERBOSE;
|
| const int mainline = add_flags & SYMFILE_MAINLINE;
|
| const int should_print = ((from_tty || info_verbose)
|
| @@ -1074,8 +1095,6 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
|
| add_flags &= ~SYMFILE_NO_READ;
|
| }
|
|
|
| - my_cleanups = make_cleanup_bfd_close (abfd);
|
| -
|
| /* Give user a chance to burp if we'd be
|
| interactively wiping out any existing symbols. */
|
|
|
| @@ -1085,8 +1104,8 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
|
| && !query (_("Load new symbol table from \"%s\"? "), name))
|
| error (_("Not confirmed."));
|
|
|
| - objfile = allocate_objfile (abfd, flags | (mainline ? OBJF_MAINLINE : 0));
|
| - discard_cleanups (my_cleanups);
|
| + objfile = allocate_objfile (abfd, name,
|
| + flags | (mainline ? OBJF_MAINLINE : 0));
|
|
|
| if (parent)
|
| add_separate_debug_objfile (objfile, parent);
|
| @@ -1105,8 +1124,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
|
| gdb_flush (gdb_stdout);
|
| }
|
| }
|
| - syms_from_objfile (objfile, addrs, offsets, num_offsets,
|
| - add_flags);
|
| + syms_from_objfile (objfile, addrs, add_flags);
|
|
|
| /* We now have at least a partial symbol table. Check to see if the
|
| user requested that all symbols be read on initial access via either
|
| @@ -1160,10 +1178,12 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd,
|
| return (objfile);
|
| }
|
|
|
| -/* Add BFD as a separate debug file for OBJFILE. */
|
| +/* Add BFD as a separate debug file for OBJFILE. For NAME description
|
| + see allocate_objfile's definition. */
|
|
|
| void
|
| -symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile)
|
| +symbol_file_add_separate (bfd *bfd, const char *name, int symfile_flags,
|
| + struct objfile *objfile)
|
| {
|
| struct objfile *new_objfile;
|
| struct section_addr_info *sap;
|
| @@ -1175,9 +1195,8 @@ symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile)
|
| sap = build_section_addr_info_from_objfile (objfile);
|
| my_cleanup = make_cleanup_free_section_addr_info (sap);
|
|
|
| - new_objfile = symbol_file_add_with_addrs_or_offsets
|
| - (bfd, symfile_flags,
|
| - sap, NULL, 0,
|
| + new_objfile = symbol_file_add_with_addrs
|
| + (bfd, name, symfile_flags, sap,
|
| objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
|
| | OBJF_USERLOADED),
|
| objfile);
|
| @@ -1187,30 +1206,32 @@ symbol_file_add_separate (bfd *bfd, int symfile_flags, struct objfile *objfile)
|
|
|
| /* Process the symbol file ABFD, as either the main file or as a
|
| dynamically loaded file.
|
| + See symbol_file_add_with_addrs's comments for details. */
|
|
|
| - See symbol_file_add_with_addrs_or_offsets's comments for
|
| - details. */
|
| struct objfile *
|
| -symbol_file_add_from_bfd (bfd *abfd, int add_flags,
|
| +symbol_file_add_from_bfd (bfd *abfd, const char *name, int add_flags,
|
| struct section_addr_info *addrs,
|
| int flags, struct objfile *parent)
|
| {
|
| - return symbol_file_add_with_addrs_or_offsets (abfd, add_flags, addrs, 0, 0,
|
| - flags, parent);
|
| + return symbol_file_add_with_addrs (abfd, name, add_flags, addrs, flags,
|
| + parent);
|
| }
|
|
|
| -
|
| /* Process a symbol file, as either the main file or as a dynamically
|
| - loaded file. See symbol_file_add_with_addrs_or_offsets's comments
|
| - for details. */
|
| + loaded file. See symbol_file_add_with_addrs's comments for details. */
|
| +
|
| struct objfile *
|
| -symbol_file_add (char *name, int add_flags, struct section_addr_info *addrs,
|
| - int flags)
|
| +symbol_file_add (const char *name, int add_flags,
|
| + struct section_addr_info *addrs, int flags)
|
| {
|
| - return symbol_file_add_from_bfd (symfile_bfd_open (name), add_flags, addrs,
|
| - flags, NULL);
|
| -}
|
| + bfd *bfd = symfile_bfd_open (name);
|
| + struct cleanup *cleanup = make_cleanup_bfd_unref (bfd);
|
| + struct objfile *objf;
|
|
|
| + objf = symbol_file_add_from_bfd (bfd, name, add_flags, addrs, flags, NULL);
|
| + do_cleanups (cleanup);
|
| + return objf;
|
| +}
|
|
|
| /* Call symbol_file_add() with default values and update whatever is
|
| affected by the loading of a new main().
|
| @@ -1221,13 +1242,13 @@ symbol_file_add (char *name, int add_flags, struct section_addr_info *addrs,
|
| command itself. */
|
|
|
| void
|
| -symbol_file_add_main (char *args, int from_tty)
|
| +symbol_file_add_main (const char *args, int from_tty)
|
| {
|
| symbol_file_add_main_1 (args, from_tty, 0);
|
| }
|
|
|
| static void
|
| -symbol_file_add_main_1 (char *args, int from_tty, int flags)
|
| +symbol_file_add_main_1 (const char *args, int from_tty, int flags)
|
| {
|
| const int add_flags = (current_inferior ()->symfile_flags
|
| | SYMFILE_MAINLINE | (from_tty ? SYMFILE_VERBOSE : 0));
|
| @@ -1249,7 +1270,7 @@ symbol_file_clear (int from_tty)
|
| && from_tty
|
| && (symfile_objfile
|
| ? !query (_("Discard symbol table from `%s'? "),
|
| - symfile_objfile->name)
|
| + objfile_name (symfile_objfile))
|
| : !query (_("Discard symbol table? "))))
|
| error (_("Not confirmed."));
|
|
|
| @@ -1264,73 +1285,6 @@ symbol_file_clear (int from_tty)
|
| printf_unfiltered (_("No symbol file now.\n"));
|
| }
|
|
|
| -static char *
|
| -get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
|
| -{
|
| - asection *sect;
|
| - bfd_size_type debuglink_size;
|
| - unsigned long crc32;
|
| - char *contents;
|
| - int crc_offset;
|
| -
|
| - sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
|
| -
|
| - if (sect == NULL)
|
| - return NULL;
|
| -
|
| - debuglink_size = bfd_section_size (objfile->obfd, sect);
|
| -
|
| - contents = xmalloc (debuglink_size);
|
| - bfd_get_section_contents (objfile->obfd, sect, contents,
|
| - (file_ptr)0, (bfd_size_type)debuglink_size);
|
| -
|
| - /* Crc value is stored after the filename, aligned up to 4 bytes. */
|
| - crc_offset = strlen (contents) + 1;
|
| - crc_offset = (crc_offset + 3) & ~3;
|
| -
|
| - crc32 = bfd_get_32 (objfile->obfd, (bfd_byte *) (contents + crc_offset));
|
| -
|
| - *crc32_out = crc32;
|
| - return contents;
|
| -}
|
| -
|
| -/* Return 32-bit CRC for ABFD. If successful store it to *FILE_CRC_RETURN and
|
| - return 1. Otherwise print a warning and return 0. ABFD seek position is
|
| - not preserved. */
|
| -
|
| -static int
|
| -get_file_crc (bfd *abfd, unsigned long *file_crc_return)
|
| -{
|
| - unsigned long file_crc = 0;
|
| -
|
| - if (bfd_seek (abfd, 0, SEEK_SET) != 0)
|
| - {
|
| - warning (_("Problem reading \"%s\" for CRC: %s"),
|
| - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
|
| - return 0;
|
| - }
|
| -
|
| - for (;;)
|
| - {
|
| - gdb_byte buffer[8 * 1024];
|
| - bfd_size_type count;
|
| -
|
| - count = bfd_bread (buffer, sizeof (buffer), abfd);
|
| - if (count == (bfd_size_type) -1)
|
| - {
|
| - warning (_("Problem reading \"%s\" for CRC: %s"),
|
| - bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
|
| - return 0;
|
| - }
|
| - if (count == 0)
|
| - break;
|
| - file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
|
| - }
|
| -
|
| - *file_crc_return = file_crc;
|
| - return 1;
|
| -}
|
| -
|
| static int
|
| separate_debug_file_exists (const char *name, unsigned long crc,
|
| struct objfile *parent_objfile)
|
| @@ -1347,10 +1301,10 @@ separate_debug_file_exists (const char *name, unsigned long 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, parent_objfile->name) == 0)
|
| + if (filename_cmp (name, objfile_name (parent_objfile)) == 0)
|
| return 0;
|
|
|
| - abfd = bfd_open_maybe_remote (name);
|
| + abfd = gdb_bfd_open_maybe_remote (name);
|
|
|
| if (!abfd)
|
| return 0;
|
| @@ -1372,7 +1326,7 @@ separate_debug_file_exists (const char *name, unsigned long crc,
|
| if (abfd_stat.st_dev == parent_stat.st_dev
|
| && abfd_stat.st_ino == parent_stat.st_ino)
|
| {
|
| - bfd_close (abfd);
|
| + gdb_bfd_unref (abfd);
|
| return 0;
|
| }
|
| verified_as_different = 1;
|
| @@ -1380,31 +1334,31 @@ separate_debug_file_exists (const char *name, unsigned long crc,
|
| else
|
| verified_as_different = 0;
|
|
|
| - file_crc_p = get_file_crc (abfd, &file_crc);
|
| + file_crc_p = gdb_bfd_crc (abfd, &file_crc);
|
|
|
| - bfd_close (abfd);
|
| + gdb_bfd_unref (abfd);
|
|
|
| if (!file_crc_p)
|
| return 0;
|
|
|
| if (crc != file_crc)
|
| {
|
| + unsigned long parent_crc;
|
| +
|
| /* If one (or both) the files are accessed for example the via "remote:"
|
| gdbserver way it does not support the bfd_stat operation. Verify
|
| whether those two files are not the same manually. */
|
|
|
| - if (!verified_as_different && !parent_objfile->crc32_p)
|
| + if (!verified_as_different)
|
| {
|
| - parent_objfile->crc32_p = get_file_crc (parent_objfile->obfd,
|
| - &parent_objfile->crc32);
|
| - if (!parent_objfile->crc32_p)
|
| + if (!gdb_bfd_crc (parent_objfile->obfd, &parent_crc))
|
| return 0;
|
| }
|
|
|
| - if (verified_as_different || parent_objfile->crc32 != file_crc)
|
| + if (verified_as_different || parent_crc != file_crc)
|
| warning (_("the debug information found in \"%s\""
|
| " does not match \"%s\" (CRC mismatch).\n"),
|
| - name, parent_objfile->name);
|
| + name, objfile_name (parent_objfile));
|
|
|
| return 0;
|
| }
|
| @@ -1430,7 +1384,9 @@ show_debug_file_directory (struct ui_file *file, int from_tty,
|
| /* Find a separate debuginfo file for OBJFILE, using DIR as the directory
|
| where the original file resides (may not be the same as
|
| dirname(objfile->name) due to symlinks), and DEBUGLINK as the file we are
|
| - looking for. Returns the name of the debuginfo, of NULL. */
|
| + 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. */
|
|
|
| static char *
|
| find_separate_debug_file (const char *dir,
|
| @@ -1489,7 +1445,10 @@ find_separate_debug_file (const char *dir,
|
| strcat (debugfile, debuglink);
|
|
|
| if (separate_debug_file_exists (debugfile, crc32, objfile))
|
| - return debugfile;
|
| + {
|
| + do_cleanups (back_to);
|
| + return debugfile;
|
| + }
|
|
|
| /* If the file is in the sysroot, try using its base path in the
|
| global debugfile directory. */
|
| @@ -1504,7 +1463,10 @@ find_separate_debug_file (const char *dir,
|
| strcat (debugfile, debuglink);
|
|
|
| if (separate_debug_file_exists (debugfile, crc32, objfile))
|
| - return debugfile;
|
| + {
|
| + do_cleanups (back_to);
|
| + return debugfile;
|
| + }
|
| }
|
| }
|
|
|
| @@ -1513,7 +1475,7 @@ find_separate_debug_file (const char *dir,
|
| return NULL;
|
| }
|
|
|
| -/* Modify PATH to contain only "directory/" part of PATH.
|
| +/* Modify PATH to contain only "[/]directory/" part of PATH.
|
| If there were no directory separators in PATH, PATH will be empty
|
| string on return. */
|
|
|
| @@ -1544,7 +1506,7 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
|
| unsigned long crc32;
|
| struct cleanup *cleanups;
|
|
|
| - debuglink = get_debug_link_info (objfile, &crc32);
|
| + debuglink = bfd_get_debug_link_info (objfile->obfd, &crc32);
|
|
|
| if (debuglink == NULL)
|
| {
|
| @@ -1554,7 +1516,7 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
|
| }
|
|
|
| cleanups = make_cleanup (xfree, debuglink);
|
| - dir = xstrdup (objfile->name);
|
| + dir = xstrdup (objfile_name (objfile));
|
| make_cleanup (xfree, dir);
|
| terminate_after_last_dir_separator (dir);
|
| canon_dir = lrealpath (dir);
|
| @@ -1571,11 +1533,12 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
|
|
|
| struct stat st_buf;
|
|
|
| - if (lstat (objfile->name, &st_buf) == 0 && S_ISLNK(st_buf.st_mode))
|
| + if (lstat (objfile_name (objfile), &st_buf) == 0
|
| + && S_ISLNK (st_buf.st_mode))
|
| {
|
| char *symlink_dir;
|
|
|
| - symlink_dir = lrealpath (objfile->name);
|
| + symlink_dir = lrealpath (objfile_name (objfile));
|
| if (symlink_dir != NULL)
|
| {
|
| make_cleanup (xfree, symlink_dir);
|
| @@ -1598,7 +1561,6 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
|
| return debugfile;
|
| }
|
|
|
| -
|
| /* This is the symbol-file command. Read the file, analyze its
|
| symbols, and add a struct symtab to a symtab list. The syntax of
|
| the command is rather bizarre:
|
| @@ -1672,11 +1634,11 @@ set_initial_language (void)
|
| lang = language_of_main;
|
| else
|
| {
|
| - const char *filename;
|
| + char *name = main_name ();
|
| + struct symbol *sym = lookup_symbol (name, NULL, VAR_DOMAIN, NULL);
|
|
|
| - filename = find_main_filename ();
|
| - if (filename != NULL)
|
| - lang = deduce_language_from_filename (filename);
|
| + if (sym != NULL)
|
| + lang = SYMBOL_LANGUAGE (sym);
|
| }
|
|
|
| if (lang == language_unknown)
|
| @@ -1690,17 +1652,21 @@ set_initial_language (void)
|
| }
|
|
|
| /* If NAME is a remote name open the file using remote protocol, otherwise
|
| - open it normally. */
|
| + open it normally. Returns a new reference to the BFD. On error,
|
| + returns NULL with the BFD error set. */
|
|
|
| bfd *
|
| -bfd_open_maybe_remote (const char *name)
|
| +gdb_bfd_open_maybe_remote (const char *name)
|
| {
|
| + bfd *result;
|
| +
|
| if (remote_filename_p (name))
|
| - return remote_bfd_open (name, gnutarget);
|
| + result = remote_bfd_open (name, gnutarget);
|
| else
|
| - return bfd_openr (name, gnutarget);
|
| -}
|
| + result = gdb_bfd_open (name, gnutarget, -1);
|
|
|
| + return result;
|
| +}
|
|
|
| /* Open the file specified by NAME and hand it off to BFD for
|
| preliminary analysis. Return a newly initialized bfd *, which
|
| @@ -1708,38 +1674,34 @@ bfd_open_maybe_remote (const char *name)
|
| absolute). In case of trouble, error() is called. */
|
|
|
| bfd *
|
| -symfile_bfd_open (char *name)
|
| +symfile_bfd_open (const char *cname)
|
| {
|
| bfd *sym_bfd;
|
| int desc;
|
| - char *absolute_name;
|
| + char *name, *absolute_name;
|
| + struct cleanup *back_to;
|
|
|
| - if (remote_filename_p (name))
|
| + if (remote_filename_p (cname))
|
| {
|
| - name = xstrdup (name);
|
| - sym_bfd = remote_bfd_open (name, gnutarget);
|
| + sym_bfd = remote_bfd_open (cname, gnutarget);
|
| if (!sym_bfd)
|
| - {
|
| - make_cleanup (xfree, name);
|
| - error (_("`%s': can't open to read symbols: %s."), name,
|
| - bfd_errmsg (bfd_get_error ()));
|
| - }
|
| + error (_("`%s': can't open to read symbols: %s."), cname,
|
| + bfd_errmsg (bfd_get_error ()));
|
|
|
| if (!bfd_check_format (sym_bfd, bfd_object))
|
| {
|
| - bfd_close (sym_bfd);
|
| - make_cleanup (xfree, name);
|
| - error (_("`%s': can't read symbols: %s."), name,
|
| + make_cleanup_bfd_unref (sym_bfd);
|
| + error (_("`%s': can't read symbols: %s."), cname,
|
| bfd_errmsg (bfd_get_error ()));
|
| }
|
|
|
| return sym_bfd;
|
| }
|
|
|
| - name = tilde_expand (name); /* Returns 1st new malloc'd copy. */
|
| + name = tilde_expand (cname); /* Returns 1st new malloc'd copy. */
|
|
|
| /* Look down path for it, allocate 2nd new malloc'd copy. */
|
| - desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, name,
|
| + desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, name,
|
| O_RDONLY | O_BINARY, &absolute_name);
|
| #if defined(__GO32__) || defined(_WIN32) || defined (__CYGWIN__)
|
| if (desc < 0)
|
| @@ -1747,8 +1709,8 @@ symfile_bfd_open (char *name)
|
| char *exename = alloca (strlen (name) + 5);
|
|
|
| strcat (strcpy (exename, name), ".exe");
|
| - desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, exename,
|
| - O_RDONLY | O_BINARY, &absolute_name);
|
| + desc = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
|
| + exename, O_RDONLY | O_BINARY, &absolute_name);
|
| }
|
| #endif
|
| if (desc < 0)
|
| @@ -1757,33 +1719,24 @@ symfile_bfd_open (char *name)
|
| perror_with_name (name);
|
| }
|
|
|
| - /* Free 1st new malloc'd copy, but keep the 2nd malloc'd copy in
|
| - bfd. It'll be freed in free_objfile(). */
|
| xfree (name);
|
| name = absolute_name;
|
| + back_to = make_cleanup (xfree, name);
|
|
|
| - sym_bfd = bfd_fopen (name, gnutarget, FOPEN_RB, desc);
|
| + sym_bfd = gdb_bfd_open (name, gnutarget, desc);
|
| if (!sym_bfd)
|
| - {
|
| - make_cleanup (xfree, name);
|
| - error (_("`%s': can't open to read symbols: %s."), name,
|
| - bfd_errmsg (bfd_get_error ()));
|
| - }
|
| + error (_("`%s': can't open to read symbols: %s."), name,
|
| + bfd_errmsg (bfd_get_error ()));
|
| bfd_set_cacheable (sym_bfd, 1);
|
|
|
| if (!bfd_check_format (sym_bfd, bfd_object))
|
| {
|
| - /* FIXME: should be checking for errors from bfd_close (for one
|
| - thing, on error it does not free all the storage associated
|
| - with the bfd). */
|
| - bfd_close (sym_bfd); /* This also closes desc. */
|
| - make_cleanup (xfree, name);
|
| + make_cleanup_bfd_unref (sym_bfd);
|
| error (_("`%s': can't read symbols: %s."), name,
|
| bfd_errmsg (bfd_get_error ()));
|
| }
|
|
|
| - /* bfd_usrdata exists for applications and libbfd must not touch it. */
|
| - gdb_assert (bfd_usrdata (sym_bfd) == NULL);
|
| + do_cleanups (back_to);
|
|
|
| return sym_bfd;
|
| }
|
| @@ -1802,14 +1755,18 @@ get_section_index (struct objfile *objfile, char *section_name)
|
| return -1;
|
| }
|
|
|
| -/* Link SF into the global symtab_fns list. Called on startup by the
|
| - _initialize routine in each object file format reader, to register
|
| - information about each format the reader is prepared to handle. */
|
| +/* Link SF into the global symtab_fns list.
|
| + FLAVOUR is the file format that SF handles.
|
| + Called on startup by the _initialize routine in each object file format
|
| + reader, to register information about each format the reader is prepared
|
| + to handle. */
|
|
|
| void
|
| -add_symtab_fns (const struct sym_fns *sf)
|
| +add_symtab_fns (enum bfd_flavour flavour, const struct sym_fns *sf)
|
| {
|
| - VEC_safe_push (sym_fns_ptr, symtab_fns, sf);
|
| + registered_sym_fns fns = { flavour, sf };
|
| +
|
| + VEC_safe_push (registered_sym_fns, symtab_fns, &fns);
|
| }
|
|
|
| /* Initialize OBJFILE to read symbols from its associated BFD. It
|
| @@ -1820,7 +1777,7 @@ add_symtab_fns (const struct sym_fns *sf)
|
| static const struct sym_fns *
|
| find_sym_fns (bfd *abfd)
|
| {
|
| - const struct sym_fns *sf;
|
| + registered_sym_fns *rsf;
|
| enum bfd_flavour our_flavour = bfd_get_flavour (abfd);
|
| int i;
|
|
|
| @@ -1829,9 +1786,9 @@ find_sym_fns (bfd *abfd)
|
| || our_flavour == bfd_target_tekhex_flavour)
|
| return NULL; /* No symbols. */
|
|
|
| - for (i = 0; VEC_iterate (sym_fns_ptr, symtab_fns, i, sf); ++i)
|
| - if (our_flavour == sf->sym_flavour)
|
| - return sf;
|
| + for (i = 0; VEC_iterate (registered_sym_fns, symtab_fns, i, rsf); ++i)
|
| + if (our_flavour == rsf->sym_flavour)
|
| + return rsf->sym_fns;
|
|
|
| error (_("I'm sorry, Dave, I can't do that. Symbol format `%s' unknown."),
|
| bfd_get_target (abfd));
|
| @@ -1843,6 +1800,8 @@ find_sym_fns (bfd *abfd)
|
| static void
|
| load_command (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
|
| @@ -1892,6 +1851,8 @@ load_command (char *arg, int from_tty)
|
| /* 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
|
| @@ -1917,7 +1878,7 @@ add_section_size_callback (bfd *abfd, asection *asec, void *data)
|
|
|
| /* Opaque data for load_section_callback. */
|
| struct load_section_data {
|
| - unsigned long load_offset;
|
| + CORE_ADDR load_offset;
|
| struct load_progress_data *progress_data;
|
| VEC(memory_write_request_s) *requests;
|
| };
|
| @@ -1963,7 +1924,7 @@ load_progress (ULONGEST bytes, void *untyped_arg)
|
| this section. */
|
| ui_out_message (current_uiout, 0, "Loading section %s, size %s lma %s\n",
|
| args->section_name, hex_string (args->section_size),
|
| - paddress (target_gdbarch, args->lma));
|
| + paddress (target_gdbarch (), args->lma));
|
| return;
|
| }
|
|
|
| @@ -1981,10 +1942,10 @@ load_progress (ULONGEST bytes, void *untyped_arg)
|
|
|
| if (target_read_memory (args->lma, check, bytes) != 0)
|
| error (_("Download verify read failed at %s"),
|
| - paddress (target_gdbarch, args->lma));
|
| + paddress (target_gdbarch (), args->lma));
|
| if (memcmp (args->buffer, check, bytes) != 0)
|
| error (_("Download verify compare failed at %s"),
|
| - paddress (target_gdbarch, args->lma));
|
| + paddress (target_gdbarch (), args->lma));
|
| do_cleanups (verify_cleanups);
|
| }
|
| totals->data_count += bytes;
|
| @@ -1992,7 +1953,7 @@ load_progress (ULONGEST bytes, void *untyped_arg)
|
| args->buffer += bytes;
|
| totals->write_count += 1;
|
| args->section_sent += bytes;
|
| - if (quit_flag
|
| + if (check_quit_flag ()
|
| || (deprecated_ui_load_progress_hook != NULL
|
| && deprecated_ui_load_progress_hook (args->section_name,
|
| args->section_sent)))
|
| @@ -2095,9 +2056,9 @@ generic_load (char *args, int from_tty)
|
|
|
| if (argv[1] != NULL)
|
| {
|
| - char *endptr;
|
| + const char *endptr;
|
|
|
| - cbdata.load_offset = strtoul (argv[1], &endptr, 0);
|
| + cbdata.load_offset = strtoulst (argv[1], &endptr, 0);
|
|
|
| /* If the last word was not a valid number then
|
| treat it as a file name with spaces in. */
|
| @@ -2109,17 +2070,14 @@ generic_load (char *args, int from_tty)
|
| }
|
|
|
| /* Open the file for loading. */
|
| - loadfile_bfd = bfd_openr (filename, gnutarget);
|
| + loadfile_bfd = gdb_bfd_open (filename, gnutarget, -1);
|
| if (loadfile_bfd == NULL)
|
| {
|
| perror_with_name (filename);
|
| return;
|
| }
|
|
|
| - /* FIXME: should be checking for errors from bfd_close (for one thing,
|
| - on error it does not free all the storage associated with the
|
| - bfd). */
|
| - make_cleanup_bfd_close (loadfile_bfd);
|
| + make_cleanup_bfd_unref (loadfile_bfd);
|
|
|
| if (!bfd_check_format (loadfile_bfd, bfd_object))
|
| {
|
| @@ -2141,8 +2099,9 @@ generic_load (char *args, int from_tty)
|
| gettimeofday (&end_time, NULL);
|
|
|
| entry = bfd_get_start_address (loadfile_bfd);
|
| + entry = gdbarch_addr_bits_remove (target_gdbarch (), entry);
|
| ui_out_text (uiout, "Start address ");
|
| - ui_out_field_fmt (uiout, "address", "%s", paddress (target_gdbarch, entry));
|
| + ui_out_field_fmt (uiout, "address", "%s", paddress (target_gdbarch (), entry));
|
| ui_out_text (uiout, ", load size ");
|
| ui_out_field_fmt (uiout, "load-size", "%lu", total_progress.data_count);
|
| ui_out_text (uiout, "\n");
|
| @@ -2175,24 +2134,6 @@ generic_load (char *args, int from_tty)
|
|
|
| /* Report how fast the transfer went. */
|
|
|
| -/* DEPRECATED: cagney/1999-10-18: report_transfer_performance is being
|
| - replaced by print_transfer_performance (with a very different
|
| - function signature). */
|
| -
|
| -void
|
| -report_transfer_performance (unsigned long data_count, time_t start_time,
|
| - time_t end_time)
|
| -{
|
| - struct timeval start, end;
|
| -
|
| - start.tv_sec = start_time;
|
| - start.tv_usec = 0;
|
| - end.tv_sec = end_time;
|
| - end.tv_usec = 0;
|
| -
|
| - print_transfer_performance (gdb_stdout, data_count, 0, &start, &end);
|
| -}
|
| -
|
| void
|
| print_transfer_performance (struct ui_file *stream,
|
| unsigned long data_count,
|
| @@ -2266,6 +2207,7 @@ add_symbol_file_command (char *args, int from_tty)
|
| int expecting_sec_name = 0;
|
| int expecting_sec_addr = 0;
|
| char **argv;
|
| + struct objfile *objf;
|
|
|
| struct sect_opt
|
| {
|
| @@ -2299,63 +2241,54 @@ add_symbol_file_command (char *args, int from_tty)
|
| filename = tilde_expand (arg);
|
| make_cleanup (xfree, filename);
|
| }
|
| + else if (argcnt == 1)
|
| + {
|
| + /* The second argument is always the text address at which
|
| + to load the program. */
|
| + sect_opts[section_index].name = ".text";
|
| + sect_opts[section_index].value = arg;
|
| + if (++section_index >= num_sect_opts)
|
| + {
|
| + num_sect_opts *= 2;
|
| + sect_opts = ((struct sect_opt *)
|
| + xrealloc (sect_opts,
|
| + num_sect_opts
|
| + * sizeof (struct sect_opt)));
|
| + }
|
| + }
|
| else
|
| - if (argcnt == 1)
|
| - {
|
| - /* The second argument is always the text address at which
|
| - to load the program. */
|
| - sect_opts[section_index].name = ".text";
|
| - sect_opts[section_index].value = arg;
|
| - if (++section_index >= num_sect_opts)
|
| - {
|
| - num_sect_opts *= 2;
|
| - sect_opts = ((struct sect_opt *)
|
| - xrealloc (sect_opts,
|
| - num_sect_opts
|
| - * sizeof (struct sect_opt)));
|
| - }
|
| - }
|
| - else
|
| - {
|
| - /* It's an option (starting with '-') or it's an argument
|
| - to an option. */
|
| -
|
| - if (*arg == '-')
|
| - {
|
| - if (strcmp (arg, "-readnow") == 0)
|
| - flags |= OBJF_READNOW;
|
| - else if (strcmp (arg, "-s") == 0)
|
| - {
|
| - expecting_sec_name = 1;
|
| - expecting_sec_addr = 1;
|
| - }
|
| - }
|
| - else
|
| - {
|
| - if (expecting_sec_name)
|
| - {
|
| - sect_opts[section_index].name = arg;
|
| - expecting_sec_name = 0;
|
| - }
|
| - else
|
| - if (expecting_sec_addr)
|
| - {
|
| - sect_opts[section_index].value = arg;
|
| - expecting_sec_addr = 0;
|
| - if (++section_index >= num_sect_opts)
|
| - {
|
| - num_sect_opts *= 2;
|
| - sect_opts = ((struct sect_opt *)
|
| - xrealloc (sect_opts,
|
| - num_sect_opts
|
| - * sizeof (struct sect_opt)));
|
| - }
|
| - }
|
| - else
|
| - error (_("USAGE: add-symbol-file <filename> <textaddress>"
|
| - " [-readnow] [-s <secname> <addr>]*"));
|
| - }
|
| - }
|
| + {
|
| + /* It's an option (starting with '-') or it's an argument
|
| + to an option. */
|
| + if (expecting_sec_name)
|
| + {
|
| + sect_opts[section_index].name = arg;
|
| + expecting_sec_name = 0;
|
| + }
|
| + else if (expecting_sec_addr)
|
| + {
|
| + sect_opts[section_index].value = arg;
|
| + expecting_sec_addr = 0;
|
| + if (++section_index >= num_sect_opts)
|
| + {
|
| + num_sect_opts *= 2;
|
| + sect_opts = ((struct sect_opt *)
|
| + xrealloc (sect_opts,
|
| + num_sect_opts
|
| + * sizeof (struct sect_opt)));
|
| + }
|
| + }
|
| + else if (strcmp (arg, "-readnow") == 0)
|
| + flags |= OBJF_READNOW;
|
| + else if (strcmp (arg, "-s") == 0)
|
| + {
|
| + expecting_sec_name = 1;
|
| + expecting_sec_addr = 1;
|
| + }
|
| + else
|
| + error (_("USAGE: add-symbol-file <filename> <textaddress>"
|
| + " [-readnow] [-s <secname> <addr>]*"));
|
| + }
|
| }
|
|
|
| /* This command takes at least two arguments. The first one is a
|
| @@ -2396,12 +2329,15 @@ add_symbol_file_command (char *args, int from_tty)
|
| 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."));
|
|
|
| - symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
|
| - section_addrs, flags);
|
| + objf = symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
|
| + section_addrs, flags);
|
| +
|
| + add_target_sections_of_objfile (objf);
|
|
|
| /* Getting new symbols may change our opinion about what is
|
| frameless. */
|
| @@ -2410,11 +2346,88 @@ add_symbol_file_command (char *args, int from_tty)
|
| }
|
|
|
|
|
| +/* This function removes a symbol file that was added via add-symbol-file. */
|
| +
|
| +static void
|
| +remove_symbol_file_command (char *args, int from_tty)
|
| +{
|
| + char **argv;
|
| + struct objfile *objf = NULL;
|
| + struct cleanup *my_cleanups;
|
| + struct program_space *pspace = current_program_space;
|
| + struct gdbarch *gdbarch = get_current_arch ();
|
| +
|
| + dont_repeat ();
|
| +
|
| + if (args == NULL)
|
| + error (_("remove-symbol-file: no symbol file provided"));
|
| +
|
| + my_cleanups = make_cleanup (null_cleanup, NULL);
|
| +
|
| + argv = gdb_buildargv (args);
|
| +
|
| + if (strcmp (argv[0], "-a") == 0)
|
| + {
|
| + /* Interpret the next argument as an address. */
|
| + CORE_ADDR addr;
|
| +
|
| + if (argv[1] == NULL)
|
| + error (_("Missing address argument"));
|
| +
|
| + if (argv[2] != NULL)
|
| + error (_("Junk after %s"), argv[1]);
|
| +
|
| + addr = parse_and_eval_address (argv[1]);
|
| +
|
| + ALL_OBJFILES (objf)
|
| + {
|
| + if (objf != 0
|
| + && objf->flags & OBJF_USERLOADED
|
| + && objf->pspace == pspace && is_addr_in_objfile (addr, objf))
|
| + break;
|
| + }
|
| + }
|
| + else if (argv[0] != NULL)
|
| + {
|
| + /* Interpret the current argument as a file name. */
|
| + char *filename;
|
| +
|
| + if (argv[1] != NULL)
|
| + error (_("Junk after %s"), argv[0]);
|
| +
|
| + filename = tilde_expand (argv[0]);
|
| + make_cleanup (xfree, filename);
|
| +
|
| + ALL_OBJFILES (objf)
|
| + {
|
| + if (objf != 0
|
| + && objf->flags & OBJF_USERLOADED
|
| + && objf->pspace == pspace
|
| + && filename_cmp (filename, objfile_name (objf)) == 0)
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (objf == NULL)
|
| + error (_("No symbol file found"));
|
| +
|
| + if (from_tty
|
| + && !query (_("Remove symbol table from file \"%s\"? "),
|
| + objfile_name (objf)))
|
| + error (_("Not confirmed."));
|
| +
|
| + free_objfile (objf);
|
| + clear_symtab_users (0);
|
| +
|
| + do_cleanups (my_cleanups);
|
| +}
|
| +
|
| typedef struct objfile *objfilep;
|
|
|
| DEF_VEC_P (objfilep);
|
|
|
| /* Re-read symbols if a symbol-file has changed. */
|
| +
|
| void
|
| reread_symbols (void)
|
| {
|
| @@ -2435,7 +2448,6 @@ reread_symbols (void)
|
|
|
| for (objfile = object_files; objfile; objfile = objfile->next)
|
| {
|
| - /* solib-sunos.c creates one objfile with obfd. */
|
| if (objfile->obfd == NULL)
|
| continue;
|
|
|
| @@ -2450,12 +2462,12 @@ reread_symbols (void)
|
| if (objfile->obfd->my_archive)
|
| res = stat (objfile->obfd->my_archive->filename, &new_statbuf);
|
| else
|
| - res = stat (objfile->name, &new_statbuf);
|
| + res = stat (objfile_name (objfile), &new_statbuf);
|
| if (res != 0)
|
| {
|
| /* FIXME, should use print_sys_errmsg but it's not filtered. */
|
| printf_unfiltered (_("`%s' has disappeared; keeping its symbols.\n"),
|
| - objfile->name);
|
| + objfile_name (objfile));
|
| continue;
|
| }
|
| new_modtime = new_statbuf.st_mtime;
|
| @@ -2464,10 +2476,10 @@ reread_symbols (void)
|
| struct cleanup *old_cleanups;
|
| struct section_offsets *offsets;
|
| int num_offsets;
|
| - char *obfd_filename;
|
| + char *original_name;
|
|
|
| printf_unfiltered (_("`%s' has changed; re-reading symbols.\n"),
|
| - objfile->name);
|
| + objfile_name (objfile));
|
|
|
| /* There are various functions like symbol_file_add,
|
| symfile_bfd_open, syms_from_objfile, etc., which might
|
| @@ -2515,21 +2527,32 @@ reread_symbols (void)
|
|
|
| clear_objfile_data (objfile);
|
|
|
| - /* Clean up any state BFD has sitting around. We don't need
|
| - to close the descriptor but BFD lacks a way of closing the
|
| - BFD without closing the descriptor. */
|
| - obfd_filename = bfd_get_filename (objfile->obfd);
|
| - if (!bfd_close (objfile->obfd))
|
| - error (_("Can't close BFD for %s: %s"), objfile->name,
|
| - bfd_errmsg (bfd_get_error ()));
|
| - objfile->obfd = bfd_open_maybe_remote (obfd_filename);
|
| - if (objfile->obfd == NULL)
|
| - error (_("Can't open %s to read symbols."), objfile->name);
|
| - else
|
| - objfile->obfd = gdb_bfd_ref (objfile->obfd);
|
| + /* Clean up any state BFD has sitting around. */
|
| + {
|
| + struct bfd *obfd = objfile->obfd;
|
| + char *obfd_filename;
|
| +
|
| + obfd_filename = bfd_get_filename (objfile->obfd);
|
| + /* Open the new BFD before freeing the old one, so that
|
| + the filename remains live. */
|
| + objfile->obfd = gdb_bfd_open_maybe_remote (obfd_filename);
|
| + if (objfile->obfd == NULL)
|
| + {
|
| + /* We have to make a cleanup and error here, rather
|
| + than erroring later, because once we unref OBFD,
|
| + OBFD_FILENAME will be freed. */
|
| + make_cleanup_bfd_unref (obfd);
|
| + error (_("Can't open %s to read symbols."), obfd_filename);
|
| + }
|
| + gdb_bfd_unref (obfd);
|
| + }
|
| +
|
| + original_name = xstrdup (objfile->original_name);
|
| + make_cleanup (xfree, original_name);
|
| +
|
| /* bfd_openr sets cacheable to true, which is what we want. */
|
| if (!bfd_check_format (objfile->obfd, bfd_object))
|
| - error (_("Can't read symbols from %s: %s."), objfile->name,
|
| + error (_("Can't read symbols from %s: %s."), objfile_name (objfile),
|
| bfd_errmsg (bfd_get_error ()));
|
|
|
| /* Save the offsets, we will nuke them with the rest of the
|
| @@ -2554,15 +2577,6 @@ reread_symbols (void)
|
| /* Free the obstacks for non-reusable objfiles. */
|
| psymbol_bcache_free (objfile->psymbol_cache);
|
| objfile->psymbol_cache = psymbol_bcache_init ();
|
| - bcache_xfree (objfile->macro_cache);
|
| - objfile->macro_cache = bcache_xmalloc (NULL, NULL);
|
| - bcache_xfree (objfile->filename_cache);
|
| - objfile->filename_cache = bcache_xmalloc (NULL,NULL);
|
| - if (objfile->demangled_names_hash != NULL)
|
| - {
|
| - htab_delete (objfile->demangled_names_hash);
|
| - objfile->demangled_names_hash = NULL;
|
| - }
|
| obstack_free (&objfile->objfile_obstack, 0);
|
| objfile->sections = NULL;
|
| objfile->symtabs = NULL;
|
| @@ -2571,7 +2585,6 @@ reread_symbols (void)
|
| objfile->free_psymtabs = NULL;
|
| objfile->template_symbols = NULL;
|
| objfile->msymbols = NULL;
|
| - objfile->deprecated_sym_private = NULL;
|
| objfile->minimal_symbol_count = 0;
|
| memset (&objfile->msymbol_hash, 0,
|
| sizeof (objfile->msymbol_hash));
|
| @@ -2582,6 +2595,22 @@ reread_symbols (void)
|
| empty. We could use obstack_specify_allocation but
|
| gdb_obstack.h specifies the alloc/dealloc functions. */
|
| obstack_init (&objfile->objfile_obstack);
|
| +
|
| + /* set_objfile_per_bfd potentially allocates the per-bfd
|
| + data on the objfile's obstack (if sharing data across
|
| + multiple users is not possible), so it's important to
|
| + do it *after* the obstack has been initialized. */
|
| + set_objfile_per_bfd (objfile);
|
| +
|
| + objfile->original_name = obstack_copy0 (&objfile->objfile_obstack,
|
| + original_name,
|
| + strlen (original_name));
|
| +
|
| + /* Reset the sym_fns pointer. The ELF reader can change it
|
| + based on whether .gdb_index is present, and we need it to
|
| + start over. PR symtab/15885 */
|
| + objfile_set_sym_fns (objfile, find_sym_fns (objfile->obfd));
|
| +
|
| build_objfile_section_table (objfile);
|
| terminate_minimal_symbol_table (objfile);
|
|
|
| @@ -2604,14 +2633,9 @@ reread_symbols (void)
|
|
|
| (*objfile->sf->sym_init) (objfile);
|
| clear_complaints (&symfile_complaints, 1, 1);
|
| - /* Do not set flags as this is safe and we don't want to be
|
| - verbose. */
|
| - (*objfile->sf->sym_read) (objfile, 0);
|
| - if ((objfile->flags & OBJF_PSYMTABS_READ) != 0)
|
| - {
|
| - objfile->flags &= ~OBJF_PSYMTABS_READ;
|
| - require_partial_symbols (objfile, 0);
|
| - }
|
| +
|
| + objfile->flags &= ~OBJF_PSYMTABS_READ;
|
| + read_symbols (objfile, 0);
|
|
|
| if (!objfile_has_symbols (objfile))
|
| {
|
| @@ -2665,7 +2689,6 @@ reread_symbols (void)
|
| }
|
|
|
|
|
| -
|
| typedef struct
|
| {
|
| char *ext;
|
| @@ -2727,8 +2750,7 @@ set_ext_lang_command (char *args, int from_tty, struct cmd_list_element *e)
|
| *cp++ = '\0';
|
|
|
| /* Find beginning of second arg, which should be a source language. */
|
| - while (*cp && isspace (*cp))
|
| - cp++;
|
| + cp = skip_spaces (cp);
|
|
|
| if (*cp == '\0')
|
| error (_("'%s': two arguments required -- "
|
| @@ -2861,8 +2883,8 @@ allocate_symtab (const char *filename, struct objfile *objfile)
|
| symtab = (struct symtab *)
|
| obstack_alloc (&objfile->objfile_obstack, sizeof (struct symtab));
|
| memset (symtab, 0, sizeof (*symtab));
|
| - symtab->filename = (char *) bcache (filename, strlen (filename) + 1,
|
| - objfile->filename_cache);
|
| + symtab->filename = bcache (filename, strlen (filename) + 1,
|
| + objfile->per_bfd->filename_cache);
|
| symtab->fullname = NULL;
|
| symtab->language = deduce_language_from_filename (filename);
|
| symtab->debugformat = "unknown";
|
| @@ -2873,17 +2895,19 @@ allocate_symtab (const char *filename, struct objfile *objfile)
|
| symtab->next = objfile->symtabs;
|
| objfile->symtabs = symtab;
|
|
|
| - if (symtab_create_debug)
|
| + /* This can be very verbose with lots of headers.
|
| + Only print at higher debug levels. */
|
| + if (symtab_create_debug >= 2)
|
| {
|
| /* Be a bit clever with debugging messages, and don't print objfile
|
| every time, only when it changes. */
|
| static char *last_objfile_name = NULL;
|
|
|
| if (last_objfile_name == NULL
|
| - || strcmp (last_objfile_name, objfile->name) != 0)
|
| + || strcmp (last_objfile_name, objfile_name (objfile)) != 0)
|
| {
|
| xfree (last_objfile_name);
|
| - last_objfile_name = xstrdup (objfile->name);
|
| + last_objfile_name = xstrdup (objfile_name (objfile));
|
| fprintf_unfiltered (gdb_stdlog,
|
| "Creating one or more symtabs for objfile %s ...\n",
|
| last_objfile_name);
|
| @@ -3103,9 +3127,9 @@ pc_in_mapped_range (CORE_ADDR pc, struct obj_section *section)
|
| return 0;
|
| }
|
|
|
| -
|
| /* Return true if the mapped ranges of sections A and B overlap, false
|
| otherwise. */
|
| +
|
| static int
|
| sections_overlap (struct obj_section *a, struct obj_section *b)
|
| {
|
| @@ -3155,7 +3179,6 @@ overlay_mapped_address (CORE_ADDR pc, struct obj_section *section)
|
| return pc;
|
| }
|
|
|
| -
|
| /* Function: symbol_overlayed_address
|
| Return one of two addresses (relative to the VMA or to the LMA),
|
| depending on whether the section is mapped or not. */
|
| @@ -3234,7 +3257,7 @@ find_pc_mapped_section (CORE_ADDR pc)
|
| /* Function: list_overlays_command
|
| Print a list of mapped sections and their PC ranges. */
|
|
|
| -void
|
| +static void
|
| list_overlays_command (char *args, int from_tty)
|
| {
|
| int nmapped = 0;
|
| @@ -3274,7 +3297,7 @@ list_overlays_command (char *args, int from_tty)
|
| /* Function: map_overlay_command
|
| Mark the named section as mapped (ie. residing at its VMA address). */
|
|
|
| -void
|
| +static void
|
| map_overlay_command (char *args, int from_tty)
|
| {
|
| struct objfile *objfile, *objfile2;
|
| @@ -3319,7 +3342,7 @@ map_overlay_command (char *args, int from_tty)
|
| Mark the overlay section as unmapped
|
| (ie. resident in its LMA address range, rather than the VMA range). */
|
|
|
| -void
|
| +static void
|
| unmap_overlay_command (char *args, int from_tty)
|
| {
|
| struct objfile *objfile;
|
| @@ -3399,7 +3422,7 @@ overlay_load_command (char *args, int from_tty)
|
| A place-holder for a mis-typed command. */
|
|
|
| /* Command list chain containing all defined "overlay" subcommands. */
|
| -struct cmd_list_element *overlaylist;
|
| +static struct cmd_list_element *overlaylist;
|
|
|
| static void
|
| overlay_command (char *args, int from_tty)
|
| @@ -3409,7 +3432,6 @@ overlay_command (char *args, int from_tty)
|
| help_list (overlaylist, "overlay ", -1, gdb_stdout);
|
| }
|
|
|
| -
|
| /* Target Overlays for the "Simplest" overlay manager:
|
|
|
| This is GDB's default target overlay layer. It works with the
|
| @@ -3453,6 +3475,7 @@ enum ovly_index
|
| };
|
|
|
| /* Throw away the cached copy of _ovly_table. */
|
| +
|
| static void
|
| simple_free_overlay_table (void)
|
| {
|
| @@ -3465,6 +3488,7 @@ simple_free_overlay_table (void)
|
|
|
| /* Read an array of ints of size SIZE from the target into a local buffer.
|
| Convert to host order. int LEN is number of ints. */
|
| +
|
| static void
|
| read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr,
|
| int len, int size, enum bfd_endian byte_order)
|
| @@ -3480,10 +3504,12 @@ read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr,
|
|
|
| /* Find and grab a copy of the target _ovly_table
|
| (and _novlys, which is needed for the table's size). */
|
| +
|
| static int
|
| simple_read_overlay_table (void)
|
| {
|
| - struct minimal_symbol *novlys_msym, *ovly_table_msym;
|
| + struct minimal_symbol *novlys_msym;
|
| + struct bound_minimal_symbol ovly_table_msym;
|
| struct gdbarch *gdbarch;
|
| int word_size;
|
| enum bfd_endian byte_order;
|
| @@ -3498,8 +3524,8 @@ simple_read_overlay_table (void)
|
| return 0;
|
| }
|
|
|
| - ovly_table_msym = lookup_minimal_symbol ("_ovly_table", NULL, NULL);
|
| - if (! ovly_table_msym)
|
| + ovly_table_msym = lookup_bound_minimal_symbol ("_ovly_table");
|
| + if (! ovly_table_msym.minsym)
|
| {
|
| error (_("Error reading inferior's overlay table: couldn't find "
|
| "`_ovly_table' array\n"
|
| @@ -3507,7 +3533,7 @@ simple_read_overlay_table (void)
|
| return 0;
|
| }
|
|
|
| - gdbarch = get_objfile_arch (msymbol_objfile (ovly_table_msym));
|
| + gdbarch = get_objfile_arch (ovly_table_msym.objfile);
|
| word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
|
| byte_order = gdbarch_byte_order (gdbarch);
|
|
|
| @@ -3515,7 +3541,7 @@ simple_read_overlay_table (void)
|
| 4, byte_order);
|
| cache_ovly_table
|
| = (void *) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
|
| - cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (ovly_table_msym);
|
| + cache_ovly_table_base = SYMBOL_VALUE_ADDRESS (ovly_table_msym.minsym);
|
| read_target_long_array (cache_ovly_table_base,
|
| (unsigned int *) cache_ovly_table,
|
| cache_novlys * 4, word_size, byte_order);
|
| @@ -3640,7 +3666,6 @@ symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy)
|
|
|
| /* Default implementation for sym_relocate. */
|
|
|
| -
|
| bfd_byte *
|
| default_symfile_relocate (struct objfile *objfile, asection *sectp,
|
| bfd_byte *buf)
|
| @@ -3704,7 +3729,6 @@ free_symfile_segment_data (struct symfile_segment_data *data)
|
| xfree (data);
|
| }
|
|
|
| -
|
| /* Given:
|
| - DATA, containing segment addresses from the object file ABFD, and
|
| the mapping from ABFD's sections onto the segments that own them,
|
| @@ -3719,8 +3743,10 @@ free_symfile_segment_data (struct symfile_segment_data *data)
|
| If there are more entries, then ignore the extra. The target may
|
| not be able to distinguish between an empty data segment and a
|
| missing data segment; a missing text segment is less plausible. */
|
| +
|
| int
|
| -symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data,
|
| +symfile_map_offsets_to_segments (bfd *abfd,
|
| + const struct symfile_segment_data *data,
|
| struct section_offsets *offsets,
|
| int num_segment_bases,
|
| const CORE_ADDR *segment_bases)
|
| @@ -3803,11 +3829,23 @@ symfile_find_segment_sections (struct objfile *objfile)
|
| free_symfile_segment_data (data);
|
| }
|
|
|
| +/* Listen for free_objfile events. */
|
| +
|
| +static void
|
| +symfile_free_objfile (struct objfile *objfile)
|
| +{
|
| + /* Remove the target sections of user-added objfiles. */
|
| + if (objfile != 0 && objfile->flags & OBJF_USERLOADED)
|
| + remove_target_sections ((void *) objfile);
|
| +}
|
| +
|
| void
|
| _initialize_symfile (void)
|
| {
|
| struct cmd_list_element *c;
|
|
|
| + observer_attach_free_objfile (symfile_free_objfile);
|
| +
|
| c = add_cmd ("symbol-file", class_files, symbol_file_command, _("\
|
| Load symbol table from executable file FILE.\n\
|
| The `file' command can also load symbol tables, as well as setting the file\n\
|
| @@ -3824,6 +3862,15 @@ with the text. SECT is a section name to be loaded at SECT_ADDR."),
|
| &cmdlist);
|
| set_cmd_completer (c, filename_completer);
|
|
|
| + c = add_cmd ("remove-symbol-file", class_files,
|
| + remove_symbol_file_command, _("\
|
| +Remove a symbol file added via the add-symbol-file command.\n\
|
| +Usage: remove-symbol-file FILENAME\n\
|
| + remove-symbol-file -a ADDRESS\n\
|
| +The file to remove can be identified by its filename or by an address\n\
|
| +that lies within the boundaries of this symbol file in memory."),
|
| + &cmdlist);
|
| +
|
| c = add_cmd ("load", class_files, load_command, _("\
|
| Dynamically load FILE into the running program, and record its symbols\n\
|
| for access from GDB.\n\
|
|
|