summaryrefslogtreecommitdiffstats
path: root/contrib/gdb/gdb/symfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/gdb/gdb/symfile.c')
-rw-r--r--contrib/gdb/gdb/symfile.c1133
1 files changed, 702 insertions, 431 deletions
diff --git a/contrib/gdb/gdb/symfile.c b/contrib/gdb/gdb/symfile.c
index c3c18bf..19ae294 100644
--- a/contrib/gdb/gdb/symfile.c
+++ b/contrib/gdb/gdb/symfile.c
@@ -1,7 +1,7 @@
/* Generic symbol file reading for the GNU debugger, GDB.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
@@ -23,6 +23,7 @@
Boston, MA 02111-1307, USA. */
#include "defs.h"
+#include "bfdlink.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "gdbcore.h"
@@ -31,15 +32,22 @@
#include "value.h"
#include "symfile.h"
#include "objfiles.h"
+#include "source.h"
#include "gdbcmd.h"
#include "breakpoint.h"
#include "language.h"
#include "complaints.h"
#include "demangle.h"
#include "inferior.h" /* for write_pc */
+#include "filenames.h" /* for DOSish file names */
#include "gdb-stabs.h"
-#include "obstack.h"
+#include "gdb_obstack.h"
#include "completer.h"
+#include "bcache.h"
+#include "hashtab.h"
+#include "readline/readline.h"
+#include "gdb_assert.h"
+#include "block.h"
#include <sys/types.h>
#include <fcntl.h>
@@ -80,21 +88,6 @@ static void clear_symtab_users_cleanup (void *ignore);
/* Global variables owned by this file */
int readnow_symbol_files; /* Read full symbols immediately */
-struct complaint oldsyms_complaint =
-{
- "Replacing old symbols for `%s'", 0, 0
-};
-
-struct complaint empty_symtab_complaint =
-{
- "Empty symbol table found for `%s'", 0, 0
-};
-
-struct complaint unknown_option_complaint =
-{
- "Unknown option `%s' ignored", 0, 0
-};
-
/* External variables and functions referenced. */
extern void report_transfer_performance (unsigned long, time_t, time_t);
@@ -116,6 +109,8 @@ static void add_symbol_file_command (char *, int);
static void add_shared_symbol_files_command (char *, int);
+static void reread_separate_symbols (struct objfile *objfile);
+
static void cashier_psymtab (struct partial_symtab *);
bfd *symfile_bfd_open (char *);
@@ -160,6 +155,8 @@ static void set_ext_lang_command (char *args, int from_tty);
static void info_ext_lang_command (char *args, int from_tty);
+static char *find_separate_debug_file (struct objfile *objfile);
+
static void init_filename_language_table (void);
void _initialize_symfile (void);
@@ -202,66 +199,17 @@ int auto_solib_add = 1;
int auto_solib_limit;
-/* Since this function is called from within qsort, in an ANSI environment
- it must conform to the prototype for qsort, which specifies that the
- comparison function takes two "void *" pointers. */
-
-static int
-compare_symbols (const void *s1p, const void *s2p)
-{
- register struct symbol **s1, **s2;
-
- s1 = (struct symbol **) s1p;
- s2 = (struct symbol **) s2p;
- return (strcmp (SYMBOL_SOURCE_NAME (*s1), SYMBOL_SOURCE_NAME (*s2)));
-}
-
-/*
-
- LOCAL FUNCTION
-
- compare_psymbols -- compare two partial symbols by name
-
- DESCRIPTION
-
- Given pointers to pointers to two partial symbol table entries,
- compare them by name and return -N, 0, or +N (ala strcmp).
- Typically used by sorting routines like qsort().
-
- NOTES
-
- Does direct compare of first two characters before punting
- and passing to strcmp for longer compares. Note that the
- original version had a bug whereby two null strings or two
- identically named one character strings would return the
- comparison of memory following the null byte.
-
- */
+/* This compares two partial symbols by names, using strcmp_iw_ordered
+ for the comparison. */
static int
compare_psymbols (const void *s1p, const void *s2p)
{
- register struct partial_symbol **s1, **s2;
- register char *st1, *st2;
-
- s1 = (struct partial_symbol **) s1p;
- s2 = (struct partial_symbol **) s2p;
- st1 = SYMBOL_SOURCE_NAME (*s1);
- st2 = SYMBOL_SOURCE_NAME (*s2);
-
+ struct partial_symbol *const *s1 = s1p;
+ struct partial_symbol *const *s2 = s2p;
- if ((st1[0] - st2[0]) || !st1[0])
- {
- return (st1[0] - st2[0]);
- }
- else if ((st1[1] - st2[1]) || !st1[1])
- {
- return (st1[1] - st2[1]);
- }
- else
- {
- return (strcmp (st1, st2));
- }
+ return strcmp_iw_ordered (SYMBOL_NATURAL_NAME (*s1),
+ SYMBOL_NATURAL_NAME (*s2));
}
void
@@ -274,54 +222,22 @@ sort_pst_symbols (struct partial_symtab *pst)
compare_psymbols);
}
-/* Call sort_block_syms to sort alphabetically the symbols of one block. */
-
-void
-sort_block_syms (register struct block *b)
-{
- qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
- sizeof (struct symbol *), compare_symbols);
-}
-
-/* Call sort_symtab_syms to sort alphabetically
- the symbols of each block of one symtab. */
-
-void
-sort_symtab_syms (register struct symtab *s)
-{
- register struct blockvector *bv;
- int nbl;
- int i;
- register struct block *b;
-
- if (s == 0)
- return;
- bv = BLOCKVECTOR (s);
- nbl = BLOCKVECTOR_NBLOCKS (bv);
- for (i = 0; i < nbl; i++)
- {
- b = BLOCKVECTOR_BLOCK (bv, i);
- if (BLOCK_SHOULD_SORT (b))
- sort_block_syms (b);
- }
-}
-
/* 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 (char *ptr, int size, struct obstack *obstackp)
+obsavestring (const char *ptr, int size, struct obstack *obstackp)
{
- register char *p = (char *) obstack_alloc (obstackp, size + 1);
+ 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? */
{
- register char *p1 = ptr;
- register char *p2 = p;
- char *end = ptr + size;
+ const char *p1 = ptr;
+ char *p2 = p;
+ const char *end = ptr + size;
while (p1 != end)
*p2++ = *p1++;
}
@@ -336,8 +252,8 @@ char *
obconcat (struct obstack *obstackp, const char *s1, const char *s2,
const char *s3)
{
- register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
- register char *val = (char *) obstack_alloc (obstackp, len);
+ int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
+ char *val = (char *) obstack_alloc (obstackp, len);
strcpy (val, s1);
strcat (val, s2);
strcat (val, s3);
@@ -360,7 +276,7 @@ decrement_reading_symtab (void *dummy)
case inline. */
struct symtab *
-psymtab_to_symtab (register struct partial_symtab *pst)
+psymtab_to_symtab (struct partial_symtab *pst)
{
/* If it's been looked up before, return it. */
if (pst->symtab)
@@ -378,41 +294,6 @@ psymtab_to_symtab (register struct partial_symtab *pst)
return pst->symtab;
}
-/* Initialize entry point information for this objfile. */
-
-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);
- }
- else
- {
- /* Examination of non-executable.o files. Short-circuit this stuff. */
- objfile->ei.entry_point = INVALID_ENTRY_POINT;
- }
- objfile->ei.entry_file_lowpc = INVALID_ENTRY_LOWPC;
- objfile->ei.entry_file_highpc = INVALID_ENTRY_HIGHPC;
- objfile->ei.entry_func_lowpc = INVALID_ENTRY_LOWPC;
- objfile->ei.entry_func_highpc = INVALID_ENTRY_HIGHPC;
- objfile->ei.main_func_lowpc = INVALID_ENTRY_LOWPC;
- objfile->ei.main_func_highpc = INVALID_ENTRY_HIGHPC;
-}
-
-/* Get current entry point address. */
-
-CORE_ADDR
-entry_point_address (void)
-{
- return symfile_objfile ? symfile_objfile->ei.entry_point : 0;
-}
-
/* Remember the lowest-addressed loadable section we've seen.
This function is called via bfd_map_over_sections.
@@ -423,7 +304,7 @@ entry_point_address (void)
lowest-addressed loadable section. */
void
-find_lowest_section (bfd *abfd, asection *sect, PTR obj)
+find_lowest_section (bfd *abfd, asection *sect, void *obj)
{
asection **lowest = (asection **) obj;
@@ -439,6 +320,22 @@ find_lowest_section (bfd *abfd, asection *sect, PTR obj)
*lowest = sect;
}
+/* Create a new section_addr_info, with room for NUM_SECTIONS. */
+
+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);
+ sap->num_sections = num_sections;
+
+ return sap;
+}
/* Build (allocate and populate) a section_addr_info struct from
an existing section table. */
@@ -451,14 +348,13 @@ build_section_addr_info_from_section_table (const struct section_table *start,
const struct section_table *stp;
int oidx;
- sap = xmalloc (sizeof (struct section_addr_info));
- memset (sap, 0, sizeof (struct section_addr_info));
+ sap = alloc_section_addr_info (end - start);
for (stp = start, oidx = 0; stp != end; stp++)
{
if (bfd_get_section_flags (stp->bfd,
stp->the_bfd_section) & (SEC_ALLOC | SEC_LOAD)
- && oidx < MAX_SECTIONS)
+ && oidx < end - start)
{
sap->other[oidx].addr = stp->addr;
sap->other[oidx].name
@@ -479,50 +375,20 @@ free_section_addr_info (struct section_addr_info *sap)
{
int idx;
- for (idx = 0; idx < MAX_SECTIONS; idx++)
+ for (idx = 0; idx < sap->num_sections; idx++)
if (sap->other[idx].name)
xfree (sap->other[idx].name);
xfree (sap);
}
-/* Parse the user's idea of an offset for dynamic linking, into our idea
- of how to represent it for fast symbol reading. This is the default
- version of the sym_fns.sym_offsets function for symbol readers that
- don't need to do anything special. It allocates a section_offsets table
- for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */
-
-void
-default_symfile_offsets (struct objfile *objfile,
- struct section_addr_info *addrs)
+/* Initialize OBJFILE's sect_index_* members. */
+static void
+init_objfile_sect_indices (struct objfile *objfile)
{
+ asection *sect;
int i;
- asection *sect = NULL;
-
- objfile->num_sections = SECT_OFF_MAX;
- objfile->section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
- memset (objfile->section_offsets, 0, SIZEOF_SECTION_OFFSETS);
-
- /* Now calculate offsets for section that were specified by the
- caller. */
- for (i = 0; i < MAX_SECTIONS && addrs->other[i].name; i++)
- {
- struct other_sections *osp ;
-
- osp = &addrs->other[i] ;
- if (osp->addr == 0)
- continue;
-
- /* Record all sections in offsets */
- /* The section_offsets in the objfile are here filled in using
- the BFD index. */
- (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
- }
-
- /* Remember the bfd indexes for the .text, .data, .bss and
- .rodata sections. */
-
+
sect = bfd_get_section_by_name (objfile->obfd, ".text");
if (sect)
objfile->sect_index_text = sect->index;
@@ -569,13 +435,73 @@ default_symfile_offsets (struct objfile *objfile,
}
}
+
+/* Parse the user's idea of an offset for dynamic linking, into our idea
+ of how to represent it for fast symbol reading. This is the default
+ version of the sym_fns.sym_offsets function for symbol readers that
+ don't need to do anything special. It allocates a section_offsets table
+ for the objectfile OBJFILE and stuffs ADDR into all of the offsets. */
+
+void
+default_symfile_offsets (struct objfile *objfile,
+ struct section_addr_info *addrs)
+{
+ int i;
+
+ objfile->num_sections = bfd_count_sections (objfile->obfd);
+ objfile->section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile->objfile_obstack,
+ SIZEOF_N_SECTION_OFFSETS (objfile->num_sections));
+ memset (objfile->section_offsets, 0,
+ SIZEOF_N_SECTION_OFFSETS (objfile->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++)
+ {
+ struct other_sections *osp ;
+
+ osp = &addrs->other[i] ;
+ if (osp->addr == 0)
+ continue;
+
+ /* Record all sections in offsets */
+ /* The section_offsets in the objfile are here filled in using
+ the BFD index. */
+ (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
+ }
+
+ /* Remember the bfd indexes for the .text, .data, .bss and
+ .rodata sections. */
+ init_objfile_sect_indices (objfile);
+}
+
+
/* Process a symbol file, as either the main file or as a dynamically
loaded file.
OBJFILE is where the symbols are to be read from.
- ADDR is the address where the text segment was loaded, unless the
- objfile is the main symbol file, in which case it is zero.
+ ADDRS is the list of section load addresses. If the user has given
+ an 'add-symbol-file' command, then this is the list of offsets and
+ addresses he or she provided as arguments to the command; or, if
+ we're handling a shared library, these are the actual addresses the
+ sections are loaded at, according to the inferior's dynamic linker
+ (as gleaned by GDB's shared library code). We convert each address
+ 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.
MAINLINE is nonzero if this is the main symbol file, or zero if
it's an extra symbol file such as dynamically loaded code.
@@ -584,33 +510,41 @@ default_symfile_offsets (struct objfile *objfile,
the symbol reading (and complaints can be more terse about it). */
void
-syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
- int mainline, int verbo)
-{
- asection *lower_sect;
- asection *sect;
- CORE_ADDR lower_offset;
- struct section_addr_info local_addr;
+syms_from_objfile (struct objfile *objfile,
+ struct section_addr_info *addrs,
+ struct section_offsets *offsets,
+ int num_offsets,
+ int mainline,
+ int verbo)
+{
+ struct section_addr_info *local_addr = NULL;
struct cleanup *old_chain;
- int i;
- /* If ADDRS is NULL, initialize the local section_addr_info struct and
- point ADDRS to it. We now establish the convention that an addr of
- zero means no load address was specified. */
-
- if (addrs == NULL)
- {
- memset (&local_addr, 0, sizeof (local_addr));
- addrs = &local_addr;
- }
+ gdb_assert (! (addrs && offsets));
init_entry_point_info (objfile);
find_sym_fns (objfile);
+ if (objfile->sf == NULL)
+ return; /* No symbols. */
+
/* 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
+ no load address was specified. */
+ if (! addrs && ! offsets)
+ {
+ local_addr
+ = alloc_section_addr_info (bfd_count_sections (objfile->obfd));
+ 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
@@ -639,15 +573,20 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
We no longer warn if the lowest section is not a text segment (as
happens for the PA64 port. */
- if (!mainline)
+ if (!mainline && addrs && addrs->other[0].name)
{
+ asection *lower_sect;
+ asection *sect;
+ CORE_ADDR lower_offset;
+ int i;
+
/* Find lowest loadable section to be used as starting point for
continguous sections. FIXME!! won't work without call to find
.text first, but this assumes text is lowest section. */
lower_sect = bfd_get_section_by_name (objfile->obfd, ".text");
if (lower_sect == NULL)
bfd_map_over_sections (objfile->obfd, find_lowest_section,
- (PTR) &lower_sect);
+ &lower_sect);
if (lower_sect == NULL)
warning ("no loadable sections found in added symbol-file %s",
objfile->name);
@@ -662,39 +601,41 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
else
lower_offset = 0;
- /* Calculate offsets for the loadable sections.
+ /* Calculate offsets for the loadable sections.
FIXME! Sections must be in order of increasing loadable section
so that contiguous sections can use the lower-offset!!!
- Adjust offsets if the segments are not contiguous.
- If the section is contiguous, its offset should be set to
+ Adjust offsets if the segments are not contiguous.
+ If the section is contiguous, its offset should be set to
the offset of the highest loadable section lower than it
(the loadable section directly below it in memory).
this_offset = lower_offset = lower_addr - lower_orig_addr */
- /* Calculate offsets for sections. */
- for (i=0 ; i < MAX_SECTIONS && addrs->other[i].name; i++)
- {
- if (addrs->other[i].addr != 0)
- {
- sect = bfd_get_section_by_name (objfile->obfd, addrs->other[i].name);
- if (sect)
- {
- addrs->other[i].addr -= bfd_section_vma (objfile->obfd, sect);
- lower_offset = addrs->other[i].addr;
- /* This is the index used by BFD. */
- addrs->other[i].sectindex = sect->index ;
- }
- else
- {
- warning ("section %s not found in %s", addrs->other[i].name,
- objfile->name);
- addrs->other[i].addr = 0;
- }
- }
- else
- addrs->other[i].addr = lower_offset;
- }
+ for (i = 0; i < addrs->num_sections && addrs->other[i].name; i++)
+ {
+ if (addrs->other[i].addr != 0)
+ {
+ sect = bfd_get_section_by_name (objfile->obfd,
+ addrs->other[i].name);
+ if (sect)
+ {
+ addrs->other[i].addr
+ -= bfd_section_vma (objfile->obfd, sect);
+ lower_offset = addrs->other[i].addr;
+ /* This is the index used by BFD. */
+ addrs->other[i].sectindex = sect->index ;
+ }
+ else
+ {
+ warning ("section %s not found in %s",
+ addrs->other[i].name,
+ objfile->name);
+ addrs->other[i].addr = 0;
+ }
+ }
+ else
+ addrs->other[i].addr = lower_offset;
+ }
}
/* Initialize symbol reading routines for this objfile, allow complaints to
@@ -702,11 +643,25 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
initial symbol reading for this file. */
(*objfile->sf->sym_init) (objfile);
- clear_complaints (1, verbo);
+ clear_complaints (&symfile_complaints, 1, verbo);
+
+ if (addrs)
+ (*objfile->sf->sym_offsets) (objfile, addrs);
+ else
+ {
+ size_t size = SIZEOF_N_SECTION_OFFSETS (num_offsets);
- (*objfile->sf->sym_offsets) (objfile, addrs);
+ /* 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);
-#ifndef IBM6000_TARGET
+ init_objfile_sect_indices (objfile);
+ }
+
+#ifndef DEPRECATED_IBM6000_TARGET
/* This is a SVR4/SunOS specific hack, I think. In any event, it
screws RS/6000. sym_offsets should be doing this sort of thing,
because it knows the mapping between bfd sections and
@@ -740,7 +695,7 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
int i;
for (i = 0;
- !s_addr && i < MAX_SECTIONS && addrs->other[i].name;
+ !s_addr && i < addrs->num_sections && addrs->other[i].name;
i++)
if (strcmp (bfd_section_name (s->objfile->obfd,
s->the_bfd_section),
@@ -754,17 +709,10 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
s->offset += s_addr;
}
}
-#endif /* not IBM6000_TARGET */
+#endif /* not DEPRECATED_IBM6000_TARGET */
(*objfile->sf->sym_read) (objfile, mainline);
- if (!have_partial_symbols () && !have_full_symbols ())
- {
- wrap_here ("");
- printf_filtered ("(no debugging symbols found)...");
- wrap_here ("");
- }
-
/* Don't allow char * to have a typename (else would get caddr_t).
Ditto void *. FIXME: Check whether this is now done by all the
symbol readers themselves (many of them now do), and if so remove
@@ -781,13 +729,6 @@ syms_from_objfile (struct objfile *objfile, struct section_addr_info *addrs,
/* Discard cleanups as symbol reading was successful. */
discard_cleanups (old_chain);
-
- /* Call this after reading in a new symbol table to give target
- dependent code a crack at the new symbols. For instance, this
- could be used to update the values of target-specific symbols GDB
- needs to keep track of (such as _sigtramp, or whatever). */
-
- TARGET_SYMFILE_POSTREAD (objfile);
}
/* Perform required actions after either reading in the initial
@@ -814,7 +755,7 @@ new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
}
/* We're done reading the symbol file; finish off complaints. */
- clear_complaints (0, verbo);
+ clear_complaints (&symfile_complaints, 0, verbo);
}
/* Process a symbol file, as either the main file or as a dynamically
@@ -822,21 +763,31 @@ new_symfile_objfile (struct objfile *objfile, int mainline, int verbo)
NAME is the file name (which will be tilde-expanded and made
absolute herein) (but we don't free or modify NAME itself).
- FROM_TTY says how verbose to be. MAINLINE specifies whether this
- is the main symbol file, or whether it's an extra symbol file such
- as dynamically loaded code. If !mainline, ADDR is the address
- where the text segment was loaded.
+
+ FROM_TTY says how verbose to be.
+
+ MAINLINE specifies whether this is the main symbol file, or whether
+ it's an extra symbol file such as dynamically loaded code.
+
+ ADDRS, OFFSETS, and NUM_OFFSETS are as described for
+ syms_from_objfile, above. ADDRS is ignored when MAINLINE is
+ non-zero.
Upon success, returns a pointer to the objfile that was added.
Upon failure, jumps back to command level (never returns). */
-
-struct objfile *
-symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
- int mainline, int flags)
+static struct objfile *
+symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
+ struct section_addr_info *addrs,
+ struct section_offsets *offsets,
+ int num_offsets,
+ int mainline, int flags)
{
struct objfile *objfile;
struct partial_symtab *psymtab;
+ char *debugfile;
bfd *abfd;
+ struct section_addr_info *orig_addrs;
+ struct cleanup *my_cleanups;
/* Open a bfd for the file, and give user a chance to burp if we'd be
interactively wiping out any existing symbols. */
@@ -851,42 +802,32 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
objfile = allocate_objfile (abfd, flags);
- /* If the objfile uses a mapped symbol file, and we have a psymtab for
- it, then skip reading any symbols at this time. */
+ orig_addrs = alloc_section_addr_info (bfd_count_sections (abfd));
+ my_cleanups = make_cleanup (xfree, orig_addrs);
+ if (addrs)
+ {
+ int i;
+ orig_addrs->num_sections = addrs->num_sections;
+ for (i = 0; i < addrs->num_sections; i++)
+ orig_addrs->other[i] = addrs->other[i];
+ }
- if ((objfile->flags & OBJF_MAPPED) && (objfile->flags & OBJF_SYMS))
+ /* We either created a new mapped symbol table, mapped an existing
+ symbol table file which has not had initial symbol reading
+ performed, or need to read an unmapped symbol table. */
+ if (from_tty || info_verbose)
{
- /* We mapped in an existing symbol table file that already has had
- initial symbol reading performed, so we can skip that part. Notify
- the user that instead of reading the symbols, they have been mapped.
- */
- if (from_tty || info_verbose)
+ if (pre_add_symbol_hook)
+ pre_add_symbol_hook (name);
+ else
{
- printf_filtered ("Mapped symbols for %s...", name);
+ printf_unfiltered ("Reading symbols from %s...", name);
wrap_here ("");
gdb_flush (gdb_stdout);
}
- init_entry_point_info (objfile);
- find_sym_fns (objfile);
- }
- else
- {
- /* We either created a new mapped symbol table, mapped an existing
- symbol table file which has not had initial symbol reading
- performed, or need to read an unmapped symbol table. */
- if (from_tty || info_verbose)
- {
- if (pre_add_symbol_hook)
- pre_add_symbol_hook (name);
- else
- {
- printf_filtered ("Reading symbols from %s...", name);
- wrap_here ("");
- gdb_flush (gdb_stdout);
- }
- }
- syms_from_objfile (objfile, addrs, mainline, from_tty);
}
+ syms_from_objfile (objfile, addrs, offsets, num_offsets,
+ mainline, from_tty);
/* 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
@@ -897,7 +838,7 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
{
if (from_tty || info_verbose)
{
- printf_filtered ("expanding to full symbols...");
+ printf_unfiltered ("expanding to full symbols...");
wrap_here ("");
gdb_flush (gdb_stdout);
}
@@ -910,17 +851,56 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
}
}
+ debugfile = find_separate_debug_file (objfile);
+ if (debugfile)
+ {
+ if (addrs != NULL)
+ {
+ objfile->separate_debug_objfile
+ = symbol_file_add (debugfile, from_tty, orig_addrs, 0, flags);
+ }
+ else
+ {
+ objfile->separate_debug_objfile
+ = symbol_file_add (debugfile, from_tty, NULL, 0, flags);
+ }
+ objfile->separate_debug_objfile->separate_debug_objfile_backlink
+ = objfile;
+
+ /* Put the separate debug object before the normal one, this is so that
+ usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+ put_objfile_before (objfile->separate_debug_objfile, objfile);
+
+ xfree (debugfile);
+ }
+
+ if (!have_partial_symbols () && !have_full_symbols ())
+ {
+ wrap_here ("");
+ printf_unfiltered ("(no debugging symbols found)...");
+ wrap_here ("");
+ }
+
if (from_tty || info_verbose)
{
if (post_add_symbol_hook)
post_add_symbol_hook ();
else
{
- printf_filtered ("done.\n");
- gdb_flush (gdb_stdout);
+ printf_unfiltered ("done.\n");
}
}
+ /* We print some messages regardless of whether 'from_tty ||
+ info_verbose' is true, so make sure they go out at the right
+ time. */
+ gdb_flush (gdb_stdout);
+
+ do_cleanups (my_cleanups);
+
+ if (objfile->sf == NULL)
+ return objfile; /* No symbols. */
+
new_symfile_objfile (objfile, mainline, from_tty);
if (target_new_objfile_hook)
@@ -929,6 +909,19 @@ symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
return (objfile);
}
+
+/* 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. */
+struct objfile *
+symbol_file_add (char *name, int from_tty, struct section_addr_info *addrs,
+ int mainline, int flags)
+{
+ return symbol_file_add_with_addrs_or_offsets (name, from_tty, addrs, 0, 0,
+ mainline, flags);
+}
+
+
/* Call symbol_file_add() with default values and update whatever is
affected by the loading of a new main().
Used when the file is supplied in the gdb command line
@@ -985,6 +978,144 @@ symbol_file_clear (int from_tty)
#endif
}
+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;
+ unsigned char *p;
+
+ 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;
+}
+
+static int
+separate_debug_file_exists (const char *name, unsigned long crc)
+{
+ unsigned long file_crc = 0;
+ int fd;
+ char buffer[8*1024];
+ int count;
+
+ fd = open (name, O_RDONLY | O_BINARY);
+ if (fd < 0)
+ return 0;
+
+ while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+ file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
+
+ close (fd);
+
+ return crc == file_crc;
+}
+
+static char *debug_file_directory = NULL;
+
+#if ! defined (DEBUG_SUBDIRECTORY)
+#define DEBUG_SUBDIRECTORY ".debug"
+#endif
+
+static char *
+find_separate_debug_file (struct objfile *objfile)
+{
+ asection *sect;
+ char *basename;
+ char *dir;
+ char *debugfile;
+ char *name_copy;
+ bfd_size_type debuglink_size;
+ unsigned long crc32;
+ int i;
+
+ basename = get_debug_link_info (objfile, &crc32);
+
+ if (basename == NULL)
+ return NULL;
+
+ dir = xstrdup (objfile->name);
+
+ /* Strip off the final filename part, leaving the directory name,
+ followed by a slash. Objfile names should always be absolute and
+ tilde-expanded, so there should always be a slash in there
+ somewhere. */
+ for (i = strlen(dir) - 1; i >= 0; i--)
+ {
+ if (IS_DIR_SEPARATOR (dir[i]))
+ break;
+ }
+ gdb_assert (i >= 0 && IS_DIR_SEPARATOR (dir[i]));
+ dir[i+1] = '\0';
+
+ debugfile = alloca (strlen (debug_file_directory) + 1
+ + strlen (dir)
+ + strlen (DEBUG_SUBDIRECTORY)
+ + strlen ("/")
+ + strlen (basename)
+ + 1);
+
+ /* First try in the same directory as the original file. */
+ strcpy (debugfile, dir);
+ strcat (debugfile, basename);
+
+ if (separate_debug_file_exists (debugfile, crc32))
+ {
+ xfree (basename);
+ xfree (dir);
+ return xstrdup (debugfile);
+ }
+
+ /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */
+ strcpy (debugfile, dir);
+ strcat (debugfile, DEBUG_SUBDIRECTORY);
+ strcat (debugfile, "/");
+ strcat (debugfile, basename);
+
+ if (separate_debug_file_exists (debugfile, crc32))
+ {
+ xfree (basename);
+ xfree (dir);
+ return xstrdup (debugfile);
+ }
+
+ /* Then try in the global debugfile directory. */
+ strcpy (debugfile, debug_file_directory);
+ strcat (debugfile, "/");
+ strcat (debugfile, dir);
+ strcat (debugfile, basename);
+
+ if (separate_debug_file_exists (debugfile, crc32))
+ {
+ xfree (basename);
+ xfree (dir);
+ return xstrdup (debugfile);
+ }
+
+ xfree (basename);
+ xfree (dir);
+ return NULL;
+}
+
+
/* 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--(1) buildargv implements various
@@ -1022,20 +1153,16 @@ symbol_file_command (char *args, int from_tty)
cleanups = make_cleanup_freeargv (argv);
while (*argv != NULL)
{
- if (STREQ (*argv, "-mapped"))
- flags |= OBJF_MAPPED;
- else
- if (STREQ (*argv, "-readnow"))
- flags |= OBJF_READNOW;
- else
- if (**argv == '-')
- error ("unknown option `%s'", *argv);
- else
- {
- name = *argv;
-
- symbol_file_add_main_1 (name, from_tty, flags);
- }
+ if (strcmp (*argv, "-readnow") == 0)
+ flags |= OBJF_READNOW;
+ else if (**argv == '-')
+ error ("unknown option `%s'", *argv);
+ else
+ {
+ name = *argv;
+
+ symbol_file_add_main_1 (name, from_tty, flags);
+ }
argv++;
}
@@ -1124,7 +1251,7 @@ symfile_bfd_open (char *name)
error ("\"%s\": can't open to read symbols: %s.", name,
bfd_errmsg (bfd_get_error ()));
}
- sym_bfd->cacheable = 1;
+ bfd_set_cacheable (sym_bfd, 1);
if (!bfd_check_format (sym_bfd, bfd_object))
{
@@ -1176,9 +1303,10 @@ find_sym_fns (struct objfile *objfile)
enum bfd_flavour our_flavour = bfd_get_flavour (objfile->obfd);
char *our_target = bfd_get_target (objfile->obfd);
- /* Special kludge for apollo. See dstread.c. */
- if (STREQN (our_target, "apollo", 6))
- our_flavour = (enum bfd_flavour) -2;
+ if (our_flavour == bfd_target_srec_flavour
+ || our_flavour == bfd_target_ihex_flavour
+ || our_flavour == bfd_target_tekhex_flavour)
+ return; /* No symbols. */
for (sf = symtab_fns; sf != NULL; sf = sf->next)
{
@@ -1402,11 +1530,11 @@ generic_load (char *args, int from_tty)
for other targets too. */
write_pc (entry);
- /* FIXME: are we supposed to call symbol_file_add or not? According to
- a comment from remote-mips.c (where a call to symbol_file_add was
- commented out), making the call confuses GDB if more than one file is
- loaded in. remote-nindy.c had no call to symbol_file_add, but remote-vx.c
- does. */
+ /* FIXME: are we supposed to call symbol_file_add or not? According
+ to a comment from remote-mips.c (where a call to symbol_file_add
+ was commented out), making the call confuses GDB if more than one
+ file is loaded in. Some targets do (e.g., remote-vx.c) but
+ others don't (or didn't - perhaphs they have all been deleted). */
print_transfer_performance (gdb_stdout, cbdata.data_count,
cbdata.write_count, end_time - start_time);
@@ -1464,7 +1592,6 @@ print_transfer_performance (struct ui_file *stream,
instead a call to target_link() (in target.c) would supply the
value to use. We are now discontinuing this type of ad hoc syntax. */
-/* ARGSUSED */
static void
add_symbol_file_command (char *args, int from_tty)
{
@@ -1479,15 +1606,21 @@ add_symbol_file_command (char *args, int from_tty)
int expecting_sec_name = 0;
int expecting_sec_addr = 0;
- struct
+ struct sect_opt
{
char *name;
char *value;
- } sect_opts[SECT_OFF_MAX];
+ };
- struct section_addr_info section_addrs;
+ struct section_addr_info *section_addrs;
+ struct sect_opt *sect_opts = NULL;
+ size_t num_sect_opts = 0;
struct cleanup *my_cleanups = make_cleanup (null_cleanup, NULL);
+ num_sect_opts = 16;
+ sect_opts = (struct sect_opt *) xmalloc (num_sect_opts
+ * sizeof (struct sect_opt));
+
dont_repeat ();
if (args == NULL)
@@ -1496,9 +1629,6 @@ add_symbol_file_command (char *args, int from_tty)
/* Make a copy of the string that we can safely write into. */
args = xstrdup (args);
- /* Ensure section_addrs is initialized */
- memset (&section_addrs, 0, sizeof (section_addrs));
-
while (*args != '\000')
{
/* Any leading spaces? */
@@ -1531,7 +1661,14 @@ add_symbol_file_command (char *args, int from_tty)
to load the program. */
sect_opts[section_index].name = ".text";
sect_opts[section_index].value = arg;
- section_index++;
+ 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
{
@@ -1540,19 +1677,13 @@ add_symbol_file_command (char *args, int from_tty)
if (*arg == '-')
{
- if (strcmp (arg, "-mapped") == 0)
- flags |= OBJF_MAPPED;
- else
- if (strcmp (arg, "-readnow") == 0)
- flags |= OBJF_READNOW;
- else
- if (strcmp (arg, "-s") == 0)
- {
- if (section_index >= SECT_OFF_MAX)
- error ("Too many sections specified.");
- expecting_sec_name = 1;
- expecting_sec_addr = 1;
- }
+ if (strcmp (arg, "-readnow") == 0)
+ flags |= OBJF_READNOW;
+ else if (strcmp (arg, "-s") == 0)
+ {
+ expecting_sec_name = 1;
+ expecting_sec_addr = 1;
+ }
}
else
{
@@ -1566,7 +1697,14 @@ add_symbol_file_command (char *args, int from_tty)
{
sect_opts[section_index].value = arg;
expecting_sec_addr = 0;
- section_index++;
+ 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> [-mapped] [-readnow] [-s <secname> <addr>]*");
@@ -1581,24 +1719,22 @@ add_symbol_file_command (char *args, int from_tty)
statements because local_hex_string returns a local static
string. */
- printf_filtered ("add symbol table from file \"%s\" at\n", filename);
+ printf_unfiltered ("add symbol table from file \"%s\" at\n", filename);
+ section_addrs = alloc_section_addr_info (section_index);
+ make_cleanup (xfree, section_addrs);
for (i = 0; i < section_index; i++)
{
CORE_ADDR addr;
char *val = sect_opts[i].value;
char *sec = sect_opts[i].name;
- val = sect_opts[i].value;
- if (val[0] == '0' && val[1] == 'x')
- addr = strtoul (val+2, NULL, 16);
- else
- addr = strtoul (val, NULL, 10);
+ addr = parse_and_eval_address (val);
/* Here we store the section offsets in the order they were
entered on the command line. */
- section_addrs.other[sec_num].name = sec;
- section_addrs.other[sec_num].addr = addr;
- printf_filtered ("\t%s_addr = %s\n",
+ section_addrs->other[sec_num].name = sec;
+ section_addrs->other[sec_num].addr = addr;
+ printf_unfiltered ("\t%s_addr = %s\n",
sec,
local_hex_string ((unsigned long)addr));
sec_num++;
@@ -1613,7 +1749,7 @@ add_symbol_file_command (char *args, int from_tty)
if (from_tty && (!query ("%s", "")))
error ("Not confirmed.");
- symbol_file_add (filename, from_tty, &section_addrs, 0, flags);
+ symbol_file_add (filename, from_tty, section_addrs, 0, flags);
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -1651,7 +1787,7 @@ reread_symbols (void)
{
if (objfile->obfd)
{
-#ifdef IBM6000_TARGET
+#ifdef DEPRECATED_IBM6000_TARGET
/* If this object is from a shared library, then you should
stat on the library name, not member name. */
@@ -1663,7 +1799,7 @@ reread_symbols (void)
if (res != 0)
{
/* FIXME, should use print_sys_errmsg but it's not filtered. */
- printf_filtered ("`%s' has disappeared; keeping its symbols.\n",
+ printf_unfiltered ("`%s' has disappeared; keeping its symbols.\n",
objfile->name);
continue;
}
@@ -1675,7 +1811,7 @@ reread_symbols (void)
int num_offsets;
char *obfd_filename;
- printf_filtered ("`%s' has changed; re-reading symbols.\n",
+ printf_unfiltered ("`%s' has changed; re-reading symbols.\n",
objfile->name);
/* There are various functions like symbol_file_add,
@@ -1708,10 +1844,12 @@ reread_symbols (void)
bfd_errmsg (bfd_get_error ()));
/* Save the offsets, we will nuke them with the rest of the
- psymbol_obstack. */
+ objfile_obstack. */
num_offsets = objfile->num_sections;
- offsets = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
- memcpy (offsets, objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+ offsets = ((struct section_offsets *)
+ alloca (SIZEOF_N_SECTION_OFFSETS (num_offsets)));
+ memcpy (offsets, objfile->section_offsets,
+ SIZEOF_N_SECTION_OFFSETS (num_offsets));
/* Nuke all the state that we will re-read. Much of the following
code which sets things to NULL really is necessary to tell
@@ -1729,21 +1867,30 @@ reread_symbols (void)
sizeof (objfile->static_psymbols));
/* Free the obstacks for non-reusable objfiles */
- free_bcache (&objfile->psymbol_cache);
- obstack_free (&objfile->psymbol_obstack, 0);
- obstack_free (&objfile->symbol_obstack, 0);
- obstack_free (&objfile->type_obstack, 0);
+ bcache_xfree (objfile->psymbol_cache);
+ objfile->psymbol_cache = bcache_xmalloc ();
+ bcache_xfree (objfile->macro_cache);
+ objfile->macro_cache = bcache_xmalloc ();
+ 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;
objfile->psymtabs = NULL;
objfile->free_psymtabs = NULL;
+ objfile->cp_namespace_symtab = NULL;
objfile->msymbols = NULL;
+ objfile->sym_private = NULL;
objfile->minimal_symbol_count = 0;
memset (&objfile->msymbol_hash, 0,
sizeof (objfile->msymbol_hash));
memset (&objfile->msymbol_demangled_hash, 0,
sizeof (objfile->msymbol_demangled_hash));
objfile->fundamental_types = NULL;
+ clear_objfile_data (objfile);
if (objfile->sf != NULL)
{
(*objfile->sf->sym_finish) (objfile);
@@ -1751,27 +1898,27 @@ reread_symbols (void)
/* We never make this a mapped file. */
objfile->md = NULL;
- /* obstack_specify_allocation also initializes the obstack so
- it is empty. */
- obstack_specify_allocation (&objfile->psymbol_cache.cache, 0, 0,
- xmalloc, xfree);
- obstack_specify_allocation (&objfile->psymbol_obstack, 0, 0,
- xmalloc, xfree);
- obstack_specify_allocation (&objfile->symbol_obstack, 0, 0,
- xmalloc, xfree);
- obstack_specify_allocation (&objfile->type_obstack, 0, 0,
- xmalloc, xfree);
+ objfile->psymbol_cache = bcache_xmalloc ();
+ objfile->macro_cache = bcache_xmalloc ();
+ /* obstack_init also initializes the obstack so it is
+ empty. We could use obstack_specify_allocation but
+ gdb_obstack.h specifies the alloc/dealloc
+ functions. */
+ obstack_init (&objfile->objfile_obstack);
if (build_objfile_section_table (objfile))
{
error ("Can't find the file sections in `%s': %s",
objfile->name, bfd_errmsg (bfd_get_error ()));
}
+ terminate_minimal_symbol_table (objfile);
/* We use the same section offsets as from last time. I'm not
sure whether that is always correct for shared libraries. */
objfile->section_offsets = (struct section_offsets *)
- obstack_alloc (&objfile->psymbol_obstack, SIZEOF_SECTION_OFFSETS);
- memcpy (objfile->section_offsets, offsets, SIZEOF_SECTION_OFFSETS);
+ obstack_alloc (&objfile->objfile_obstack,
+ SIZEOF_N_SECTION_OFFSETS (num_offsets));
+ memcpy (objfile->section_offsets, offsets,
+ SIZEOF_N_SECTION_OFFSETS (num_offsets));
objfile->num_sections = num_offsets;
/* What the hell is sym_new_init for, anyway? The concept of
@@ -1786,7 +1933,7 @@ reread_symbols (void)
}
(*objfile->sf->sym_init) (objfile);
- clear_complaints (1, 1);
+ clear_complaints (&symfile_complaints, 1, 1);
/* The "mainline" parameter is a hideous hack; I think leaving it
zero is OK since dbxread.c also does what it needs to do if
objfile->global_psymbols.size is 0. */
@@ -1794,13 +1941,13 @@ reread_symbols (void)
if (!have_partial_symbols () && !have_full_symbols ())
{
wrap_here ("");
- printf_filtered ("(no debugging symbols found)\n");
+ printf_unfiltered ("(no debugging symbols found)\n");
wrap_here ("");
}
objfile->flags |= OBJF_SYMS;
/* We're done reading the symbol file; finish off complaints. */
- clear_complaints (0, 1);
+ clear_complaints (&symfile_complaints, 0, 1);
/* Getting new symbols may change our opinion about what is
frameless. */
@@ -1815,13 +1962,7 @@ reread_symbols (void)
again now. */
objfile->mtime = new_modtime;
reread_one = 1;
-
- /* Call this after reading in a new symbol table to give target
- dependent code a crack at the new symbols. For instance, this
- could be used to update the values of target-specific symbols GDB
- needs to keep track of (such as _sigtramp, or whatever). */
-
- TARGET_SYMFILE_POSTREAD (objfile);
+ reread_separate_symbols (objfile);
}
}
}
@@ -1829,6 +1970,72 @@ reread_symbols (void)
if (reread_one)
clear_symtab_users ();
}
+
+
+/* Handle separate debug info for OBJFILE, which has just been
+ re-read:
+ - If we had separate debug info before, but now we don't, get rid
+ of the separated objfile.
+ - If we didn't have separated debug info before, but now we do,
+ read in the new separated debug info file.
+ - If the debug link points to a different file, toss the old one
+ and read the new one.
+ This function does *not* handle the case where objfile is still
+ using the same separate debug info file, but that file's timestamp
+ has changed. That case should be handled by the loop in
+ reread_symbols already. */
+static void
+reread_separate_symbols (struct objfile *objfile)
+{
+ char *debug_file;
+ unsigned long crc32;
+
+ /* Does the updated objfile's debug info live in a
+ separate file? */
+ debug_file = find_separate_debug_file (objfile);
+
+ if (objfile->separate_debug_objfile)
+ {
+ /* There are two cases where we need to get rid of
+ the old separated debug info objfile:
+ - if the new primary objfile doesn't have
+ separated debug info, or
+ - if the new primary objfile has separate debug
+ info, but it's under a different filename.
+
+ If the old and new objfiles both have separate
+ debug info, under the same filename, then we're
+ okay --- if the separated file's contents have
+ changed, we will have caught that when we
+ visited it in this function's outermost
+ loop. */
+ if (! debug_file
+ || strcmp (debug_file, objfile->separate_debug_objfile->name) != 0)
+ free_objfile (objfile->separate_debug_objfile);
+ }
+
+ /* If the new objfile has separate debug info, and we
+ haven't loaded it already, do so now. */
+ if (debug_file
+ && ! objfile->separate_debug_objfile)
+ {
+ /* Use the same section offset table as objfile itself.
+ Preserve the flags from objfile that make sense. */
+ objfile->separate_debug_objfile
+ = (symbol_file_add_with_addrs_or_offsets
+ (debug_file,
+ info_verbose, /* from_tty: Don't override the default. */
+ 0, /* No addr table. */
+ objfile->section_offsets, objfile->num_sections,
+ 0, /* Not mainline. See comments about this above. */
+ objfile->flags & (OBJF_REORDERED | OBJF_SHARED | OBJF_READNOW
+ | OBJF_USERLOADED)));
+ objfile->separate_debug_objfile->separate_debug_objfile_backlink
+ = objfile;
+ }
+}
+
+
@@ -1948,9 +2155,7 @@ init_filename_language_table (void)
add_filename_language (".c++", language_cplus);
add_filename_language (".java", language_java);
add_filename_language (".class", language_java);
- add_filename_language (".ch", language_chill);
- add_filename_language (".c186", language_chill);
- add_filename_language (".c286", language_chill);
+ add_filename_language (".m", language_objc);
add_filename_language (".f", language_fortran);
add_filename_language (".F", language_fortran);
add_filename_language (".s", language_asm);
@@ -1993,17 +2198,17 @@ deduce_language_from_filename (char *filename)
struct symtab *
allocate_symtab (char *filename, struct objfile *objfile)
{
- register struct symtab *symtab;
+ struct symtab *symtab;
symtab = (struct symtab *)
- obstack_alloc (&objfile->symbol_obstack, sizeof (struct symtab));
+ obstack_alloc (&objfile->objfile_obstack, sizeof (struct symtab));
memset (symtab, 0, sizeof (*symtab));
symtab->filename = obsavestring (filename, strlen (filename),
- &objfile->symbol_obstack);
+ &objfile->objfile_obstack);
symtab->fullname = NULL;
symtab->language = deduce_language_from_filename (filename);
symtab->debugformat = obsavestring ("unknown", 7,
- &objfile->symbol_obstack);
+ &objfile->objfile_obstack);
/* Hook it to the objfile it comes from */
@@ -2034,12 +2239,12 @@ allocate_psymtab (char *filename, struct objfile *objfile)
}
else
psymtab = (struct partial_symtab *)
- obstack_alloc (&objfile->psymbol_obstack,
+ obstack_alloc (&objfile->objfile_obstack,
sizeof (struct partial_symtab));
memset (psymtab, 0, sizeof (struct partial_symtab));
psymtab->filename = obsavestring (filename, strlen (filename),
- &objfile->psymbol_obstack);
+ &objfile->objfile_obstack);
psymtab->symtab = NULL;
/* Prepend it to the psymtab list for the objfile it belongs to.
@@ -2103,8 +2308,7 @@ clear_symtab_users (void)
clear_internalvars ();
breakpoint_re_set ();
set_default_breakpoint (0, 0, 0, 0);
- current_source_symtab = 0;
- current_source_line = 0;
+ clear_current_source_symtab_and_line ();
clear_pc_function_cache ();
if (target_new_objfile_hook)
target_new_objfile_hook (NULL);
@@ -2189,7 +2393,7 @@ cashier_psymtab (struct partial_symtab *pst)
partial_symbol lists (global_psymbols/static_psymbols) that
this psymtab points to. These just take up space until all
the psymtabs are reclaimed. Ditto the dependencies list and
- filename, which are all in the psymbol_obstack. */
+ filename, which are all in the objfile_obstack. */
/* We need to cashier any psymtab that has this one as a dependency... */
again:
@@ -2233,9 +2437,9 @@ free_named_symtabs (char *name)
compilation units. We want to blow away any old info about these
compilation units, regardless of which objfiles they arrived in. --gnu. */
- register struct symtab *s;
- register struct symtab *prev;
- register struct partial_symtab *ps;
+ struct symtab *s;
+ struct symtab *prev;
+ struct partial_symtab *ps;
struct blockvector *bv;
int blewit = 0;
@@ -2252,7 +2456,7 @@ free_named_symtabs (char *name)
again2:
for (ps = partial_symtab_list; ps; ps = ps->next)
{
- if (STREQ (name, ps->filename))
+ if (strcmp (name, ps->filename) == 0)
{
cashier_psymtab (ps); /* Blow it away...and its little dog, too. */
goto again2; /* Must restart, chain has been munged */
@@ -2263,7 +2467,7 @@ again2:
for (s = symtab_list; s; s = s->next)
{
- if (STREQ (name, s->filename))
+ if (strcmp (name, s->filename) == 0)
break;
prev = s;
}
@@ -2290,15 +2494,16 @@ again2:
|| BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK))
|| BLOCK_NSYMS (BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)))
{
- complain (&oldsyms_complaint, name);
-
+ complaint (&symfile_complaints, "Replacing old symbols for `%s'",
+ name);
clear_symtab_users_queued++;
make_cleanup (clear_symtab_users_once, 0);
blewit = 1;
}
else
{
- complain (&empty_symtab_complaint, name);
+ complaint (&symfile_complaints, "Empty symbol table found for `%s'",
+ name);
}
free_symtab (s);
@@ -2344,16 +2549,28 @@ start_psymtab_common (struct objfile *objfile,
}
/* Add a symbol with a long value to a psymtab.
- Since one arg is a struct, we pass in a ptr and deref it (sigh). */
-
-void
-add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
+ Since one arg is a struct, we pass in a ptr and deref it (sigh).
+ Return the partial symbol that has been added. */
+
+/* NOTE: carlton/2003-09-11: The reason why we return the partial
+ symbol is so that callers can get access to the symbol's demangled
+ name, which they don't have any cheap way to determine otherwise.
+ (Currenly, dwarf2read.c is the only file who uses that information,
+ though it's possible that other readers might in the future.)
+ Elena wasn't thrilled about that, and I don't blame her, but we
+ couldn't come up with a better way to get that information. If
+ it's needed in other situations, we could consider breaking up
+ SYMBOL_SET_NAMES to provide access to the demangled name lookup
+ cache. */
+
+const struct partial_symbol *
+add_psymbol_to_list (char *name, int namelength, domain_enum domain,
enum address_class class,
struct psymbol_allocation_list *list, long val, /* Value as a long */
CORE_ADDR coreaddr, /* Value as a CORE_ADDR */
enum language language, struct objfile *objfile)
{
- register struct partial_symbol *psym;
+ struct partial_symbol *psym;
char *buf = alloca (namelength + 1);
/* psymbol is static so that there will be no uninitialized gaps in the
structure which might contain random data, causing cache misses in
@@ -2363,7 +2580,6 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
/* Create local copy of the partial symbol */
memcpy (buf, name, namelength);
buf[namelength] = '\0';
- SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
/* val and coreaddr are mutually exclusive, one of them *will* be zero */
if (val != 0)
{
@@ -2375,12 +2591,14 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
}
SYMBOL_SECTION (&psymbol) = 0;
SYMBOL_LANGUAGE (&psymbol) = language;
- PSYMBOL_NAMESPACE (&psymbol) = namespace;
+ PSYMBOL_DOMAIN (&psymbol) = domain;
PSYMBOL_CLASS (&psymbol) = class;
- SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
+
+ SYMBOL_SET_NAMES (&psymbol, buf, namelength, objfile);
/* Stash the partial symbol away in the cache */
- psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
+ psym = deprecated_bcache (&psymbol, sizeof (struct partial_symbol),
+ objfile->psymbol_cache);
/* Save pointer to partial symbol in psymtab, growing symtab if needed. */
if (list->next >= list->list + list->size)
@@ -2389,6 +2607,8 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
}
*list->next++ = psym;
OBJSTAT (objfile, n_psyms++);
+
+ return psym;
}
/* Add a symbol with a long value to a psymtab. This differs from
@@ -2397,14 +2617,14 @@ add_psymbol_to_list (char *name, int namelength, namespace_enum namespace,
void
add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
- int dem_namelength, namespace_enum namespace,
+ int dem_namelength, domain_enum domain,
enum address_class class,
struct psymbol_allocation_list *list, long val, /* Value as a long */
CORE_ADDR coreaddr, /* Value as a CORE_ADDR */
enum language language,
struct objfile *objfile)
{
- register struct partial_symbol *psym;
+ struct partial_symbol *psym;
char *buf = alloca (namelength + 1);
/* psymbol is static so that there will be no uninitialized gaps in the
structure which might contain random data, causing cache misses in
@@ -2415,7 +2635,8 @@ add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
memcpy (buf, name, namelength);
buf[namelength] = '\0';
- SYMBOL_NAME (&psymbol) = bcache (buf, namelength + 1, &objfile->psymbol_cache);
+ DEPRECATED_SYMBOL_NAME (&psymbol) = deprecated_bcache (buf, namelength + 1,
+ objfile->psymbol_cache);
buf = alloca (dem_namelength + 1);
memcpy (buf, dem_name, dem_namelength);
@@ -2426,12 +2647,8 @@ add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
case language_c:
case language_cplus:
SYMBOL_CPLUS_DEMANGLED_NAME (&psymbol) =
- bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
+ deprecated_bcache (buf, dem_namelength + 1, objfile->psymbol_cache);
break;
- case language_chill:
- SYMBOL_CHILL_DEMANGLED_NAME (&psymbol) =
- bcache (buf, dem_namelength + 1, &objfile->psymbol_cache);
-
/* FIXME What should be done for the default case? Ignoring for now. */
}
@@ -2446,12 +2663,13 @@ add_psymbol_with_dem_name_to_list (char *name, int namelength, char *dem_name,
}
SYMBOL_SECTION (&psymbol) = 0;
SYMBOL_LANGUAGE (&psymbol) = language;
- PSYMBOL_NAMESPACE (&psymbol) = namespace;
+ PSYMBOL_DOMAIN (&psymbol) = domain;
PSYMBOL_CLASS (&psymbol) = class;
SYMBOL_INIT_LANGUAGE_SPECIFIC (&psymbol, language);
/* Stash the partial symbol away in the cache */
- psym = bcache (&psymbol, sizeof (struct partial_symbol), &objfile->psymbol_cache);
+ psym = deprecated_bcache (&psymbol, sizeof (struct partial_symbol),
+ objfile->psymbol_cache);
/* Save pointer to partial symbol in psymtab, growing symtab if needed. */
if (list->next >= list->list + list->size)
@@ -2471,11 +2689,11 @@ init_psymbol_list (struct objfile *objfile, int total_symbols)
if (objfile->global_psymbols.list)
{
- xmfree (objfile->md, (PTR) objfile->global_psymbols.list);
+ xmfree (objfile->md, objfile->global_psymbols.list);
}
if (objfile->static_psymbols.list)
{
- xmfree (objfile->md, (PTR) objfile->static_psymbols.list);
+ xmfree (objfile->md, objfile->static_psymbols.list);
}
/* Current best guess is that approximately a twentieth
@@ -2691,7 +2909,7 @@ pc_in_mapped_range (CORE_ADDR pc, asection *section)
/* Return true if the mapped ranges of sections A and B overlap, false
otherwise. */
-int
+static int
sections_overlap (asection *a, asection *b)
{
/* FIXME: need bfd *, so we can use bfd_section_vma methods. */
@@ -2893,7 +3111,7 @@ the 'overlay manual' command.");
sec2->the_bfd_section))
{
if (info_verbose)
- printf_filtered ("Note: section %s unmapped by overlap\n",
+ printf_unfiltered ("Note: section %s unmapped by overlap\n",
bfd_section_name (objfile->obfd,
sec2->the_bfd_section));
sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2 */
@@ -2943,7 +3161,7 @@ overlay_auto_command (char *args, int from_tty)
overlay_debugging = ovly_auto;
enable_overlay_breakpoints ();
if (info_verbose)
- printf_filtered ("Automatic overlay debugging enabled.");
+ printf_unfiltered ("Automatic overlay debugging enabled.");
}
/* Function: overlay_manual_command
@@ -2956,7 +3174,7 @@ overlay_manual_command (char *args, int from_tty)
overlay_debugging = ovly_on;
disable_overlay_breakpoints ();
if (info_verbose)
- printf_filtered ("Overlay debugging enabled.");
+ printf_unfiltered ("Overlay debugging enabled.");
}
/* Function: overlay_off_command
@@ -2969,7 +3187,7 @@ overlay_off_command (char *args, int from_tty)
overlay_debugging = ovly_off;
disable_overlay_breakpoints ();
if (info_verbose)
- printf_filtered ("Overlay debugging disabled.");
+ printf_unfiltered ("Overlay debugging disabled.");
}
static void
@@ -3247,6 +3465,45 @@ simple_overlay_update (struct obj_section *osect)
}
}
+/* Set the output sections and output offsets for section SECTP in
+ ABFD. The relocation code in BFD will read these offsets, so we
+ need to be sure they're initialized. We map each section to itself,
+ with no offset; this means that SECTP->vma will be honored. */
+
+static void
+symfile_dummy_outputs (bfd *abfd, asection *sectp, void *dummy)
+{
+ sectp->output_section = sectp;
+ sectp->output_offset = 0;
+}
+
+/* Relocate the contents of a debug section SECTP in ABFD. The
+ contents are stored in BUF if it is non-NULL, or returned in a
+ malloc'd buffer otherwise.
+
+ For some platforms and debug info formats, shared libraries contain
+ relocations against the debug sections (particularly for DWARF-2;
+ one affected platform is PowerPC GNU/Linux, although it depends on
+ the version of the linker in use). Also, ELF object files naturally
+ have unresolved relocations for their debug sections. We need to apply
+ the relocations in order to get the locations of symbols correct. */
+
+bfd_byte *
+symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf)
+{
+ /* We're only interested in debugging sections with relocation
+ information. */
+ if ((sectp->flags & SEC_RELOC) == 0)
+ return NULL;
+ if ((sectp->flags & SEC_DEBUGGING) == 0)
+ return NULL;
+
+ /* We will handle section offsets properly elsewhere, so relocate as if
+ all sections begin at 0. */
+ bfd_map_over_sections (abfd, symfile_dummy_outputs, NULL);
+
+ return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
+}
void
_initialize_symfile (void)
@@ -3257,7 +3514,7 @@ _initialize_symfile (void)
"Load symbol table from executable file FILE.\n\
The `file' command can also load symbol tables, as well as setting the file\n\
to execute.", &cmdlist);
- c->completer = filename_completer;
+ set_cmd_completer (c, filename_completer);
c = add_cmd ("add-symbol-file", class_files, add_symbol_file_command,
"Usage: add-symbol-file FILE ADDR [-s <SECT> <SECT_ADDR> -s <SECT> <SECT_ADDR> ...]\n\
@@ -3265,9 +3522,9 @@ Load the symbols from FILE, assuming FILE has been dynamically loaded.\n\
ADDR is the starting address of the file's text.\n\
The optional arguments are section-name section-address pairs and\n\
should be specified if the data and bss segments are not contiguous\n\
-with the text. SECT is a section name to be loaded at SECT_ADDR.",
+with the text. SECT is a section name to be loaded at SECT_ADDR.",
&cmdlist);
- c->completer = filename_completer;
+ set_cmd_completer (c, filename_completer);
c = add_cmd ("add-shared-symbol-files", class_files,
add_shared_symbol_files_command,
@@ -3279,7 +3536,7 @@ with the text. SECT is a section name to be loaded at SECT_ADDR.",
c = add_cmd ("load", class_files, load_command,
"Dynamically load FILE into the running program, and record its symbols\n\
for access from GDB.", &cmdlist);
- c->completer = filename_completer;
+ set_cmd_completer (c, filename_completer);
add_show_from_set
(add_set_cmd ("symbol-reloading", class_support, var_boolean,
@@ -3336,4 +3593,18 @@ Usage: set extension-language .foo bar",
"cache.\n",
&setlist),
&showlist);
+
+ debug_file_directory = xstrdup (DEBUGDIR);
+ c = (add_set_cmd
+ ("debug-file-directory", class_support, var_string,
+ (char *) &debug_file_directory,
+ "Set the directory where separate debug symbols are searched for.\n"
+ "Separate debug symbols are first searched for in the same\n"
+ "directory as the binary, then in the `" DEBUG_SUBDIRECTORY
+ "' subdirectory,\n"
+ "and lastly at the path of the directory of the binary with\n"
+ "the global debug-file directory prepended\n",
+ &setlist));
+ add_show_from_set (c, &showlist);
+ set_cmd_completer (c, filename_completer);
}
OpenPOWER on IntegriCloud