This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

initial faster startup patch


I pushed a new branch, named "archer-tromey-delayed-symfile".
This holds the initial patch to speed "attach" time.

With this patch, attaching to a running OO.o (with all the debuginfo
installed) went from:

    26.31user 2.75system 1:00.50elapsed

to:

    8.62user 0.90system 0:19.05elapsed

I also checked and "thread apply all bt full" seems to still be pretty
fast.  So, I don't think we are paying a big price for this.

Essentially this works by delaying the reading of partial symbols.
Whenever partial symbols for an objfile are actually needed, you must
now call require_partial_symbols.  I sprinkled these around where I
found they were needed, either via the test suite or by interactive
use.  I also made a couple tweaks to make it possible to delay reading
partial symbols in some cases.

One open question is what to do about the "(no debugging symbols
found)" messages.  Right now I just drop them.  Emitting them when we
actually read psymbols seems weird, since the message could show up
almost anywhere.

I've appended the patch.  Let me know what you think.  It is
faster-enough that I am wondering if there is something big I missed.

Tom

(Oh, BTW, the bfd/ change is just a --enable-targets=all build fix.
That is in upstream, it only appears here because I hadn't done that
when I made this branch.)


2008-09-09  Tom Tromey  <tromey@redhat.com>

	* symtab.c (find_pc_sect_psymtab): Use the quick addrmap.
	(find_main_psymtab): Search OBJF_MAIN objfiles first.
	* symfile.h: (dwarf2_create_quick_addrmap): Declare.
	* symfile.c (symbol_file_add_with_addrs_or_offsets): Set OBJF_MAIN
	flag.
	* objfiles.h (struct objfile) <quick_addrmap>: New field.
	(OBJF_MAIN): New define.
	* elfread.c (elf_symfile_read): Call dwarf2_create_quick_addrmap.
	* dwarf2read.c (read_comp_unit_head): Forward declare.
	(dwarf2_has_info): Make idempotent.
	(dwarf2_locate_sections): Only update sizes when asked.
	(dwarf2_create_quick_addrmap): New function.

2008-09-09  Tom Tromey  <tromey@redhat.com>

	* symfile.c (symbol_file_add_with_addrs_or_offsets): Reorder
	condition.
	* objfiles.c (have_partial_symbols): Add second loop.

2008-09-09  Tom Tromey  <tromey@redhat.com>

	* xcoffread.c (xcoff_sym_fns): Update.
	* symtab.h (require_partial_symbols): Declare.
	* symtab.c (lookup_partial_symtab): Use ALL_PSYMTABS_REQUIRED.
	(find_pc_sect_psymtab): Require partial symbols.
	(require_partial_symbols): New function.
	(lookup_symbol_aux_psymtabs): Use ALL_PSYMTABS_REQUIRED.
	(lookup_global_symbol_from_objfile): Require partial symbols.
	(find_main_psymtab): Update.
	(search_symbols): Update.
	* symfile.h (struct sym_fns) <sym_read_psymbols>: New field.
	* symfile.c (symbol_file_add_with_addrs_or_offsets): Require
	partial symbols.  Don't print "no debugging symbols found".
	(reread_symbols): Don't print "no debugging symbols found".
	* stack.c (backtrace_command_1): Read partial symbols for all
	frames.
	* objfiles.h (OBJF_SYMTABS_READ): New define.
	(ALL_PSYMTABS_REQUIRED): Likewise.
	* objfiles.c (have_partial_symbols): Require partial symbols.
	* mipsread.c (ecoff_sym_fns): Update.
	* elfread.c (elf_symfile_read): Don't read dwarf symbols here...
	(read_psyms): ... but here.  New function.
	(elf_sym_fns): Update.
	* dbxread.c (aout_sym_fns): Update.
	* coffread.c (coff_sym_fns): Update.

diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index 43a4604..69c5434 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -1409,7 +1409,7 @@ section_allows_mips16_refs_p (asection *section)
    function, or 0 if we can't decide which function that is.  */
 
 static unsigned long
-mips16_stub_symndx (asection *sec, const Elf_Internal_Rela *relocs,
+mips16_stub_symndx (asection *sec ATTRIBUTE_UNUSED, const Elf_Internal_Rela *relocs,
 		    const Elf_Internal_Rela *relend)
 {
   const Elf_Internal_Rela *rel;
diff --git a/gdb/coffread.c b/gdb/coffread.c
index de81d47..a7d6441 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -2104,6 +2104,7 @@ static struct sym_fns coff_sym_fns =
   coff_new_init,		/* sym_new_init: init anything gbl to entire symtab */
   coff_symfile_init,		/* sym_init: read initial info, setup for sym_read() */
   coff_symfile_read,		/* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   coff_symfile_finish,		/* sym_finish: finished with file, cleanup */
   default_symfile_offsets,	/* sym_offsets:  xlate external to internal form */
   default_symfile_segments,	/* sym_segments: Get segment information from
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index 25ec313..eda1810 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -3534,6 +3534,7 @@ static struct sym_fns aout_sym_fns =
   dbx_new_init,		/* sym_new_init: init anything gbl to entire symtab */
   dbx_symfile_init,	/* sym_init: read initial info, setup for sym_read() */
   dbx_symfile_read,		/* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   dbx_symfile_finish,		/* sym_finish: finished with file, cleanup */
   default_symfile_offsets, /* sym_offsets: parse user's offsets to
 			      internal form */
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 5cb444e..5cc9a2d 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -102,7 +102,7 @@ typedef struct pubnames_header
 _PUBNAMES_HEADER;
 #define _ACTUAL_PUBNAMES_HEADER_SIZE 13
 
-/* .debug_pubnames header
+/* .debug_aranges header
    Because of alignment constraints, this structure has padding and cannot
    be mapped directly onto the beginning of the .debug_info section.  */
 typedef struct aranges_header
@@ -758,6 +758,9 @@ static void scan_partial_symbols (struct partial_die_info *,
 static void add_partial_symbol (struct partial_die_info *,
 				struct dwarf2_cu *);
 
+static gdb_byte *read_comp_unit_head (struct comp_unit_head *, gdb_byte *,
+				      bfd *);
+
 static int pdi_needs_namespace (enum dwarf_tag tag);
 
 static void add_partial_namespace (struct partial_die_info *pdi,
@@ -1076,13 +1079,19 @@ static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
 int
 dwarf2_has_info (struct objfile *objfile)
 {
-  struct dwarf2_per_objfile *data;
+  int update_sizes = 0;
 
   /* Initialize per-objfile state.  */
-  data = obstack_alloc (&objfile->objfile_obstack, sizeof (*data));
-  memset (data, 0, sizeof (*data));
-  set_objfile_data (objfile, dwarf2_objfile_data_key, data);
-  dwarf2_per_objfile = data;
+  dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+  if (!dwarf2_per_objfile)
+    {
+      struct dwarf2_per_objfile *data
+	= obstack_alloc (&objfile->objfile_obstack, sizeof (*data));
+      memset (data, 0, sizeof (*data));
+      set_objfile_data (objfile, dwarf2_objfile_data_key, data);
+      dwarf2_per_objfile = data;
+      update_sizes = 1;
+    }
 
   dwarf_info_section = 0;
   dwarf_abbrev_section = 0;
@@ -1093,8 +1102,9 @@ dwarf2_has_info (struct objfile *objfile)
   dwarf_eh_frame_section = 0;
   dwarf_ranges_section = 0;
   dwarf_loc_section = 0;
+  dwarf_aranges_section = 0;
   
-  bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, NULL);
+  bfd_map_over_sections (objfile->obfd, dwarf2_locate_sections, &update_sizes);
   return (dwarf_info_section != NULL && dwarf_abbrev_section != NULL);
 }
 
@@ -1115,51 +1125,61 @@ section_is_p (asection *sectp, const char *name)
    in.  */
 
 static void
-dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
+dwarf2_locate_sections (bfd *abfd, asection *sectp, void *user_data)
 {
+  int update_sizes = * (int *) user_data;
   if (section_is_p (sectp, INFO_SECTION))
     {
-      dwarf2_per_objfile->info_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->info_size = bfd_get_section_size (sectp);
       dwarf_info_section = sectp;
     }
   else if (section_is_p (sectp, ABBREV_SECTION))
     {
-      dwarf2_per_objfile->abbrev_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->abbrev_size = bfd_get_section_size (sectp);
       dwarf_abbrev_section = sectp;
     }
   else if (section_is_p (sectp, LINE_SECTION))
     {
-      dwarf2_per_objfile->line_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->line_size = bfd_get_section_size (sectp);
       dwarf_line_section = sectp;
     }
   else if (section_is_p (sectp, PUBNAMES_SECTION))
     {
-      dwarf2_per_objfile->pubnames_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->pubnames_size = bfd_get_section_size (sectp);
       dwarf_pubnames_section = sectp;
     }
   else if (section_is_p (sectp, ARANGES_SECTION))
     {
-      dwarf2_per_objfile->aranges_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->aranges_size = bfd_get_section_size (sectp);
       dwarf_aranges_section = sectp;
     }
   else if (section_is_p (sectp, LOC_SECTION))
     {
-      dwarf2_per_objfile->loc_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->loc_size = bfd_get_section_size (sectp);
       dwarf_loc_section = sectp;
     }
   else if (section_is_p (sectp, MACINFO_SECTION))
     {
-      dwarf2_per_objfile->macinfo_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->macinfo_size = bfd_get_section_size (sectp);
       dwarf_macinfo_section = sectp;
     }
   else if (section_is_p (sectp, STR_SECTION))
     {
-      dwarf2_per_objfile->str_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->str_size = bfd_get_section_size (sectp);
       dwarf_str_section = sectp;
     }
   else if (section_is_p (sectp, FRAME_SECTION))
     {
-      dwarf2_per_objfile->frame_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->frame_size = bfd_get_section_size (sectp);
       dwarf_frame_section = sectp;
     }
   else if (section_is_p (sectp, EH_FRAME_SECTION))
@@ -1167,13 +1187,15 @@ dwarf2_locate_sections (bfd *abfd, asection *sectp, void *ignore_ptr)
       flagword aflag = bfd_get_section_flags (ignore_abfd, sectp);
       if (aflag & SEC_HAS_CONTENTS)
         {
-          dwarf2_per_objfile->eh_frame_size = bfd_get_section_size (sectp);
+	  if (update_sizes)
+	    dwarf2_per_objfile->eh_frame_size = bfd_get_section_size (sectp);
           dwarf_eh_frame_section = sectp;
         }
     }
   else if (section_is_p (sectp, RANGES_SECTION))
     {
-      dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp);
+      if (update_sizes)
+	dwarf2_per_objfile->ranges_size = bfd_get_section_size (sectp);
       dwarf_ranges_section = sectp;
     }
   
@@ -1216,6 +1238,74 @@ dwarf2_resize_section (asection *sectp, bfd_size_type new_size)
                     sectp->name);
 }
 
+/* Read the .debug_aranges section and construct an address map.  */
+
+void
+dwarf2_create_quick_addrmap (struct objfile *objfile)
+{
+  char *aranges_buffer, *aranges_ptr;
+  bfd *abfd = objfile->obfd;
+  CORE_ADDR baseaddr;
+
+  baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+
+  /* FIXME: this reads it onto the objfile obstack -- but this is just
+     wasted memory.  */
+  aranges_buffer = dwarf2_read_section (objfile, dwarf_aranges_section);
+  aranges_ptr = aranges_buffer;
+
+  /* FIXME: use a different obstack?  Isn't the old addrmap
+     discardable?  */
+  objfile->quick_addrmap = addrmap_create_mutable (&objfile->objfile_obstack);
+
+  while ((aranges_ptr - aranges_buffer) < dwarf2_per_objfile->aranges_size)
+    {
+      struct comp_unit_head cu_header;
+      unsigned int bytes_read, segment_size, delta;
+      LONGEST info_offset;
+      struct dwarf2_cu cu;
+
+      cu_header.initial_length_size = 0;
+      /* FIXME is this cheating?  */
+      aranges_ptr = read_comp_unit_head (&cu_header, aranges_ptr, abfd);
+
+      segment_size = read_1_byte (abfd, aranges_ptr);
+      aranges_ptr += 1;
+
+      /* Align the pointer to twice the pointer size.  I didn't see
+	 this in the spec but it appears to be required.  */
+      delta = (aranges_ptr - aranges_buffer) % (2 * cu_header.addr_size);
+      delta = (2 * cu_header.addr_size - delta) % (2 * cu_header.addr_size);
+      aranges_ptr += delta;
+
+      memset (&cu, 0, sizeof (cu));
+      cu.header.addr_size = cu_header.addr_size;
+
+      while (1)
+	{
+	  CORE_ADDR address, length;
+
+	  address = read_address (abfd, aranges_ptr, &cu, &bytes_read);
+	  aranges_ptr += bytes_read;
+
+	  length = read_address (abfd, aranges_ptr, &cu, &bytes_read);
+	  aranges_ptr += bytes_read;
+
+	  if (address == 0 && length == 0)
+	    break;
+
+	  address += baseaddr;
+
+	  addrmap_set_empty (objfile->quick_addrmap, address, address + length,
+			     objfile);
+	}
+    }
+
+  objfile->quick_addrmap = addrmap_create_fixed (objfile->quick_addrmap,
+						 &objfile->objfile_obstack);
+}
+
+
 /* Build a partial symbol table.  */
 
 void
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 17f86ba..01f46a2 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -727,10 +727,18 @@ elf_symfile_read (struct objfile *objfile, int mainline)
 				str_sect->filepos,
 				bfd_section_size (abfd, str_sect));
     }
+
+  if (dwarf2_has_info (objfile))
+    dwarf2_create_quick_addrmap (objfile);
+}
+
+static void
+read_psyms (struct objfile *objfile)
+{
   if (dwarf2_has_info (objfile))
     {
       /* DWARF 2 sections */
-      dwarf2_build_psymtabs (objfile, mainline);
+      dwarf2_build_psymtabs (objfile, 0);
     }
 
   /* FIXME: kettenis/20030504: This still needs to be integrated with
@@ -880,6 +888,7 @@ static struct sym_fns elf_sym_fns =
   elf_new_init,			/* sym_new_init: init anything gbl to entire symtab */
   elf_symfile_init,		/* sym_init: read initial info, setup for sym_read() */
   elf_symfile_read,		/* sym_read: read a symbol file into symtab */
+  read_psyms,			/* sym_read_psymbols */
   elf_symfile_finish,		/* sym_finish: finished with file, cleanup */
   default_symfile_offsets,	/* sym_offsets:  Translate ext. to int. relocation */
   elf_symfile_segments,		/* sym_segments: Get segment information from
diff --git a/gdb/mipsread.c b/gdb/mipsread.c
index fdd8634..5c4d7c2 100644
--- a/gdb/mipsread.c
+++ b/gdb/mipsread.c
@@ -394,6 +394,7 @@ static struct sym_fns ecoff_sym_fns =
   mipscoff_new_init,		/* sym_new_init: init anything gbl to entire symtab */
   mipscoff_symfile_init,	/* sym_init: read initial info, setup for sym_read() */
   mipscoff_symfile_read,	/* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   mipscoff_symfile_finish,	/* sym_finish: finished with file, cleanup */
   default_symfile_offsets,	/* sym_offsets: dummy FIXME til implem sym reloc */
   default_symfile_segments,	/* sym_segments: Get segment information from
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 16be84a..73bdb26 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -691,6 +691,20 @@ have_partial_symbols (void)
 	return 1;
       }
   }
+
+  /* Try again, after reading partial symbols.  We do this in two
+     passes because objfiles are always added to the head of the list,
+     and there might be a later objfile for which we've already read
+     partial symbols.  */
+  ALL_OBJFILES (ofp)
+  {
+    require_partial_symbols (ofp);
+    if (ofp->psymtabs != NULL)
+      {
+	return 1;
+      }
+  }
+
   return 0;
 }
 
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index d98eabb..a5168dd 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -212,6 +212,11 @@ struct objfile
 
     struct partial_symtab *psymtabs;
 
+    /* An address map that can be used to quickly determine if an
+       address comes from this objfile.  This can be NULL.  */
+
+    struct addrmap *quick_addrmap;
+
     /* Map addresses to the entries of PSYMTABS.  It would be more efficient to
        have a map per the whole process but ADDRMAP cannot selectively remove
        its items during FREE_OBJFILE.  This mapping is already present even for
@@ -423,6 +428,15 @@ struct objfile
 
 #define OBJF_USERLOADED	(1 << 5)	/* User loaded */
 
+/* Set if we have tried to read partial symtabs for this objfile.
+   This is used to allow lazy reading of partial symtabs.  */
+
+#define OBJF_SYMTABS_READ (1 << 6)
+
+/* This flag is set for the main objfile.  */
+
+#define OBJF_MAIN (1 << 7)
+
 /* The object file that the main symbol table was loaded from (e.g. the
    argument to the "symbol-file" or "file" command).  */
 
@@ -562,6 +576,13 @@ extern void *objfile_data (struct objfile *objfile,
   ALL_OBJFILES (objfile)	 \
     ALL_OBJFILE_PSYMTABS (objfile, p)
 
+/* Like ALL_PSYMTABS, but ensure that partial symbols have been read
+   before examining the objfile.  */
+
+#define ALL_PSYMTABS_REQUIRED(objfile, p)			\
+  ALL_OBJFILES (objfile)					\
+    ALL_OBJFILE_PSYMTABS (require_partial_symbols (objfile), p)
+
 /* Traverse all minimal symbols in all objfiles.  */
 
 #define	ALL_MSYMBOLS(objfile, m) \
diff --git a/gdb/stack.c b/gdb/stack.c
index d9c4f0a..beab952 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1201,24 +1201,24 @@ backtrace_command_1 (char *count_exp, int show_locals, int from_tty)
   else
     count = -1;
 
-  if (info_verbose)
-    {
-      struct partial_symtab *ps;
-
-      /* Read in symbols for all of the frames.  Need to do this in a
-         separate pass so that "Reading in symbols for xxx" messages
-         don't screw up the appearance of the backtrace.  Also if
-         people have strong opinions against reading symbols for
-         backtrace this may have to be an option.  */
-      i = count;
-      for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi))
-	{
-	  QUIT;
-	  ps = find_pc_psymtab (get_frame_address_in_block (fi));
-	  if (ps)
-	    PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in.  */
-	}
-    }
+  {
+    struct partial_symtab *ps;
+
+    /* Read in symbols for all of the frames.  Need to do this
+       unconditionally to ensure that psymbols are read.  Also need to
+       do this in a separate pass so that "Reading in symbols for xxx"
+       messages don't screw up the appearance of the backtrace.  Also
+       if people have strong opinions against reading symbols for
+       backtrace this may have to be an option.  */
+    i = count;
+    for (fi = trailing; fi != NULL && i--; fi = get_prev_frame (fi))
+      {
+	QUIT;
+	ps = find_pc_psymtab (get_frame_address_in_block (fi));
+	if (info_verbose && ps)
+	  PSYMTAB_TO_SYMTAB (ps); /* Force syms to come in.  */
+      }
+  }
 
   for (i = 0, fi = trailing; fi && count--; i++, fi = get_prev_frame (fi))
     {
diff --git a/gdb/symfile.c b/gdb/symfile.c
index faa375b..a069843 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -978,13 +978,15 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
   /* Give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
 
-  if ((have_full_symbols () || have_partial_symbols ())
-      && mainline
+  if (mainline
       && from_tty
+      && (have_full_symbols () || have_partial_symbols ())
       && !query ("Load new symbol table from \"%s\"? ", name))
     error (_("Not confirmed."));
 
   objfile = allocate_objfile (abfd, flags);
+  if (mainline)
+    objfile->flags |= OBJF_MAIN;
   discard_cleanups (my_cleanups);
 
   if (addrs)
@@ -1020,6 +1022,8 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
 
   if ((flags & OBJF_READNOW) || readnow_symbol_files)
     {
+      require_partial_symbols (objfile);
+
       if ((from_tty || info_verbose) && print_symbol_loading)
 	{
 	  printf_unfiltered (_("expanding to full symbols..."));
@@ -1062,6 +1066,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
       xfree (debugfile);
     }
 
+#if 0
   if (!have_partial_symbols () && !have_full_symbols ()
       && print_symbol_loading)
     {
@@ -1073,6 +1078,7 @@ symbol_file_add_with_addrs_or_offsets (bfd *abfd, int from_tty,
         printf_filtered ("\n");
       wrap_here ("");
     }
+#endif
 
   if (from_tty || info_verbose)
     {
@@ -2408,13 +2414,16 @@ reread_symbols (void)
 	         zero is OK since dbxread.c also does what it needs to do if
 	         objfile->global_psymbols.size is 0.  */
 	      (*objfile->sf->sym_read) (objfile, 0);
+#if 0
 	      if (!have_partial_symbols () && !have_full_symbols ())
 		{
 		  wrap_here ("");
 		  printf_unfiltered (_("(no debugging symbols found)\n"));
 		  wrap_here ("");
 		}
+#endif
 	      objfile->flags |= OBJF_SYMS;
+	      objfile->flags &= ~OBJF_SYMTABS_READ;
 
 	      /* We're done reading the symbol file; finish off complaints.  */
 	      clear_complaints (&symfile_complaints, 0, 1);
diff --git a/gdb/symfile.h b/gdb/symfile.h
index 02fb7df..dfb4cbe 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -139,6 +139,12 @@ struct sym_fns
 
   void (*sym_read) (struct objfile *, int);
 
+  /* Read the partial symbols for an objfile.  This may be NULL, in
+     which case gdb assumes that sym_read already read the partial
+     symbols.  */
+
+  void (*sym_read_psymbols) (struct objfile *);
+
   /* Called when we are finished with an objfile.  Should do all
      cleanup that is specific to the object file format for the
      particular objfile.  */
@@ -368,7 +374,7 @@ void free_symfile_segment_data (struct symfile_segment_data *data);
 /* From dwarf2read.c */
 
 extern int dwarf2_has_info (struct objfile *);
-
+extern void dwarf2_create_quick_addrmap (struct objfile *);
 extern void dwarf2_build_psymtabs (struct objfile *, int);
 extern void dwarf2_build_frame_info (struct objfile *);
 
diff --git a/gdb/symtab.c b/gdb/symtab.c
index db84f4f..b4e545c 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -271,7 +271,7 @@ lookup_partial_symtab (const char *name)
       make_cleanup (xfree, real_path);
     }
 
-  ALL_PSYMTABS (objfile, pst)
+  ALL_PSYMTABS_REQUIRED (objfile, pst)
   {
     if (FILENAME_CMP (name, pst->filename) == 0)
       {
@@ -865,7 +865,13 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
      than the later used TEXTLOW/TEXTHIGH one.  */
 
   ALL_OBJFILES (objfile)
-    if (objfile->psymtabs_addrmap != NULL)
+  {
+    if (objfile->quick_addrmap)
+      {
+	if (!addrmap_find (objfile->quick_addrmap, pc))
+	  continue;
+      }
+    if (require_partial_symbols (objfile)->psymtabs_addrmap != NULL)
       {
 	struct partial_symtab *pst;
 
@@ -898,6 +904,7 @@ find_pc_sect_psymtab (CORE_ADDR pc, asection *section)
 	    return pst;
 	  }
       }
+  }
 
   /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
      which still have no corresponding full SYMTABs read.  But it is not
@@ -1165,6 +1172,22 @@ fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
   return psym;
 }
 
+/* Ensure that the partial symbols for OBJFILE have been loaded.  This
+   function always returns its argument, as a convenience.  */
+
+struct objfile *
+require_partial_symbols (struct objfile *objfile)
+{
+  if ((objfile->flags & OBJF_SYMTABS_READ) == 0)
+    {
+      objfile->flags |= OBJF_SYMTABS_READ;
+
+      if (objfile->sf->sym_read_psymbols)
+	(*objfile->sf->sym_read_psymbols) (objfile);
+    }
+  return objfile;
+}
+
 /* Find the definition for a specified symbol name NAME
    in domain DOMAIN, visible from lexical block BLOCK.
    Returns the struct symbol pointer, or zero if no symbol is found.
@@ -1445,6 +1468,7 @@ lookup_global_symbol_from_objfile (const struct objfile *objfile,
   }
 
   /* Now go through psymtabs.  */
+  require_partial_symbols ((struct objfile *) objfile);
   ALL_OBJFILE_PSYMTABS (objfile, ps)
   {
     if (!ps->readin
@@ -1515,7 +1539,7 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name,
   struct symtab *s;
   const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
 
-  ALL_PSYMTABS (objfile, ps)
+  ALL_PSYMTABS_REQUIRED (objfile, ps)
   {
     if (!ps->readin
 	&& lookup_partial_symbol (ps, name, linkage_name,
@@ -1889,7 +1913,21 @@ find_main_psymtab (void)
   struct partial_symtab *pst;
   struct objfile *objfile;
 
-  ALL_PSYMTABS (objfile, pst)
+  ALL_OBJFILES (objfile)
+  {
+    if ((objfile->flags & OBJF_MAIN) == 0)
+      continue;
+    require_partial_symbols (objfile);
+    ALL_OBJFILE_PSYMTABS (objfile, pst)
+    {
+      if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN))
+	{
+	  return pst;
+	}
+    }
+  }
+
+  ALL_PSYMTABS_REQUIRED (objfile, pst)
   {
     if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN))
       {
@@ -3081,7 +3119,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
      matching the regexp.  That way we don't have to reproduce all of
      the machinery below. */
 
-  ALL_PSYMTABS (objfile, ps)
+  ALL_PSYMTABS_REQUIRED (objfile, ps)
   {
     struct partial_symbol **bound, **gbound, **sbound;
     int keep_going = 1;
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 31aed86..25a927a 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1040,6 +1040,8 @@ extern void clear_pc_function_cache (void);
 
 /* from symtab.c: */
 
+struct objfile *require_partial_symbols (struct objfile *);
+
 /* lookup partial symbol table by filename */
 
 extern struct partial_symtab *lookup_partial_symtab (const char *);
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index 54e2aba..c903fae 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -3020,6 +3020,7 @@ static struct sym_fns xcoff_sym_fns =
   xcoff_new_init,		/* sym_new_init: init anything gbl to entire symtab */
   xcoff_symfile_init,		/* sym_init: read initial info, setup for sym_read() */
   xcoff_initial_scan,		/* sym_read: read a symbol file into symtab */
+  NULL,				/* sym_read_psymbols */
   xcoff_symfile_finish,		/* sym_finish: finished with file, cleanup */
   xcoff_symfile_offsets,	/* sym_offsets: xlate offsets ext->int form */
   default_symfile_segments,	/* sym_segments: Get segment information from


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]