Blame SOURCES/gdb-6.3-ia64-gcore-speedup-20050714.patch

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