[ia64-linux] Allow libunwind to fetch register 0
authorJoel Brobecker <brobecker@gnat.com>
Wed, 28 Mar 2012 17:08:48 +0000 (17:08 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Wed, 28 Mar 2012 17:08:48 +0000 (17:08 +0000)
On ia64-linux, GDB sometimes prints the following error when trying
to switch to a different task:

    (gdb) task 3
    Register 0 is not available

This is a random failure that sometimes happens, sometimes does not.
The error comes from the fact that the libunwind library is requesting
the value of register 0 (zero): This eventually leads us to
ia64-linux-nat.c:ia64_linux_fetch_register.

This function relies on ia64_cannot_fetch_register to determine
whether or not we have access to the register's value.  The ptrace
interface does not provide the r0 value, and so we end up telling
the regcache that this register's value is not available.  And yet,
for r0, we do not need to ask ptrace for its value, since it is
always zero.

So, the fix was to add a special rule for supplying a nul value
when regnum == IA64_GR0_REGNUM.

gdb/ChangeLog:

        * ia64-linux-nat.c (ia64_linux_fetch_register): Add special
        handling for r0.

gdb/ChangeLog
gdb/ia64-linux-nat.c

index 0fb6602c32e14c9fb3af8f59c5822f4e18377928..0b3f886a3ef2d3d7cb36a838691ccea34e509229 100644 (file)
@@ -1,3 +1,8 @@
+2012-03-28  Joel Brobecker  <brobecker@adacore.com>
+
+       * ia64-linux-nat.c (ia64_linux_fetch_register): Add special
+       handling for r0.
+
 2012-03-27  Pedro Alves  <palves@redhat.com>
 
        Eliminate struct ui_stream.
index 19b827f84a66c656a526f0589b4d470542e03816..60b873be3879e80ac98153028a73349eed0863aa 100644 (file)
@@ -680,6 +680,16 @@ ia64_linux_fetch_register (struct regcache *regcache, int regnum)
   PTRACE_TYPE_RET *buf;
   int pid, i;
 
+  /* r0 cannot be fetched but is always zero.  */
+  if (regnum == IA64_GR0_REGNUM)
+    {
+      const gdb_byte zero[8] = { 0 };
+
+      gdb_assert (sizeof (zero) == register_size (gdbarch, regnum));
+      regcache_raw_supply (regcache, regnum, zero);
+      return;
+    }
+
   if (ia64_cannot_fetch_register (gdbarch, regnum))
     {
       regcache_raw_supply (regcache, regnum, NULL);