|
|
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 |
{
|