diff options
Diffstat (limited to 'gdb/ia64-hpux-nat.c')
-rw-r--r-- | gdb/ia64-hpux-nat.c | 52 |
1 files changed, 49 insertions, 3 deletions
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. */ |