This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [RFA/ARM] Framificate the ARM port [3/3]
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: Daniel Jacobowitz <drow at mvista dot com>
- Cc: gdb-patches at sources dot redhat dot com, rearnsha at arm dot com
- Date: Tue, 01 Jul 2003 11:32:48 -0400
- Subject: Re: [RFA/ARM] Framificate the ARM port [3/3]
- References: <20030630225509.GA30844@nevyn.them.org>
So much code gets deleted, Ya!
Here are some ``GDB speak'' comments - help clarify use of `prev',
`this', and `next'. Some of them (e.g., s/our/THIS/ are probably not
GNU PC).
===================================================================
--- gdb.orig/arm-tdep.c 2003-06-30 18:28:56.000000000 -0400
+++ gdb/arm-tdep.c 2003-06-30 18:28:57.000000000 -0400
@@ -34,6 +34,9 @@
#include "value.h"
#include "arch-utils.h"
#include "osabi.h"
+#include "frame-unwind.h"
+#include "frame-base.h"
+#include "trad-frame.h"
#include "arm-tdep.h"
#include "gdb/sim-arm.h"
@@ -155,21 +158,31 @@ static void convert_from_extended (const
static void convert_to_extended (const struct floatformat *, void *,
const void *);
-/* Define other aspects of the stack frame. We keep the offsets of
- all saved registers, 'cause we need 'em a lot! We also keep the
- current size of the stack frame, and the offset of the frame
- pointer from the stack pointer (for frameless functions, and when
- we're still in the prologue of a function with a frame). */
-
-#define arm_get_cache(fi) ((struct arm_prologue_cache *) get_frame_extra_info (fi))
-
struct arm_prologue_cache
{
- CORE_ADDR unwound_sp, unwound_pc;
+ /* The stack pointer at the time this frame was created; i.e. our caller's
+ stack pointer when we were called. We use this to identify the frame. */
+ CORE_ADDR unwound_sp;
I'd call it ``prev_sp'', and ``It is used used to identify THIS frame''.
+ /* The current PC in this frame; i.e. our callee's resume address, if we are
+ not the innermost frame. This is not constant throughout the lifetime
+ of this frame, so we don't use it to identify the frame, just to find
+ the function. */
+ CORE_ADDR unwound_pc;
Hmm, ``unwound_sp'' belongs to the PREV frame but ``unwound_pc'' belongs
to THIS frame :-(
Suggest instead using a function local ``this_pc'' variable and not even
cacheing the THIS frame's PC value. frame_pc_unwind(next_frame) is
effecient (it already caches the PC) and in the past bad kama has
resulted from redundant caching of pc values (cf deprecated update frame
pc hack).
+ /* The frame base for this frame is just unwound_sp + frame offset - frame
+ size. FRAMESIZE is the size of the stack frame, and FRAMEOFFSET
+ if the initial offset from the stack pointer (our stack pointer, not
+ UNWOUND_SP) to the frame base. */
+
int framesize;
int frameoffset;
Um, which SP? THIS or PREV?
+ /* The register used to hold the frame pointer for this frame. */
int framereg;
- CORE_ADDR saved_regs[1];
+
+ /* Saved register offsets. */
+ struct trad_frame_saved_reg *saved_regs;
};
/* Addresses for calling Thumb functions have the bit 0 set.
+ /* Check that we're not going round in circles with the same frame
+ ID (but avoid applying the test to sentinel frames which do go
+ round in circles). */
This shouldn't be needed. Hmm, ah, I never enabled (from frame.c):
/* Check that this and the next frame are different. If they are
not, there is most likely a stack cycle. As with the inner-than
test, avoid the inner-most and sentinel frames. */
/* FIXME: cagney/2003-03-17: Can't yet enable this this check. The
frame_id_eq() method doesn't yet use function addresses when
comparing frame IDs. */
if (0
&& this_frame->level > 0
&& frame_id_eq (get_frame_id (this_frame),
get_frame_id (this_frame->next)))
error ("This frame identical to next frame (corrupt stack?)");
+ if (frame_relative_level (next_frame) >= 0
+ && get_frame_type (next_frame) == NORMAL_FRAME
+ && frame_id_eq (get_frame_id (next_frame), id))
+ return;
+ if (*this_cache == NULL)
+ *this_cache = arm_make_prologue_cache (next_frame);
+ cache = *this_cache;
+
+ /* If we are asked to unwind the PC, then we need to return the LR instead.
+ The saved value of PC points into this frame's prologue, not the
+ next frame's resume location. */
+ if (prev_regnum == ARM_PC_REGNUM)
+ prev_regnum = ARM_LR_REGNUM;
See above, eliminating unwound_pc would get rid of the confusion.
+ /* If someone asks for the stack pointer, then they want unwound_sp,
+ which was our stack pointer at the time of the call. SP is not
+ generally saved to the stack. */
(I can't stand the GNU style of using first and second person in code,
it's way too ambigious :-() I'd just state:
``The PREV frame's stack pointer was previously computed and saved in
cache->prev_sp. The SP is not generally saved to the stack.''
+ if (prev_regnum == ARM_SP_REGNUM)
+ {
+ *lvalp = not_lval;
+ if (valuep)
+ store_unsigned_integer (valuep, 4, cache->unwound_sp);
+ return;
+ }
+static const struct frame_unwind *
+arm_sigtramp_unwind_p (CORE_ADDR pc)
+{
+ /* Note: If an ARM PC_IN_SIGTRAMP method ever needs to compare
+ against the name of the function, the code below will have to be
+ changed to first fetch the name of the function and then pass
+ this name to PC_IN_SIGTRAMP. */
- memcpy (get_frame_extra_info (fi), cache, (sizeof (struct arm_prologue_cache)
- + ((NUM_REGS + NUM_PSEUDO_REGS - 1)
- * sizeof (CORE_ADDR))));
- memcpy (get_frame_saved_regs (fi), cache->saved_regs,
- (NUM_REGS + NUM_PSEUDO_REGS - 1) * sizeof (CORE_ADDR));
-}
+ if (SIGCONTEXT_REGISTER_ADDRESS_P () && PC_IN_SIGTRAMP (pc, (char *) 0))
+ return &arm_sigtramp_unwind;
Can PC_IN_SIGTRAMP be eliminated here?
+/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
+ dummy frame. The frame ID's base needs to match the TOS value
+ saved by save_dummy_frame_tos(), and the PC match the dummy frame's
+ breakpoint. */
... tos() and returned by arm_push_dummy_call.
+/* Given THIS_FRAME, find the frame's resume PC (which will be part of the
+ frame ID for THIS_FRAME's caller's frame). */
Given THIS_FRAME, find the PREV frame's resume PC (which will be used to
find the PREV frame's function and that in turn used to construct the
PREV frame's ID).
static CORE_ADDR
-arm_read_fp (void)
+arm_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
- if (read_register (ARM_PS_REGNUM) & 0x20) /* Bit 5 is Thumb state bit */
- return read_register (THUMB_FP_REGNUM); /* R7 if Thumb */
- else
- return read_register (ARM_FP_REGNUM); /* R11 if ARM */
+ CORE_ADDR pc;
+ pc = frame_unwind_register_unsigned (this_frame, ARM_PC_REGNUM);
+ return IS_THUMB_ADDR (pc) ? UNMAKE_THUMB_ADDR (pc) : pc;
}
Nice,
Andrew