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]

Re: [RFA] Save the call dummy address


Andrew Cagney wrote:
> 
> Hello,
> 
> The attached patch modifies generic dummy frames so that they save the
> address of the call dummy code.  This in turn makes it possible to
> modify the generic_pc_in_call_dummy() function so that it uses the PC
> (instead of the FP) to determine if the PC is in a call dummy (yes you
> read that right :-).
> 
> It also has the (er un-intended) side effect of removing the restriction
> that generic dummy frames only work with the AT_ENTRY mechanism.
> 
> The only potential problem I can see is with someone typing ``(gdb) jump
> *_start'' when there are dummy frames present.  It could trigger a false
> positive.  I think that is a separate problem and I don't even know if
> it really can occure.
> 
> Tested on NetBSD/PPC (which uses generic dummy frames) without regressions.
> 
> Michael, I suspect you're the ``maintainer'' of this code.  Look ok?

Yes.  I wish that the calls to generic_push_dummy_frame, 
generic_save_dummy_frame_tos, and generic_save_dummy_frame_addr
could be combined into one (for data locality), but that does
not have to hold up this patch.  The spread is getting worse, though...

> 
> enjoy,
> Andrew
> 
>   ------------------------------------------------------------------------
> 2002-04-14  Andrew Cagney  <ac131313@redhat.com>
> 
>         * valops.c (hand_function_call): Call
>         generic_save_call_dummy_addr.
>         * frame.h (generic_save_call_dummy_addr): Declare.
>         * blockframe.c (struct dummy_frame): Add fields call_lo and
>         call_hi.
>         (generic_find_dummy_frame): Check for PC in range call_lo to
>         call_hi instead of entry_point_address.
>         (generic_pc_in_call_dummy): Search the dummy frames for a PC in
>         the call_lo to call_hi range.  Allow for DECR_PC_AFTER_BREAK.
>         (generic_save_call_dummy_addr): New function.
> 
> Index: blockframe.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/blockframe.c,v
> retrieving revision 1.24
> diff -u -r1.24 blockframe.c
> --- blockframe.c        14 Apr 2002 13:38:06 -0000      1.24
> +++ blockframe.c        14 Apr 2002 14:52:05 -0000
> @@ -1070,42 +1070,59 @@
>    CORE_ADDR sp;
>    CORE_ADDR top;
>    char *registers;
> +
> +  /* Address range of the call dummy code.  Look for PC in the range
> +     [LO..HI) (after allowing for DECR_PC_AFTER_BREAK).  */
> +  CORE_ADDR call_lo;
> +  CORE_ADDR call_hi;
>  };
> 
>  static struct dummy_frame *dummy_frame_stack = NULL;
> 
>  /* Function: find_dummy_frame(pc, fp, sp)
> -   Search the stack of dummy frames for one matching the given PC, FP and SP.
> -   This is the work-horse for pc_in_call_dummy and read_register_dummy     */
> +
> +   Search the stack of dummy frames for one matching the given PC, FP
> +   and SP.  Unlike PC_IN_CALL_DUMMY, this function doesn't need to
> +   adjust for DECR_PC_AFTER_BREAK.  This is because it is only legal
> +   to call this function after the PC has been adjusted.  */
> 
>  char *
>  generic_find_dummy_frame (CORE_ADDR pc, CORE_ADDR fp)
>  {
>    struct dummy_frame *dummyframe;
> 
> -  if (pc != entry_point_address ())
> -    return 0;
> -
>    for (dummyframe = dummy_frame_stack; dummyframe != NULL;
>         dummyframe = dummyframe->next)
> -    if (fp == dummyframe->fp
> -       || fp == dummyframe->sp
> -       || fp == dummyframe->top)
> +    if ((pc >= dummyframe->call_lo && pc < dummyframe->call_hi)
> +       && (fp == dummyframe->fp
> +           || fp == dummyframe->sp
> +           || fp == dummyframe->top))
>        /* The frame in question lies between the saved fp and sp, inclusive */
>        return dummyframe->registers;
> 
>    return 0;
>  }
> 
> -/* Function: pc_in_call_dummy (pc, fp)
> -   Return true if this is a dummy frame created by gdb for an inferior call */
> +/* Function: pc_in_call_dummy (pc, sp, fp)
> +
> +   Return true if the PC falls in a dummy frame created by gdb for an
> +   inferior call.  The code below which allows DECR_PC_AFTER_BREAK is
> +   for infrun.c, which may give the function a PC without that
> +   subtracted out.  */
> 
>  int
>  generic_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp)
>  {
> -  /* if find_dummy_frame succeeds, then PC is in a call dummy */
> -  /* Note: SP and not FP is passed on. */
> -  return (generic_find_dummy_frame (pc, sp) != 0);
> +  struct dummy_frame *dummyframe;
> +  for (dummyframe = dummy_frame_stack;
> +       dummyframe != NULL;
> +       dummyframe = dummyframe->next)
> +    {
> +      if ((pc >= dummyframe->call_lo)
> +         && (pc < dummyframe->call_hi + DECR_PC_AFTER_BREAK))
> +       return 1;
> +    }
> +  return 0;
>  }
> 
>  /* Function: read_register_dummy
> @@ -1168,6 +1185,15 @@
>  generic_save_dummy_frame_tos (CORE_ADDR sp)
>  {
>    dummy_frame_stack->top = sp;
> +}
> +
> +/* Record the upper/lower bounds on the address of the call dummy.  */
> +
> +void
> +generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi)
> +{
> +  dummy_frame_stack->call_lo = lo;
> +  dummy_frame_stack->call_hi = hi;
>  }
> 
>  /* Restore the machine state from either the saved dummy stack or a
> Index: frame.h
> ===================================================================
> RCS file: /cvs/src/src/gdb/frame.h,v
> retrieving revision 1.12
> diff -u -r1.12 frame.h
> --- frame.h     12 Apr 2002 18:18:57 -0000      1.12
> +++ frame.h     14 Apr 2002 14:52:07 -0000
> @@ -277,6 +277,8 @@
>                                         struct frame_info *, int,
>                                         enum lval_type *);
> 
> +extern void generic_save_call_dummy_addr (CORE_ADDR lo, CORE_ADDR hi);
> +
>  extern void get_saved_register (char *raw_buffer, int *optimized,
>                                 CORE_ADDR * addrp,
>                                 struct frame_info *frame,
> Index: valops.c
> ===================================================================
> RCS file: /cvs/src/src/gdb/valops.c,v
> retrieving revision 1.53
> diff -u -r1.53 valops.c
> --- valops.c    22 Mar 2002 18:57:08 -0000      1.53
> +++ valops.c    14 Apr 2002 14:52:15 -0000
> @@ -1385,6 +1385,8 @@
>    if (CALL_DUMMY_LOCATION == ON_STACK)
>      {
>        write_memory (start_sp, (char *) dummy1, sizeof_dummy1);
> +      if (USE_GENERIC_DUMMY_FRAMES)
> +       generic_save_call_dummy_addr (start_sp, start_sp + sizeof_dummy1);
>      }
> 
>    if (CALL_DUMMY_LOCATION == BEFORE_TEXT_END)
> @@ -1401,6 +1403,8 @@
>        sp = old_sp;
>        real_pc = text_end - sizeof_dummy1;
>        write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
> +      if (USE_GENERIC_DUMMY_FRAMES)
> +       generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
>      }
> 
>    if (CALL_DUMMY_LOCATION == AFTER_TEXT_END)
> @@ -1412,11 +1416,18 @@
>        errcode = target_write_memory (real_pc, (char *) dummy1, sizeof_dummy1);
>        if (errcode != 0)
>         error ("Cannot write text segment -- call_function failed");
> +      if (USE_GENERIC_DUMMY_FRAMES)
> +       generic_save_call_dummy_addr (real_pc, real_pc + sizeof_dummy1);
>      }
> 
>    if (CALL_DUMMY_LOCATION == AT_ENTRY_POINT)
>      {
>        real_pc = funaddr;
> +      if (USE_GENERIC_DUMMY_FRAMES)
> +       /* NOTE: cagney/2002-04-13: The entry point is going to be
> +           modified with a single breakpoint.  */
> +       generic_save_call_dummy_addr (CALL_DUMMY_ADDRESS (),
> +                                     CALL_DUMMY_ADDRESS () + 1);
>      }
> 
>  #ifdef lint


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