This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[wip] Convert MIPS to generic dummy frames
- From: Andrew Cagney <ac131313 at ges dot redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Thu, 12 Sep 2002 20:02:40 -0400
- Subject: [wip] Convert MIPS to generic dummy frames
Just FYI,
I'm going to break it down a little and explain each patch individually.
However, a brief summary is:
- had to hack mips to use the new unwind stuff as otherwize it wouldn't
find dummy frame registers correctly (hack is the work as it munges the
return value). I need to look back over kevin's patch which did similar.
- had to modify generic_find_dummy_frame() so that, when it only tested
against sp/fp XOR tos
- added a signed [ulgh mips] dummy frame register read (but I think I
can do better --- the dummy frame specific functions are redundant.
- eliminated the MIPS's FP_REGNUM pseudo register!!!!!
- look at adding per frame methods for returning frame-chain and saved-pc.
- various other hacks.
enjoy,
Andrew
Wed Sep 11 14:18:01 2002 Andrew Cagney <cagney@redhat.com>
* mips-tdep.c (mips_gdbarch_init): Set read_fp to mips_read_sp.
Tue Sep 10 13:27:37 2002 Andrew Cagney <cagney@redhat.com>
* frame.h (find_saved_register): Delete declaration.
* frame.c (find_saved_register): Move function from here ...
* mips-tdep.c (find_saved_register): ... to here. Make static.
* blockframe.c (generic_find_dummy_frame): Only compare against
the dummy frame top when that was saved.
* mips-tdep.c (mips_init_extra_frame_info): Don't reset the FP
when a dummy frame.
* frame.h (generic_read_signed_register_dummy): Declare.
* blockframe.c (generic_read_signed_register_dummy): New function.
* mips-tdep.c (mips_gdbarch_init): Set use_generic_dummy_frames.
Set push_dummy_frame to generic_push_dummy_frame. Set
pc_in_call_dummy to generic_pc_in_call_dummy.
(mips_frame_chain): Detect a dummy frame.
(mips_pop_frame): Ditto.
(mips_frame_saved_pc): Ditto.
Index: blockframe.c
===================================================================
RCS file: /cvs/src/src/gdb/blockframe.c,v
retrieving revision 1.39
diff -u -r1.39 blockframe.c
--- blockframe.c 6 Sep 2002 20:17:40 -0000 1.39
+++ blockframe.c 12 Sep 2002 23:51:01 -0000
@@ -1164,9 +1164,9 @@
for (dummyframe = dummy_frame_stack; dummyframe != NULL;
dummyframe = dummyframe->next)
if ((pc >= dummyframe->call_lo && pc < dummyframe->call_hi)
- && (fp == dummyframe->fp
- || fp == dummyframe->sp
- || fp == dummyframe->top))
+ && ((SAVE_DUMMY_FRAME_TOS_P () && fp == dummyframe->top)
+ || (!SAVE_DUMMY_FRAME_TOS_P () && (fp == dummyframe->fp
+ || fp == dummyframe->sp))))
/* The frame in question lies between the saved fp and sp, inclusive */
return dummyframe->regcache;
@@ -1225,6 +1225,21 @@
[NUM_REGS .. NUM_REGS+NUM_PSEUDO_REGS) range. */
ULONGEST val;
regcache_cooked_read_unsigned (dummy_regs, regno, &val);
+ return val;
+ }
+ else
+ return 0;
+}
+
+CORE_ADDR
+generic_read_signed_register_dummy (CORE_ADDR pc, CORE_ADDR fp, int regno)
+{
+ struct regcache *dummy_regs = generic_find_dummy_frame (pc, fp);
+
+ if (dummy_regs)
+ {
+ ULONGEST val;
+ regcache_cooked_read_signed (dummy_regs, regno, &val);
return val;
}
else
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.15
diff -u -r1.15 frame.c
--- frame.c 21 Aug 2002 03:34:22 -0000 1.15
+++ frame.c 12 Sep 2002 23:51:01 -0000
@@ -78,43 +78,6 @@
return NULL;
}
-/* FIND_SAVED_REGISTER ()
-
- Return the address in which frame FRAME's value of register REGNUM
- has been saved in memory. Or return zero if it has not been saved.
- If REGNUM specifies the SP, the value we return is actually
- the SP value, not an address where it was saved. */
-
-CORE_ADDR
-find_saved_register (struct frame_info *frame, int regnum)
-{
- register struct frame_info *frame1 = NULL;
- register CORE_ADDR addr = 0;
-
- if (frame == NULL) /* No regs saved if want current frame */
- return 0;
-
- /* Note that the following loop assumes that registers used in
- frame x will be saved only in the frame that x calls and frames
- interior to it. */
- while (1)
- {
- QUIT;
- frame1 = get_next_frame (frame);
- if (frame1 == 0)
- break;
- frame = frame1;
- FRAME_INIT_SAVED_REGS (frame1);
- if (frame1->saved_regs[regnum])
- {
- addr = frame1->saved_regs[regnum];
- break;
- }
- }
-
- return addr;
-}
-
void
frame_register_unwind (struct frame_info *frame, int regnum,
int *optimizedp, enum lval_type *lvalp,
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.22
diff -u -r1.22 frame.h
--- frame.h 2 Jul 2002 19:08:53 -0000 1.22
+++ frame.h 12 Sep 2002 23:51:01 -0000
@@ -296,8 +296,6 @@
extern void show_frame_info (struct frame_info *, int, int, int);
-extern CORE_ADDR find_saved_register (struct frame_info *, int);
-
extern struct frame_info *block_innermost_frame (struct block *);
extern struct frame_info *find_frame_addr_in_frame_chain (CORE_ADDR);
@@ -306,6 +304,8 @@
extern CORE_ADDR generic_read_register_dummy (CORE_ADDR pc,
CORE_ADDR fp, int);
+extern CORE_ADDR generic_read_signed_register_dummy (CORE_ADDR pc,
+ CORE_ADDR fp, int);
extern void generic_push_dummy_frame (void);
extern void generic_pop_current_frame (void (*)(struct frame_info *));
extern void generic_pop_dummy_frame (void);
Index: mips-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/mips-tdep.c,v
retrieving revision 1.120
diff -u -r1.120 mips-tdep.c
--- mips-tdep.c 5 Sep 2002 18:31:07 -0000 1.120
+++ mips-tdep.c 12 Sep 2002 23:51:15 -0000
@@ -1589,21 +1589,27 @@
static CORE_ADDR
read_next_frame_reg (struct frame_info *fi, int regno)
{
- for (; fi; fi = fi->next)
+ int optimized;
+ CORE_ADDR addr;
+ int realnum;
+ enum lval_type lval;
+ void *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+ frame_register_unwind (fi, regno, &optimized, &lval, &addr, &realnum,
+ raw_buffer);
+
+ /* Hackup GPR registers when the ABI specifies that less than the
+ full register is stored on the stack. */
+ if (lval == lval_memory)
{
- /* We have to get the saved sp from the sigcontext
- if it is a signal handler frame. */
- if (regno == SP_REGNUM && !fi->signal_handler_caller)
- return fi->frame;
- else
+ if (regno < 32)
{
- if (fi->saved_regs == NULL)
- FRAME_INIT_SAVED_REGS (fi);
- if (fi->saved_regs[regno])
- return read_memory_integer (ADDR_BITS_REMOVE (fi->saved_regs[regno]), MIPS_SAVED_REGSIZE);
+ /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
+ saved. */
+ return read_memory_integer (addr, MIPS_SAVED_REGSIZE);
}
}
- return read_signed_register (regno);
+
+ return extract_signed_integer (raw_buffer, REGISTER_VIRTUAL_SIZE (regno));
}
/* mips_addr_bits_remove - remove useless address bits */
@@ -1696,7 +1702,10 @@
int pcreg = frame->signal_handler_caller ? PC_REGNUM
: (proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM);
- if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
+ if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame))
+ saved_pc = generic_read_signed_register_dummy (frame->pc, frame->frame,
+ PC_REGNUM);
+ else if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
saved_pc = read_memory_integer (frame->frame - MIPS_SAVED_REGSIZE, MIPS_SAVED_REGSIZE);
else
saved_pc = read_next_frame_reg (frame, pcreg);
@@ -2413,6 +2422,15 @@
if ((tmp = SKIP_TRAMPOLINE_CODE (saved_pc)) != 0)
saved_pc = tmp;
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (saved_pc, 0, 0))
+ {
+ /* A dummy frame, uses SP not FP. Get the old SP value. If all
+ is well, frame->frame the bottom of the current frame will
+ contain that value. */
+ return frame->frame;
+ }
+
/* Look up the procedure descriptor for this PC. */
proc_desc = find_proc_desc (saved_pc, frame, 1);
if (!proc_desc)
@@ -2429,7 +2447,7 @@
and have frame size zero. */
&& !frame->signal_handler_caller
/* Check if this is a call dummy frame. */
- && frame->pc != CALL_DUMMY_ADDRESS ())
+ && !PC_IN_CALL_DUMMY (frame->pc, 0, 0))
return 0;
else
return get_frame_pointer (frame, proc_desc);
@@ -2459,7 +2477,7 @@
if (fci->pc == PROC_LOW_ADDR (proc_desc)
&& !PROC_DESC_IS_DUMMY (proc_desc))
fci->frame = read_next_frame_reg (fci->next, SP_REGNUM);
- else
+ else if (!PC_IN_CALL_DUMMY (fci->pc, 0, 0))
fci->frame = get_frame_pointer (fci->next, proc_desc);
if (proc_desc == &temp_proc_desc)
@@ -3767,9 +3785,16 @@
register int regnum;
struct frame_info *frame = get_current_frame ();
CORE_ADDR new_sp = FRAME_FP (frame);
-
mips_extra_func_info_t proc_desc = frame->extra_info->proc_desc;
+ if (USE_GENERIC_DUMMY_FRAMES
+ && PC_IN_CALL_DUMMY (frame->pc, 0, 0))
+ {
+ generic_pop_dummy_frame ();
+ flush_cached_frames ();
+ return;
+ }
+
write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
if (frame->saved_regs == NULL)
FRAME_INIT_SAVED_REGS (frame);
@@ -5414,6 +5439,43 @@
return current_language->la_language == language_c;
}
+/* FIND_SAVED_REGISTER ()
+
+ Return the address in which frame FRAME's value of register REGNUM
+ has been saved in memory. Or return zero if it has not been saved.
+ If REGNUM specifies the SP, the value we return is actually
+ the SP value, not an address where it was saved. */
+
+static CORE_ADDR
+find_saved_register (struct frame_info *frame, int regnum)
+{
+ register struct frame_info *frame1 = NULL;
+ register CORE_ADDR addr = 0;
+
+ if (frame == NULL) /* No regs saved if want current frame */
+ return 0;
+
+ /* Note that the following loop assumes that registers used in
+ frame x will be saved only in the frame that x calls and frames
+ interior to it. */
+ while (1)
+ {
+ QUIT;
+ frame1 = get_next_frame (frame);
+ if (frame1 == 0)
+ break;
+ frame = frame1;
+ FRAME_INIT_SAVED_REGS (frame1);
+ if (frame1->saved_regs[regnum])
+ {
+ addr = frame1->saved_regs[regnum];
+ break;
+ }
+ }
+
+ return addr;
+}
+
/* When debugging a 64 MIPS target running a 32 bit ABI, the size of
the register stored on the stack (32) is different to its real raw
size (64). The below ensures that registers are fetched from the
@@ -5425,59 +5487,44 @@
static void
mips_get_saved_register (char *raw_buffer,
- int *optimized,
+ int *optimizedp,
CORE_ADDR *addrp,
struct frame_info *frame,
int regnum,
- enum lval_type *lval)
+ enum lval_type *lvalp)
{
- CORE_ADDR addr;
+ CORE_ADDR addrx;
+ enum lval_type lvalx;
+ int optimizedx;
+ int realnum;
if (!target_has_registers)
error ("No registers.");
- /* Normal systems don't optimize out things with register numbers. */
- if (optimized != NULL)
- *optimized = 0;
- addr = find_saved_register (frame, regnum);
- if (addr != 0)
- {
- if (lval != NULL)
- *lval = lval_memory;
- if (regnum == SP_REGNUM)
- {
- if (raw_buffer != NULL)
- {
- /* Put it back in target format. */
- store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
- (LONGEST) addr);
- }
- if (addrp != NULL)
- *addrp = 0;
- return;
- }
+ /* Make certain that all needed parameters are present. */
+ if (addrp == NULL)
+ addrp = &addrx;
+ if (lvalp == NULL)
+ lvalp = &lvalx;
+ if (optimizedp == NULL)
+ optimizedp = &optimizedx;
+ frame_register_unwind (get_next_frame (frame), regnum, optimizedp, lvalp, addrp,
+ &realnum, raw_buffer);
+ /* Hackup GPR registers when the ABI specifies that less than the
+ full register on the stack. */
+ if ((*lvalp) == lval_memory)
+ {
if (raw_buffer != NULL)
{
- LONGEST val;
if (regnum < 32)
- /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
- saved. */
- val = read_memory_integer (addr, MIPS_SAVED_REGSIZE);
- else
- val = read_memory_integer (addr, REGISTER_RAW_SIZE (regnum));
- store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), val);
+ {
+ /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
+ saved. */
+ LONGEST val = read_memory_integer ((*addrp), MIPS_SAVED_REGSIZE);
+ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), val);
+ }
}
}
- else
- {
- if (lval != NULL)
- *lval = lval_register;
- addr = REGISTER_BYTE (regnum);
- if (raw_buffer != NULL)
- read_register_gen (regnum, raw_buffer);
- }
- if (addrp != NULL)
- *addrp = addr;
}
/* Immediately after a function call, return the saved pc.
@@ -5918,7 +5965,7 @@
set_gdbarch_register_name (gdbarch, mips_register_name);
set_gdbarch_read_pc (gdbarch, mips_read_pc);
set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
- set_gdbarch_read_fp (gdbarch, generic_target_read_fp);
+ set_gdbarch_read_fp (gdbarch, mips_read_sp); /* Draft FP from SP. */
set_gdbarch_read_sp (gdbarch, mips_read_sp);
set_gdbarch_write_sp (gdbarch, generic_target_write_sp);
@@ -5943,21 +5990,22 @@
set_gdbarch_call_dummy_p (gdbarch, 1);
set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
- set_gdbarch_use_generic_dummy_frames (gdbarch, 0);
+ set_gdbarch_use_generic_dummy_frames (gdbarch, 1);
set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT);
set_gdbarch_call_dummy_address (gdbarch, mips_call_dummy_address);
set_gdbarch_push_return_address (gdbarch, mips_push_return_address);
- set_gdbarch_push_dummy_frame (gdbarch, mips_push_dummy_frame);
+ set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
set_gdbarch_pop_frame (gdbarch, mips_pop_frame);
set_gdbarch_call_dummy_start_offset (gdbarch, 0);
set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
set_gdbarch_call_dummy_length (gdbarch, 0);
set_gdbarch_fix_call_dummy (gdbarch, mips_fix_call_dummy);
- set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_at_entry_point);
+ set_gdbarch_pc_in_call_dummy (gdbarch, generic_pc_in_call_dummy);
set_gdbarch_call_dummy_words (gdbarch, mips_call_dummy_words);
set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (mips_call_dummy_words));
set_gdbarch_push_return_address (gdbarch, mips_push_return_address);
+ set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
set_gdbarch_register_convertible (gdbarch, mips_register_convertible);
set_gdbarch_register_convert_to_virtual (gdbarch,
mips_register_convert_to_virtual);