From 2886f8b253118f6414e46d6944fb715fb8c92fcb Mon Sep 17 00:00:00 2001 From: John Gilmore Date: Fri, 18 Sep 1992 09:20:15 +0000 Subject: [PATCH] Support for accessing arbitrary MIPS stack frames in memory. * blockframe.c (get_prev_frame_info): If INIT_FRAME_PC_FIRST is set, run it before INIT_EXTRA_FRAME_INFO. * stack.c (frame_info): If PRINT_EXTRA_FRAME_INFO defined, call it. * mips-tdep.c (init_extra_frame_info): Only clobber the `frame' (FP) value in the frame_info struct if it is zero (as from top of execution stack). (setup_arbitrary_frame): Implement FRAME_SPECIFICATION_DYADIC. * mips-xdep.c (fetch_inferior_registers): ZERO_REGNUM always comes back as zero. So does FP_REGNUM, as a trigger for init_extra_frame_info. * tm-mips.h (INIT_FRAME_PC_FIRST): Kludge, FIXME, defined to get the program counter set before INIT_EXTRA_FRAME_INFO is run. (INIT_FRAME_PC): Defined to null. (PRINT_EXTRA_FRAME_INFO): print frame pointer location via symtab. (FRAME_SPECIFICATION_DYADIC): Ask for two args in frame command. Briefly explain MIPS stacks in GDB. --- gdb/ChangeLog | 24 ++++++++++++++++++++++++ gdb/mips-xdep.c | 6 ++++++ gdb/tm-mips.h | 28 ++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1ff89d48a4b..0242843aa0d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,27 @@ +Fri Sep 18 02:07:39 1992 John Gilmore (gnu@cygnus.com) + + Support for accessing arbitrary MIPS stack frames in memory. + + * blockframe.c (get_prev_frame_info): If INIT_FRAME_PC_FIRST is + set, run it before INIT_EXTRA_FRAME_INFO. + * stack.c (frame_info): If PRINT_EXTRA_FRAME_INFO defined, call it. + + * mips-tdep.c (init_extra_frame_info): Only clobber the `frame' + (FP) value in the frame_info struct if it is zero (as from top of + execution stack). + (setup_arbitrary_frame): Implement FRAME_SPECIFICATION_DYADIC. + + * mips-xdep.c (fetch_inferior_registers): ZERO_REGNUM always + comes back as zero. So does FP_REGNUM, as a trigger for + init_extra_frame_info. + + * tm-mips.h (INIT_FRAME_PC_FIRST): Kludge, FIXME, defined to get + the program counter set before INIT_EXTRA_FRAME_INFO is run. + (INIT_FRAME_PC): Defined to null. + (PRINT_EXTRA_FRAME_INFO): print frame pointer location via symtab. + (FRAME_SPECIFICATION_DYADIC): Ask for two args in frame command. + Briefly explain MIPS stacks in GDB. + Thu Sep 17 03:49:59 1992 John Gilmore (gnu@cygnus.com) * copying.awk, copying.c (show_copying_command, diff --git a/gdb/mips-xdep.c b/gdb/mips-xdep.c index 6c0e5195530..e314bf7c18e 100644 --- a/gdb/mips-xdep.c +++ b/gdb/mips-xdep.c @@ -81,6 +81,8 @@ store_inferior_registers (regno) : regno >= FP0_REGNUM ? FPR_BASE + (regno - FP0_REGNUM) \ : 0) +static const char zerobuf[MAX_REGISTER_RAW_SIZE]; + /* Get all registers from the inferior */ void @@ -104,6 +106,10 @@ fetch_inferior_registers (regno) } supply_register (regno, buf); } + + supply_register (ZERO_REGNUM, zerobuf); + /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */ + supply_register (FP_REGNUM, zerobuf); } /* Store our register values back into the inferior. diff --git a/gdb/tm-mips.h b/gdb/tm-mips.h index b8d8016ef37..0604ddb9035 100644 --- a/gdb/tm-mips.h +++ b/gdb/tm-mips.h @@ -318,6 +318,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ (((int*)dummyname)[11] |= (((unsigned long)(fun)) >> 16), \ ((int*)dummyname)[12] |= (unsigned short)(fun)) +/* There's a mess in stack frame creation. See comments in blockframe.c + near reference to INIT_FRAME_PC_FIRST. */ + +#define INIT_FRAME_PC(fromleaf, prev) /* nada */ + +#define INIT_FRAME_PC_FIRST(fromleaf, prev) \ + (prev)->pc = ((fromleaf) ? SAVED_PC_AFTER_CALL ((prev)->next) : \ + (prev)->next ? FRAME_SAVED_PC ((prev)->next) : read_pc ()); + /* Specific information about a procedure. This overlays the MIPS's PDR records, mipsread.c (ab)uses this to save memory */ @@ -334,6 +343,25 @@ typedef struct mips_extra_func_info { #define INIT_EXTRA_FRAME_INFO(fromleaf, fci) init_extra_frame_info(fci) +#define PRINT_EXTRA_FRAME_INFO(fi) \ + { \ + if (fi && fi->proc_desc && fi->proc_desc->pdr.framereg < NUM_REGS) \ + printf_filtered (" frame pointer is at %s+%d\n", \ + reg_names[fi->proc_desc->pdr.framereg], \ + fi->proc_desc->pdr.frameoffset); \ + } + +/* It takes two values to specify a frame (at least!) on the MIPS. Sigh. + + In fact, at the moment, the *PC* is the primary value that sets up + a frame. The PC is looked up to see what function it's in; symbol + information from that function tells us which register is the frame + pointer base, and what offset from there is the "virtual frame pointer". + (This is usually an offset from SP.) FIXME -- this should be cleaned + up so that the primary value is the SP, and the PC is used to disambiguate + multiple functions with the same SP that are at different stack levels. */ +#define FRAME_SPECIFICATION_DYADIC + #define STAB_REG_TO_REGNUM(num) ((num) < 32 ? (num) : (num)+FP0_REGNUM-32) /* Size of elements in jmpbuf */ -- 2.30.2