*** empty log message ***
[deliverable/binutils-gdb.git] / gdb / hppa-tdep.c
index 072b0a4b9163af4a5b070145c4434fff584d8243..3890fc2f77315ab5ea05b30b3f4e1466f5da82c8 100644 (file)
@@ -1,6 +1,7 @@
 /* Target-dependent code for the HP PA architecture, for GDB.
-   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
    University of Utah (pa-gdb-bugs@cs.utah.edu).
@@ -28,6 +29,7 @@
 #include "inferior.h"
 #include "value.h"
 #include "regcache.h"
+#include "completer.h"
 
 /* For argument passing to the inferior */
 #include "symtab.h"
@@ -148,7 +150,7 @@ extern int hp_som_som_object_present;
 extern int exception_catchpoints_are_fragile;
 
 /* This is defined in valops.c. */
-extern value_ptr find_function_in_inferior (char *);
+extern struct value *find_function_in_inferior (char *);
 
 /* Should call_function allocate stack space for a struct return?  */
 int
@@ -631,7 +633,8 @@ pc_in_interrupt_handler (CORE_ADDR pc)
      its frame isn't a pure interrupt frame.  Deal with this.  */
   msym_us = lookup_minimal_symbol_by_pc (pc);
 
-  return u->HP_UX_interrupt_marker && !IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us));
+  return (u->HP_UX_interrupt_marker
+         && !PC_IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)));
 }
 
 /* Called when no unwind descriptor was found for PC.  Returns 1 if it
@@ -746,8 +749,10 @@ find_proc_framesize (CORE_ADDR pc)
 
   /* If Save_SP is set, and we're not in an interrupt or signal caller,
      then we have a frame pointer.  Use it.  */
-  if (u->Save_SP && !pc_in_interrupt_handler (pc)
-      && !IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)))
+  if (u->Save_SP
+      && !pc_in_interrupt_handler (pc)
+      && msym_us
+      && !PC_IN_SIGTRAMP (pc, SYMBOL_NAME (msym_us)))
     return -1;
 
   return u->Total_frame_size << 3;
@@ -1667,7 +1672,7 @@ restore_pc_queue (struct frame_saved_regs *fsr)
    to the callee, so we do that too.  */
    
 CORE_ADDR
-hppa_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
+hppa_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
                     int struct_return, CORE_ADDR struct_addr)
 {
   /* array of arguments' offsets */
@@ -1786,7 +1791,7 @@ hppa_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
    arguments into registers as needed by the ABI. */
    
 CORE_ADDR
-hppa_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
+hppa_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
                     int struct_return, CORE_ADDR struct_addr)
 {
   /* array of arguments' offsets */
@@ -1815,7 +1820,8 @@ hppa_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
         target.  */
       bytes_reserved = (lengths[i] + REGISTER_SIZE - 1) & -REGISTER_SIZE;
 
-      offset[i] = cum_bytes_reserved + lengths[i];
+      offset[i] = (cum_bytes_reserved
+                  + (lengths[i] > 4 ? bytes_reserved : lengths[i]));
 
       /* If the argument is a double word argument, then it needs to be
         double word aligned.  */
@@ -1875,10 +1881,10 @@ hppa_push_arguments (int nargs, value_ptr *args, CORE_ADDR sp,
    This function does the same stuff as value_being_returned in values.c, but
    gets the value from the stack rather than from the buffer where all the
    registers were saved when the function called completed. */
-value_ptr
+struct value *
 hppa_value_returned_from_stack (register struct type *valtype, CORE_ADDR addr)
 {
-  register value_ptr val;
+  register struct value *val;
 
   val = allocate_value (valtype);
   CHECK_TYPEDEF (valtype);
@@ -1914,15 +1920,16 @@ find_stub_with_shl_get (struct minimal_symbol *function, CORE_ADDR handle)
   struct symbol *get_sym, *symbol2;
   struct minimal_symbol *buff_minsym, *msymbol;
   struct type *ftype;
-  value_ptr *args;
-  value_ptr funcval, val;
+  struct value **args;
+  struct value *funcval;
+  struct value *val;
 
   int x, namelen, err_value, tmp = -1;
   CORE_ADDR endo_buff_addr, value_return_addr, errno_return_addr;
   CORE_ADDR stub_addr;
 
 
-  args = (value_ptr *) alloca (sizeof (value_ptr) * 8);                /* 6 for the arguments and one null one??? */
+  args = alloca (sizeof (struct value *) * 8);         /* 6 for the arguments and one null one??? */
   funcval = find_function_in_inferior ("__d_shl_get");
   get_sym = lookup_symbol ("__d_shl_get", NULL, VAR_NAMESPACE, NULL, NULL);
   buff_minsym = lookup_minimal_symbol ("__buffer", NULL, NULL);
@@ -2009,7 +2016,7 @@ cover_find_stub_with_shl_get (PTR args_untyped)
 
 CORE_ADDR
 hppa_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
-                    value_ptr *args, struct type *type, int gcc_p)
+                    struct value **args, struct type *type, int gcc_p)
 {
   CORE_ADDR dyncall_addr;
   struct minimal_symbol *msymbol;
@@ -2483,7 +2490,7 @@ pa_do_registers_info (int regnum, int fpregs)
   /* Make a copy of gdb's save area (may cause actual
      reads from the target). */
   for (i = 0; i < NUM_REGS; i++)
-    read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i));
+    frame_register_read (selected_frame, i, raw_regs + REGISTER_BYTE (i));
 
   if (regnum == -1)
     pa_print_registers (raw_regs, regnum, fpregs);
@@ -2497,15 +2504,15 @@ pa_do_registers_info (int regnum, int fpregs)
 
       if (!is_pa_2)
        {
-         printf_unfiltered ("%s %x\n", REGISTER_NAME (regnum), reg_val[1]);
+         printf_unfiltered ("%s %lx\n", REGISTER_NAME (regnum), reg_val[1]);
        }
       else
        {
          /* Fancy % formats to prevent leading zeros. */
          if (reg_val[0] == 0)
-           printf_unfiltered ("%s %x\n", REGISTER_NAME (regnum), reg_val[1]);
+           printf_unfiltered ("%s %lx\n", REGISTER_NAME (regnum), reg_val[1]);
          else
-           printf_unfiltered ("%s %x%8.8x\n", REGISTER_NAME (regnum),
+           printf_unfiltered ("%s %lx%8.8lx\n", REGISTER_NAME (regnum),
                               reg_val[0], reg_val[1]);
        }
     }
@@ -2527,7 +2534,7 @@ pa_do_strcat_registers_info (int regnum, int fpregs, struct ui_file *stream,
   /* Make a copy of gdb's save area (may cause actual
      reads from the target). */
   for (i = 0; i < NUM_REGS; i++)
-    read_relative_register_raw_bytes (i, raw_regs + REGISTER_BYTE (i));
+    frame_register_read (selected_frame, i, raw_regs + REGISTER_BYTE (i));
 
   if (regnum == -1)
     pa_strcat_registers (raw_regs, regnum, fpregs, stream);
@@ -2542,16 +2549,16 @@ pa_do_strcat_registers_info (int regnum, int fpregs, struct ui_file *stream,
 
       if (!is_pa_2)
        {
-         fprintf_unfiltered (stream, "%s %x", REGISTER_NAME (regnum), reg_val[1]);
+         fprintf_unfiltered (stream, "%s %lx", REGISTER_NAME (regnum), reg_val[1]);
        }
       else
        {
          /* Fancy % formats to prevent leading zeros. */
          if (reg_val[0] == 0)
-           fprintf_unfiltered (stream, "%s %x", REGISTER_NAME (regnum),
+           fprintf_unfiltered (stream, "%s %lx", REGISTER_NAME (regnum),
                                reg_val[1]);
          else
-           fprintf_unfiltered (stream, "%s %x%8.8x", REGISTER_NAME (regnum),
+           fprintf_unfiltered (stream, "%s %lx%8.8lx", REGISTER_NAME (regnum),
                                reg_val[0], reg_val[1]);
        }
     }
@@ -2698,17 +2705,17 @@ pa_print_registers (char *raw_regs, int regnum, int fpregs)
              /* Being big-endian, on this machine the low bits
                 (the ones we want to look at) are in the second longword. */
              long_val = extract_signed_integer (&raw_val[1], 4);
-             printf_filtered ("%10.10s: %8x   ",
+             printf_filtered ("%10.10s: %8lx   ",
                               REGISTER_NAME (regnum), long_val);
            }
          else
            {
              /* raw_val = extract_signed_integer(&raw_val, 8); */
              if (raw_val[0] == 0)
-               printf_filtered ("%10.10s:         %8x   ",
+               printf_filtered ("%10.10s:         %8lx   ",
                                 REGISTER_NAME (regnum), raw_val[1]);
              else
-               printf_filtered ("%10.10s: %8x%8.8x   ",
+               printf_filtered ("%10.10s: %8lx%8.8lx   ",
                                 REGISTER_NAME (regnum),
                                 raw_val[0], raw_val[1]);
            }
@@ -2749,17 +2756,19 @@ pa_strcat_registers (char *raw_regs, int regnum, int fpregs,
              /* Being big-endian, on this machine the low bits
                 (the ones we want to look at) are in the second longword. */
              long_val = extract_signed_integer (&raw_val[1], 4);
-             fprintf_filtered (stream, "%8.8s: %8x  ", REGISTER_NAME (i + (j * 18)), long_val);
+             fprintf_filtered (stream, "%8.8s: %8lx  ",
+                               REGISTER_NAME (i + (j * 18)), long_val);
            }
          else
            {
              /* raw_val = extract_signed_integer(&raw_val, 8); */
              if (raw_val[0] == 0)
-               fprintf_filtered (stream, "%8.8s:         %8x  ", REGISTER_NAME (i + (j * 18)),
-                                 raw_val[1]);
+               fprintf_filtered (stream, "%8.8s:         %8lx  ",
+                                 REGISTER_NAME (i + (j * 18)), raw_val[1]);
              else
-               fprintf_filtered (stream, "%8.8s: %8x%8.8x  ", REGISTER_NAME (i + (j * 18)),
-                                 raw_val[0], raw_val[1]);
+               fprintf_filtered (stream, "%8.8s: %8lx%8.8lx  ",
+                                 REGISTER_NAME (i + (j * 18)), raw_val[0],
+                                 raw_val[1]);
            }
        }
       fprintf_unfiltered (stream, "\n");
@@ -2777,7 +2786,7 @@ pa_print_fp_reg (int i)
   char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
 
   /* Get 32bits of data.  */
-  read_relative_register_raw_bytes (i, raw_buffer);
+  frame_register_read (selected_frame, i, raw_buffer);
 
   /* Put it in the buffer.  No conversions are ever necessary.  */
   memcpy (virtual_buffer, raw_buffer, REGISTER_RAW_SIZE (i));
@@ -2795,7 +2804,7 @@ pa_print_fp_reg (int i)
   if ((i % 2) == 0)
     {
       /* Get the data in raw format for the 2nd half.  */
-      read_relative_register_raw_bytes (i + 1, raw_buffer);
+      frame_register_read (selected_frame, i + 1, raw_buffer);
 
       /* Copy it into the appropriate part of the virtual buffer.  */
       memcpy (virtual_buffer + REGISTER_RAW_SIZE (i), raw_buffer,
@@ -2823,7 +2832,7 @@ pa_strcat_fp_reg (int i, struct ui_file *stream, enum precision_type precision)
   print_spaces_filtered (8 - strlen (REGISTER_NAME (i)), stream);
 
   /* Get 32bits of data.  */
-  read_relative_register_raw_bytes (i, raw_buffer);
+  frame_register_read (selected_frame, i, raw_buffer);
 
   /* Put it in the buffer.  No conversions are ever necessary.  */
   memcpy (virtual_buffer, raw_buffer, REGISTER_RAW_SIZE (i));
@@ -2834,7 +2843,7 @@ pa_strcat_fp_reg (int i, struct ui_file *stream, enum precision_type precision)
       char raw_buf[MAX_REGISTER_RAW_SIZE];
 
       /* Get the data in raw format for the 2nd half.  */
-      read_relative_register_raw_bytes (i + 1, raw_buf);
+      frame_register_read (selected_frame, i + 1, raw_buf);
 
       /* Copy it into the appropriate part of the virtual buffer.  */
       memcpy (virtual_buffer + REGISTER_RAW_SIZE (i), raw_buf, REGISTER_RAW_SIZE (i));
@@ -3289,7 +3298,7 @@ skip_trampoline_code (CORE_ADDR pc, char *name)
          stubsym = lookup_minimal_symbol_by_pc (loc);
          if (stubsym == NULL)
            {
-             warning ("Unable to find symbol for 0x%x", loc);
+             warning ("Unable to find symbol for 0x%lx", loc);
              return orig_pc == pc ? 0 : pc & ~0x3;
            }
 
@@ -4456,7 +4465,7 @@ child_get_current_exception_event (void)
   if (level != 0)
     return (struct exception_event_record *) NULL;
 
-  select_frame (fi, -1);
+  select_frame (fi);
 
   /* Read in the arguments */
   /* __d_eh_notify_callback() is called with 3 arguments:
@@ -4482,11 +4491,11 @@ child_get_current_exception_event (void)
   if (level != 0)
     return (struct exception_event_record *) NULL;
 
-  select_frame (fi, -1);
+  select_frame (fi);
   throw_addr = fi->pc;
 
   /* Go back to original (top) frame */
-  select_frame (curr_frame, -1);
+  select_frame (curr_frame);
 
   current_ex_event.kind = (enum exception_event_kind) event_kind;
   current_ex_event.throw_sal = find_pc_line (throw_addr, 1);
@@ -4516,7 +4525,8 @@ unwind_command (char *exp, int from_tty)
       return;
     }
 
-  printf_unfiltered ("unwind_table_entry (0x%x):\n", u);
+  printf_unfiltered ("unwind_table_entry (0x%s):\n",
+                    paddr_nz (host_pointer_to_address (u)));
 
   printf_unfiltered ("\tregion_start = ");
   print_address (u->region_start, gdb_stdout);
@@ -4594,7 +4604,10 @@ unwind_command (char *exp, int from_tty)
    putting the BPT instruction in and taking it out.
 
    Note that this implementation is potentially redundant now that
-   default_prepare_to_proceed() has been added.  */
+   default_prepare_to_proceed() has been added.
+
+   FIXME This may not support switching threads after Ctrl-C
+   correctly. The default implementation does support this. */
 int
 hppa_prepare_to_proceed (void)
 {
@@ -4667,9 +4680,94 @@ hppa_skip_permanent_breakpoint (void)
 void
 _initialize_hppa_tdep (void)
 {
+  struct cmd_list_element *c;
+  void break_at_finish_command (char *arg, int from_tty);
+  void tbreak_at_finish_command (char *arg, int from_tty);
+  void break_at_finish_at_depth_command (char *arg, int from_tty);
+
   tm_print_insn = print_insn_hppa;
 
   add_cmd ("unwind", class_maintenance, unwind_command,
           "Print unwind table entry at given address.",
           &maintenanceprintlist);
+
+  deprecate_cmd (add_com ("xbreak", class_breakpoint, 
+                         break_at_finish_command,
+                         concat ("Set breakpoint at procedure exit. \n\
+Argument may be function name, or \"*\" and an address.\n\
+If function is specified, break at end of code for that function.\n\
+If an address is specified, break at the end of the function that contains \n\
+that exact address.\n",
+                  "With no arg, uses current execution address of selected stack frame.\n\
+This is useful for breaking on return to a stack frame.\n\
+\n\
+Multiple breakpoints at one place are permitted, and useful if conditional.\n\
+\n\
+Do \"help breakpoints\" for info on other commands dealing with breakpoints.", NULL)), NULL);
+  deprecate_cmd (add_com_alias ("xb", "xbreak", class_breakpoint, 1), NULL);
+  deprecate_cmd (add_com_alias ("xbr", "xbreak", class_breakpoint, 1), NULL);
+  deprecate_cmd (add_com_alias ("xbre", "xbreak", class_breakpoint, 1), NULL);
+  deprecate_cmd (add_com_alias ("xbrea", "xbreak", class_breakpoint, 1), NULL);
+
+  deprecate_cmd (c = add_com ("txbreak", class_breakpoint, 
+                             tbreak_at_finish_command,
+"Set temporary breakpoint at procedure exit.  Either there should\n\
+be no argument or the argument must be a depth.\n"), NULL);
+  set_cmd_completer (c, location_completer);
+  
+  if (xdb_commands)
+    deprecate_cmd (add_com ("bx", class_breakpoint, 
+                           break_at_finish_at_depth_command,
+"Set breakpoint at procedure exit.  Either there should\n\
+be no argument or the argument must be a depth.\n"), NULL);
+}
+
+/* Copy the function value from VALBUF into the proper location
+   for a function return.
+
+   Called only in the context of the "return" command.  */
+
+void
+hppa_store_return_value (struct type *type, char *valbuf)
+{
+  /* For software floating point, the return value goes into the
+     integer registers.  But we do not have any flag to key this on,
+     so we always store the value into the integer registers.
+
+     If its a float value, then we also store it into the floating
+     point registers.  */
+  write_register_bytes (REGISTER_BYTE (28)
+                       + (TYPE_LENGTH (type) > 4
+                          ? (8 - TYPE_LENGTH (type))
+                          : (4 - TYPE_LENGTH (type))),
+                       valbuf,
+                       TYPE_LENGTH (type));
+  if (! SOFT_FLOAT && TYPE_CODE (type) == TYPE_CODE_FLT)
+    write_register_bytes (REGISTER_BYTE (FP4_REGNUM),
+                         valbuf,
+                         TYPE_LENGTH (type));
+}
+
+/* Copy the function's return value into VALBUF.
+
+   This function is called only in the context of "target function calls",
+   ie. when the debugger forces a function to be called in the child, and
+   when the debugger forces a fucntion to return prematurely via the
+   "return" command.  */
+
+void
+hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+  if (! SOFT_FLOAT && TYPE_CODE (type) == TYPE_CODE_FLT)
+    memcpy (valbuf,
+           (char *)regbuf + REGISTER_BYTE (FP4_REGNUM),
+           TYPE_LENGTH (type));
+  else
+    memcpy (valbuf,
+           ((char *)regbuf
+            + REGISTER_BYTE (28)
+            + (TYPE_LENGTH (type) > 4
+               ? (8 - TYPE_LENGTH (type))
+               : (4 - TYPE_LENGTH (type)))),
+           TYPE_LENGTH (type));
 }
This page took 0.028646 seconds and 4 git commands to generate.