* target.h: Add enum target_waitkind, enum target_signal, and
[deliverable/binutils-gdb.git] / gdb / hppa-tdep.c
index c4a858057f48851123e4ef23615c8f73695fde4a..5e6f0b3944384c3dd5ba5d4ae06a9bff40275092 100644 (file)
@@ -61,6 +61,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 static int restore_pc_queue PARAMS ((struct frame_saved_regs *fsr));
 static int hppa_alignof PARAMS ((struct type *arg));
+static FRAME_ADDR dig_fp_from_stack PARAMS ((FRAME frame,
+                                            struct unwind_table_entry *u));
 CORE_ADDR frame_saved_pc PARAMS ((FRAME frame));
 
 \f
@@ -242,8 +244,6 @@ extract_17 (word)
                      (word & 0x1) << 16, 17) << 2;
 }
 \f
-static int use_unwind = 0;
-
 /* Lookup the unwind (stack backtrace) info for the given PC.  We search all
    of the objfiles seeking the unwind table entry for this PC.  Each objfile
    contains a sorted list of struct unwind_table_entry.  Since we do a binary
@@ -296,6 +296,77 @@ find_unwind_entry(pc)
   return NULL;
 }
 
+/* Called when no unwind descriptor was found for PC.  Returns 1 if it
+   appears that PC is in a linker stub.  */
+static int pc_in_linker_stub PARAMS ((CORE_ADDR));
+
+static int
+pc_in_linker_stub (pc)
+     CORE_ADDR pc;
+{
+  int found_magic_instruction = 0;
+  int i;
+  char buf[4];
+
+  /* If unable to read memory, assume pc is not in a linker stub.  */
+  if (target_read_memory (pc, buf, 4) != 0)
+    return 0;
+
+  /* We are looking for something like
+
+     ; $$dyncall jams RP into this special spot in the frame (RP')
+     ; before calling the "call stub"
+     ldw     -18(sp),rp
+
+     ldsid   (rp),r1         ; Get space associated with RP into r1
+     mtsp    r1,sp           ; Move it into space register 0
+     be,n    0(sr0),rp)      ; back to your regularly scheduled program
+     */
+
+  /* Maximum known linker stub size is 4 instructions.  Search forward
+     from the given PC, then backward.  */
+  for (i = 0; i < 4; i++)
+    {
+      /* If we hit something with an unwind, stop searching this direction.  */
+
+      if (find_unwind_entry (pc + i * 4) != 0)
+       break;
+
+      /* Check for ldsid (rp),r1 which is the magic instruction for a 
+        return from a cross-space function call.  */
+      if (read_memory_integer (pc + i * 4, 4) == 0x004010a1)
+       {
+         found_magic_instruction = 1;
+         break;
+       }
+      /* Add code to handle long call/branch and argument relocation stubs
+        here.  */
+    }
+
+  if (found_magic_instruction != 0)
+    return 1;
+
+  /* Now look backward.  */
+  for (i = 0; i < 4; i++)
+    {
+      /* If we hit something with an unwind, stop searching this direction.  */
+
+      if (find_unwind_entry (pc - i * 4) != 0)
+       break;
+
+      /* Check for ldsid (rp),r1 which is the magic instruction for a 
+        return from a cross-space function call.  */
+      if (read_memory_integer (pc - i * 4, 4) == 0x004010a1)
+       {
+         found_magic_instruction = 1;
+         break;
+       }
+      /* Add code to handle long call/branch and argument relocation stubs
+        here.  */
+    }
+  return found_magic_instruction;
+}
+
 static int
 find_return_regnum(pc)
      CORE_ADDR pc;
@@ -313,19 +384,23 @@ find_return_regnum(pc)
   return RP_REGNUM;
 }
 
+/* Return size of frame, or -1 if we should use a frame pointer.  */
 int
 find_proc_framesize(pc)
      CORE_ADDR pc;
 {
   struct unwind_table_entry *u;
 
-  if (!use_unwind)
-    return -1;
-
   u = find_unwind_entry (pc);
 
   if (!u)
-    return -1;
+    {
+      if (pc_in_linker_stub (pc))
+       /* Linker stubs have a zero size frame.  */
+       return 0;
+      else
+       return -1;
+    }
 
   if (u->Save_SP)
     /* If this bit is set, it means there is a frame pointer and we should
@@ -335,18 +410,28 @@ find_proc_framesize(pc)
   return u->Total_frame_size << 3;
 }
 
-int
-rp_saved(pc)
+/* Return offset from sp at which rp is saved, or 0 if not saved.  */
+static int rp_saved PARAMS ((CORE_ADDR));
+
+static int
+rp_saved (pc)
+     CORE_ADDR pc;
 {
   struct unwind_table_entry *u;
 
   u = find_unwind_entry (pc);
 
   if (!u)
-    return 0;
+    {
+      if (pc_in_linker_stub (pc))
+       /* This is the so-called RP'.  */
+       return -24;
+      else
+       return 0;
+    }
 
   if (u->Save_RP)
-    return 1;
+    return -20;
   else
     return 0;
 }
@@ -355,20 +440,14 @@ int
 frameless_function_invocation (frame)
      FRAME frame;
 {
+  struct unwind_table_entry *u;
 
-  if (use_unwind)
-    {
-      struct unwind_table_entry *u;
-
-      u = find_unwind_entry (frame->pc);
-
-      if (u == 0)
-       return 0;
+  u = find_unwind_entry (frame->pc);
 
-      return (u->Total_frame_size == 0);
-    }
-  else
+  if (u == 0)
     return frameless_look_for_prologue (frame);
+
+  return (u->Total_frame_size == 0);
 }
 
 CORE_ADDR
@@ -396,10 +475,15 @@ frame_saved_pc (frame)
 
       return read_register (ret_regnum) & ~0x3;
     }
-  else if (rp_saved (pc))
-    return read_memory_integer (frame->frame - 20, 4) & ~0x3;
   else
-    return read_register (RP_REGNUM) & ~0x3;
+    {
+      int rp_offset = rp_saved (pc);
+
+      if (rp_offset == 0)
+       return read_register (RP_REGNUM) & ~0x3;
+      else
+       return read_memory_integer (frame->frame + rp_offset, 4) & ~0x3;
+    }
 }
 \f
 /* We need to correct the PC and the FP for the outermost frame when we are
@@ -413,42 +497,183 @@ init_extra_frame_info (fromleaf, frame)
   int flags;
   int framesize;
 
-  if (frame->next)             /* Only do this for outermost frame */
+  if (frame->next && !fromleaf)
     return;
 
+  /* If the next frame represents a frameless function invocation
+     then we have to do some adjustments that are normally done by
+     FRAME_CHAIN.  (FRAME_CHAIN is not called in this case.)  */
+  if (fromleaf)
+    {
+      /* Find the framesize of *this* frame without peeking at the PC
+        in the current frame structure (it isn't set yet).  */
+      framesize = find_proc_framesize (FRAME_SAVED_PC (get_next_frame (frame)));
+
+      /* Now adjust our base frame accordingly.  If we have a frame pointer
+        use it, else subtract the size of this frame from the current
+        frame.  (we always want frame->frame to point at the lowest address
+        in the frame).  */
+      if (framesize == -1)
+       frame->frame = read_register (FP_REGNUM);
+      else
+       frame->frame -= framesize;
+      return;
+    }
+
   flags = read_register (FLAGS_REGNUM);
   if (flags & 2)       /* In system call? */
     frame->pc = read_register (31) & ~0x3;
 
-  /* The outermost frame is always derived from PC-framesize */
+  /* The outermost frame is always derived from PC-framesize
+
+     One might think frameless innermost frames should have
+     a frame->frame that is the same as the parent's frame->frame.
+     That is wrong; frame->frame in that case should be the *high*
+     address of the parent's frame.  It's complicated as hell to
+     explain, but the parent *always* creates some stack space for
+     the child.  So the child actually does have a frame of some
+     sorts, and its base is the high address in its parent's frame.  */
   framesize = find_proc_framesize(frame->pc);
   if (framesize == -1)
     frame->frame = read_register (FP_REGNUM);
   else
     frame->frame = read_register (SP_REGNUM) - framesize;
-
-  if (!frameless_function_invocation (frame)) /* Frameless? */
-    return;                                /* No, quit now */
-
-  /* For frameless functions, we need to look at the caller's frame */
-  framesize = find_proc_framesize(FRAME_SAVED_PC(frame));
-  if (framesize != -1)
-    frame->frame -= framesize;
 }
 \f
+/* Given a GDB frame, determine the address of the calling function's frame.
+   This will be used to create a new GDB frame struct, and then
+   INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
+
+   This may involve searching through prologues for several functions
+   at boundaries where GCC calls HP C code, or where code which has
+   a frame pointer calls code without a frame pointer.  */
+  
+
 FRAME_ADDR
 frame_chain (frame)
      struct frame_info *frame;
 {
-  int framesize;
+  int my_framesize, caller_framesize;
+  struct unwind_table_entry *u;
 
-  framesize = find_proc_framesize(FRAME_SAVED_PC(frame));
+  /* Get frame sizes for the current frame and the frame of the 
+     caller.  */
+  my_framesize = find_proc_framesize (frame->pc);
+  caller_framesize = find_proc_framesize (FRAME_SAVED_PC(frame));
 
-  if (framesize != -1)
-    return frame->frame - framesize;
+  /* If caller does not have a frame pointer, then its frame
+     can be found at current_frame - caller_framesize.  */
+  if (caller_framesize != -1)
+    return frame->frame - caller_framesize;
 
-  return read_memory_integer (frame->frame, 4);
+  /* Both caller and callee have frame pointers and are GCC compiled
+     (SAVE_SP bit in unwind descriptor is on for both functions.
+     The previous frame pointer is found at the top of the current frame.  */
+  if (caller_framesize == -1 && my_framesize == -1)
+    return read_memory_integer (frame->frame, 4);
+
+  /* Caller has a frame pointer, but callee does not.  This is a little
+     more difficult as GCC and HP C lay out locals and callee register save
+     areas very differently.
+
+     The previous frame pointer could be in a register, or in one of 
+     several areas on the stack.
+
+     Walk from the current frame to the innermost frame examining 
+     unwind descriptors to determine if %r3 ever gets saved into the
+     stack.  If so return whatever value got saved into the stack.
+     If it was never saved in the stack, then the value in %r3 is still
+     valid, so use it. 
+
+     We use information from unwind descriptors to determine if %r3
+     is saved into the stack (Entry_GR field has this information).  */
+
+  while (frame)
+    {
+      u = find_unwind_entry (frame->pc);
+
+      if (!u)
+       {
+         /* We could find this information by examining prologues.  I don't
+            think anyone has actually written any tools (not even "strip")
+            which leave them out of an executable, so maybe this is a moot
+            point.  */
+         warning ("Unable to find unwind for PC 0x%x -- Help!", frame->pc);
+         return 0;
+       }
+
+      /* Entry_GR specifies the number of callee-saved general registers
+        saved in the stack.  It starts at %r3, so %r3 would be 1.  */
+      if (u->Entry_GR >= 1 || u->Save_SP)
+       break;
+      else
+       frame = frame->next;
+    }
+
+  if (frame)
+    {
+      /* We may have walked down the chain into a function with a frame
+        pointer.  */
+      if (u->Save_SP)
+       return read_memory_integer (frame->frame, 4);
+      /* %r3 was saved somewhere in the stack.  Dig it out.  */
+      else 
+       return dig_fp_from_stack (frame, u);
+    }
+  else
+    {
+      /* The value in %r3 was never saved into the stack (thus %r3 still
+        holds the value of the previous frame pointer).  */
+      return read_register (FP_REGNUM);
+    }
 }
+
+/* Given a frame and an unwind descriptor return the value for %fr (aka fp)
+   which was saved into the stack.  FIXME: Why can't we just use the standard
+   saved_regs stuff?  */
+
+static FRAME_ADDR
+dig_fp_from_stack (frame, u)
+     FRAME frame;
+     struct unwind_table_entry *u;
+{
+  CORE_ADDR pc = u->region_start;
+
+  /* Search the function for the save of %r3.  */
+  while (pc != u->region_end)
+    {
+      char buf[4];
+      unsigned long inst;
+      int status;
+
+      /* We need only look for the standard stw %r3,X(%sp) instruction,
+        the other variants (eg stwm) are only used on the first register
+        save (eg %r3).  */
+      status = target_read_memory (pc, buf, 4);
+      inst = extract_unsigned_integer (buf, 4);
+
+      if (status != 0)
+       memory_error (status, pc);
+
+      /* Check for stw %r3,X(%sp).  */
+      if ((inst & 0xffffc000) == 0x6bc30000)
+       {
+         /* Found the instruction which saves %r3.  The offset (relative
+            to this frame) is framesize + immed14 (derived from the 
+            store instruction).  */
+         int offset = (u->Total_frame_size << 3) + extract_14 (inst);
+
+         return read_memory_integer (frame->frame + offset, 4);
+       }
+
+      /* Keep looking.  */
+      pc += 4;
+    }
+
+  warning ("Unable to find %%r3 in stack.\n");
+  return 0;
+}
+
 \f
 /* To see if a frame chain is valid, see if the caller looks like it
    was compiled with gcc. */
@@ -458,33 +683,38 @@ frame_chain_valid (chain, thisframe)
      FRAME_ADDR chain;
      FRAME thisframe;
 {
-  struct minimal_symbol *msym;
+  struct minimal_symbol *msym_us;
+  struct minimal_symbol *msym_start;
+  struct unwind_table_entry *u;
 
   if (!chain)
     return 0;
 
-  if (use_unwind)
-    {
+  u = find_unwind_entry (thisframe->pc);
+
+  /* We can't just check that the same of msym_us is "_start", because
+     someone idiotically decided that they were going to make a Ltext_end
+     symbol with the same address.  This Ltext_end symbol is totally
+     indistinguishable (as nearly as I can tell) from the symbol for a function
+     which is (legitimately, since it is in the user's namespace)
+     named Ltext_end, so we can't just ignore it.  */
+  msym_us = lookup_minimal_symbol_by_pc (FRAME_SAVED_PC (thisframe));
+  msym_start = lookup_minimal_symbol ("_start", NULL);
+  if (msym_us
+      && msym_start
+      && SYMBOL_VALUE_ADDRESS (msym_us) == SYMBOL_VALUE_ADDRESS (msym_start))
+    return 0;
 
-      struct unwind_table_entry *u;
+  if (u == NULL)
+    return 1;
 
-      u = find_unwind_entry (thisframe->pc);
+  if (u->Save_SP || u->Total_frame_size)
+    return 1;
 
-      if (u && (u->Save_SP || u->Total_frame_size))
-       return 1;
-      else
-       return 0;
-    }
-  else
-    {
-      msym = lookup_minimal_symbol_by_pc (FRAME_SAVED_PC (thisframe));
+  if (pc_in_linker_stub (thisframe->pc))
+    return 1;
 
-      if (msym
-         && (strcmp (SYMBOL_NAME (msym), "_start") == 0))
-       return 0;
-      else
-       return 1;
-    }
+  return 0;
 }
 
 /*
@@ -602,10 +832,15 @@ hppa_pop_frame ()
     write_register (SAR_REGNUM,
                     read_memory_integer (fsr.regs[SAR_REGNUM], 4));
 
+  /* If the PC was explicitly saved, then just restore it.  */
   if (fsr.regs[PCOQ_TAIL_REGNUM])
     write_register (PCOQ_TAIL_REGNUM,
                     read_memory_integer (fsr.regs[PCOQ_TAIL_REGNUM], 4));
 
+  /* Else use the value in %rp to set the new PC.  */
+  else 
+    target_write_pc (read_register (RP_REGNUM));
+
   write_register (FP_REGNUM, read_memory_integer (fp, 4));
 
   if (fsr.regs[IPSW_REGNUM])    /* call dummy */
@@ -629,7 +864,7 @@ restore_pc_queue (fsr)
   CORE_ADDR pc = read_pc ();
   CORE_ADDR new_pc = read_memory_integer (fsr->regs[PCOQ_HEAD_REGNUM], 4);
   int pid;
-  WAITTYPE w;
+  struct target_waitstatus w;
   int insn_count;
 
   /* Advance past break instruction in the call dummy. */
@@ -653,19 +888,26 @@ restore_pc_queue (fsr)
 
   for (insn_count = 0; insn_count < 3; insn_count++)
     {
+      /* FIXME: What if the inferior gets a signal right now?  Want to
+        merge this into wait_for_inferior (as a special kind of
+        watchpoint?  By setting a breakpoint at the end?  Is there
+        any other choice?  Is there *any* way to do this stuff with
+        ptrace() or some equivalent?).  */
       resume (1, 0);
-      target_wait(&w);
+      target_wait (inferior_pid, &w);
 
-      if (!WIFSTOPPED (w))
+      if (w.kind == TARGET_WAITKIND_SIGNALLED)
         {
-          stop_signal = WTERMSIG (w);
+          stop_signal = w.value.sig;
           terminal_ours_for_output ();
-          printf ("\nProgram terminated with signal %d, %s\n",
-                  stop_signal, safe_strsignal (stop_signal));
-          fflush (stdout);
+          printf_unfiltered ("\nProgram terminated with signal %s, %s.\n",
+                            target_signal_to_name (stop_signal),
+                            target_signal_to_string (stop_signal));
+          gdb_flush (gdb_stdout);
           return 0;
         }
     }
+  target_terminal_ours ();
   fetch_inferior_registers (-1);
   return 1;
 }
@@ -720,7 +962,7 @@ hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
 
 CORE_ADDR
 hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
-     REGISTER_TYPE *dummy;
+     char *dummy;
      CORE_ADDR pc;
      CORE_ADDR fun;
      int nargs;
@@ -730,6 +972,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
 {
   CORE_ADDR dyncall_addr, sr4export_addr;
   struct minimal_symbol *msymbol;
+  int flags = read_register (FLAGS_REGNUM);
 
   msymbol = lookup_minimal_symbol ("$$dyncall", (struct objfile *) NULL);
   if (msymbol == NULL)
@@ -743,14 +986,72 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
 
   sr4export_addr = SYMBOL_VALUE_ADDRESS (msymbol);
 
-  dummy[9] = deposit_21 (fun >> 11, dummy[9]);
-  dummy[10] = deposit_14 (fun & MASK_11, dummy[10]);
-  dummy[12] = deposit_21 (sr4export_addr >> 11, dummy[12]);
-  dummy[13] = deposit_14 (sr4export_addr & MASK_11, dummy[13]);
+  store_unsigned_integer
+    (&dummy[9*REGISTER_SIZE],
+     REGISTER_SIZE,
+     deposit_21 (fun >> 11,
+                extract_unsigned_integer (&dummy[9*REGISTER_SIZE],
+                                          REGISTER_SIZE)));
+  store_unsigned_integer
+    (&dummy[10*REGISTER_SIZE],
+     REGISTER_SIZE,
+     deposit_14 (fun & MASK_11,
+                extract_unsigned_integer (&dummy[10*REGISTER_SIZE],
+                                          REGISTER_SIZE)));
+  store_unsigned_integer
+    (&dummy[12*REGISTER_SIZE],
+     REGISTER_SIZE,
+     deposit_21 (sr4export_addr >> 11,
+                extract_unsigned_integer (&dummy[12*REGISTER_SIZE],
+                                          REGISTER_SIZE)));
+  store_unsigned_integer
+    (&dummy[13*REGISTER_SIZE],
+     REGISTER_SIZE,
+     deposit_14 (sr4export_addr & MASK_11,
+                extract_unsigned_integer (&dummy[13*REGISTER_SIZE],
+                                          REGISTER_SIZE)));
 
   write_register (22, pc);
 
-  return dyncall_addr;
+  /* If we are in a syscall, then we should call the stack dummy
+     directly.  $$dyncall is not needed as the kernel sets up the
+     space id registers properly based on the value in %r31.  In
+     fact calling $$dyncall will not work because the value in %r22
+     will be clobbered on the syscall exit path.  */
+  if (flags & 2)
+    return pc;
+  else
+    return dyncall_addr;
+
+}
+
+/* Get the PC from %r31 if currently in a syscall.  Also mask out privilege
+   bits.  */
+CORE_ADDR
+target_read_pc ()
+{
+  int flags = read_register (FLAGS_REGNUM);
+
+  if (flags & 2)
+    return read_register (31) & ~0x3;
+  return read_register (PC_REGNUM) & ~0x3;
+}
+
+/* Write out the PC.  If currently in a syscall, then also write the new
+   PC value into %r31.  */
+void
+target_write_pc (v)
+     CORE_ADDR v;
+{
+  int flags = read_register (FLAGS_REGNUM);
+
+  /* If in a syscall, then set %r31.  Also make sure to get the 
+     privilege bits set correctly.  */
+  if (flags & 2)
+    write_register (31, (long) (v | 0x3));
+
+  write_register (PC_REGNUM, (long) v);
+  write_register (NPC_REGNUM, (long) v + 4);
 }
 
 /* return the alignment of a type in bytes. Structures have the maximum
@@ -801,7 +1102,7 @@ pa_do_registers_info (regnum, fpregs)
   if (regnum == -1)
     pa_print_registers (raw_regs, regnum, fpregs);
   else if (regnum < FP0_REGNUM)
-    printf ("%s %x\n", reg_names[regnum], *(long *)(raw_regs +
+    printf_unfiltered ("%s %x\n", reg_names[regnum], *(long *)(raw_regs +
                                                    REGISTER_BYTE (regnum)));
   else
     pa_print_fp_reg (regnum);
@@ -815,7 +1116,7 @@ pa_print_registers (raw_regs, regnum, fpregs)
   int i;
 
   for (i = 0; i < 18; i++)
-    printf ("%8.8s: %8x  %8.8s: %8x  %8.8s: %8x  %8.8s: %8x\n",
+    printf_unfiltered ("%8.8s: %8x  %8.8s: %8x  %8.8s: %8x  %8.8s: %8x\n",
            reg_names[i],
            *(int *)(raw_regs + REGISTER_BYTE (i)),
            reg_names[i + 18],
@@ -835,16 +1136,26 @@ pa_print_fp_reg (i)
 {
   unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE];
   unsigned char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
-  REGISTER_TYPE val;
 
-  /* Get the data in raw format, then convert also to virtual format.  */
+  /* Get the data in raw format.  */
   read_relative_register_raw_bytes (i, raw_buffer);
-  REGISTER_CONVERT_TO_VIRTUAL (i, raw_buffer, virtual_buffer);
 
-  fputs_filtered (reg_names[i], stdout);
-  print_spaces_filtered (15 - strlen (reg_names[i]), stdout);
+  /* Convert raw data to virtual format if necessary.  */
+#ifdef REGISTER_CONVERTIBLE
+  if (REGISTER_CONVERTIBLE (i))
+    {
+      REGISTER_CONVERT_TO_VIRTUAL (i, REGISTER_VIRTUAL_TYPE (i),
+                                  raw_buffer, virtual_buffer);
+    }
+  else
+#endif
+    memcpy (virtual_buffer, raw_buffer,
+           REGISTER_VIRTUAL_SIZE (i));
 
-  val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, stdout, 0,
+  fputs_filtered (reg_names[i], gdb_stdout);
+  print_spaces_filtered (15 - strlen (reg_names[i]), gdb_stdout);
+
+  val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, gdb_stdout, 0,
             1, 0, Val_pretty_default);
   printf_filtered ("\n");
 }
@@ -913,19 +1224,21 @@ skip_prologue(pc)
 
   if (inst == 0x6BC23FD9)      /* stw rp,-20(sp) */
     {
-      if (read_memory_integer (pc + 4, 4) == 0x8040241)        /* copy r4,r1 */
+      if (read_memory_integer (pc + 4, 4) == 0x8030241)        /* copy r3,r1 */
        pc += 16;
-      else if ((read_memory_integer (pc + 4, 4) & ~MASK_14) == 0x68810000) /* stw r1,(r4) */
+      else if ((read_memory_integer (pc + 4, 4) & ~MASK_14) == 0x68710000) /* stw r1,(r3) */
        pc += 8;
     }
-  else if (read_memory_integer (pc, 4) == 0x8040241) /* copy r4,r1 */
+  else if (read_memory_integer (pc, 4) == 0x8030241) /* copy r3,r1 */
     pc += 12;
-  else if ((read_memory_integer (pc, 4) & ~MASK_14) == 0x68810000) /* stw r1,(r4) */
+  else if ((read_memory_integer (pc, 4) & ~MASK_14) == 0x68710000) /* stw r1,(r3) */
     pc += 4;
 
   return pc;
 }
 
+#ifdef MAINTENANCE_CMDS
+
 static void
 unwind_command (exp, from_tty)
      char *exp;
@@ -949,21 +1262,21 @@ unwind_command (exp, from_tty)
 
   if (!xxx.u)
     {
-      printf ("Can't find unwind table entry for PC 0x%x\n", address);
+      printf_unfiltered ("Can't find unwind table entry for PC 0x%x\n", address);
       return;
     }
 
-  printf ("%08x\n%08X\n%08X\n%08X\n", xxx.foo[0], xxx.foo[1], xxx.foo[2],
+  printf_unfiltered ("%08x\n%08X\n%08X\n%08X\n", xxx.foo[0], xxx.foo[1], xxx.foo[2],
          xxx.foo[3]);
 }
+#endif /* MAINTENANCE_CMDS */
 
 void
 _initialize_hppa_tdep ()
 {
-  add_com ("unwind", class_obscure, unwind_command, "Print unwind info\n");
-  add_show_from_set
-    (add_set_cmd ("use_unwind", class_obscure, var_boolean,
-                 (char *)&use_unwind,
-                 "Set the usage of unwind info", &setlist),
-     &showlist);
+#ifdef MAINTENANCE_CMDS
+  add_cmd ("unwind", class_maintenance, unwind_command,
+          "Print unwind table entry at given address.",
+          &maintenanceprintlist);
+#endif /* MAINTENANCE_CMDS */
 }
This page took 0.029887 seconds and 4 git commands to generate.