Re: [RFA] Improve Sparc epilogue analysis

David S. Miller
2002-04-25T02:10:35Z

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.

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);