2011-02-15 Paul Pluzhnikov <ppluzhnikov@google.com>
authorPaul Pluzhnikov <ppluzhnikov@google.com>
Tue, 15 Feb 2011 21:43:25 +0000 (21:43 +0000)
committerPaul Pluzhnikov <ppluzhnikov@google.com>
Tue, 15 Feb 2011 21:43:25 +0000 (21:43 +0000)
* breakpoint.c (longjmp_names): New variable.
(struct breakpoint_objfile_data): New type.
(breakpoint_objfile_key): New variable.
(msym_not_found): New variable.
(msym_not_found_p): New predicate.
(get_breakpoint_objfile_data): New function.
(create_overlay_event_breakpoint): Check per-objfile cache for
symbols first.
(create_longjmp_master_breakpoint): Likewise.
(create_std_terminate_master_breakpoint): Likewise.
(create_exception_master_breakpoint): Likewise.
(_initialize_breakpoint): Register per-objfile data key.

gdb/ChangeLog
gdb/breakpoint.c

index eba948a86fe553c660ed900907057efef6b0d885..24ab512e75da1417ff02524f273154efd21c07c1 100644 (file)
@@ -1,3 +1,18 @@
+2011-02-15  Paul Pluzhnikov  <ppluzhnikov@google.com>
+
+       * breakpoint.c (longjmp_names): New variable.
+       (struct breakpoint_objfile_data): New type.
+       (breakpoint_objfile_key): New variable.
+       (msym_not_found): New variable.
+       (msym_not_found_p): New predicate.
+       (get_breakpoint_objfile_data): New function.
+       (create_overlay_event_breakpoint): Check per-objfile cache for
+       symbols first.
+       (create_longjmp_master_breakpoint): Likewise.
+       (create_std_terminate_master_breakpoint): Likewise.
+       (create_exception_master_breakpoint): Likewise.
+       (_initialize_breakpoint): Register per-objfile data key.
+
 2011-02-15  Paul Pluzhnikov  <ppluzhnikov@google.com>
 
        * breakpoint.c ((create_overlay_event_breakpoint): Const-propagate
index 029ce6b22edca8d801cd3da89dc00ffba40d415d..ca56c435943b80c389fa87eb4da1828e6c328637 100644 (file)
@@ -2217,6 +2217,61 @@ create_internal_breakpoint (struct gdbarch *gdbarch,
   return b;
 }
 
+static const char *const longjmp_names[] =
+  {
+    "longjmp", "_longjmp", "siglongjmp", "_siglongjmp"
+  };
+#define NUM_LONGJMP_NAMES ARRAY_SIZE(longjmp_names)
+
+/* Per-objfile data private to breakpoint.c.  */
+struct breakpoint_objfile_data
+{
+  /* Minimal symbol for "_ovly_debug_event" (if any).  */
+  struct minimal_symbol *overlay_msym;
+
+  /* Minimal symbol(s) for "longjmp", "siglongjmp", etc. (if any).  */
+  struct minimal_symbol *longjmp_msym[NUM_LONGJMP_NAMES];
+
+  /* Minimal symbol for "std::terminate()" (if any).  */
+  struct minimal_symbol *terminate_msym;
+
+  /* Minimal symbol for "_Unwind_DebugHook" (if any).  */
+  struct minimal_symbol *exception_msym;
+};
+
+static const struct objfile_data *breakpoint_objfile_key;
+
+/* Minimal symbol not found sentinel.  */
+static struct minimal_symbol msym_not_found;
+
+/* Returns TRUE if MSYM point to the "not found" sentinel.  */
+
+static int
+msym_not_found_p (const struct minimal_symbol *msym)
+{
+  return msym == &msym_not_found;
+}
+
+/* Return per-objfile data needed by breakpoint.c.
+   Allocate the data if necessary.  */
+
+static struct breakpoint_objfile_data *
+get_breakpoint_objfile_data (struct objfile *objfile)
+{
+  struct breakpoint_objfile_data *bp_objfile_data;
+
+  bp_objfile_data = objfile_data (objfile, breakpoint_objfile_key);
+  if (bp_objfile_data == NULL)
+    {
+      bp_objfile_data = obstack_alloc (&objfile->objfile_obstack,
+                                      sizeof (*bp_objfile_data));
+
+      memset (bp_objfile_data, 0, sizeof (*bp_objfile_data));
+      set_objfile_data (objfile, breakpoint_objfile_key, bp_objfile_data);
+    }
+  return bp_objfile_data;
+}
+
 static void
 create_overlay_event_breakpoint (void)
 {
@@ -2226,14 +2281,30 @@ create_overlay_event_breakpoint (void)
   ALL_OBJFILES (objfile)
     {
       struct breakpoint *b;
-      struct minimal_symbol *m;
+      struct breakpoint_objfile_data *bp_objfile_data;
+      CORE_ADDR addr;
 
-      m = lookup_minimal_symbol_text (func_name, objfile);
-      if (m == NULL)
-        continue;
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+
+      if (msym_not_found_p (bp_objfile_data->overlay_msym))
+       continue;
+
+      if (bp_objfile_data->overlay_msym == NULL)
+       {
+         struct minimal_symbol *m;
+
+         m = lookup_minimal_symbol_text (func_name, objfile);
+         if (m == NULL)
+           {
+             /* Avoid future lookups in this objfile.  */
+             bp_objfile_data->overlay_msym = &msym_not_found;
+             continue;
+           }
+         bp_objfile_data->overlay_msym = m;
+       }
 
-      b = create_internal_breakpoint (get_objfile_arch (objfile),
-                                     SYMBOL_VALUE_ADDRESS (m),
+      addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->overlay_msym);
+      b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
                                       bp_overlay_event);
       b->addr_string = xstrdup (func_name);
 
@@ -2267,31 +2338,42 @@ create_longjmp_master_breakpoint (void)
 
     ALL_OBJFILES (objfile)
     {
-      const char *const longjmp_names[]
-       = { "longjmp", "_longjmp", "siglongjmp", "_siglongjmp" };
-      const int num_longjmp_names
-       = sizeof (longjmp_names) / sizeof (longjmp_names[0]);
       int i;
       struct gdbarch *gdbarch;
+      struct breakpoint_objfile_data *bp_objfile_data;
 
       gdbarch = get_objfile_arch (objfile);
       if (!gdbarch_get_longjmp_target_p (gdbarch))
        continue;
 
-      for (i = 0; i < num_longjmp_names; i++)
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+
+      for (i = 0; i < NUM_LONGJMP_NAMES; i++)
        {
          struct breakpoint *b;
-         struct minimal_symbol *m;
          const char *func_name;
+         CORE_ADDR addr;
 
-         func_name = longjmp_names[i];
-         m = lookup_minimal_symbol_text (func_name, objfile);
-         if (m == NULL)
+         if (msym_not_found_p (bp_objfile_data->longjmp_msym[i]))
            continue;
 
-         b = create_internal_breakpoint (gdbarch,
-                                         SYMBOL_VALUE_ADDRESS (m),
-                                         bp_longjmp_master);
+         func_name = longjmp_names[i];
+         if (bp_objfile_data->longjmp_msym[i] == NULL)
+           {
+             struct minimal_symbol *m;
+
+             m = lookup_minimal_symbol_text (func_name, objfile);
+             if (m == NULL)
+               {
+                 /* Prevent future lookups in this objfile.  */
+                 bp_objfile_data->longjmp_msym[i] = &msym_not_found;
+                 continue;
+               }
+             bp_objfile_data->longjmp_msym[i] = m;
+           }
+
+         addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->longjmp_msym[i]);
+         b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master);
          b->addr_string = xstrdup (func_name);
          b->enable_state = bp_disabled;
        }
@@ -2307,31 +2389,51 @@ static void
 create_std_terminate_master_breakpoint (void)
 {
   struct program_space *pspace;
-  struct objfile *objfile;
   struct cleanup *old_chain;
   const char *const func_name = "std::terminate()";
 
   old_chain = save_current_program_space ();
 
   ALL_PSPACES (pspace)
+  {
+    struct objfile *objfile;
+    CORE_ADDR addr;
+
+    set_current_program_space (pspace);
+
     ALL_OBJFILES (objfile)
     {
       struct breakpoint *b;
-      struct minimal_symbol *m;
+      struct breakpoint_objfile_data *bp_objfile_data;
 
-      set_current_program_space (pspace);
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
 
-      m = lookup_minimal_symbol (func_name, NULL, objfile);
-      if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
-                       && MSYMBOL_TYPE (m) != mst_file_text))
-        continue;
+      if (msym_not_found_p (bp_objfile_data->terminate_msym))
+       continue;
+
+      if (bp_objfile_data->terminate_msym == NULL)
+       {
+         struct minimal_symbol *m;
+
+         m = lookup_minimal_symbol (func_name, NULL, objfile);
+         if (m == NULL || (MSYMBOL_TYPE (m) != mst_text
+                           && MSYMBOL_TYPE (m) != mst_file_text))
+           {
+             /* Prevent future lookups in this objfile.  */
+             bp_objfile_data->terminate_msym = &msym_not_found;
+             continue;
+           }
+         bp_objfile_data->terminate_msym = m;
+       }
 
-      b = create_internal_breakpoint (get_objfile_arch (objfile),
-                                     SYMBOL_VALUE_ADDRESS (m),
+      addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->terminate_msym);
+      b = create_internal_breakpoint (get_objfile_arch (objfile), addr,
                                       bp_std_terminate_master);
       b->addr_string = xstrdup (func_name);
       b->enable_state = bp_disabled;
     }
+  }
+
   update_global_location_list (1);
 
   do_cleanups (old_chain);
@@ -2343,24 +2445,42 @@ void
 create_exception_master_breakpoint (void)
 {
   struct objfile *objfile;
+  const char *const func_name = "_Unwind_DebugHook";
 
   ALL_OBJFILES (objfile)
     {
-      struct minimal_symbol *debug_hook;
+      struct breakpoint *b;
+      struct gdbarch *gdbarch;
+      struct breakpoint_objfile_data *bp_objfile_data;
+      CORE_ADDR addr;
+
+      bp_objfile_data = get_breakpoint_objfile_data (objfile);
+
+      if (msym_not_found_p (bp_objfile_data->exception_msym))
+       continue;
+
+      gdbarch = get_objfile_arch (objfile);
 
-      debug_hook = lookup_minimal_symbol ("_Unwind_DebugHook", NULL, objfile);
-      if (debug_hook != NULL)
+      if (bp_objfile_data->exception_msym == NULL)
        {
-         struct breakpoint *b;
-         CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (debug_hook);
-         struct gdbarch *gdbarch = get_objfile_arch (objfile);
+         struct minimal_symbol *debug_hook;
 
-         addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
-                                                    &current_target);
-         b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
-         b->addr_string = xstrdup ("_Unwind_DebugHook");
-         b->enable_state = bp_disabled;
+         debug_hook = lookup_minimal_symbol (func_name, NULL, objfile);
+         if (debug_hook == NULL)
+           {
+             bp_objfile_data->exception_msym = &msym_not_found;
+             continue;
+           }
+
+         bp_objfile_data->exception_msym = debug_hook;
        }
+
+      addr = SYMBOL_VALUE_ADDRESS (bp_objfile_data->exception_msym);
+      addr = gdbarch_convert_from_func_ptr_addr (gdbarch, addr,
+                                                &current_target);
+      b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
+      b->addr_string = xstrdup (func_name);
+      b->enable_state = bp_disabled;
     }
 
   update_global_location_list (1);
@@ -12074,6 +12194,8 @@ _initialize_breakpoint (void)
   observer_attach_inferior_exit (clear_syscall_counts);
   observer_attach_memory_changed (invalidate_bp_value_on_memory_change);
 
+  breakpoint_objfile_key = register_objfile_data ();
+
   breakpoint_chain = 0;
   /* Don't bother to call set_breakpoint_count.  $bpnum isn't useful
      before a breakpoint is set.  */