Re: [RFA] Improve Sparc epilogue analysis

Michael Snyder
2002-04-23T19:32:02Z

"David S. Miller" wrote:
>
> Unlike other ports, Sparc only had a manual prologue discovery
> mechanism. Most other port have a manual prologue examiner, but they
> also first try to use line number information.
>
> To this end, we look for line number information (the first two ".loc"
> entries for a function have the same line number, the second one
> begins at the end of the prologue) and if found we use it. Else
> we just drop into the existing code.
>
> Also, in sparc_init_extra_frame_info we were using grotty code to find
> out if the save instruction in the prologue had executed yet.
> Firstly, this relied on the debugging info being there. Secondly
> such things need to be done within the prologue range only, and
> examine_prologue was created to figure this out.
>
> Due to a bug in dwarf2 gas up until a week ago, gas would eliminate
> these duplicate .loc entries used for prologue discovery by accident.
>
> For those of you playing at home:
>
> sparc32 sparc64
> failures before 88 124
> failures after 83 111
>
> More to come.

No. Examine prologue serves two roles. One is simply
to skip to the end of the prologue, but the other is to
actually determine where the registers are saved by the
prologue. You've short-circuited the second usage.

Your idea is sound, though -- you've just implemented
it in the wrong place. Instead of modifying examine_prologue,
how about if you modify sparc_gdbarch_skip_prologue?

>
> 2002-04-19 David S. Miller <davem@redhat.com>
>
> * sparc-tdep.c (examine_prologue): Put forward declaration before
> sparc_init_extra_frame_info.
> (sparc_init_extra_frame_info): Use it to determine if the save
> instruction has been executed yet instead of solely relying upon
> line number information. Some versions of gas delete duplicates.
> (examine_prologue): Use line number information to find end of
> prologue, if available. Else, use existing by-hand insn
> examination.
>
> --- sparc-tdep.c.~1~ Fri Apr 19 23:03:54 2002
> +++ sparc-tdep.c Fri Apr 19 23:53:57 2002
> @@ -279,6 +279,9 @@ struct frame_extra_info
> int sp_offset;
> };
>
> +static CORE_ADDR examine_prologue (CORE_ADDR, int, struct frame_info *,
> + CORE_ADDR *);
> +
> /* Call this for each newly created frame. For SPARC, we need to
> calculate the bottom of the frame, and do some extra work if the
> prologue has been generated via the -mflat option to GCC. In
> @@ -393,25 +396,20 @@ sparc_init_extra_frame_info (int fromlea
> to the current value of the stack pointer and set
> the in_prologue flag. */
> CORE_ADDR addr;
> - struct symtab_and_line sal;
>
> - sal = find_pc_line (prologue_start, 0);
> - if (sal.line == 0) /* no line info, use PC */
> - prologue_end = fi->pc;
> - else if (sal.end < prologue_end)
> - prologue_end = sal.end;
> + prologue_end = examine_prologue (prologue_start, 0, NULL, NULL);
> if (fi->pc < prologue_end)
> {
> - for (addr = prologue_start; addr < fi->pc; addr += 4)
> + for (addr = fi->pc; addr < prologue_end; addr += 4)
> {
> insn = read_memory_integer (addr, 4);
> if (X_OP (insn) == 2 && X_OP3 (insn) == 0x3c)
> break; /* SAVE seen, stop searching */
> }
> - if (addr >= fi->pc)
> + if (addr < prologue_end)
> {
> fi->extra_info->in_prologue = 1;
> - fi->frame = read_register (SP_REGNUM);
> + fi->frame = read_sp ();
> }
> }
> }
> @@ -546,9 +544,6 @@ setup_arbitrary_frame (int argc, CORE_AD
> This routine should be more specific in its actions; making sure
> that it uses the same register in the initial prologue section. */
>
> -static CORE_ADDR examine_prologue (CORE_ADDR, int, struct frame_info *,
> - CORE_ADDR *);
> -
> static CORE_ADDR
> examine_prologue (CORE_ADDR start_pc, int frameless_p, struct frame_info *fi,
> CORE_ADDR *saved_regs)
> @@ -557,7 +552,21 @@ examine_prologue (CORE_ADDR start_pc, in
> int dest = -1;
> CORE_ADDR pc = start_pc;
> int is_flat = 0;
> + 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. */
> insn = fetch_instruction (pc);
>
> /* Recognize the `sethi' insn and record its destination. */