This is the mail archive of the gdb-patches@sourceware.org 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]

[RFC/rs6000] suggest to get rid of rs6000_framedata...


In rs6000-tdep.c, rs6000_framedata is a struct used to record the
frame information collected during the prologue analysis, to be used
to initialized the frame cache. In particular, it records the smallest
number of the general purpose register has been saved on the stack
(field gpr_saved). The prologue analysis assumes that all registers
with a number greater than gpr_saved have been saved.

This assumption seems to be wrong. Not mentioned in the ABI; and, in
practise, gcc can generate code that breaks this assertion. Typically,
in the GNAT run-time lib:

0x1000a650 <__gnat_raise_exception>:    mflr    r0
0x1000a654 <__gnat_raise_exception+4>:  stw     r29,-12(r1)
0x1000a658 <__gnat_raise_exception+8>:  stw     r30,-8(r1)
0x1000a65c <__gnat_raise_exception+12>: stw     r0,8(r1)
0x1000a660 <__gnat_raise_exception+16>: stwu    r1,-80(r1)
0x1000a664 <__gnat_raise_exception+20>: lwz     r30,184(r2)
0x1000a668 <__gnat_raise_exception+24>: mr      r29,r3
0x1000a66c <__gnat_raise_exception+28>:
    bl      0x10008068 <ada__exceptions__exception_data__set_exception_msgXn>


Here, r29 and r30 are saved, r31 is not.

This can certainly be fixed by refining rs6000_framedata, adding some
information of which register have been saved. Say, a bitmap, as the
patch in attachment (given as an example, not meant to be checked
in). But I would prefer to manipulate a trad_frame_saved_reg
here. What about getting rid of rs6000_framedata and let skip_prologue
manipulate a frame cache directly? It seems that rs6000_framedata is
some legacy frome the pre-framified era of rs6000-tdep.c; it serves no
useful purpose now; or am I missing something?





2008-01-03  Jerome Guitton  <guitton@adacore.com>

	* rs6000-tdep.c (rs6000_framedata): Add new field.
	(SET_REG_IN_MAP, GET_REG_IN_MAP): New macros.
	(skip_prologue): Update register map when a register is saved.
	(rs6000_frame_cache): Only set register address if the corresponding
	register has been saved.

Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.302
diff -u -p -r1.302 rs6000-tdep.c
--- rs6000-tdep.c	1 Jan 2008 22:53:12 -0000	1.302
+++ rs6000-tdep.c	3 Jan 2008 17:35:42 -0000
@@ -118,6 +118,9 @@ struct rs6000_framedata
 				   by which we decrement sp to allocate
 				   the frame */
     int saved_gpr;		/* smallest # of saved gpr */
+    unsigned int saved_gpr_map; /* saved gpr map; for any reg in gprs,
+                                   iff bit "# of reg" of saved_gprs_map is 1
+                                   then reg is saved */
     int saved_fpr;		/* smallest # of saved fpr */
     int saved_vr;               /* smallest # of saved vr */
     int saved_ev;               /* smallest # of saved ev */
@@ -1123,6 +1126,9 @@ rs6000_software_single_step (struct fram
 
 #define GET_SRC_REG(x) (((x) >> 21) & 0x1f)
 
+#define SET_REG_IN_MAP(map,x) ((map |= 1 << x))
+#define GET_REG_IN_MAP(map,x) ((map & (1 << x)))
+
 /* Limit the number of skipped non-prologue instructions, as the examining
    of the prologue is expensive.  */
 static int max_skip_non_prologue_insns = 10;
@@ -1236,6 +1242,7 @@ bl_to_blrl_insn_p (CORE_ADDR pc, int ins
    - offset is the initial size of this stack frame --- the amount by
    which we decrement the sp to allocate the frame.
    - saved_gpr is the number of the first saved gpr.
+   - saved_gpr_map is the map of saved gprs.
    - saved_fpr is the number of the first saved fpr.
    - saved_vr is the number of the first saved vr.
    - saved_ev is the number of the first saved ev.
@@ -1277,6 +1284,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR l
 
   memset (fdata, 0, sizeof (struct rs6000_framedata));
   fdata->saved_gpr = -1;
+  fdata->saved_gpr_map = 0;
   fdata->saved_fpr = -1;
   fdata->saved_vr = -1;
   fdata->saved_ev = -1;
@@ -1355,6 +1363,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR l
 	{
 
 	  reg = GET_SRC_REG (op);
+          SET_REG_IN_MAP (fdata->saved_gpr_map, reg);
 	  if (fdata->saved_gpr == -1 || fdata->saved_gpr > reg)
 	    {
 	      fdata->saved_gpr = reg;
@@ -2962,7 +2971,8 @@ rs6000_frame_cache (struct frame_info *n
       CORE_ADDR gpr_addr = cache->base + fdata.gpr_offset;
       for (i = fdata.saved_gpr; i < ppc_num_gprs; i++)
 	{
-	  cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr;
+          if (GET_REG_IN_MAP (fdata.saved_gpr_map,i))
+            cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr;
 	  gpr_addr += wordsize;
 	}
     }

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