From e1703d1f535a7320b1043c8330f17728087e4afd Mon Sep 17 00:00:00 2001 From: Michael Snyder Date: Tue, 5 Nov 1996 19:06:11 +0000 Subject: [PATCH] Tue Nov 5 10:21:02 1996 Michael Snyder * m32r-tdep.c: Improved frame_chain and fn prologue analysis. * config/tm-m32r.h: Add framesize and register to extra_frame_info. --- gdb/ChangeLog | 7 ++++++ gdb/config/m32r/tm-m32r.h | 13 +++++++---- gdb/m32r-tdep.c | 56 ++++++++++++++++++++++++----------------------- 3 files changed, 45 insertions(+), 31 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 295f1e9..2e0a8f4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +start-sanitize-m32r +Tue Nov 5 10:21:02 1996 Michael Snyder + + * m32r-tdep.c: Improved frame_chain and fn prologue analysis. + * config/tm-m32r.h: Add framesize and register to extra_frame_info. +end-sanitize-m32r + Tue Nov 5 10:08:07 1996 Stu Grossman (grossman@critters.cygnus.com) * mswin/gdbwin.h: Remove bogus definition of CORE_ADDR. diff --git a/gdb/config/m32r/tm-m32r.h b/gdb/config/m32r/tm-m32r.h index 4dc04be..f9d1ad8 100644 --- a/gdb/config/m32r/tm-m32r.h +++ b/gdb/config/m32r/tm-m32r.h @@ -92,13 +92,18 @@ struct type; struct value; #endif -/* #define EXTRA_FRAME_INFO struct frame_saved_regs fsr; */ /* Define other aspects of the stack frame. - we keep a copy of the worked out return pc lying around, since it - is a useful bit of info */ + 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 whether + the frame pointer is valid (for frameless functions, and when we're + still in the prologue of a function with a frame) */ /* mvs_check EXTRA_FRAME_INFO */ -#define EXTRA_FRAME_INFO struct frame_saved_regs fsr; +#define EXTRA_FRAME_INFO \ + struct frame_saved_regs fsr; \ + int framesize; \ + int using_frame_pointer; + extern void m32r_init_extra_frame_info PARAMS ((struct frame_info *fi)); /* mvs_check INIT_EXTRA_FRAME_INFO */ diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c index 98fca39..1e6ec8d 100644 --- a/gdb/m32r-tdep.c +++ b/gdb/m32r-tdep.c @@ -93,9 +93,6 @@ m32r_scan_prologue (fi, fsr) /* this code essentially duplicates skip_prologue, but we need the start address below. */ - if (fsr) - memset (fsr->regs, '\000', sizeof fsr->regs); - if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) { sal = find_pc_line (prologue_start, 0); @@ -109,7 +106,7 @@ m32r_scan_prologue (fi, fsr) prologue_end = sal.end; /* (probably means no prologue) */ } else - prologue_end = prologue_start + 48; /* We're in the boondocks: allow for */ + prologue_end = prologue_start + 40; /* We're in the boondocks: allow for */ /* 16 pushes, an add, and "mv fp,sp" */ prologue_end = min (prologue_end, fi->pc); @@ -149,15 +146,20 @@ m32r_scan_prologue (fi, fsr) insn &= 0x00ffffff; /* positive */ framesize += insn; } - else if (insn == 0x1d8f) /* mv fp, sp */ - break; /* end of stack adjustments */ + else if (insn == 0x1d8f) { /* mv fp, sp */ + fi->using_frame_pointer = 1; /* fp is now valid */ + break; /* end of stack adjustments */ + } + else + break; /* anything else isn't prologue */ } return framesize; } /* This function actually figures out the frame address for a given pc and - sp. This is tricky on the v850 because we only use an explicit frame - pointer when using alloca(). The only reliable way to get this info is to + sp. This is tricky on the m32r because we sometimes don't use an explicit + frame pointer, and the previous stack pointer isn't necessarily recorded + on the stack. The only reliable way to get this info is to examine the prologue. */ @@ -166,23 +168,31 @@ m32r_init_extra_frame_info (fi) struct frame_info *fi; { int reg; - int framesize; if (fi->next) fi->pc = FRAME_SAVED_PC (fi->next); - framesize = m32r_scan_prologue (fi, &fi->fsr); + memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); + fi->using_frame_pointer = 0; + fi->framesize = m32r_scan_prologue (fi, &fi->fsr); #if 0 if (PC_IN_CALL_DUMMY (fi->pc, NULL, NULL)) fi->frame = dummy_frame_stack->sp; else #endif if (!fi->next) - fi->frame = read_register (SP_REGNUM); + if (fi->using_frame_pointer) + fi->frame = read_register (FP_REGNUM); + else + fi->frame = read_register (SP_REGNUM); + else /* fi->next means this is not the innermost frame */ + if (fi->using_frame_pointer) /* we have an FP */ + if (fi->next->fsr.regs[FP_REGNUM] != 0) /* caller saved our FP */ + fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4); for (reg = 0; reg < NUM_REGS; reg++) if (fi->fsr.regs[reg] != 0) - fi->fsr.regs[reg] = fi->frame + framesize - fi->fsr.regs[reg]; + fi->fsr.regs[reg] = fi->frame + fi->framesize - fi->fsr.regs[reg]; } /* Find the caller of this frame. We do this by seeing if RP_REGNUM is saved @@ -222,27 +232,19 @@ m32r_find_callers_reg (fi, regnum) /* Given a GDB frame, determine the address of the calling function's frame. This will be used to create a new GDB frame struct, and then INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. - For m32r, simply get the saved FP off the stack. + For m32r, we save the frame size when we initialize the frame_info. */ CORE_ADDR m32r_frame_chain (fi) struct frame_info *fi; { - CORE_ADDR saved_fp = fi->fsr.regs[FP_REGNUM]; - CORE_ADDR fn_start, fn_end; - - if (saved_fp != 0) - return read_memory_integer (saved_fp, 4); - else { - if (find_pc_partial_function (fi->pc, 0, &fn_start, &fn_end)) - if (fn_start == entry_point_address ()) - return 0; /* in _start fn, don't chain further */ - else - return read_register (FP_REGNUM); - else /* in the woods, what to do? */ - return 0; /* for now, play it safe and give up... */ - } + CORE_ADDR fn_start; + + if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) + if (fn_start == entry_point_address ()) + return 0; /* in _start fn, don't chain further */ + return fi->frame + fi->framesize; } /* All we do here is record SP and FP on the call dummy stack */ -- 2.7.4