* config/m68k/monitor.mt (TDEPFILE): Add remote-es.o.
[deliverable/binutils-gdb.git] / gdb / solib.c
index e4bf9d73ec4625a5c13c0462de5bdb3bf7bd29e8..854d6ea2df22dc35a40c7622bb75b93eb80132e6 100644 (file)
@@ -42,6 +42,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "frame.h"
 #include "regex.h"
 #include "inferior.h"
+#include "language.h"
 
 #define MAX_PATH_SIZE 256              /* FIXME: Should be dynamic */
 
@@ -57,6 +58,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #define BKPT_AT_SYMBOL 1
 
+#if defined (BKPT_AT_SYMBOL) && defined (SVR4_SHARED_LIBS)
 static char *bkpt_names[] = {
 #ifdef SOLIB_BKPT_NAME
   SOLIB_BKPT_NAME,             /* Prefer configured name if it exists. */
@@ -65,6 +67,7 @@ static char *bkpt_names[] = {
   "main",
   NULL
 };
+#endif
 
 /* local data declarations */
 
@@ -103,7 +106,7 @@ struct so_list {
   struct section_table *sections;
   struct section_table *sections_end;
   struct section_table *textsection;
-  bfd *bfd;
+  bfd *abfd;
 };
 
 static struct so_list *so_list_head;   /* List of known shared objects */
@@ -212,9 +215,9 @@ solib_map_sections (so)
     {
       perror_with_name (filename);
     }
-  /* Leave scratch_pathname allocated.  bfd->name will point to it.  */
+  /* Leave scratch_pathname allocated.  abfd->name will point to it.  */
 
-  abfd = bfd_fdopenr (scratch_pathname, NULL, scratch_chan);
+  abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
   if (!abfd)
     {
       close (scratch_chan);
@@ -222,7 +225,7 @@ solib_map_sections (so)
             scratch_pathname, bfd_errmsg (bfd_error));
     }
   /* Leave bfd open, core_xfer_memory and "info files" need it.  */
-  so -> bfd = abfd;
+  so -> abfd = abfd;
   abfd -> cacheable = true;
 
   if (!bfd_check_format (abfd, bfd_object))
@@ -259,6 +262,17 @@ solib_map_sections (so)
 
 #ifndef SVR4_SHARED_LIBS
 
+/* In GDB 4.9 this routine was a real performance hog.  According to
+   some gprof data which mtranle@paris.IntelliCorp.COM (Minh Tran-Le)
+   sent, almost all the time spend in solib_add (up to 20 minutes with
+   35 shared libraries) was spent here, with 5/6 in
+   lookup_minimal_symbol and 1/6 in read_memory.
+
+   To fix this, we moved the call to special_symbol_handling out of the
+   loop in solib_add, so this only gets called once, rather than once
+   for every shared library, and also removed the call to lookup_minimal_symbol
+   in this routine.  */
+
 static void
 solib_add_common_symbols (rtc_symp, objfile)
     struct rtc_symb *rtc_symp;
@@ -298,15 +312,21 @@ solib_add_common_symbols (rtc_symp, objfile)
              name++;
            }
 
+#if 0
+         /* I think this is unnecessary, GDB can probably deal with
+            duplicate minimal symbols, more or less.  And the duplication
+            which used to happen because this was called for each shared
+            library is gone now that we are just called once.  */
          /* FIXME:  Do we really want to exclude symbols which happen
             to match symbols for other locations in the inferior's
             address space, even when they are in different linkage units? */
          if (lookup_minimal_symbol (name, (struct objfile *) NULL) == NULL)
+#endif
            {
              name = obsavestring (name, strlen (name),
                                   &objfile -> symbol_obstack);
              prim_record_minimal_symbol (name, inferior_rtc_nlist.n_value,
-                                         mst_bss);
+                                         mst_bss, objfile);
            }
          free (origname);
        }
@@ -422,7 +442,7 @@ look_for_base (fd, baseaddr)
      mapped memory segment, so skip it.  Also, if the fd corresponds
      to the exec file, skip it as well. */
 
-  if ((fd == -1) || fdmatch (fileno ((FILE *)(exec_bfd -> iostream)), fd))
+  if ((fd == -1) || fdmatch (fileno ((GDB_FILE *)(exec_bfd -> iostream)), fd))
     {
       return (0);
     }
@@ -431,7 +451,7 @@ look_for_base (fd, baseaddr)
      we have no way currently to find the filename.  Don't gripe about
      any problems we might have, just fail. */
 
-  if ((interp_bfd = bfd_fdopenr ("unnamed", NULL, fd)) == NULL)
+  if ((interp_bfd = bfd_fdopenr ("unnamed", gnutarget, fd)) == NULL)
     {
       return (0);
     }
@@ -739,6 +759,10 @@ solib_add (arg_string, from_tty, target)
      struct target_ops *target;
 {      
   register struct so_list *so = NULL;          /* link map state variable */
+
+  /* Last shared library that we read.  */
+  struct so_list *so_last = NULL;
+
   char *re_err;
   int count;
   int old;
@@ -761,14 +785,15 @@ solib_add (arg_string, from_tty, target)
            {
              if (from_tty)
                {
-                 printf ("Symbols already loaded for %s\n", so -> so_name);
+                 printf_unfiltered ("Symbols already loaded for %s\n", so -> so_name);
                }
            }
          else if (catch_errors
                   (symbol_add_stub, (char *) so,
-                   "Error while reading shared library symbols:\n"))
+                   "Error while reading shared library symbols:\n",
+                   RETURN_MASK_ALL))
            {
-             special_symbol_handling (so);
+             so_last = so;
              so -> symbols_loaded = 1;
            }
        }
@@ -796,14 +821,14 @@ solib_add (arg_string, from_tty, target)
            {
              old = target -> to_sections_end - target -> to_sections;
              target -> to_sections = (struct section_table *)
-               realloc ((char *)target -> to_sections,
+               xrealloc ((char *)target -> to_sections,
                         (sizeof (struct section_table)) * (count + old));
            }
          else
            {
              old = 0;
              target -> to_sections = (struct section_table *)
-               malloc ((sizeof (struct section_table)) * count);
+               xmalloc ((sizeof (struct section_table)) * count);
            }
          target -> to_sections_end = target -> to_sections + (count + old);
          
@@ -821,6 +846,19 @@ solib_add (arg_string, from_tty, target)
            }
        }
     }
+
+  /* Calling this once at the end means that we put all the minimal
+     symbols for commons into the objfile for the last shared library.
+     Since they are in common, this should not be a problem.  If we
+     delete the objfile with the minimal symbols, we can put all the
+     symbols into a new objfile (and will on the next call to solib_add).
+
+     An alternate approach would be to create an objfile just for
+     common minsyms, thus not needing any objfile argument to
+     solib_add_common_symbols.  */
+
+  if (so_last)
+    special_symbol_handling (so_last);
 }
 
 /*
@@ -849,7 +887,7 @@ info_sharedlibrary_command (ignore, from_tty)
   
   if (exec_bfd == NULL)
     {
-      printf ("No exec file.\n");
+      printf_unfiltered ("No exec file.\n");
       return;
     }
   while ((so = find_solib (so)) != NULL)
@@ -858,19 +896,23 @@ info_sharedlibrary_command (ignore, from_tty)
        {
          if (!header_done)
            {
-             printf("%-12s%-12s%-12s%s\n", "From", "To", "Syms Read",
+             printf_unfiltered("%-12s%-12s%-12s%s\n", "From", "To", "Syms Read",
                     "Shared Object Library");
              header_done++;
            }
-         printf ("%-12s", local_hex_string_custom ((int) LM_ADDR (so), "08"));
-         printf ("%-12s", local_hex_string_custom (so -> lmend, "08"));
-         printf ("%-12s", so -> symbols_loaded ? "Yes" : "No");
-         printf ("%s\n",  so -> so_name);
+         printf_unfiltered ("%-12s",
+                 local_hex_string_custom ((unsigned long) LM_ADDR (so),
+                                          "08l"));
+         printf_unfiltered ("%-12s",
+                 local_hex_string_custom ((unsigned long) so -> lmend,
+                                          "08l"));
+         printf_unfiltered ("%-12s", so -> symbols_loaded ? "Yes" : "No");
+         printf_unfiltered ("%s\n",  so -> so_name);
        }
     }
   if (so_list_head == NULL)
     {
-      printf ("No shared libraries loaded at this time.\n");   
+      printf_unfiltered ("No shared libraries loaded at this time.\n");        
     }
 }
 
@@ -932,10 +974,10 @@ clear_solib()
        {
          free ((PTR)so_list_head -> sections);
        }
-      if (so_list_head -> bfd)
+      if (so_list_head -> abfd)
        {
-         bfd_filename = bfd_get_filename (so_list_head -> bfd);
-         bfd_close (so_list_head -> bfd);
+         bfd_filename = bfd_get_filename (so_list_head -> abfd);
+         bfd_close (so_list_head -> abfd);
        }
       else
        /* This happens for the executable on SVR4.  */
@@ -1198,12 +1240,17 @@ FIXME
 void 
 solib_create_inferior_hook()
 {
-  
+  /* If we are using the BKPT_AT_SYMBOL code, then we don't need the base
+     yet.  In fact, in the case of a SunOS4 executable being run on
+     Solaris, we can't get it yet.  find_solib will get it when it needs
+     it.  */
+#if !(defined (SVR4_SHARED_LIBS) && defined (BKPT_AT_SYMBOL))
   if ((debug_base = locate_base ()) == 0)
     {
       /* Can't find the symbol or the executable is statically linked. */
       return;
     }
+#endif
 
   if (!enable_break ())
     {
@@ -1221,7 +1268,7 @@ solib_create_inferior_hook()
   stop_signal = 0;
   do
     {
-      target_resume (0, stop_signal);
+      target_resume (-1, 0, stop_signal);
       wait_for_inferior ();
     }
   while (stop_signal != SIGTRAP);
This page took 0.028087 seconds and 4 git commands to generate.