From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13634 invoked by alias); 5 Feb 2002 00:40:16 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 13418 invoked from network); 5 Feb 2002 00:40:07 -0000 Received: from unknown (HELO cygnus.com) (205.180.230.5) by sources.redhat.com with SMTP; 5 Feb 2002 00:40:07 -0000 Received: from redhat.com (reddwarf.sfbay.redhat.com [205.180.231.12]) by runyon.cygnus.com (8.8.7-cygnus/8.8.7) with ESMTP id QAA28283; Mon, 4 Feb 2002 16:39:53 -0800 (PST) Message-ID: <3C5F2831.1282E68B@redhat.com> Date: Mon, 04 Feb 2002 16:40:00 -0000 From: Michael Snyder Organization: Red Hat, Inc. X-Mailer: Mozilla 4.76 [en] (X11; U; Linux 2.4.2-2smp i686) X-Accept-Language: en MIME-Version: 1.0 To: Michael Snyder CC: gdb-patches@sources.redhat.com, ezannoni@redhat.com, jimb@redhat.com Subject: [RFA] Improved support for overlay breakpoints in ROM References: <200202050011.g150BfB21148@reddwarf.cygnus.com> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-SW-Source: 2002-02/txt/msg00093.txt.bz2 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 > > * 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 > > * 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; > } >