This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[offbyone] Merge with mainline
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Wed, 05 Mar 2003 20:00:23 -0500
- Subject: [offbyone] Merge with mainline
FYI,
I've committed the attached. It merges that branch with the mainline.
Andrew
2003-03-05 Andrew Cagney <cagney at redhat dot com>
* dummy-frame.c (dummy_frame_id_unwind): Abort if called.
(cached_find_dummy_frame): Add hack to obtain this thread's id
without calling id unwind.
* frame.h: Merge with mainline.
* d10v-tdep.c: Merge with mainline.
* frame.c: Merge with mainline.
Index: d10v-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/d10v-tdep.c,v
retrieving revision 1.80.2.2
diff -u -r1.80.2.2 d10v-tdep.c
--- d10v-tdep.c 5 Mar 2003 05:00:03 -0000 1.80.2.2
+++ d10v-tdep.c 6 Mar 2003 00:56:23 -0000
@@ -616,8 +616,11 @@
CORE_ADDR base;
int size;
CORE_ADDR *saved_regs;
- LONGEST next_addr;
- LONGEST r11_addr;
+ /* How far the SP and r11 (FP) have been offset from the start of
+ the stack frame (as defined by the previous frame's stack
+ pointer). */
+ LONGEST sp_offset;
+ LONGEST r11_offset;
int uses_frame;
void **regs;
};
@@ -632,8 +635,8 @@
if ((op & 0x7E1F) == 0x6C1F)
{
n = (op & 0x1E0) >> 5;
- info->next_addr -= 2;
- info->saved_regs[n] = info->next_addr;
+ info->sp_offset -= 2;
+ info->saved_regs[n] = info->sp_offset;
return 1;
}
@@ -641,9 +644,9 @@
else if ((op & 0x7E3F) == 0x6E1F)
{
n = (op & 0x1E0) >> 5;
- info->next_addr -= 4;
- info->saved_regs[n] = info->next_addr;
- info->saved_regs[n + 1] = info->next_addr + 2;
+ info->sp_offset -= 4;
+ info->saved_regs[n] = info->sp_offset;
+ info->saved_regs[n + 1] = info->sp_offset + 2;
return 1;
}
@@ -653,7 +656,7 @@
n = (op & 0x1E) >> 1;
if (n == 0)
n = 16;
- info->next_addr -= n;
+ info->sp_offset -= n;
return 1;
}
@@ -661,7 +664,7 @@
if (op == 0x417E)
{
info->uses_frame = 1;
- info->r11_addr = info->next_addr;
+ info->r11_offset = info->sp_offset;
return 1;
}
@@ -669,7 +672,7 @@
if ((op & 0x7E1F) == 0x6816)
{
n = (op & 0x1E0) >> 5;
- info->saved_regs[n] = info->r11_addr;
+ info->saved_regs[n] = info->r11_offset;
return 1;
}
@@ -681,7 +684,7 @@
if ((op & 0x7E1F) == 0x681E)
{
n = (op & 0x1E0) >> 5;
- info->saved_regs[n] = info->next_addr;
+ info->saved_regs[n] = info->sp_offset;
return 1;
}
@@ -689,8 +692,8 @@
if ((op & 0x7E3F) == 0x3A1E)
{
n = (op & 0x1E0) >> 5;
- info->saved_regs[n] = info->next_addr;
- info->saved_regs[n + 1] = info->next_addr + 2;
+ info->saved_regs[n] = info->sp_offset;
+ info->saved_regs[n + 1] = info->sp_offset + 2;
return 1;
}
@@ -708,8 +711,8 @@
void **this_cache)
{
CORE_ADDR pc;
- ULONGEST sp;
- ULONGEST base;
+ ULONGEST prev_sp;
+ ULONGEST this_base;
unsigned long op;
unsigned short op1, op2;
int i;
@@ -724,7 +727,7 @@
info->size = 0;
- info->next_addr = 0;
+ info->sp_offset = 0;
pc = get_pc_function_start (frame_pc_unwind (next_frame));
@@ -739,22 +742,22 @@
{
/* add3 sp,sp,n */
short n = op & 0xFFFF;
- info->next_addr += n;
+ info->sp_offset += n;
}
else if ((op & 0x3F0F0000) == 0x340F0000)
{
/* st rn, @(offset,sp) */
short offset = op & 0xFFFF;
short n = (op >> 20) & 0xF;
- info->saved_regs[n] = info->next_addr + offset;
+ info->saved_regs[n] = info->sp_offset + offset;
}
else if ((op & 0x3F1F0000) == 0x350F0000)
{
/* st2w rn, @(offset,sp) */
short offset = op & 0xFFFF;
short n = (op >> 20) & 0xF;
- info->saved_regs[n] = info->next_addr + offset;
- info->saved_regs[n + 1] = info->next_addr + offset + 2;
+ info->saved_regs[n] = info->sp_offset + offset;
+ info->saved_regs[n + 1] = info->sp_offset + offset + 2;
}
else
break;
@@ -779,52 +782,50 @@
pc += 4;
}
- info->size = -info->next_addr;
+ info->size = -info->sp_offset;
- /* Compute the frame's base. */
+ /* Compute the frame's base, and the previous frame's SP. */
if (info->uses_frame)
{
- /* The SP was moved into the FP. This indicates that a new
- frame was created. Get THIS frame's FP value by unwinding it
- from the next frame. */
- frame_unwind_unsigned_register (next_frame, FP_REGNUM, &base);
+ /* The SP was moved to the FP. This indicates that a new frame
+ was created. Get THIS frame's FP value by unwinding it from
+ the next frame. */
+ frame_unwind_unsigned_register (next_frame, FP_REGNUM, &this_base);
/* The FP points at the last saved register. Adjust the FP back
to before the first saved register giving the SP. */
- sp = base + info->size;
+ prev_sp = this_base + info->size;
}
else if (info->saved_regs[SP_REGNUM])
{
/* The SP was saved (which is very unusual), the frame base is
just the PREV's frame's TOP-OF-STACK. */
- base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM],
- register_size (current_gdbarch,
- SP_REGNUM));
- sp = base;
+ this_base = read_memory_unsigned_integer (info->saved_regs[SP_REGNUM],
+ register_size (current_gdbarch,
+ SP_REGNUM));
+ prev_sp = this_base;
}
else
{
/* Assume that the FP is this frame's SP but with that pushed
stack space added back. */
- frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
- sp = base + info->size;
+ frame_unwind_unsigned_register (next_frame, SP_REGNUM, &this_base);
+ prev_sp = this_base + info->size;
}
- info->base = d10v_make_daddr (base);
- sp = d10v_make_daddr (sp);
+ info->base = d10v_make_daddr (this_base);
+ prev_sp = d10v_make_daddr (prev_sp);
/* Adjust all the saved registers so that they contain addresses and
not offsets. */
for (i = 0; i < NUM_REGS - 1; i++)
- {
- if (info->saved_regs[i])
- {
- info->saved_regs[i] = (sp + info->saved_regs[i]);
- }
- }
+ if (info->saved_regs[i])
+ {
+ info->saved_regs[i] = (prev_sp + info->saved_regs[i]);
+ }
/* The SP_REGNUM is special. Instead of the address of the SP, the
previous frame's SP value is saved. */
- info->saved_regs[SP_REGNUM] = sp;
+ info->saved_regs[SP_REGNUM] = prev_sp;
return info;
}
@@ -1587,18 +1588,6 @@
lvalp, addrp, realnump, bufferp);
}
-
-static struct frame_id
-d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
-{
- ULONGEST base;
- struct frame_id id;
- id.pc = frame_pc_unwind (next_frame);
- frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
- id.base = d10v_make_daddr (base);
- return id;
-}
-
static void
d10v_frame_pop (struct frame_info *next_frame, void **this_cache,
struct regcache *regcache)
@@ -1646,6 +1635,22 @@
return &d10v_frame_unwind;
}
+/* 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. */
+
+static struct frame_id
+d10v_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ ULONGEST base;
+ struct frame_id id;
+ id.pc = frame_pc_unwind (next_frame);
+ frame_unwind_unsigned_register (next_frame, SP_REGNUM, &base);
+ id.base = d10v_make_daddr (base);
+ return id;
+}
+
static gdbarch_init_ftype d10v_gdbarch_init;
static struct gdbarch *
@@ -1782,6 +1787,8 @@
set_gdbarch_print_registers_info (gdbarch, d10v_print_registers_info);
frame_unwind_append_predicate (gdbarch, d10v_frame_p);
+
+ /* Methods for saving / extracting a dummy frame's ID. */
set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id);
set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
Index: dummy-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dummy-frame.c,v
retrieving revision 1.10.4.1
diff -u -r1.10.4.1 dummy-frame.c
--- dummy-frame.c 4 Mar 2003 23:15:23 -0000 1.10.4.1
+++ dummy-frame.c 6 Mar 2003 00:56:23 -0000
@@ -108,8 +108,13 @@
cached_find_dummy_frame (struct frame_info *next_frame, void **this_cache)
{
if ((*this_cache) == NULL)
- (*this_cache) = find_dummy_frame (frame_pc_unwind (next_frame),
- frame_id_unwind (next_frame).base);
+ {
+ /* FIXME: hack to find the frame ID of this frame. Need to do
+ this better. */
+ gdb_assert (next_frame->prev != NULL);
+ (*this_cache) = find_dummy_frame (frame_pc_unwind (next_frame),
+ next_frame->prev->frame);
+ }
return (*this_cache);
}
@@ -396,6 +401,7 @@
void **this_cache,
struct frame_id *this_id)
{
+#if 0
struct dummy_frame *dummy = cached_find_dummy_frame (next_frame, this_cache);
/* Oops! In a dummy-frame but can't find the stack dummy. Pretend
that the frame doesn't unwind. Should this function instead
@@ -404,6 +410,14 @@
(*this_id) = null_frame_id;
else
(*this_id) = dummy->id;
+#else
+ /* FIXME - with all the frames shuffled by one, it becomes possible
+ to move the dummy frame unwind code to here. This is because,
+ unlike the mainline, this function is called when determining the
+ ID of the dummy, and not the ID of the dummy's caller. For the
+ moment, this function is never called. */
+ internal_error (__FILE__, __LINE__, "dummy_frame_pc_unwind called");
+#endif
}
static struct frame_unwind dummy_frame_unwind =
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.71.2.3
diff -u -r1.71.2.3 frame.c
--- frame.c 5 Mar 2003 05:00:03 -0000 1.71.2.3
+++ frame.c 6 Mar 2003 00:56:23 -0000
@@ -146,18 +146,6 @@
return this_frame->pc_unwind_cache;
}
-struct frame_id
-frame_id_unwind (struct frame_info *this_frame)
-{
- if (!this_frame->id_unwind_cache_p)
- {
- this_frame->unwind->id (this_frame->next, &this_frame->unwind_cache,
- &this_frame->id_unwind_cache);
- this_frame->id_unwind_cache_p = 1;
- }
- return this_frame->id_unwind_cache;
-}
-
void
frame_pop (struct frame_info *frame)
{
@@ -1346,83 +1334,87 @@
prev_frame->pc);
/* Find the prev's frame's ID. */
- {
- switch (prev_frame->type)
- {
- case DUMMY_FRAME:
- /* A dummy doesn't have anything resembling either a sane
- frame or PC. The PC is sitting in the entry code and the
- stack, which has nothing to do with that entry address, is
- a down right mess. Trying to use the standard frame ID
- unwind code to get the previous frame ID is just asking for
- trouble. */
- if (gdbarch_unwind_dummy_id_p (current_gdbarch))
- {
- /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS,
- previously saved the dummy ID that is being obtained
- here. Things only work if the two match. */
- gdb_assert (SAVE_DUMMY_FRAME_TOS_P ());
- /* Use an architecture specific method to extract the
- prev's dummy ID from the next frame. Note that this
- method typically uses frame_register_unwind to obtain
- register values needed to determine the dummy ID. */
- next_frame->id_unwind_cache =
- gdbarch_unwind_dummy_id (current_gdbarch, next_frame);
- }
- else if (next_frame->level == 0)
- {
- /* We're `unwinding' the sentinel frame. Just fake up the
- ID the same way that the traditional hacks did it. */
- next_frame->id_unwind_cache.pc = read_pc ();
- next_frame->id_unwind_cache.pc = read_fp ();
- }
- else
- {
- /* Outch! We're not on the innermost frame yet we're
- trying to unwind to a dummy. The architecture must
- provide the unwind_dummy_id() method. */
- internal_error (__FILE__, __LINE__,
+ switch (prev_frame->type)
+ {
+ case DUMMY_FRAME:
+ /* When unwinding a normal frame, the stack structure is
+ determined by analyzing the frame's function's code (be it
+ using brute force prologue analysis, or the dwarf2 CFI). In
+ the case of a dummy frame, that simply isn't possible. The
+ The PC is either the program entry point, or some random
+ address on the stack. Trying to use that PC to apply
+ standard frame ID unwind techniques is just asking for
+ trouble. */
+ if (gdbarch_unwind_dummy_id_p (current_gdbarch))
+ {
+ /* Assume hand_function_call(), via SAVE_DUMMY_FRAME_TOS,
+ previously saved the dummy frame's ID. Things only work
+ if the two return the same value. */
+ gdb_assert (SAVE_DUMMY_FRAME_TOS_P ());
+ /* Use an architecture specific method to extract the prev's
+ dummy ID from the next frame. Note that this method uses
+ frame_register_unwind to obtain the register values
+ needed to determine the dummy frame's ID. */
+ prev_frame->id = gdbarch_unwind_dummy_id (current_gdbarch,
+ next_frame);
+ }
+ else if (next_frame->level < 0)
+ {
+ /* We're unwinding a sentinel frame, the PC of which is
+ pointing at a stack dummy. Fake up the dummy frame's ID
+ using the same sequence as is found a traditional
+ unwinder. Once all architectures supply the
+ unwind_dummy_id method, this code can go away. */
+ prev_frame->id.base = read_fp ();
+ prev_frame->id.pc = read_pc ();
+ }
+ else
+ {
+ /* Outch! We're not on the innermost frame yet we're trying
+ to unwind to a dummy. The architecture must provide the
+ unwind_dummy_id() method. Abandon the unwind process but
+ only after first warning the user. */
+ internal_warning (__FILE__, __LINE__,
"Missing unwind_dummy_id architecture method");
- }
- break;
- case NORMAL_FRAME:
- case SIGTRAMP_FRAME:
- prev_frame->unwind->id (next_frame, &prev_frame->unwind_cache,
- &next_frame->id_unwind_cache);
- /* Check that the unwound ID is valid. */
- if (!frame_id_p (next_frame->id_unwind_cache))
- {
- if (frame_debug)
- fprintf_unfiltered (gdb_stdlog,
- "Outermost frame - unwound frame ID invalid\n");
- return NULL;
- }
- /* Check that the new frame isn't inner to (younger, below,
- next) the old frame. If that happens the frame unwind is
- going backwards. */
- /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since
- that doesn't have a valid frame ID. Should instead set the
- sentinel frame's frame ID to a `sentinel'. Leave it until
- after the switch to storing the frame ID, instead of the
- frame base, in the frame object. */
- if (next_frame->level >= 0
- && frame_id_inner (next_frame->id_unwind_cache,
- get_frame_id (next_frame)))
- error ("Unwound frame inner-to selected frame (corrupt stack?)");
- /* Note that, due to frameless functions, the stronger test of
- the new frame being outer to the old frame can't be used -
- frameless functions differ by only their PC value. */
- break;
- default:
- internal_error (__FILE__, __LINE__, "bad switch");
- }
- /* FIXME: cagney/2002-12-18: Instead of this hack, the frame ID
- should be directly stored in the `struct frame_info'.
- Unfortunatly, GDB isn't quite ready for this, need to get HP/UX
- multi-arch and make 'struct frame_info' opaque. */
- next_frame->id_unwind_cache_p = 1;
- prev_frame->frame = next_frame->id_unwind_cache.base;
- }
+ return NULL;
+ }
+ break;
+ case NORMAL_FRAME:
+ case SIGTRAMP_FRAME:
+ prev_frame->unwind->id (next_frame, &prev_frame->unwind_cache,
+ &prev_frame->id);
+ /* Check that the unwound ID is valid. */
+ if (!frame_id_p (prev_frame->id))
+ {
+ if (frame_debug)
+ fprintf_unfiltered (gdb_stdlog,
+ "Outermost frame - unwound frame ID invalid\n");
+ return NULL;
+ }
+ /* Check that the new frame isn't inner to (younger, below,
+ next) the old frame. If that happens the frame unwind is
+ going backwards. */
+ /* FIXME: cagney/2003-02-25: Ignore the sentinel frame since
+ that doesn't have a valid frame ID. Should instead set the
+ sentinel frame's frame ID to a `sentinel'. Leave it until
+ after the switch to storing the frame ID, instead of the
+ frame base, in the frame object. */
+ if (next_frame->level >= 0
+ && frame_id_inner (prev_frame->id, get_frame_id (next_frame)))
+ error ("Unwound frame inner-to selected frame (corrupt stack?)");
+ /* Note that, due to frameless functions, the stronger test of
+ the new frame being outer to the old frame can't be used -
+ frameless functions differ by only their PC value. */
+ break;
+ default:
+ internal_error (__FILE__, __LINE__, "bad switch");
+ }
+
+ /* FIXME: cagney/2002-12-18: Instead of this hack, should only store
+ the frame ID in PREV_FRAME. Unfortunatly, some architectures
+ (HP/UX) still reply on EXTRA_FRAME_INFO and, hence, still poke at
+ the "struct frame_info" object directly. */
+ prev_frame->frame = prev_frame->id.base;
/* Link it in. */
next_frame->prev = prev_frame;
@@ -1557,11 +1549,11 @@
deprecated_update_frame_pc_hack (struct frame_info *frame, CORE_ADDR pc)
{
/* See comment in "frame.h". */
- gdb_assert (frame->next != NULL);
- /* Fix up this PC's value. */
frame->pc = pc;
- /* While we're at it, also update the cache, in NEXT, that also
- contains that value. */
+ /* While we're at it, update this frame's cached PC value, found in
+ the next frame. Oh, for the day when "struct frame_info" is
+ opaque and this hack on hack can go. */
+ gdb_assert (frame->next != NULL);
frame->next->pc_unwind_cache = pc;
frame->next->pc_unwind_cache_p = 1;
}
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.70.2.2
diff -u -r1.70.2.2 frame.h
--- frame.h 4 Mar 2003 23:15:24 -0000 1.70.2.2
+++ frame.h 6 Mar 2003 00:56:23 -0000
@@ -310,10 +310,6 @@
extern CORE_ADDR frame_pc_unwind (struct frame_info *frame);
-/* Unwind the frame ID. Return an ID that uniquely identifies the
- caller's frame. */
-extern struct frame_id frame_id_unwind (struct frame_info *frame);
-
/* Discard the specified frame. Restoring the registers to the state
of the caller. */
extern void frame_pop (struct frame_info *frame);
@@ -412,9 +408,9 @@
int pc_unwind_cache_p;
CORE_ADDR pc_unwind_cache;
- /* Cached copy of the previous frame's ID. */
- int id_unwind_cache_p;
- struct frame_id id_unwind_cache;
+ /* This frame's ID. Note that the frame's ID, base and PC contain
+ redundant information. */
+ struct frame_id id;
/* Pointers to the next (down, inner, younger) and previous (up,
outer, older) frame_info's in the frame cache. */