This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] mips 32/64 register/stack fix


Hi Andrew, Daniel,

This patch applies to the case where you have a mips64 target
(eg. mipsisa64-elf), but you're compiling in 32 bit mode (gcc -mips32).

In this case mips_regsize (gdbarch) is 64, but mips_saved_regsize (tdep)
is 32 (ie. only 32 bits are used to save a register on the stack).

trad_frame_prev_register can't handle that case (AFAICT), because
it relies on what the regcache says about the regsize.

So I've added come code to mips_mdebug_frame_prev_register
to handle it.  This fixes at least 500 testsuite failures,
and in fact makes the results for -mips32 almost identical
with the results for -mips64 (they were woefully different
before).

2004-04-22  Michael Snyder  <msnyder@redhat.com>

	* mips-tdep.c (mips_mdebug_frame_prev_register): Don't call
	trad_frame_prev_register when stack-save-size is not equal
	to register-size.

Index: mips-tdep.c
===================================================================
RCS file: /cvs/cvsfiles/gnupro/gdb/mips-tdep.c,v
retrieving revision 1.11
diff -p -r1.11 mips-tdep.c
*** mips-tdep.c	14 Apr 2004 00:54:43 -0000	1.11
--- mips-tdep.c	22 Apr 2004 01:01:34 -0000
*************** mips_mdebug_frame_prev_register (struct 
*** 1684,1693 ****
  				 enum lval_type *lvalp, CORE_ADDR *addrp,
  				 int *realnump, void *valuep)
  {
    struct mips_frame_cache *info = mips_mdebug_frame_cache (next_frame,
  							   this_cache);
!   trad_frame_prev_register (next_frame, info->saved_regs, regnum,
! 			    optimizedp, lvalp, addrp, realnump, valuep);
  }
  
  static const struct frame_unwind mips_mdebug_frame_unwind =
--- 1684,1719 ----
  				 enum lval_type *lvalp, CORE_ADDR *addrp,
  				 int *realnump, void *valuep)
  {
+   struct gdbarch *gdbarch = get_frame_arch (next_frame);
+   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
    struct mips_frame_cache *info = mips_mdebug_frame_cache (next_frame,
  							   this_cache);
!   if (mips_saved_regsize (tdep) < mips_regsize (gdbarch) &&
!       trad_frame_addr_p (info->saved_regs, regnum))
!     {
!       char tmp[MAX_REGISTER_SIZE];
!       /* The register was saved in memory, but the size on the stack
! 	 is not the same as the size in the regcache.  Trad_frame
! 	 cannot handle this case.  */
!       *optimizedp = 0;
!       *lvalp = lval_memory;
!       *addrp = info->saved_regs[regnum].addr;
!       *realnump = -1;
!       if (valuep != NULL)
! 	{
! 	  /* Clear the input buffer, read the value into it from memory
! 	     (offset by the difference between its size on the stack and
! 	     its size in the register).  */
! 	  get_frame_memory (next_frame, info->saved_regs[regnum].addr, 
! 			    tmp, mips_saved_regsize (tdep));
! 	  store_signed_integer (valuep, mips_regsize (gdbarch), 
! 				extract_signed_integer (tmp, 
! 							mips_saved_regsize (tdep)));
! 	}
!     }
!   else
!     trad_frame_prev_register (next_frame, info->saved_regs, regnum,
! 			      optimizedp, lvalp, addrp, realnump, valuep);
  }
  
  static const struct frame_unwind mips_mdebug_frame_unwind =

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]