Re: [RFA] Improve Sparc epilogue analysis

Michael Snyder
2002-04-25T21:25:51Z

"David S. Miller" wrote:
>
> Ok, broken apart. He is a smaller chunk this time.
>
> We use line debugging information, if possible, to determine
> the end of the instructions that compose the prologue of a
> function on Sparc. examine_prologue is used as a backup in
> this case, if we cannot fetch the necessary debugging information.
>
> Here is how I modified sparc_skip_prologue:
>
> It is only called every with it's frameless_p
> argument set to zero, so this argument is removed.
>
> We check for a symtab_and_line, if it does not compose
> the whole function and the start_pc given to us is
> within the range, we return the end of the symtab_and_line
> which should be the end of the prologue.
>
> Else we fall back to the current behavior, which is to
> interrogate the instructions by hand to determine the
> bounds of the prologue.
>
> Also, we had two functions doing the same thing, one for multi-arch
> and one for the non-multiarch case of the same exact interface.
> So I killed one of them.
>
> Finally, I call examine_prologue directly from
> sparc_prologue_frameless_p() instead of going through
> sparc_skip_prologue(). This way there doesn't need to be an
> "if (frameless_p)" test guarding the symbol table prologue stuff. We
> can tackle trying to use symbol table information in
> sparc_prologue_frameless_p() in a future patch.

This patch is approved. Thank you.

> 2002-04-24 David S. Miller <davem@redhat.com>
>
> * sparc-tdep.c (sparc_gdbarch_skip_prologue): Kill, duplicates
> sparc_skip_prologue.
> (sparc_skip_prologue): Kill frameless_p arg, and use line number
> information to find prologue when possible.
> (sparc_prologue_frameless_p): Call examine_prologue directly.
> (sparc_gdbarch_init): Update set_gdbarch_skip_prologue call.
> * config/sparc/tm-sparc.h (sparc_skip_prologue): Update for killed
> second argument.
> (SKIP_PROLOGUE): Likewise.
>
> --- ./config/sparc/tm-sparc.h.~1~ Sun Apr 21 19:18:59 2002
> +++ ./config/sparc/tm-sparc.h Wed Apr 24 17:54:53 2002
> @@ -250,8 +250,8 @@ extern int sparc_intreg_size (void);
> /* Advance PC across any function entry prologue instructions
> to reach some "real" code. */
>
> -extern CORE_ADDR sparc_skip_prologue (CORE_ADDR, int);
> -#define SKIP_PROLOGUE(PC) sparc_skip_prologue (PC, 0)
> +extern CORE_ADDR sparc_skip_prologue (CORE_ADDR);
> +#define SKIP_PROLOGUE(PC) sparc_skip_prologue (PC)
>
> /* Immediately after a function call, return the saved pc.
> Can't go through the frames for this because on some machines
> --- ./sparc-tdep.c.~1~ Wed Apr 24 17:52:27 2002
> +++ ./sparc-tdep.c Wed Apr 24 19:04:51 2002
> @@ -685,10 +685,28 @@ examine_prologue (CORE_ADDR start_pc, in
> return pc;
> }
>
> +/* Advance PC across any function entry prologue instructions to reach
> + some "real" code. */
> +
> CORE_ADDR
> -sparc_skip_prologue (CORE_ADDR start_pc, int frameless_p)
> +sparc_skip_prologue (CORE_ADDR start_pc)
> {
> - return examine_prologue (start_pc, frameless_p, NULL, NULL);
> + struct symtab_and_line sal;
> + CORE_ADDR func_start, func_end;
> +
> + /* This is the preferred method, find the end of the prologue by
> + using the debugging information. */
> + if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
> + {
> + sal = find_pc_line (func_start, 0);
> +
> + if (sal.end < func_end
> + && start_pc <= sal.end)
> + return sal.end;
> + }
> +
> + /* Oh well, examine the code by hand. */
> + return examine_prologue (start_pc, 0, NULL, NULL);
> }
>
> /* Is the prologue at IP frameless? */
> @@ -696,7 +714,7 @@ sparc_skip_prologue (CORE_ADDR start_pc,
> int
> sparc_prologue_frameless_p (CORE_ADDR ip)
> {
> - return ip == sparc_skip_prologue (ip, 1);
> + return ip == examine_prologue (ip, 1, NULL, NULL);
> }
>
> /* Check instruction at ADDR to see if it is a branch.
> @@ -2784,15 +2802,6 @@ sparc64_register_byte (int regno)
> return 64 * 8 + (regno - 80) * 8;
> }
>
> -/* Advance PC across any function entry prologue instructions to reach
> - some "real" code. */
> -
> -static CORE_ADDR
> -sparc_gdbarch_skip_prologue (CORE_ADDR ip)
> -{
> - return examine_prologue (ip, 0, NULL, NULL);
> -}
> -
> /* Immediately after a function call, return the saved pc.
> Can't go through the frames for this because on some machines
> the new frame is not set up until the new function executes
> @@ -2993,7 +3002,7 @@ sparc_gdbarch_init (struct gdbarch_info
> set_gdbarch_saved_pc_after_call (gdbarch, sparc_saved_pc_after_call);
> set_gdbarch_prologue_frameless_p (gdbarch, sparc_prologue_frameless_p);
> set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
> - set_gdbarch_skip_prologue (gdbarch, sparc_gdbarch_skip_prologue);
> + set_gdbarch_skip_prologue (gdbarch, sparc_skip_prologue);
> set_gdbarch_sp_regnum (gdbarch, SPARC_SP_REGNUM);
> set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
> set_gdbarch_write_pc (gdbarch, generic_target_write_pc);