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