This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB 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]

[PATCH] Improved support for overlay breakpoints in ROM



This patch allows gdb to handle breakpoints in overlays, even if the
overlays are kept in ROM when not being executed.  It works by allowing
the overlay manager to notify gdb whenever there is a change in the
overlay mapping table, thus allowing gdb to update breakpoints.

2002-02-04  Michael Snyder  <msnyder@redhat.com>

	* breakpoint.h (enum bptype): Add new overlay event bp type.
	(enable_overlay_breakpoints, disable_overlay_breakpoints): Export.
	
	* breakpoint.c (create_internal_breakpoint): New function.
	(intenal_breakpoint_number): Moved into create_internal_breakpoint.
	(create_longjmp_breakpoint): Use create_internal_breakpoint.
	(create_thread_event_breakpoint): Ditto.
	(create_solib_event_breakpoint): Ditto.
	(create_overlay_event_breakpoint): New function.
	(enable_overlay_breakpoints, disable_overlay_breakpoints): New funcs.
	(update_breakpoints_after_exec): Delete and re-initialize
	overlay event breakpoints after an exec.  Add FIXME comment
	about longjmp breakpoint.
	(print_it_typical): Ignore overlay event breakpoints.
	(print_one_breakpoint): Ditto.
	(mention): Ditto.
	(bpstat_what): Do not stop for overlay event breakpoints.
	(delete_breakpoint): Don't delete overlay event breakpoints.
	(breakpoint_re_set_one): Delete the overlay event breakpoint.
	(breakpoint_re_set): Re-create overlay event breakpoint.

	* symfile.c (overlay_auto_command): Enable overlay breakpoints.
	(overlay_manual_command): Disable overlay breakpoints.
	(overlay_off_command): Disable overlay breakpoints.

2002-02-04  Michael Snyder  <msnyder@redhat.com>

	* testsuite/gdb.base/ovlymgr.c (_ovly_debug_event): New function.
	(OverlayLoad, OverlayUnload): Add calls to _ovly_debug_event.

Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.64
diff -c -3 -p -r1.64 breakpoint.c
*** breakpoint.c	2002/02/03 11:43:19	1.64
--- breakpoint.c	2002/02/04 23:54:30
*************** static int get_number_trailer (char **, 
*** 117,126 ****
  
  void set_breakpoint_count (int);
  
- #if 0
- static struct breakpoint *create_temp_exception_breakpoint (CORE_ADDR);
- #endif
- 
  typedef enum
    {
      mark_inserted,
--- 117,122 ----
*************** static void maintenance_info_breakpoints
*** 151,156 ****
--- 147,154 ----
  static void create_longjmp_breakpoint (char *);
  #endif
  
+ static void create_overlay_event_breakpoint (char *);
+ 
  static int hw_breakpoint_used_count (void);
  
  static int hw_watchpoint_used_count (enum bptype, int *);
*************** void _initialize_breakpoint (void);
*** 218,225 ****
  
  extern int addressprint;	/* Print machine addresses? */
  
- static int internal_breakpoint_number = -1;
- 
  /* Are we executing breakpoint commands?  */
  static int executing_breakpoint_commands;
  
--- 216,221 ----
*************** update_breakpoints_after_exec (void)
*** 1107,1114 ****
  	continue;
        }
  
!     /* Thread event breakpoints must be set anew after an exec().  */
!     if (b->type == bp_thread_event)
        {
  	delete_breakpoint (b);
  	continue;
--- 1103,1111 ----
  	continue;
        }
  
!     /* Thread event breakpoints must be set anew after an exec(),
!        as must overlay event breakpoints.  */
!     if (b->type == bp_thread_event || b->type == bp_overlay_event)
        {
  	delete_breakpoint (b);
  	continue;
*************** update_breakpoints_after_exec (void)
*** 1216,1221 ****
--- 1213,1220 ----
         So I think this assignment could be deleted without effect.  */
      b->address = (CORE_ADDR) NULL;
    }
+   /* FIXME what about longjmp breakpoints?  Re-create them here?  */
+   create_overlay_event_breakpoint ("_ovly_debug_event");
  }
  
  int
*************** print_it_typical (bpstat bs)
*** 1910,1915 ****
--- 1909,1920 ----
        return PRINT_NOTHING;
        break;
  
+     case bp_overlay_event:
+       /* By analogy with the thread event, GDB should not stop for these. */
+       printf_filtered ("Overlay Event Breakpoint: gdb should not stop!\n");
+       return PRINT_NOTHING;
+       break;
+ 
      case bp_catch_load:
        annotate_catchpoint (bs->breakpoint_at->number);
        printf_filtered ("\nCatchpoint %d (", bs->breakpoint_at->number);
*************** bpstat_what (bpstat bs)
*** 2896,2901 ****
--- 2901,2907 ----
  	  bs_class = shlib_event;
  	  break;
  	case bp_thread_event:
+ 	case bp_overlay_event:
  	  bs_class = bp_nostop;
  	  break;
  	case bp_catch_load:
*************** print_one_breakpoint (struct breakpoint 
*** 3072,3077 ****
--- 3078,3084 ----
      {bp_call_dummy, "call dummy"},
      {bp_shlib_event, "shlib events"},
      {bp_thread_event, "thread events"},
+     {bp_overlay_event, "overlay events"},
      {bp_catch_load, "catch load"},
      {bp_catch_unload, "catch unload"},
      {bp_catch_fork, "catch fork"},
*************** print_one_breakpoint (struct breakpoint 
*** 3228,3233 ****
--- 3235,3241 ----
      case bp_call_dummy:
      case bp_shlib_event:
      case bp_thread_event:
+     case bp_overlay_event:
        if (addressprint)
  	{
  	  annotate_field (4);
*************** make_breakpoint_permanent (struct breakp
*** 3731,3766 ****
    b->inserted = 1;
  }
  
  #ifdef GET_LONGJMP_TARGET
  
  static void
  create_longjmp_breakpoint (char *func_name)
  {
-   struct symtab_and_line sal;
    struct breakpoint *b;
  
!   INIT_SAL (&sal);		/* initialize to zeroes */
!   if (func_name != NULL)
      {
!       struct minimal_symbol *m;
! 
!       m = lookup_minimal_symbol_text (func_name, NULL, 
! 				      (struct objfile *) NULL);
!       if (m)
! 	sal.pc = SYMBOL_VALUE_ADDRESS (m);
!       else
  	return;
      }
-   sal.section = find_pc_overlay (sal.pc);
-   b = set_raw_breakpoint (sal,
-                           func_name != NULL ? bp_longjmp : bp_longjmp_resume);
  
-   b->disposition = disp_donttouch;
    b->enable_state = bp_disabled;
    b->silent = 1;
    if (func_name)
      b->addr_string = xstrdup (func_name);
-   b->number = internal_breakpoint_number--;
  }
  
  #endif /* #ifdef GET_LONGJMP_TARGET */
--- 3739,3785 ----
    b->inserted = 1;
  }
  
+ static struct breakpoint *
+ create_internal_breakpoint (CORE_ADDR address, enum bptype type)
+ {
+   static int internal_breakpoint_number = -1;
+   struct symtab_and_line sal;
+   struct breakpoint *b;
+ 
+   INIT_SAL (&sal);		/* initialize to zeroes */
+ 
+   sal.pc = address;
+   sal.section = find_pc_overlay (sal.pc);
+ 
+   b = set_raw_breakpoint (sal, type);
+   b->number = internal_breakpoint_number--;
+   b->disposition = disp_donttouch;
+ 
+   return b;
+ }
+ 
  #ifdef GET_LONGJMP_TARGET
  
  static void
  create_longjmp_breakpoint (char *func_name)
  {
    struct breakpoint *b;
+   struct minimal_symbol *m;
  
!   if (func_name == NULL)
!     b = create_internal_breakpoint (0, bp_longjmp_resume);
!   else
      {
!       if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL)
  	return;
+  
+       b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
      }
  
    b->enable_state = bp_disabled;
    b->silent = 1;
    if (func_name)
      b->addr_string = xstrdup (func_name);
  }
  
  #endif /* #ifdef GET_LONGJMP_TARGET */
*************** disable_longjmp_breakpoint (void)
*** 3796,3815 ****
      }
  }
  
  struct breakpoint *
  create_thread_event_breakpoint (CORE_ADDR address)
  {
    struct breakpoint *b;
-   struct symtab_and_line sal;
    char addr_string[80];		/* Surely an addr can't be longer than that. */
  
!   INIT_SAL (&sal);		/* initialize to zeroes */
!   sal.pc = address;
!   sal.section = find_pc_overlay (sal.pc);
!   b = set_raw_breakpoint (sal, bp_thread_event);
    
-   b->number = internal_breakpoint_number--;
-   b->disposition = disp_donttouch;
    b->enable_state = bp_enabled;
    /* addr_string has to be used or breakpoint_re_set will delete me.  */
    sprintf (addr_string, "*0x%s", paddr (b->address));
--- 3815,3875 ----
      }
  }
  
+ static struct breakpoint *
+ create_overlay_event_breakpoint (char *func_name)
+ {
+   struct breakpoint *b;
+   struct minimal_symbol *m;
+ 
+   if ((m = lookup_minimal_symbol_text (func_name, NULL, NULL)) == NULL)
+     return NULL;
+  
+   b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), 
+ 				  bp_overlay_event);
+   b->addr_string = xstrdup (func_name);
+ 
+   if (overlay_debugging == ovly_auto)
+     b->enable_state = bp_enabled;
+   else 
+     b->enable_state = bp_disabled;
+ 
+   return b;
+ }
+ 
+ void
+ enable_overlay_breakpoints (void)
+ {
+   register struct breakpoint *b;
+ 
+   ALL_BREAKPOINTS (b)
+     if (b->type == bp_overlay_event)
+     {
+       b->enable_state = bp_enabled;
+       check_duplicates (b);
+     }
+ }
+ 
+ void
+ disable_overlay_breakpoints (void)
+ {
+   register struct breakpoint *b;
+ 
+   ALL_BREAKPOINTS (b)
+     if (b->type == bp_overlay_event)
+     {
+       b->enable_state = bp_disabled;
+       check_duplicates (b);
+     }
+ }
+ 
  struct breakpoint *
  create_thread_event_breakpoint (CORE_ADDR address)
  {
    struct breakpoint *b;
    char addr_string[80];		/* Surely an addr can't be longer than that. */
  
!   b = create_internal_breakpoint (address, bp_thread_event);
    
    b->enable_state = bp_enabled;
    /* addr_string has to be used or breakpoint_re_set will delete me.  */
    sprintf (addr_string, "*0x%s", paddr (b->address));
*************** struct breakpoint *
*** 3843,3857 ****
  create_solib_event_breakpoint (CORE_ADDR address)
  {
    struct breakpoint *b;
-   struct symtab_and_line sal;
  
!   INIT_SAL (&sal);		/* initialize to zeroes */
!   sal.pc = address;
!   sal.section = find_pc_overlay (sal.pc);
!   b = set_raw_breakpoint (sal, bp_shlib_event);
!   b->number = internal_breakpoint_number--;
!   b->disposition = disp_donttouch;
! 
    return b;
  }
  
--- 3903,3910 ----
  create_solib_event_breakpoint (CORE_ADDR address)
  {
    struct breakpoint *b;
  
!   b = create_internal_breakpoint (address, bp_shlib_event);
    return b;
  }
  
*************** mention (struct breakpoint *b)
*** 4311,4316 ****
--- 4364,4370 ----
      case bp_watchpoint_scope:
      case bp_shlib_event:
      case bp_thread_event:
+     case bp_overlay_event:
        break;
      }
    if (say_where)
*************** delete_command (char *arg, int from_tty)
*** 6665,6670 ****
--- 6719,6725 ----
  	if (b->type != bp_call_dummy &&
  	    b->type != bp_shlib_event &&
  	    b->type != bp_thread_event &&
+ 	    b->type != bp_overlay_event &&
  	    b->number >= 0)
  	  breaks_to_delete = 1;
        }
*************** delete_command (char *arg, int from_tty)
*** 6678,6683 ****
--- 6733,6739 ----
  	    if (b->type != bp_call_dummy &&
  		b->type != bp_shlib_event &&
  		b->type != bp_thread_event &&
+ 		b->type != bp_overlay_event &&
  		b->number >= 0)
  	      delete_breakpoint (b);
  	  }
*************** breakpoint_re_set_one (PTR bint)
*** 6861,6870 ****
      default:
        printf_filtered ("Deleting unknown breakpoint type %d\n", b->type);
        /* fall through */
!       /* Delete longjmp breakpoints, they will be reset later by
!          breakpoint_re_set.  */
      case bp_longjmp:
      case bp_longjmp_resume:
        delete_breakpoint (b);
        break;
  
--- 6917,6927 ----
      default:
        printf_filtered ("Deleting unknown breakpoint type %d\n", b->type);
        /* fall through */
!       /* Delete longjmp and overlay event breakpoints; they will be
!          reset later by breakpoint_re_set.  */
      case bp_longjmp:
      case bp_longjmp_resume:
+     case bp_overlay_event:
        delete_breakpoint (b);
        break;
  
*************** breakpoint_re_set (void)
*** 6919,6924 ****
--- 6976,6982 ----
    create_longjmp_breakpoint ("_siglongjmp");
    create_longjmp_breakpoint (NULL);
  #endif
+   create_overlay_event_breakpoint ("_ovly_debug_event");
  }
  
  /* Reset the thread number of this breakpoint:
*************** map_breakpoint_numbers (char *args, void
*** 7046,7051 ****
--- 7104,7113 ----
        p = p1;
      }
  }
+ 
+ /* Set ignore-count of breakpoint number BPTNUM to COUNT.
+    If from_tty is nonzero, it prints a message to that effect,
+    which ends with a period (no newline).  */
  
  void
  disable_breakpoint (struct breakpoint *bpt)
Index: breakpoint.h
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.h,v
retrieving revision 1.10
diff -c -3 -p -r1.10 breakpoint.h
*** breakpoint.h	2001/10/20 23:54:29	1.10
--- breakpoint.h	2002/02/04 23:54:30
*************** enum bptype
*** 107,112 ****
--- 107,120 ----
  
      bp_thread_event,
  
+     /* On the same principal, an overlay manager can arrange to call a
+        magic location in the inferior whenever there is an interesting
+        change in overlay status.  GDB can update its overlay tables
+        and fiddle with breakpoints in overlays when this breakpoint 
+        is hit.  */
+ 
+     bp_overlay_event, 
+ 
      /* These breakpoints are used to implement the "catch load" command
         on platforms whose dynamic linkers support such functionality.  */
      bp_catch_load,
*************** extern void update_breakpoints_after_exe
*** 603,610 ****
  extern int detach_breakpoints (int);
  
  extern void enable_longjmp_breakpoint (void);
- 
  extern void disable_longjmp_breakpoint (void);
  
  extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_info *);
  /* These functions respectively disable or reenable all currently
--- 611,619 ----
  extern int detach_breakpoints (int);
  
  extern void enable_longjmp_breakpoint (void);
  extern void disable_longjmp_breakpoint (void);
+ extern void enable_overlay_breakpoint (void);
+ extern void disable_overlay_breakpoint (void);
  
  extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_info *);
  /* These functions respectively disable or reenable all currently
Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.51
diff -c -3 -p -r1.51 symfile.c
*** symfile.c	2002/02/01 01:14:20	1.51
--- symfile.c	2002/02/04 23:54:31
*************** static void
*** 2898,2903 ****
--- 2898,2904 ----
  overlay_auto_command (char *args, int from_tty)
  {
    overlay_debugging = ovly_auto;
+   enable_overlay_breakpoints ();
    if (info_verbose)
      printf_filtered ("Automatic overlay debugging enabled.");
  }
*************** static void
*** 2910,2915 ****
--- 2911,2917 ----
  overlay_manual_command (char *args, int from_tty)
  {
    overlay_debugging = ovly_on;
+   disable_overlay_breakpoints ();
    if (info_verbose)
      printf_filtered ("Overlay debugging enabled.");
  }
*************** static void
*** 2922,2927 ****
--- 2924,2930 ----
  overlay_off_command (char *args, int from_tty)
  {
    overlay_debugging = ovly_off;
+   disable_overlay_breakpoints ();
    if (info_verbose)
      printf_filtered ("Overlay debugging disabled.");
  }
Index: testsuite/gdb.base/ovlymgr.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/ovlymgr.c,v
retrieving revision 1.1.1.1
diff -c -3 -p -r1.1.1.1 ovlymgr.c
*** ovlymgr.c	1999/04/16 01:34:31	1.1.1.1
--- ovlymgr.c	2002/02/05 00:11:50
*************** FlushCache (void)
*** 30,35 ****
--- 30,44 ----
  #endif
  }
  
+ /* _ovly_debug_event:
+  * Debuggers may set a breakpoint here, to be notified 
+  * when the overlay table has been modified.
+  */
+ static void
+ _ovly_debug_event (void)
+ {
+ }
+ 
  /* OverlayLoad:
   * Copy the overlay into its runtime region,
   * and mark the overlay as "mapped".
*************** OverlayLoad (unsigned long ovlyno)
*** 58,63 ****
--- 67,74 ----
  
    FlushCache ();
  
+   /* Notify debugger, if any. */
+   _ovly_debug_event ();
    return TRUE;
  }
  
*************** OverlayUnload (unsigned long ovlyno)
*** 80,85 ****
--- 91,100 ----
  	     _ovly_table[ovlyno][VMA],
  	     _ovly_table[ovlyno][SIZE]);
  
+ #if 0
+   /* Does the debugger need to be notified of an unload event? */
+   _ovly_debug_event ();
+ #endif
    return TRUE;
  }
  


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