8464198
2005-07-14  Jeff Johnsotn  <jjohnstn@redhat.com>
8464198
8464198
	* linux-nat.c (linux_nat_xfer_memory): Incorporate Fujitsu
8464198
	work-around to use /proc/mem for storage, but to fall-back
8464198
	to PTRACE for ia64 rse register areas.
8464198
	* ia64-linux-nat.c (ia64_rse_slot_num): New static function.
8464198
	(ia64_rse_skip_regs): Ditto.
8464198
	(ia64_linux_check_stack_region): New function.
8464198
	
e5611bf
Index: gdb-6.8.50.20090803/gdb/linux-nat.c
9231e41
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/linux-nat.c	2009-08-04 06:29:55.000000000 +0200
e5611bf
+++ gdb-6.8.50.20090803/gdb/linux-nat.c	2009-08-04 06:30:53.000000000 +0200
e5611bf
@@ -4495,15 +4495,38 @@ linux_xfer_partial (struct target_ops *o
e5611bf
 	offset &= ((ULONGEST) 1 << addr_bit) - 1;
e5611bf
     }
8464198
 
9231e41
-#ifndef NATIVE_XFER_UNWIND_TABLE
8464198
-  /* FIXME: For ia64, we cannot currently use linux_proc_xfer_memory
407ebe9
-	    for accessing thread storage.  Revert when Bugzilla 147436
9231e41
-	    is fixed.  */
9231e41
   xfer = linux_proc_xfer_partial (ops, object, annex, readbuf, writebuf,
9231e41
 				  offset, len);
9231e41
   if (xfer != 0)
9231e41
-    return xfer;
9231e41
+    {
8464198
+#ifdef NATIVE_XFER_UNWIND_TABLE
9231e41
+      struct mem_region range;
9231e41
+      range.lo = memaddr;
9231e41
+      range.hi = memaddr + len;
8464198
+
9231e41
+      /* FIXME: For ia64, we cannot currently use
9231e41
+	 linux_proc_xfer_partial for accessing rse register storage.
9231e41
+	 Revert when Bugzilla 147436 is fixed.  */
1592379
+#ifdef NATIVE_XFER_UNWIND_TABLE
1592379
+      extern int ia64_linux_check_stack_region (struct lwp_info *lwp,
1592379
+						void *range);
1592379
+#endif
9231e41
+      if (iterate_over_lwps (ia64_linux_check_stack_region, &range) != NULL)
9231e41
+	{ /* This region contains ia64 rse registers, we have to re-read.  */
9231e41
+	  int xxfer;
9231e41
+
9231e41
+	  /* Re-read register stack area.  */
9231e41
+	  xxfer = super_xfer_partial (ops, object, annex,
9231e41
+				      readbuf + (range.lo - memaddr),
9231e41
+				      writebuf + (range.lo - memaddr),
9231e41
+				      offset + (range.lo - memaddr),
9231e41
+				      range.hi - range.lo);
9231e41
+	  if (xxfer == 0)
9231e41
+	    xfer = 0;
9231e41
+	}
9231e41
 #endif
9231e41
+      return xfer;
8464198
+    }
9231e41
 
9231e41
   return super_xfer_partial (ops, object, annex, readbuf, writebuf,
9231e41
 			     offset, len);
e5611bf
Index: gdb-6.8.50.20090803/gdb/ia64-linux-nat.c
9231e41
===================================================================
e5611bf
--- gdb-6.8.50.20090803.orig/gdb/ia64-linux-nat.c	2009-02-23 01:03:49.000000000 +0100
e5611bf
+++ gdb-6.8.50.20090803/gdb/ia64-linux-nat.c	2009-08-04 06:30:53.000000000 +0200
1592379
@@ -809,6 +809,64 @@ ia64_linux_xfer_partial (struct target_o
9231e41
 
9231e41
 void _initialize_ia64_linux_nat (void);
8464198
 
8464198
+/*
8464198
+ * Note: taken from ia64_tdep.c
8464198
+ *
8464198
+ */
8464198
+
8464198
+static __inline__ unsigned long
8464198
+ia64_rse_slot_num (unsigned long addr)
8464198
+{
8464198
+  return (addr >> 3) & 0x3f;
8464198
+}
8464198
+
8464198
+/* Skip over a designated number of registers in the backing
8464198
+   store, remembering every 64th position is for NAT.  */
8464198
+static __inline__ unsigned long
8464198
+ia64_rse_skip_regs (unsigned long  addr, long num_regs)
8464198
+{
8464198
+  long delta = ia64_rse_slot_num(addr) + num_regs;
8464198
+
8464198
+  if (num_regs < 0)
8464198
+    delta -= 0x3e;
8464198
+  return addr + ((num_regs + delta/0x3f) << 3);
8464198
+}
8464198
+
8464198
+/*
8464198
+ * Check mem_region is stack or not. If stack, /proc/<pid>/mem cannot return 
8464198
+ * expected value.
8464198
+ */
8464198
+int ia64_linux_check_stack_region(struct lwp_info *ti, struct mem_region *range)
8464198
+{
8464198
+	CORE_ADDR addr;
8464198
+	int error;
8464198
+	unsigned long bsp, cfm, bspstore;
8464198
+	long sof;
8464198
+	pid_t pid = ptid_get_lwp(ti->ptid);
8464198
+	bsp = ptrace(PTRACE_PEEKUSER, pid, PT_AR_BSP ,NULL);
8464198
+	if (bsp == (unsigned long)-1) {
8464198
+		return 1;
8464198
+	}
8464198
+	/* stack is allocated by one-segment, not separated into several segments.
8464198
+	   So, we only have to check whether bsp is in *range* or not. */ 		
8464198
+	if((range->lo <= bsp) && (bsp <= range->hi)) {
8464198
+		bspstore = ptrace(PTRACE_PEEKUSER, pid, PT_AR_BSPSTORE, NULL);
8464198
+		cfm = ptrace(PTRACE_PEEKUSER, pid, PT_CFM, NULL);
8464198
+		sof = cfm & 0x3f;
8464198
+		bsp = ia64_rse_skip_regs(bsp, -sof);
8464198
+		range->lo = bspstore;
8464198
+		range->hi = bsp;
8464198
+		/* we have to check the size of dirty register stack area */
8464198
+		/*
8464198
+		fprintf_unfiltered(gdb_stdlog, "<%d> <%p>  <%lx> <%p> <%p>\n",
8464198
+				   pid, bsp, sof, range->lo, range->hi);
8464198
+		*/
8464198
+		return 1;
8464198
+	}
8464198
+	
8464198
+	return 0;
8464198
+}
8464198
+
8464198
 void
8464198
 _initialize_ia64_linux_nat (void)
8464198
 {