[PATCH RFA] TARGET_ADJUST_BREAKPOINT_ADDRESS...
Andrew Cagney
ac131313@cygnus.com
Thu Jun 28 14:55:00 GMT 2001
Kevin, this patch is still out there. The only person to comment was Eli:
> Printing a message is a good idea, but making it a warning IMHO is
> not. Warning is for some potential trouble, while in this case GDB is
> doing The Right Thing. Printing a warning will confuse users.
>
> Perhaps we should make the information about moving the breakpoint
> part of the "Breakpoint 1 at ..." message.
>
> My other comment is about hardware-assisted breakpoints: it looks
> like, at least in some of the examples you gave, the address of
> hardware-assisted breakpoints will also need to be adjusted in the
> same way. So I think we need some provision for that as well.
I tend to agree with Eli. Anyway, if you do want to persue this then
the good news is you're now able to talk about IA64 :-)
Andrew
> I request approval for committing the changes below.
>
> The patches below add a new gdbarch operation called
> TARGET_ADJUST_BREAKPOINT_ADDRESS. It is intended to be used by
> targets which have architectural constraints on the addresses at which
> a breakpoint may be placed.
>
> E.g, a VLIW or EPIC architecture may have rules about where in the
> instruction word a breakpoint may be placed. On such architectures,
> an instruction consists of several sub-instructions all of which are
> executed in parallel. The compiler could emit code which causes
> portions of two source language statements to share the same
> instruction. The debugging info could then indicate that a particular
> statement starts at an address at which it is not acceptable to place
> a breakpoint.
>
> For such a target, one would define a TARGET_ADJUST_BREAKPOINT_ADDRESS
> operation which, given an address, would return a (possibly adjusted)
> address at which it is acceptable to place a breakoint.
>
> A RISC architecture could define this operation to make sure that a
> breakpoint address is aligned on a word boundary. And the IA-64
> architecture could use this operation to ensure that the user
> specified a valid slot address (changing the address to something
> reasonable if incorrect).
>
> If a breakpoint address is adjusted, there's some new code in
> breakpoint.c which'll print out a warning. Such a warning might
> look something like this...
>
> (gdb) b foo
> warning: Breakpoint address moved from 0x06200090 to 0x0620008c.
> Breakpoint 1 at 0x0620008c: file bar.c, line 21.
>
> I will submit a separate documentation patch once the patches below
> are accepted.
>
> * gdbarch.sh (TARGET_ADJUST_BREAKPOINT_ADDRESS): New entry.
> * gdbarch.h, gdbarch.c: Regenerated from gdbarch.sh.
>
> * arch-utils.c, arch-utils.h
> (default_target_adjust_breakpoint_address): New function.
>
> * breakpoint.c (adjust_breakpoint_address): New function.
> (set_raw_breakpoint, set_longjmp_resume_breakpoint,
> watch_command_1, breakpoint_re_set_one): When setting the
> breakpoint's address, call adjust_breakpoint_address() to
> account for architectural constraints on locations where a
> breakpoint may be placed.
>
> Index: arch-utils.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/arch-utils.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 arch-utils.c
> --- arch-utils.c 2000/06/10 05:37:47 1.10
> +++ arch-utils.c 2000/06/21 02:19:27
> @@ -95,6 +95,21 @@ legacy_breakpoint_from_pc (CORE_ADDR * p
> return NULL;
> }
>
> +/* Some architectures have constraints about where a breakpoint may be
> + placed. TARGET_ADJUST_BREAKPOINT_ADDRESS is given an address that is
> + adjusted (and returned) to conform to the constraints imposed by
> + the architecture.
> +
> + Targets which have no architectural constraints on breakpoint placement
> + should use default_target_adjust_breakpoint_address which merely returns
> + the breakpoint address unadjusted */
> +
> +CORE_ADDR
> +default_target_adjust_breakpoint_address (CORE_ADDR bpaddr)
> +{
> + return bpaddr;
> +}
> +
> int
> generic_frameless_function_invocation_not (struct frame_info *fi)
> {
> Index: arch-utils.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/arch-utils.h,v
> retrieving revision 1.7
> diff -u -p -r1.7 arch-utils.h
> --- arch-utils.h 2000/06/07 04:38:02 1.7
> +++ arch-utils.h 2000/06/21 02:19:28
> @@ -36,6 +36,11 @@ extern gdbarch_frame_num_args_ftype fram
> targets that don't yet implement their own breakpoint_from_pc(). */
> extern gdbarch_breakpoint_from_pc_ftype legacy_breakpoint_from_pc;
>
> +/* Identity function for targets which don't have architectural constraints
> + on placement of breakpoints. */
> +extern gdbarch_target_adjust_breakpoint_address_ftype
> + default_target_adjust_breakpoint_address;
> +
> /* Frameless functions not identifable. */
> extern gdbarch_frameless_function_invocation_ftype generic_frameless_function_invocation_not;
>
> Index: breakpoint.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/breakpoint.c,v
> retrieving revision 1.13
> diff -u -p -r1.13 breakpoint.c
> --- breakpoint.c 2000/06/12 21:17:21 1.13
> +++ breakpoint.c 2000/06/21 02:19:36
> @@ -96,6 +96,8 @@ struct breakpoint *set_raw_breakpoint (s
>
> static void check_duplicates (CORE_ADDR, asection *);
>
> +static CORE_ADDR adjust_breakpoint_address (CORE_ADDR bpaddr);
> +
> static void describe_other_breakpoints (CORE_ADDR, asection *);
>
> static void breakpoints_info (char *, int);
> @@ -3827,6 +3829,30 @@ check_duplicates (address, section)
> }
> }
>
> +/* Call TARGET_ADJUST_BREAKPOINT_ADDRESS and print warning if an address
> + adjustment was made. Returns the adjusted address. */
> +
> +static CORE_ADDR
> +adjust_breakpoint_address (CORE_ADDR bpaddr)
> +{
> + CORE_ADDR adjusted_bpaddr;
> +
> + adjusted_bpaddr = TARGET_ADJUST_BREAKPOINT_ADDRESS (bpaddr);
> +
> + if (adjusted_bpaddr != bpaddr)
> + {
> + char astr1[50];
> + char astr2[50];
> + strcpy (astr1, local_hex_string_custom ((unsigned long) bpaddr, "08l"));
> + strcpy (astr2,
> + local_hex_string_custom ((unsigned long) adjusted_bpaddr,
> + "08l"));
> + warning ("Breakpoint address moved from %s to %s.", astr1, astr2);
> + }
> +
> + return adjusted_bpaddr;
> +}
> +
> /* Low level routine to set a breakpoint.
> Takes as args the three things that every breakpoint must have.
> Returns the breakpoint object so caller can set other things.
> @@ -3845,7 +3871,7 @@ set_raw_breakpoint (sal)
>
> b = (struct breakpoint *) xmalloc (sizeof (struct breakpoint));
> memset (b, 0, sizeof (*b));
> - b->address = sal.pc;
> + b->address = adjust_breakpoint_address (sal.pc);
> if (sal.symtab == NULL)
> b->source_file = NULL;
> else
> @@ -4327,7 +4353,7 @@ set_longjmp_resume_breakpoint (pc, frame
> ALL_BREAKPOINTS (b)
> if (b->type == bp_longjmp_resume)
> {
> - b->address = pc;
> + b->address = adjust_breakpoint_address (pc);
> b->enable = enabled;
> if (frame != NULL)
> b->frame = frame->frame;
> @@ -5506,7 +5532,8 @@ watch_command_1 (arg, accessflag, from_t
> scope_breakpoint->frame = prev_frame->frame;
>
> /* Set the address at which we will stop. */
> - scope_breakpoint->address = get_frame_pc (prev_frame);
> + scope_breakpoint->address =
> + adjust_breakpoint_address (get_frame_pc (prev_frame));
>
> /* The scope breakpoint is related to the watchpoint. We
> will need to act on them together. */
> @@ -7162,7 +7189,7 @@ breakpoint_re_set_one (bint)
> savestring (sals.sals[i].symtab->filename,
> strlen (sals.sals[i].symtab->filename));
> b->line_number = sals.sals[i].line;
> - b->address = sals.sals[i].pc;
> + b->address = adjust_breakpoint_address (sals.sals[i].pc);
>
> /* Used to check for duplicates here, but that can
> cause trouble, as it doesn't check for disable
> Index: gdbarch.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbarch.c,v
> retrieving revision 1.29
> diff -u -p -r1.29 gdbarch.c
> --- gdbarch.c 2000/06/12 00:35:33 1.29
> +++ gdbarch.c 2000/06/21 02:19:39
> @@ -205,6 +205,7 @@ struct gdbarch
> gdbarch_prologue_frameless_p_ftype *prologue_frameless_p;
> gdbarch_inner_than_ftype *inner_than;
> gdbarch_breakpoint_from_pc_ftype *breakpoint_from_pc;
> + gdbarch_target_adjust_breakpoint_address_ftype *target_adjust_breakpoint_address;
> gdbarch_memory_insert_breakpoint_ftype *memory_insert_breakpoint;
> gdbarch_memory_remove_breakpoint_ftype *memory_remove_breakpoint;
> CORE_ADDR decr_pc_after_break;
> @@ -340,6 +341,7 @@ struct gdbarch startup_gdbarch =
> 0,
> 0,
> 0,
> + 0,
> /* startup_gdbarch() */
> };
>
> @@ -391,6 +393,7 @@ gdbarch_alloc (const struct gdbarch_info
> gdbarch->return_value_on_stack = generic_return_value_on_stack_not;
> gdbarch->prologue_frameless_p = generic_prologue_frameless_p;
> gdbarch->breakpoint_from_pc = legacy_breakpoint_from_pc;
> + gdbarch->target_adjust_breakpoint_address = default_target_adjust_breakpoint_address;
> gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint;
> gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint;
> gdbarch->decr_pc_after_break = -1;
> @@ -611,6 +614,7 @@ verify_gdbarch (struct gdbarch *gdbarch)
> && (gdbarch->inner_than == 0))
> internal_error ("gdbarch: verify_gdbarch: inner_than invalid");
> /* Skip verify of breakpoint_from_pc, invalid_p == 0 */
> + /* Skip verify of target_adjust_breakpoint_address, invalid_p == 0 */
> /* Skip verify of memory_insert_breakpoint, invalid_p == 0 */
> /* Skip verify of memory_remove_breakpoint, invalid_p == 0 */
> if ((GDB_MULTI_ARCH >= 2)
> @@ -1124,6 +1128,12 @@ gdbarch_dump (struct gdbarch *gdbarch, s
> "BREAKPOINT_FROM_PC(pcptr, lenptr)",
> XSTRING (BREAKPOINT_FROM_PC (pcptr, lenptr)));
> #endif
> +#ifdef TARGET_ADJUST_BREAKPOINT_ADDRESS
> + fprintf_unfiltered (file,
> + "gdbarch_dump: %s # %s\n",
> + "TARGET_ADJUST_BREAKPOINT_ADDRESS(bpaddr)",
> + XSTRING (TARGET_ADJUST_BREAKPOINT_ADDRESS (bpaddr)));
> +#endif
> #ifdef MEMORY_INSERT_BREAKPOINT
> fprintf_unfiltered (file,
> "gdbarch_dump: %s # %s\n",
> @@ -1724,6 +1734,13 @@ gdbarch_dump (struct gdbarch *gdbarch, s
> (long) current_gdbarch->breakpoint_from_pc
> /*BREAKPOINT_FROM_PC ()*/);
> #endif
> +#ifdef TARGET_ADJUST_BREAKPOINT_ADDRESS
> + if (GDB_MULTI_ARCH)
> + fprintf_unfiltered (file,
> + "gdbarch_dump: TARGET_ADJUST_BREAKPOINT_ADDRESS = 0x%08lx\n",
> + (long) current_gdbarch->target_adjust_breakpoint_address
> + /*TARGET_ADJUST_BREAKPOINT_ADDRESS ()*/);
> +#endif
> #ifdef MEMORY_INSERT_BREAKPOINT
> if (GDB_MULTI_ARCH)
> fprintf_unfiltered (file,
> @@ -3177,6 +3194,23 @@ set_gdbarch_breakpoint_from_pc (struct g
> gdbarch_breakpoint_from_pc_ftype breakpoint_from_pc)
> {
> gdbarch->breakpoint_from_pc = breakpoint_from_pc;
> +}
> +
> +CORE_ADDR
> +gdbarch_target_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
> +{
> + if (gdbarch->target_adjust_breakpoint_address == 0)
> + internal_error ("gdbarch: gdbarch_target_adjust_breakpoint_address invalid");
> + if (gdbarch_debug >= 2)
> + fprintf_unfiltered (gdb_stdlog, "gdbarch_target_adjust_breakpoint_address called\n");
> + return gdbarch->target_adjust_breakpoint_address (bpaddr);
> +}
> +
> +void
> +set_gdbarch_target_adjust_breakpoint_address (struct gdbarch *gdbarch,
> + gdbarch_target_adjust_breakpoint_address_ftype target_adjust_breakpoint_address)
> +{
> + gdbarch->target_adjust_breakpoint_address = target_adjust_breakpoint_address;
> }
>
> int
> Index: gdbarch.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbarch.h,v
> retrieving revision 1.23
> diff -u -p -r1.23 gdbarch.h
> --- gdbarch.h 2000/06/10 05:37:47 1.23
> +++ gdbarch.h 2000/06/21 02:19:41
> @@ -862,6 +862,20 @@ extern void set_gdbarch_breakpoint_from_
> #endif
>
> /* Default (function) for non- multi-arch platforms. */
> +#if (GDB_MULTI_ARCH == 0) && !defined (TARGET_ADJUST_BREAKPOINT_ADDRESS)
> +#define TARGET_ADJUST_BREAKPOINT_ADDRESS(bpaddr) (default_target_adjust_breakpoint_address (bpaddr))
> +#endif
> +
> +typedef CORE_ADDR (gdbarch_target_adjust_breakpoint_address_ftype) (CORE_ADDR bpaddr);
> +extern CORE_ADDR gdbarch_target_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr);
> +extern void set_gdbarch_target_adjust_breakpoint_address (struct gdbarch *gdbarch, gdbarch_target_adjust_breakpoint_address_ftype *target_adjust_breakpoint_address);
> +#if GDB_MULTI_ARCH
> +#if (GDB_MULTI_ARCH > 1) || !defined (TARGET_ADJUST_BREAKPOINT_ADDRESS)
> +#define TARGET_ADJUST_BREAKPOINT_ADDRESS(bpaddr) (gdbarch_target_adjust_breakpoint_address (current_gdbarch, bpaddr))
> +#endif
> +#endif
> +
> +/* Default (function) for non- multi-arch platforms. */
> #if (GDB_MULTI_ARCH == 0) && !defined (MEMORY_INSERT_BREAKPOINT)
> #define MEMORY_INSERT_BREAKPOINT(addr, contents_cache) (default_memory_insert_breakpoint (addr, contents_cache))
> #endif
> Index: gdbarch.sh
> ===================================================================
> RCS file: /cvs/src/src/gdb/gdbarch.sh,v
> retrieving revision 1.29
> diff -u -p -r1.29 gdbarch.sh
> --- gdbarch.sh 2000/06/12 00:35:34 1.29
> +++ gdbarch.sh 2000/06/21 02:19:43
> @@ -364,6 +364,7 @@ f:2:SKIP_PROLOGUE:CORE_ADDR:skip_prologu
> f:2:PROLOGUE_FRAMELESS_P:int:prologue_frameless_p:CORE_ADDR ip:ip::0:generic_prologue_frameless_p::0
> f:2:INNER_THAN:int:inner_than:CORE_ADDR lhs, CORE_ADDR rhs:lhs, rhs::0:0
> f:2:BREAKPOINT_FROM_PC:unsigned char *:breakpoint_from_pc:CORE_ADDR *pcptr, int *lenptr:pcptr, lenptr:::legacy_breakpoint_from_pc::0
> +f:2:TARGET_ADJUST_BREAKPOINT_ADDRESS:CORE_ADDR:target_adjust_breakpoint_address:CORE_ADDR bpaddr:bpaddr:::default_target_adjust_breakpoint_address::0
> f:2:MEMORY_INSERT_BREAKPOINT:int:memory_insert_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_insert_breakpoint::0
> f:2:MEMORY_REMOVE_BREAKPOINT:int:memory_remove_breakpoint:CORE_ADDR addr, char *contents_cache:addr, contents_cache::0:default_memory_remove_breakpoint::0
> v:2:DECR_PC_AFTER_BREAK:CORE_ADDR:decr_pc_after_break::::0:-1
>
>
>
More information about the Gdb-patches
mailing list