#include "target.h"
#include "value.h"
#include "symfile.h"
+#include "objfiles.h"
#include "gdbcmd.h"
#include "breakpoint.h"
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
+#include <ctype.h>
/* Global variables owned by this file */
-CORE_ADDR entry_point; /* Where execution starts in symfile */
int readnow_symbol_files; /* Read full symbols immediately */
/* External variables and functions referenced. */
extern int info_verbose;
-extern CORE_ADDR startup_file_start; /* From blockframe.c */
-extern CORE_ADDR startup_file_end; /* From blockframe.c */
-
/* Functions this file defines */
static void
static void
find_sym_fns PARAMS ((struct objfile *));
-static void
+void
clear_symtab_users_once PARAMS ((void));
/* List of all available sym_fns. On gdb startup, each object file reader
static struct sym_fns *symtab_fns = NULL;
-/* When we need to allocate a new type, we need to know which type_obstack
- to allocate the type on, since there is one for each objfile. The places
- where types are allocated are deeply buried in function call hierarchies
- which know nothing about objfiles, so rather than trying to pass a
- particular objfile down to them, we just do an end run around them and
- set current_objfile to be whatever objfile we expect to be using at the
- time types are being allocated. For instance, when we start reading
- symbols for a particular objfile, we set current_objfile to point to that
- objfile, and when we are done, we set it back to NULL, to ensure that we
- never put a type someplace other than where we are expecting to put it.
- FIXME: Maybe we should review the entire type handling system and
- see if there is a better way to avoid this problem. */
-
-struct objfile *current_objfile = NULL;
-
-/* The object file that the main symbol table was loaded from (e.g. the
- argument to the "symbol-file" or "file" command). */
-
-struct objfile *symfile_objfile = NULL;
-
/* Structures with which to manage partial symbol allocation. */
struct psymbol_allocation_list global_psymbols = {0}, static_psymbols = {0};
return pst->symtab;
}
+/* Initialize entry point information for this objfile. */
+
+void
+init_entry_point_info (objfile)
+ 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. */
+ /* ~0 will not be in any file, we hope. */
+ objfile -> ei.entry_point = ~0;
+ /* set the startup file to be an empty range. */
+ objfile -> ei.entry_file_lowpc = 0;
+ objfile -> ei.entry_file_highpc = 0;
+ }
+}
+
+/* Remember the lowest-addressed loadable section we've seen.
+ This function is called via bfd_map_over_sections. */
+
+#if 0 /* Not used yet */
+static void
+find_lowest_section (abfd, sect, obj)
+ bfd *abfd;
+ asection *sect;
+ PTR obj;
+{
+ asection **lowest = (asection **)obj;
+
+ if (0 == (bfd_get_section_flags (abfd, sect) & SEC_LOAD))
+ return;
+ if (!*lowest)
+ *lowest = sect; /* First loadable section */
+ else if (bfd_section_vma (abfd, *lowest) >= bfd_section_vma (abfd, sect))
+ *lowest = sect; /* A lower loadable section */
+}
+#endif
+
/* Process a symbol file, as either the main file or as a dynamically
loaded file.
int mainline;
int verbo;
{
- asection *text_sect;
+ struct section_offsets *section_offsets;
+ asection *lowest_sect;
/* There is a distinction between having no symbol table
(we refuse to read the file, leaving the old set of symbols around)
and having no debugging symbols in your symbol table (we read
- the file and end up with a mostly empty symbol table). */
+ the file and end up with a mostly empty symbol table).
+
+ FIXME: This strategy works correctly when the debugging symbols are
+ intermixed with "normal" symbols. However, when the debugging symbols
+ are separate, such as with ELF/DWARF, it is perfectly plausible for
+ the symbol table to be missing but still have all the DWARF info
+ intact. Thus in general it is wrong to assume that having no symbol
+ table implies no debugging information. */
if (!(bfd_get_file_flags (objfile -> obfd) & HAS_SYMS))
return;
- /* 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. */
- entry_point = bfd_get_start_address (objfile -> obfd);
- }
- else
- {
- /* Examination of non-executable.o files. Short-circuit this stuff. */
- /* ~0 will not be in any file, we hope. */
- entry_point = ~0;
- /* set the startup file to be an empty range. */
- startup_file_start = 0;
- startup_file_end = 0;
- }
-
+ init_entry_point_info (objfile);
find_sym_fns (objfile);
if (mainline)
}
(*objfile -> sf -> sym_new_init) (objfile);
+ }
+
+ /* Convert addr into an offset rather than an absolute address.
+ We find the lowest address of a loaded segment in the objfile,
+ and assume that <addr> is where that got loaded. Due to historical
+ precedent, we warn if that doesn't happen to be the ".text"
+ segment. */
- /* For mainline, caller didn't know the specified address of the
- text section. We fix that here. */
+ if (mainline)
+ {
+ addr = 0; /* No offset from objfile addresses. */
+ }
+ else
+ {
+ lowest_sect = bfd_get_section_by_name (objfile->obfd, ".text");
+#if 0
+ lowest_sect = 0;
+ bfd_map_over_sections (objfile->obfd, find_lowest_section,
+ (PTR) &lowest_sect);
+#endif
- text_sect = bfd_get_section_by_name (objfile -> obfd, ".text");
- addr = bfd_section_vma (objfile -> obfd, text_sect);
+ if (lowest_sect == 0)
+ warning ("no loadable sections found in added symbol-file %s",
+ objfile->name);
+ else if (0 == bfd_get_section_name (objfile->obfd, lowest_sect)
+ || 0 != strcmp(".text",
+ bfd_get_section_name (objfile->obfd, lowest_sect)))
+ warning ("Lowest section in %s is %s at 0x%x",
+ objfile->name,
+ bfd_section_name (objfile->obfd, lowest_sect),
+ bfd_section_vma (objfile->obfd, lowest_sect));
+
+ if (lowest_sect)
+ addr -= bfd_section_vma (objfile->obfd, lowest_sect);
}
/* Initialize symbol reading routines for this objfile, allow complaints to
(*objfile -> sf -> sym_init) (objfile);
clear_complaints (1, verbo);
- (*objfile -> sf -> sym_read) (objfile, addr, mainline);
+ section_offsets = (*objfile -> sf -> sym_offsets) (objfile, addr);
+ (*objfile -> sf -> sym_read) (objfile, section_offsets, mainline);
/* Don't allow char * to have a typename (else would get caddr_t.) */
/* Ditto void *. FIXME should do this for all the builtin types. */
TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
TYPE_NAME (lookup_pointer_type (builtin_type_void)) = 0;
+ /* Mark the objfile has having had initial symbol read attempted. Note
+ that this does not mean we found any symbols... */
+
+ objfile -> flags |= OBJF_SYMS;
+}
+
+/* Perform required actions immediately after either reading in the initial
+ symbols for a new objfile, or mapping in the symbols from a reusable
+ objfile. */
+
+void
+new_symfile_objfile (objfile, mainline, verbo)
+ struct objfile *objfile;
+ int mainline;
+ int verbo;
+{
if (mainline)
{
/* OK, make it the "real" symbol file. */
struct objfile *objfile;
struct partial_symtab *psymtab;
bfd *abfd;
- int mapped_it;
/* Open a bfd for the file and then check to see if the file has a
symbol table. There is a distinction between having no symbol table
&& !query ("Load new symbol table from \"%s\"? ", name))
error ("Not confirmed.");
+ /* Getting new symbols may change our opinion about what is
+ frameless. */
+
+ reinit_frame_cache ();
+
objfile = allocate_objfile (abfd, mapped);
/* If the objfile uses a mapped symbol file, and we have a psymtab for
it, then skip reading any symbols at this time. */
- if ((objfile -> flags & OBJF_MAPPED) && (objfile -> psymtabs != NULL))
+ if ((objfile -> flags & OBJF_MAPPED) && (objfile -> flags & OBJF_SYMS))
{
/* We mapped in an existing symbol table file that already has had
- the psymbols read in. So we can skip that part. Notify the user
- that instead of reading the symbols, they have been mapped. */
+ 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)
{
printf_filtered ("Mapped symbols for %s...", name);
wrap_here ("");
fflush (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 with no partial symbols, or need to read an
- unmapped symbol table. */
+ symbol table file which has not had initial symbol reading
+ performed, or need to read an unmapped symbol table. */
if (from_tty || info_verbose)
{
printf_filtered ("Reading symbols from %s...", name);
syms_from_objfile (objfile, addr, mainline, from_tty);
}
+ new_symfile_objfile (objfile, 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
the gdb startup command line or on a per symbol file basis. Expand
all partial symbol tables for this objfile if so. */
- readnow |= readnow_symbol_files;
- if (readnow)
+ if (readnow || readnow_symbol_files)
{
if (from_tty || info_verbose)
{
psymtab != NULL;
psymtab = psymtab -> next)
{
- (void) psymtab_to_symtab (psymtab);
+ psymtab_to_symtab (psymtab);
}
}
char **argv;
char *name = NULL;
struct cleanup *cleanups;
- struct objfile *objfile;
int mapped = 0;
int readnow = 0;
error ("Not confirmed.");
free_all_objfiles ();
symfile_objfile = NULL;
+ current_source_symtab = NULL;
+ current_source_line = 0;
+ if (from_tty)
+ {
+ printf_filtered ("No symbol file now.\n");
+ }
}
else
{
}
else
{
- /* Getting new symbols may change our opinion about what is
- frameless. */
- reinit_frame_cache ();
- objfile = symbol_file_add (name, from_tty, (CORE_ADDR)0, 1,
- mapped, readnow);
+ symbol_file_add (name, from_tty, (CORE_ADDR)0, 1, mapped, readnow);
}
do_cleanups (cleanups);
}
}
free (name); /* Free 1st new malloc'd copy */
name = absolute_name; /* Keep 2nd malloc'd copy in bfd */
+ /* It'll be freed in free_objfile(). */
sym_bfd = bfd_fdopenr (name, NULL, desc);
if (!sym_bfd)
find_sym_fns (objfile)
struct objfile *objfile;
{
- struct sym_fns *sf, *sf2;
+ struct sym_fns *sf;
for (sf = symtab_fns; sf != NULL; sf = sf -> next)
{
char *name = NULL;
CORE_ADDR text_addr;
char *arg;
- int readnow;
- int mapped;
+ int readnow = 0;
+ int mapped = 0;
dont_repeat ();
name, local_hex_string (text_addr)))
error ("Not confirmed.");
- /* Getting new symbols may change our opinion about what is
- frameless. */
-
- reinit_frame_cache ();
-
- (void) symbol_file_add (name, 0, text_addr, 0, mapped, readnow);
+ symbol_file_add (name, 0, text_addr, 0, mapped, readnow);
}
\f
/* Re-read symbols if a symbol-file has changed. */
the_big_top:
for (objfile = object_files; objfile; objfile = objfile->next) {
if (objfile->obfd) {
-#ifdef IBM6000
+#ifdef IBM6000_TARGET
/* If this object is from a shared library, then you should
stat on the library name, not member name. */
symtab = (struct symtab *)
obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symtab));
- (void) memset (symtab, 0, sizeof (*symtab));
+ memset (symtab, 0, sizeof (*symtab));
symtab -> filename = obsavestring (filename, strlen (filename),
&objfile -> symbol_obstack);
symtab -> fullname = NULL;
obstack_alloc (&objfile -> psymbol_obstack,
sizeof (struct partial_symtab));
- (void) memset (psymtab, 0, sizeof (struct partial_symtab));
+ memset (psymtab, 0, sizeof (struct partial_symtab));
psymtab -> filename = obsavestring (filename, strlen (filename),
&objfile -> psymbol_obstack);
psymtab -> symtab = NULL;
static int clear_symtab_users_queued;
static int clear_symtab_users_done;
-static void
+void
clear_symtab_users_once ()
{
/* Enforce once-per-`do_cleanups'-semantics */
return;
clear_symtab_users_done = clear_symtab_users_queued;
- printf ("Resetting debugger state after updating old symbol tables\n");
+ printf_filtered ("Resetting debugger state after updating old symbol tables\n");
/* Someday, we should do better than this, by only blowing away
the things that really need to be blown. */
free_named_symtabs (name)
char *name;
{
- register struct symtab *s;
- register struct symtab *prev;
- register struct partial_symtab *ps;
- struct blockvector *bv;
- int blewit = 0;
-
#if 0
/* FIXME: With the new method of each objfile having it's own
psymtab list, this function needs serious rethinking. In particular,
why was it ever necessary to toss psymtabs with specific compilation
unit filenames, as opposed to all psymtabs from a particular symbol
- file. */
+ file? -- fnf
+ Well, the answer is that some systems permit reloading of particular
+ 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 blockvector *bv;
+ int blewit = 0;
/* We only wack things if the symbol-reload switch is set. */
if (!symbol_reloading)
struct partial_symtab *
-start_psymtab_common (objfile, addr,
+start_psymtab_common (objfile, section_offsets,
filename, textlow, global_syms, static_syms)
struct objfile *objfile;
- CORE_ADDR addr;
+ struct section_offsets *section_offsets;
char *filename;
CORE_ADDR textlow;
struct partial_symbol *global_syms;
struct partial_symtab *psymtab;
psymtab = allocate_psymtab (filename, objfile);
- psymtab -> addr = addr;
+ psymtab -> section_offsets = section_offsets;
psymtab -> textlow = textlow;
psymtab -> texthigh = psymtab -> textlow; /* default */
psymtab -> globals_offset = global_syms - objfile -> global_psymbols.list;
psymtab -> statics_offset = static_syms - objfile -> static_psymbols.list;
return (psymtab);
}
+\f
+/* Debugging versions of functions that are usually inline macros
+ (see symfile.h). */
+
+#if 0 /* Don't quite work nowadays... */
+
+/* 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 (name, namelength, namespace, class, list, val)
+ char *name;
+ int namelength;
+ enum namespace namespace;
+ enum address_class class;
+ struct psymbol_allocation_list *list;
+ long val;
+{
+ ADD_PSYMBOL_VT_TO_LIST (name, namelength, namespace, class, (*list), val,
+ SYMBOL_VALUE);
+}
+
+/* Add a symbol with a CORE_ADDR value to a psymtab. */
+
+void
+add_psymbol_addr_to_list (name, namelength, namespace, class, list, val)
+ char *name;
+ int namelength;
+ enum namespace namespace;
+ enum address_class class;
+ struct psymbol_allocation_list *list;
+ CORE_ADDR val;
+{
+ ADD_PSYMBOL_VT_TO_LIST (name, namelength, namespace, class, (*list), val,
+ SYMBOL_VALUE_ADDRESS);
+}
+#endif /* 0 */
\f
void
_initialize_symfile ()