[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