This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[RFA] Improved support for overlay breakpoints in ROM
- From: Michael Snyder <msnyder at redhat dot com>
- To: Michael Snyder <msnyder at cygnus dot com>
- Cc: gdb-patches at sources dot redhat dot com, ezannoni at redhat dot com, jimb at redhat dot com
- Date: Mon, 04 Feb 2002 16:32:49 -0800
- Subject: [RFA] Improved support for overlay breakpoints in ROM
- Organization: Red Hat, Inc.
- References: <200202050011.g150BfB21148@reddwarf.cygnus.com>
Err, I meant to say [RFA], not [PATCH]...
Michael Snyder wrote:
>
> 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;
> }
>