diff options
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/ia64-hpux-nat.c | 52 |
2 files changed, 57 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f52139f..ec0532e 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,13 @@ 2012-08-16 Joel Brobecker <brobecker@adacore.com> + * ia64-hpux-nat.c (ia64_hpux_get_register_from_save_state_t): + New function. + (ia64_hpux_xfer_memory): Check if inferior_ptid is known before + using the regache. Use ia64_hpux_get_register_from_save_state_t + to access the bsp and bspstore registers if not. + +2012-08-16 Joel Brobecker <brobecker@adacore.com> + * breakpoint.h (detach_breakpoints): pid parameter is now a ptid. * breakpoint.c (detach_breakpoints): Change pid parameter into a ptid. Adjust code accordingly. diff --git a/gdb/ia64-hpux-nat.c b/gdb/ia64-hpux-nat.c index 07a433e..741d3d8 100644 --- a/gdb/ia64-hpux-nat.c +++ b/gdb/ia64-hpux-nat.c @@ -485,6 +485,37 @@ ia64_hpux_xfer_memory_bs (struct target_ops *ops, const char *annex, return 0; } +/* Get a register value as a unsigned value directly from the system, + instead of going through the regcache. + + This function is meant to be used when inferior_ptid is not + a thread/process known to GDB. */ + +static ULONGEST +ia64_hpux_get_register_from_save_state_t (int regnum, int reg_size) +{ + gdb_byte *buf = alloca (reg_size); + int offset = u_offsets[regnum]; + int status; + + /* The register is assumed to be available for fetching. */ + gdb_assert (offset != -1); + + status = ia64_hpux_read_register_from_save_state_t (offset, buf, reg_size); + if (status < 0) + { + /* This really should not happen. If it does, emit a warning + and pretend the register value is zero. Not exactly the best + error recovery mechanism, but better than nothing. We will + try to do better if we can demonstrate that this can happen + under normal circumstances. */ + warning (_("Failed to read value of register number %d."), regnum); + return 0; + } + + return extract_unsigned_integer (buf, reg_size, BFD_ENDIAN_BIG); +} + /* The "xfer_partial" target_ops routine for ia64-hpux, in the case where the requested object is TARGET_OBJECT_MEMORY. */ @@ -504,9 +535,24 @@ ia64_hpux_xfer_memory (struct target_ops *ops, const char *annex, (3) The region inside the backing-store, which needs to be read/written specially. */ - regcache_raw_read_unsigned (get_current_regcache (), IA64_BSP_REGNUM, &bsp); - regcache_raw_read_unsigned (get_current_regcache (), IA64_BSPSTORE_REGNUM, - &bspstore); + if (in_inferior_list (ptid_get_pid (inferior_ptid))) + { + struct regcache *regcache = get_current_regcache (); + + regcache_raw_read_unsigned (regcache, IA64_BSP_REGNUM, &bsp); + regcache_raw_read_unsigned (regcache, IA64_BSPSTORE_REGNUM, &bspstore); + } + else + { + /* This is probably a child of our inferior created by a fork. + Because this process has not been added to our inferior list + (we are probably in the process of handling that child + process), we do not have a regcache to read the registers + from. So get those values directly from the kernel. */ + bsp = ia64_hpux_get_register_from_save_state_t (IA64_BSP_REGNUM, 8); + bspstore = + ia64_hpux_get_register_from_save_state_t (IA64_BSPSTORE_REGNUM, 8); + } /* 1. Memory region before BSPSTORE. */ |