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]

[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);

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