* target.h: Add enum target_waitkind, enum target_signal, and
[deliverable/binutils-gdb.git] / gdb / hppa-tdep.c
index 08f9e4ed2e577f36509f516f1ba9ac48b680d546..5e6f0b3944384c3dd5ba5d4ae06a9bff40275092 100644 (file)
@@ -497,27 +497,47 @@ 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.
@@ -560,12 +580,12 @@ frame_chain (frame)
      several areas on the stack.
 
      Walk from the current frame to the innermost frame examining 
-     unwind descriptors to determine if %r4 ever gets saved into the
+     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 %r4 is still
+     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 %r4
+     We use information from unwind descriptors to determine if %r3
      is saved into the stack (Entry_GR field has this information).  */
 
   while (frame)
@@ -583,8 +603,8 @@ frame_chain (frame)
        }
 
       /* Entry_GR specifies the number of callee-saved general registers
-        saved in the stack.  It starts at %r3, so %r4 would be 2.  */
-      if (u->Entry_GR >= 2 || u->Save_SP)
+        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;
@@ -596,15 +616,15 @@ frame_chain (frame)
         pointer.  */
       if (u->Save_SP)
        return read_memory_integer (frame->frame, 4);
-      /* %r4 was saved somewhere in the stack.  Dig it out.  */
+      /* %r3 was saved somewhere in the stack.  Dig it out.  */
       else 
        return dig_fp_from_stack (frame, u);
     }
   else
     {
-      /* The value in %r4 was never saved into the stack (thus %r4 still
+      /* The value in %r3 was never saved into the stack (thus %r3 still
         holds the value of the previous frame pointer).  */
-      return read_register (4);
+      return read_register (FP_REGNUM);
     }
 }
 
@@ -619,14 +639,14 @@ dig_fp_from_stack (frame, u)
 {
   CORE_ADDR pc = u->region_start;
 
-  /* Search the function for the save of %r4.  */
+  /* 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 %r4,X(%sp) instruction,
+      /* 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);
@@ -635,10 +655,10 @@ dig_fp_from_stack (frame, u)
       if (status != 0)
        memory_error (status, pc);
 
-      /* Check for stw %r4,X(%sp).  */
-      if ((inst & 0xffffc000) == 0x6bc40000)
+      /* Check for stw %r3,X(%sp).  */
+      if ((inst & 0xffffc000) == 0x6bc30000)
        {
-         /* Found the instruction which saves %r4.  The offset (relative
+         /* 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);
@@ -650,7 +670,7 @@ dig_fp_from_stack (frame, u)
       pc += 4;
     }
 
-  warning ("Unable to find %%r4 in stack.\n");
+  warning ("Unable to find %%r3 in stack.\n");
   return 0;
 }
 
@@ -844,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. */
@@ -874,15 +894,16 @@ restore_pc_queue (fsr)
         any other choice?  Is there *any* way to do this stuff with
         ptrace() or some equivalent?).  */
       resume (1, 0);
-      target_wait(inferior_pid, &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;
         }
     }
@@ -941,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;
@@ -965,10 +986,30 @@ 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);
 
@@ -1061,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);
@@ -1075,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],
@@ -1095,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));
+
+  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, stdout, 0,
+  val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, gdb_stdout, 0,
             1, 0, Val_pretty_default);
   printf_filtered ("\n");
 }
@@ -1173,14 +1224,14 @@ 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;
@@ -1211,20 +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 ()
 {
+#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.027596 seconds and 4 git commands to generate.