2003-03-25 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / hppa-tdep.c
index 25dbcfba3c269f584783ac03431e23203391989e..1ad9a5b879060952f0236803b830b19bfc95ecbb 100644 (file)
@@ -1,6 +1,7 @@
 /* Target-dependent code for the HP PA architecture, for GDB.
-   Copyright 1986, 87, 89, 90, 91, 92, 93, 94, 95, 96, 1999
-   Free Software Foundation, Inc.
+
+   Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
    Contributed by the Center for Software Science at the
    University of Utah (pa-gdb-bugs@cs.utah.edu).
 #include "bfd.h"
 #include "inferior.h"
 #include "value.h"
+#include "regcache.h"
+#include "completer.h"
+#include "language.h"
+#include "osabi.h"
+#include "gdb_assert.h"
 
 /* For argument passing to the inferior */
 #include "symtab.h"
@@ -50,7 +56,7 @@
 /*#include <sys/user.h>         After a.out.h  */
 #include <sys/file.h>
 #include "gdb_stat.h"
-#include "wait.h"
+#include "gdb_wait.h"
 
 #include "gdbcore.h"
 #include "gdbcmd.h"
 #include "symfile.h"
 #include "objfiles.h"
 
-/* To support asking "What CPU is this?" */
-#include <unistd.h>
+/* Some local constants.  */
+static const int hppa_num_regs = 128;
 
 /* To support detection of the pseudo-initial frame
    that threads have. */
 #define THREAD_INITIAL_FRAME_SYMBOL  "__pthread_exit"
 #define THREAD_INITIAL_FRAME_SYM_LEN  sizeof(THREAD_INITIAL_FRAME_SYMBOL)
 
-static int extract_5_load PARAMS ((unsigned int));
+static int extract_5_load (unsigned int);
 
-static unsigned extract_5R_store PARAMS ((unsigned int));
+static unsigned extract_5R_store (unsigned int);
 
-static unsigned extract_5r_store PARAMS ((unsigned int));
+static unsigned extract_5r_store (unsigned int);
 
-static void find_dummy_frame_regs PARAMS ((struct frame_info *,
-                                          struct frame_saved_regs *));
+static void find_dummy_frame_regs (struct frame_info *,
+                                  struct frame_saved_regs *);
 
-static int find_proc_framesize PARAMS ((CORE_ADDR));
+static int find_proc_framesize (CORE_ADDR);
 
-static int find_return_regnum PARAMS ((CORE_ADDR));
+static int find_return_regnum (CORE_ADDR);
 
-struct unwind_table_entry *find_unwind_entry PARAMS ((CORE_ADDR));
+struct unwind_table_entry *find_unwind_entry (CORE_ADDR);
 
-static int extract_17 PARAMS ((unsigned int));
+static int extract_17 (unsigned int);
 
-static unsigned deposit_21 PARAMS ((unsigned int, unsigned int));
+static unsigned deposit_21 (unsigned int, unsigned int);
 
-static int extract_21 PARAMS ((unsigned));
+static int extract_21 (unsigned);
 
-static unsigned deposit_14 PARAMS ((int, unsigned int));
+static unsigned deposit_14 (int, unsigned int);
 
-static int extract_14 PARAMS ((unsigned));
+static int extract_14 (unsigned);
 
-static void unwind_command PARAMS ((char *, int));
+static void unwind_command (char *, int);
 
-static int low_sign_extend PARAMS ((unsigned int, unsigned int));
+static int low_sign_extend (unsigned int, unsigned int);
 
-static int sign_extend PARAMS ((unsigned int, unsigned int));
+static int sign_extend (unsigned int, unsigned int);
 
-static int restore_pc_queue PARAMS ((struct frame_saved_regs *));
+static int restore_pc_queue (struct frame_saved_regs *);
 
-static int hppa_alignof PARAMS ((struct type *));
+static int hppa_alignof (struct type *);
 
 /* To support multi-threading and stepping. */
-int hppa_prepare_to_proceed PARAMS (());
-
-static int prologue_inst_adjust_sp PARAMS ((unsigned long));
-
-static int is_branch PARAMS ((unsigned long));
-
-static int inst_saves_gr PARAMS ((unsigned long));
-
-static int inst_saves_fr PARAMS ((unsigned long));
-
-static int pc_in_interrupt_handler PARAMS ((CORE_ADDR));
-
-static int pc_in_linker_stub PARAMS ((CORE_ADDR));
-
-static int compare_unwind_entries PARAMS ((const void *, const void *));
-
-static void read_unwind_info PARAMS ((struct objfile *));
-
-static void internalize_unwinds PARAMS ((struct objfile *,
-                                        struct unwind_table_entry *,
-                                        asection *, unsigned int,
-                                        unsigned int, CORE_ADDR));
-static void pa_print_registers PARAMS ((char *, int, int));
-static void pa_strcat_registers PARAMS ((char *, int, int, GDB_FILE *));
-static void pa_register_look_aside PARAMS ((char *, int, long *));
-static void pa_print_fp_reg PARAMS ((int));
-static void pa_strcat_fp_reg PARAMS ((int, GDB_FILE *, enum precision_type));
+int hppa_prepare_to_proceed ();
+
+static int prologue_inst_adjust_sp (unsigned long);
+
+static int is_branch (unsigned long);
+
+static int inst_saves_gr (unsigned long);
+
+static int inst_saves_fr (unsigned long);
+
+static int pc_in_interrupt_handler (CORE_ADDR);
+
+static int pc_in_linker_stub (CORE_ADDR);
+
+static int compare_unwind_entries (const void *, const void *);
+
+static void read_unwind_info (struct objfile *);
+
+static void internalize_unwinds (struct objfile *,
+                                struct unwind_table_entry *,
+                                asection *, unsigned int,
+                                unsigned int, CORE_ADDR);
+static void pa_print_registers (char *, int, int);
+static void pa_strcat_registers (char *, int, int, struct ui_file *);
+static void pa_register_look_aside (char *, int, long *);
+static void pa_print_fp_reg (int);
+static void pa_strcat_fp_reg (int, struct ui_file *, enum precision_type);
+static void record_text_segment_lowaddr (bfd *, asection *, void *);
+/* FIXME: brobecker 2002-11-07: We will likely be able to make the
+   following functions static, once we hppa is partially multiarched.  */
+int hppa_reg_struct_has_addr (int gcc_p, struct type *type);
+CORE_ADDR hppa_skip_prologue (CORE_ADDR pc);
+CORE_ADDR hppa_skip_trampoline_code (CORE_ADDR pc);
+int hppa_in_solib_call_trampoline (CORE_ADDR pc, char *name);
+int hppa_in_solib_return_trampoline (CORE_ADDR pc, char *name);
+CORE_ADDR hppa_saved_pc_after_call (struct frame_info *frame);
+int hppa_inner_than (CORE_ADDR lhs, CORE_ADDR rhs);
+CORE_ADDR hppa_stack_align (CORE_ADDR sp);
+int hppa_pc_requires_run_before_use (CORE_ADDR pc);
+int hppa_instruction_nullified (void);
+int hppa_register_raw_size (int reg_nr);
+int hppa_register_byte (int reg_nr);
+struct type * hppa_register_virtual_type (int reg_nr);
+void hppa_store_struct_return (CORE_ADDR addr, CORE_ADDR sp);
+void hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf);
+int hppa_use_struct_convention (int gcc_p, struct type *type);
+void hppa_store_return_value (struct type *type, char *valbuf);
+CORE_ADDR hppa_extract_struct_value_address (char *regbuf);
+int hppa_cannot_store_register (int regnum);
+void hppa_init_extra_frame_info (int fromleaf, struct frame_info *frame);
+CORE_ADDR hppa_frame_chain (struct frame_info *frame);
+int hppa_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe);
+int hppa_frameless_function_invocation (struct frame_info *frame);
+CORE_ADDR hppa_frame_saved_pc (struct frame_info *frame);
+CORE_ADDR hppa_frame_args_address (struct frame_info *fi);
+CORE_ADDR hppa_frame_locals_address (struct frame_info *fi);
+int hppa_frame_num_args (struct frame_info *frame);
+void hppa_push_dummy_frame (void);
+void hppa_pop_frame (void);
+CORE_ADDR hppa_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
+                               int nargs, struct value **args,
+                               struct type *type, int gcc_p);
+CORE_ADDR hppa_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+                              int struct_return, CORE_ADDR struct_addr);
+CORE_ADDR hppa_smash_text_address (CORE_ADDR addr);
+CORE_ADDR hppa_target_read_pc (ptid_t ptid);
+void hppa_target_write_pc (CORE_ADDR v, ptid_t ptid);
+CORE_ADDR hppa_target_read_fp (void);
 
 typedef struct
   {
@@ -138,7 +185,7 @@ typedef struct
   }
 args_for_find_stub;
 
-static int cover_find_stub_with_shl_get (PTR);
+static int cover_find_stub_with_shl_get (void *);
 
 static int is_pa_2 = 0;                /* False */
 
@@ -148,17 +195,12 @@ extern int hp_som_som_object_present;
 /* In breakpoint.c */
 extern int exception_catchpoints_are_fragile;
 
-/* This is defined in valops.c. */
-extern value_ptr
-  find_function_in_inferior PARAMS ((char *));
-
 /* Should call_function allocate stack space for a struct return?  */
+
 int
-hppa_use_struct_convention (gcc_p, type)
-     int gcc_p;
-     struct type *type;
+hppa_use_struct_convention (int gcc_p, struct type *type)
 {
-  return (TYPE_LENGTH (type) > 8);
+  return (TYPE_LENGTH (type) > 2 * REGISTER_SIZE);
 }
 \f
 
@@ -169,8 +211,7 @@ hppa_use_struct_convention (gcc_p, type)
    value. */
 
 static int
-sign_extend (val, bits)
-     unsigned val, bits;
+sign_extend (unsigned val, unsigned bits)
 {
   return (int) (val >> (bits - 1) ? (-1 << bits) | val : val);
 }
@@ -178,8 +219,7 @@ sign_extend (val, bits)
 /* For many immediate values the sign bit is the low bit! */
 
 static int
-low_sign_extend (val, bits)
-     unsigned val, bits;
+low_sign_extend (unsigned val, unsigned bits)
 {
   return (int) ((val & 0x1 ? (-1 << (bits - 1)) : 0) | val >> 1);
 }
@@ -187,8 +227,7 @@ low_sign_extend (val, bits)
 /* extract the immediate field from a ld{bhw}s instruction */
 
 static int
-extract_5_load (word)
-     unsigned word;
+extract_5_load (unsigned word)
 {
   return low_sign_extend (word >> 16 & MASK_5, 5);
 }
@@ -196,8 +235,7 @@ extract_5_load (word)
 /* extract the immediate field from a break instruction */
 
 static unsigned
-extract_5r_store (word)
-     unsigned word;
+extract_5r_store (unsigned word)
 {
   return (word & MASK_5);
 }
@@ -205,8 +243,7 @@ extract_5r_store (word)
 /* extract the immediate field from a {sr}sm instruction */
 
 static unsigned
-extract_5R_store (word)
-     unsigned word;
+extract_5R_store (unsigned word)
 {
   return (word >> 16 & MASK_5);
 }
@@ -214,8 +251,7 @@ extract_5R_store (word)
 /* extract a 14 bit immediate field */
 
 static int
-extract_14 (word)
-     unsigned word;
+extract_14 (unsigned word)
 {
   return low_sign_extend (word & MASK_14, 14);
 }
@@ -223,9 +259,7 @@ extract_14 (word)
 /* deposit a 14 bit constant in a word */
 
 static unsigned
-deposit_14 (opnd, word)
-     int opnd;
-     unsigned word;
+deposit_14 (int opnd, unsigned word)
 {
   unsigned sign = (opnd < 0 ? 1 : 0);
 
@@ -235,8 +269,7 @@ deposit_14 (opnd, word)
 /* extract a 21 bit constant */
 
 static int
-extract_21 (word)
-     unsigned word;
+extract_21 (unsigned word)
 {
   int val;
 
@@ -259,8 +292,7 @@ extract_21 (word)
    the low 21 bits of opnd are relevant */
 
 static unsigned
-deposit_21 (opnd, word)
-     unsigned opnd, word;
+deposit_21 (unsigned opnd, unsigned word)
 {
   unsigned val = 0;
 
@@ -280,8 +312,7 @@ deposit_21 (opnd, word)
    19 bit signed value. */
 
 static int
-extract_17 (word)
-     unsigned word;
+extract_17 (unsigned word)
 {
   return sign_extend (GET_FIELD (word, 19, 28) |
                      GET_FIELD (word, 29, 29) << 10 |
@@ -295,9 +326,7 @@ extract_17 (word)
    larger than the first, and zero if they are equal.  */
 
 static int
-compare_unwind_entries (arg1, arg2)
-     const void *arg1;
-     const void *arg2;
+compare_unwind_entries (const void *arg1, const void *arg2)
 {
   const struct unwind_table_entry *a = arg1;
   const struct unwind_table_entry *b = arg2;
@@ -310,13 +339,21 @@ compare_unwind_entries (arg1, arg2)
     return 0;
 }
 
+static CORE_ADDR low_text_segment_address;
+
+static void
+record_text_segment_lowaddr (bfd *abfd, asection *section, void *ignored)
+{
+  if (((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
+       == (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
+      && section->vma < low_text_segment_address)
+    low_text_segment_address = section->vma;
+}
+
 static void
-internalize_unwinds (objfile, table, section, entries, size, text_offset)
-     struct objfile *objfile;
-     struct unwind_table_entry *table;
-     asection *section;
-     unsigned int entries, size;
-     CORE_ADDR text_offset;
+internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table,
+                    asection *section, unsigned int entries, unsigned int size,
+                    CORE_ADDR text_offset)
 {
   /* We will read the unwind entries into temporary memory, then
      fill in the actual unwind table.  */
@@ -326,6 +363,26 @@ internalize_unwinds (objfile, table, section, entries, size, text_offset)
       unsigned i;
       char *buf = alloca (size);
 
+      low_text_segment_address = -1;
+
+      /* If addresses are 64 bits wide, then unwinds are supposed to
+        be segment relative offsets instead of absolute addresses. 
+
+        Note that when loading a shared library (text_offset != 0) the
+        unwinds are already relative to the text_offset that will be
+        passed in.  */
+      if (TARGET_PTR_BIT == 64 && text_offset == 0)
+       {
+         bfd_map_over_sections (objfile->obfd,
+                                record_text_segment_lowaddr, NULL);
+
+         /* ?!? Mask off some low bits.  Should this instead subtract
+            out the lowest section's filepos or something like that?
+            This looks very hokey to me.  */
+         low_text_segment_address &= ~0xfff;
+         text_offset += low_text_segment_address;
+       }
+
       bfd_get_section_contents (objfile->obfd, section, buf, 0, size);
 
       /* Now internalize the information being careful to handle host/target
@@ -388,12 +445,11 @@ internalize_unwinds (objfile, table, section, entries, size, text_offset)
    gets freed when the objfile is destroyed.  */
 
 static void
-read_unwind_info (objfile)
-     struct objfile *objfile;
+read_unwind_info (struct objfile *objfile)
 {
-  asection *unwind_sec, *elf_unwind_sec, *stub_unwind_sec;
-  unsigned unwind_size, elf_unwind_size, stub_unwind_size, total_size;
-  unsigned index, unwind_entries, elf_unwind_entries;
+  asection *unwind_sec, *stub_unwind_sec;
+  unsigned unwind_size, stub_unwind_size, total_size;
+  unsigned index, unwind_entries;
   unsigned stub_entries, total_entries;
   CORE_ADDR text_offset;
   struct obj_unwind_info *ui;
@@ -407,35 +463,32 @@ read_unwind_info (objfile)
   ui->cache = NULL;
   ui->last = -1;
 
-  /* Get hooks to all unwind sections.   Note there is no linker-stub unwind
-     section in ELF at the moment.  */
-  unwind_sec = bfd_get_section_by_name (objfile->obfd, "$UNWIND_START$");
-  elf_unwind_sec = bfd_get_section_by_name (objfile->obfd, ".PARISC.unwind");
-  stub_unwind_sec = bfd_get_section_by_name (objfile->obfd, "$UNWIND_END$");
-
-  /* Get sizes and unwind counts for all sections.  */
-  if (unwind_sec)
+  /* For reasons unknown the HP PA64 tools generate multiple unwinder
+     sections in a single executable.  So we just iterate over every
+     section in the BFD looking for unwinder sections intead of trying
+     to do a lookup with bfd_get_section_by_name. 
+
+     First determine the total size of the unwind tables so that we
+     can allocate memory in a nice big hunk.  */
+  total_entries = 0;
+  for (unwind_sec = objfile->obfd->sections;
+       unwind_sec;
+       unwind_sec = unwind_sec->next)
     {
-      unwind_size = bfd_section_size (objfile->obfd, unwind_sec);
-      unwind_entries = unwind_size / UNWIND_ENTRY_SIZE;
-    }
-  else
-    {
-      unwind_size = 0;
-      unwind_entries = 0;
-    }
+      if (strcmp (unwind_sec->name, "$UNWIND_START$") == 0
+         || strcmp (unwind_sec->name, ".PARISC.unwind") == 0)
+       {
+         unwind_size = bfd_section_size (objfile->obfd, unwind_sec);
+         unwind_entries = unwind_size / UNWIND_ENTRY_SIZE;
 
-  if (elf_unwind_sec)
-    {
-      elf_unwind_size = bfd_section_size (objfile->obfd, elf_unwind_sec);      /* purecov: deadcode */
-      elf_unwind_entries = elf_unwind_size / UNWIND_ENTRY_SIZE;                /* purecov: deadcode */
-    }
-  else
-    {
-      elf_unwind_size = 0;
-      elf_unwind_entries = 0;
+         total_entries += unwind_entries;
+       }
     }
 
+  /* Now compute the size of the stub unwinds.  Note the ELF tools do not
+     use stub unwinds at the curren time.  */
+  stub_unwind_sec = bfd_get_section_by_name (objfile->obfd, "$UNWIND_END$");
+
   if (stub_unwind_sec)
     {
       stub_unwind_size = bfd_section_size (objfile->obfd, stub_unwind_sec);
@@ -448,7 +501,7 @@ read_unwind_info (objfile)
     }
 
   /* Compute total number of unwind entries and their total size.  */
-  total_entries = unwind_entries + elf_unwind_entries + stub_entries;
+  total_entries += stub_entries;
   total_size = total_entries * sizeof (struct unwind_table_entry);
 
   /* Allocate memory for the unwind table.  */
@@ -456,16 +509,26 @@ read_unwind_info (objfile)
     obstack_alloc (&objfile->psymbol_obstack, total_size);
   ui->last = total_entries - 1;
 
-  /* Internalize the standard unwind entries.  */
+  /* Now read in each unwind section and internalize the standard unwind
+     entries.  */
   index = 0;
-  internalize_unwinds (objfile, &ui->table[index], unwind_sec,
-                      unwind_entries, unwind_size, text_offset);
-  index += unwind_entries;
-  internalize_unwinds (objfile, &ui->table[index], elf_unwind_sec,
-                      elf_unwind_entries, elf_unwind_size, text_offset);
-  index += elf_unwind_entries;
-
-  /* Now internalize the stub unwind entries.  */
+  for (unwind_sec = objfile->obfd->sections;
+       unwind_sec;
+       unwind_sec = unwind_sec->next)
+    {
+      if (strcmp (unwind_sec->name, "$UNWIND_START$") == 0
+         || strcmp (unwind_sec->name, ".PARISC.unwind") == 0)
+       {
+         unwind_size = bfd_section_size (objfile->obfd, unwind_sec);
+         unwind_entries = unwind_size / UNWIND_ENTRY_SIZE;
+
+         internalize_unwinds (objfile, &ui->table[index], unwind_sec,
+                              unwind_entries, unwind_size, text_offset);
+         index += unwind_entries;
+       }
+    }
+
+  /* Now read in and internalize the stub unwind entries.  */
   if (stub_unwind_size > 0)
     {
       unsigned int i;
@@ -510,8 +573,9 @@ read_unwind_info (objfile)
                       sizeof (obj_private_data_t));
       obj_private->unwind_info = NULL;
       obj_private->so_info = NULL;
+      obj_private->dp = 0;
 
-      objfile->obj_private = (PTR) obj_private;
+      objfile->obj_private = obj_private;
     }
   obj_private = (obj_private_data_t *) objfile->obj_private;
   obj_private->unwind_info = ui;
@@ -523,8 +587,7 @@ read_unwind_info (objfile)
    search of the unwind tables, we depend upon them to be sorted.  */
 
 struct unwind_table_entry *
-find_unwind_entry (pc)
-     CORE_ADDR pc;
+find_unwind_entry (CORE_ADDR pc)
 {
   int first, middle, last;
   struct objfile *objfile;
@@ -544,7 +607,7 @@ find_unwind_entry (pc)
       {
        read_unwind_info (objfile);
        if (objfile->obj_private == NULL)
-         error ("Internal error reading unwind information.");         /* purecov: deadcode */
+         error ("Internal error reading unwind information.");
        ui = ((obj_private_data_t *) (objfile->obj_private))->unwind_info;
       }
 
@@ -586,8 +649,7 @@ find_unwind_entry (pc)
    bizarre way in which someone (?) decided they wanted to handle
    frame pointerless code in GDB.  */
 int
-hpread_adjust_stack_address (func_addr)
-     CORE_ADDR func_addr;
+hpread_adjust_stack_address (CORE_ADDR func_addr)
 {
   struct unwind_table_entry *u;
 
@@ -602,8 +664,7 @@ hpread_adjust_stack_address (func_addr)
    kind.  */
 
 static int
-pc_in_interrupt_handler (pc)
-     CORE_ADDR pc;
+pc_in_interrupt_handler (CORE_ADDR pc)
 {
   struct unwind_table_entry *u;
   struct minimal_symbol *msym_us;
@@ -616,15 +677,17 @@ pc_in_interrupt_handler (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, DEPRECATED_SYMBOL_NAME (msym_us)));
 }
 
 /* Called when no unwind descriptor was found for PC.  Returns 1 if it
-   appears that PC is in a linker stub.  */
+   appears that PC is in a linker stub.
+
+   ?!? Need to handle stubs which appear in PA64 code.  */
 
 static int
-pc_in_linker_stub (pc)
-     CORE_ADDR pc;
+pc_in_linker_stub (CORE_ADDR pc)
 {
   int found_magic_instruction = 0;
   int i;
@@ -689,8 +752,7 @@ pc_in_linker_stub (pc)
 }
 
 static int
-find_return_regnum (pc)
-     CORE_ADDR pc;
+find_return_regnum (CORE_ADDR pc)
 {
   struct unwind_table_entry *u;
 
@@ -707,8 +769,7 @@ find_return_regnum (pc)
 
 /* Return size of frame, or -1 if we should use a frame pointer.  */
 static int
-find_proc_framesize (pc)
-     CORE_ADDR pc;
+find_proc_framesize (CORE_ADDR pc)
 {
   struct unwind_table_entry *u;
   struct minimal_symbol *msym_us;
@@ -732,19 +793,20 @@ find_proc_framesize (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, DEPRECATED_SYMBOL_NAME (msym_us)))
     return -1;
 
   return u->Total_frame_size << 3;
 }
 
 /* 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 (CORE_ADDR);
 
 static int
-rp_saved (pc)
-     CORE_ADDR pc;
+rp_saved (CORE_ADDR pc)
 {
   struct unwind_table_entry *u;
 
@@ -764,7 +826,7 @@ rp_saved (pc)
     }
 
   if (u->Save_RP)
-    return -20;
+    return (TARGET_PTR_BIT == 64 ? -16 : -20);
   else if (u->stub_unwind.stub_type != 0)
     {
       switch (u->stub_unwind.stub_type)
@@ -783,8 +845,7 @@ rp_saved (pc)
 }
 \f
 int
-frameless_function_invocation (frame)
-     struct frame_info *frame;
+hppa_frameless_function_invocation (struct frame_info *frame)
 {
   struct unwind_table_entry *u;
 
@@ -796,9 +857,13 @@ frameless_function_invocation (frame)
   return (u->Total_frame_size == 0 && u->stub_unwind.stub_type == 0);
 }
 
+/* Immediately after a function call, return the saved pc.
+   Can't go through the frames for this because on some machines
+   the new frame is not set up until the new function executes
+   some instructions.  */
+
 CORE_ADDR
-saved_pc_after_call (frame)
-     struct frame_info *frame;
+hppa_saved_pc_after_call (struct frame_info *frame)
 {
   int ret_regnum;
   CORE_ADDR pc;
@@ -811,14 +876,13 @@ saved_pc_after_call (frame)
      the stub will return to out of the stack.  */
   u = find_unwind_entry (pc);
   if (u && u->stub_unwind.stub_type != 0)
-    return FRAME_SAVED_PC (frame);
+    return DEPRECATED_FRAME_SAVED_PC (frame);
   else
     return pc;
 }
 \f
 CORE_ADDR
-hppa_frame_saved_pc (frame)
-     struct frame_info *frame;
+hppa_frame_saved_pc (struct frame_info *frame)
 {
   CORE_ADDR pc = get_frame_pc (frame);
   struct unwind_table_entry *u;
@@ -831,11 +895,33 @@ hppa_frame_saved_pc (frame)
      are saved in the exact same order as GDB numbers registers.  How
      convienent.  */
   if (pc_in_interrupt_handler (pc))
-    return read_memory_integer (frame->frame + PC_REGNUM * 4, 4) & ~0x3;
+    return read_memory_integer (frame->frame + PC_REGNUM * 4,
+                               TARGET_PTR_BIT / 8) & ~0x3;
+
+  if ((frame->pc >= frame->frame
+       && frame->pc <= (frame->frame
+                        /* A call dummy is sized in words, but it is
+                           actually a series of instructions.  Account
+                           for that scaling factor.  */
+                        + ((REGISTER_SIZE / INSTRUCTION_SIZE)
+                           * CALL_DUMMY_LENGTH)
+                        /* Similarly we have to account for 64bit
+                           wide register saves.  */
+                        + (32 * REGISTER_SIZE)
+                        /* We always consider FP regs 8 bytes long.  */
+                        + (NUM_REGS - FP0_REGNUM) * 8
+                        /* Similarly we have to account for 64bit
+                           wide register saves.  */
+                        + (6 * REGISTER_SIZE))))
+    {
+      return read_memory_integer ((frame->frame
+                                  + (TARGET_PTR_BIT == 64 ? -16 : -20)),
+                                 TARGET_PTR_BIT / 8) & ~0x3;
+    }
 
 #ifdef FRAME_SAVED_PC_IN_SIGTRAMP
   /* Deal with signal handler caller frames too.  */
-  if (frame->signal_handler_caller)
+  if ((get_frame_type (frame) == SIGTRAMP_FRAME))
     {
       CORE_ADDR rp;
       FRAME_SAVED_PC_IN_SIGTRAMP (frame, &rp);
@@ -843,7 +929,7 @@ hppa_frame_saved_pc (frame)
     }
 #endif
 
-  if (frameless_function_invocation (frame))
+  if (hppa_frameless_function_invocation (frame))
     {
       int ret_regnum;
 
@@ -854,25 +940,29 @@ hppa_frame_saved_pc (frame)
          register area to get the return pointer (the values
          in the registers may not correspond to anything useful).  */
       if (frame->next
-         && (frame->next->signal_handler_caller
+         && ((get_frame_type (frame->next) == SIGTRAMP_FRAME)
              || pc_in_interrupt_handler (frame->next->pc)))
        {
          struct frame_saved_regs saved_regs;
 
-         get_frame_saved_regs (frame->next, &saved_regs);
-         if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) & 0x2)
+         deprecated_get_frame_saved_regs (frame->next, &saved_regs);
+         if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM],
+                                  TARGET_PTR_BIT / 8) & 0x2)
            {
-             pc = read_memory_integer (saved_regs.regs[31], 4) & ~0x3;
+             pc = read_memory_integer (saved_regs.regs[31],
+                                       TARGET_PTR_BIT / 8) & ~0x3;
 
              /* Syscalls are really two frames.  The syscall stub itself
                 with a return pointer in %rp and the kernel call with
                 a return pointer in %r31.  We return the %rp variant
                 if %r31 is the same as frame->pc.  */
              if (pc == frame->pc)
-               pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3;
+               pc = read_memory_integer (saved_regs.regs[RP_REGNUM],
+                                         TARGET_PTR_BIT / 8) & ~0x3;
            }
          else
-           pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3;
+           pc = read_memory_integer (saved_regs.regs[RP_REGNUM],
+                                     TARGET_PTR_BIT / 8) & ~0x3;
        }
       else
        pc = read_register (ret_regnum) & ~0x3;
@@ -890,25 +980,29 @@ hppa_frame_saved_pc (frame)
          information out of the saved register info.  */
       if (rp_offset == 0
          && frame->next
-         && (frame->next->signal_handler_caller
+         && ((get_frame_type (frame->next) == SIGTRAMP_FRAME)
              || pc_in_interrupt_handler (frame->next->pc)))
        {
          struct frame_saved_regs saved_regs;
 
-         get_frame_saved_regs (frame->next, &saved_regs);
-         if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4) & 0x2)
+         deprecated_get_frame_saved_regs (frame->next, &saved_regs);
+         if (read_memory_integer (saved_regs.regs[FLAGS_REGNUM],
+                                  TARGET_PTR_BIT / 8) & 0x2)
            {
-             pc = read_memory_integer (saved_regs.regs[31], 4) & ~0x3;
+             pc = read_memory_integer (saved_regs.regs[31],
+                                       TARGET_PTR_BIT / 8) & ~0x3;
 
              /* Syscalls are really two frames.  The syscall stub itself
                 with a return pointer in %rp and the kernel call with
                 a return pointer in %r31.  We return the %rp variant
                 if %r31 is the same as frame->pc.  */
              if (pc == frame->pc)
-               pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3;
+               pc = read_memory_integer (saved_regs.regs[RP_REGNUM],
+                                         TARGET_PTR_BIT / 8) & ~0x3;
            }
          else
-           pc = read_memory_integer (saved_regs.regs[RP_REGNUM], 4) & ~0x3;
+           pc = read_memory_integer (saved_regs.regs[RP_REGNUM],
+                                     TARGET_PTR_BIT / 8) & ~0x3;
        }
       else if (rp_offset == 0)
        {
@@ -918,7 +1012,8 @@ hppa_frame_saved_pc (frame)
       else
        {
          old_pc = pc;
-         pc = read_memory_integer (frame->frame + rp_offset, 4) & ~0x3;
+         pc = read_memory_integer (frame->frame + rp_offset,
+                                   TARGET_PTR_BIT / 8) & ~0x3;
        }
     }
 
@@ -966,9 +1061,7 @@ hppa_frame_saved_pc (frame)
    in a system call.  */
 
 void
-init_extra_frame_info (fromleaf, frame)
-     int fromleaf;
-     struct frame_info *frame;
+hppa_init_extra_frame_info (int fromleaf, struct frame_info *frame)
 {
   int flags;
   int framesize;
@@ -976,14 +1069,15 @@ init_extra_frame_info (fromleaf, 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 the next frame represents a frameless function invocation then
+     we have to do some adjustments that are normally done by
+     DEPRECATED_FRAME_CHAIN.  (DEPRECATED_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)));
+      framesize = find_proc_framesize (DEPRECATED_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
@@ -1016,23 +1110,29 @@ init_extra_frame_info (fromleaf, frame)
     frame->frame = read_register (SP_REGNUM) - 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.
+/* 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 DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_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.  */
 
 CORE_ADDR
-frame_chain (frame)
-     struct frame_info *frame;
+hppa_frame_chain (struct frame_info *frame)
 {
   int my_framesize, caller_framesize;
   struct unwind_table_entry *u;
   CORE_ADDR frame_base;
   struct frame_info *tmp_frame;
 
+  /* A frame in the current frame list, or zero.  */
+  struct frame_info *saved_regs_frame = 0;
+  /* Where the registers were saved in saved_regs_frame.
+     If saved_regs_frame is zero, this is garbage.  */
+  struct frame_saved_regs saved_regs;
+
   CORE_ADDR caller_pc;
 
   struct minimal_symbol *min_frame_symbol;
@@ -1055,7 +1155,7 @@ frame_chain (frame)
          pthread library itself, you'd get errors.
 
          So for today, we don't make that check. */
-      frame_symbol_name = SYMBOL_NAME (min_frame_symbol);
+      frame_symbol_name = DEPRECATED_SYMBOL_NAME (min_frame_symbol);
       if (frame_symbol_name != 0)
        {
          if (0 == strncmp (frame_symbol_name,
@@ -1073,9 +1173,10 @@ frame_chain (frame)
      pull the old stack pointer from.  Also see frame_saved_pc for
      code to dig a saved PC out of the save state structure.  */
   if (pc_in_interrupt_handler (frame->pc))
-    frame_base = read_memory_integer (frame->frame + SP_REGNUM * 4, 4);
+    frame_base = read_memory_integer (frame->frame + SP_REGNUM * 4,
+                                     TARGET_PTR_BIT / 8);
 #ifdef FRAME_BASE_BEFORE_SIGTRAMP
-  else if (frame->signal_handler_caller)
+  else if ((get_frame_type (frame) == SIGTRAMP_FRAME))
     {
       FRAME_BASE_BEFORE_SIGTRAMP (frame, &frame_base);
     }
@@ -1086,7 +1187,7 @@ frame_chain (frame)
   /* Get frame sizes for the current frame and the frame of the 
      caller.  */
   my_framesize = find_proc_framesize (frame->pc);
-  caller_pc = FRAME_SAVED_PC (frame);
+  caller_pc = DEPRECATED_FRAME_SAVED_PC (frame);
 
   /* If we can't determine the caller's PC, then it's not likely we can
      really determine anything meaningful about its frame.  We'll consider
@@ -1094,7 +1195,7 @@ frame_chain (frame)
   if (caller_pc == (CORE_ADDR) 0)
     return (CORE_ADDR) 0;
 
-  caller_framesize = find_proc_framesize (FRAME_SAVED_PC (frame));
+  caller_framesize = find_proc_framesize (DEPRECATED_FRAME_SAVED_PC (frame));
 
   /* If caller does not have a frame pointer, then its frame
      can be found at current_frame - caller_framesize.  */
@@ -1107,7 +1208,7 @@ frame_chain (frame)
      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_base, 4);
+      return read_memory_integer (frame_base, TARGET_PTR_BIT / 8);
     }
   /* 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
@@ -1125,8 +1226,7 @@ frame_chain (frame)
      We use information from unwind descriptors to determine if %r3
      is saved into the stack (Entry_GR field has this information).  */
 
-  tmp_frame = frame;
-  while (tmp_frame)
+  for (tmp_frame = frame; tmp_frame; tmp_frame = tmp_frame->next)
     {
       u = find_unwind_entry (tmp_frame->pc);
 
@@ -1146,14 +1246,25 @@ frame_chain (frame)
          return (CORE_ADDR) 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
-         || tmp_frame->signal_handler_caller
+      if (u->Save_SP
+         || (get_frame_type (tmp_frame) == SIGTRAMP_FRAME)
          || pc_in_interrupt_handler (tmp_frame->pc))
        break;
-      else
-       tmp_frame = tmp_frame->next;
+
+      /* 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)
+       {
+         /* The unwind entry claims that r3 is saved here.  However,
+            in optimized code, GCC often doesn't actually save r3.
+            We'll discover this if we look at the prologue.  */
+         deprecated_get_frame_saved_regs (tmp_frame, &saved_regs);
+         saved_regs_frame = tmp_frame;
+
+         /* If we have an address for r3, that's good.  */
+         if (saved_regs.regs[FP_REGNUM])
+           break;
+       }
     }
 
   if (tmp_frame)
@@ -1161,16 +1272,14 @@ frame_chain (frame)
       /* We may have walked down the chain into a function with a frame
          pointer.  */
       if (u->Save_SP
-         && !tmp_frame->signal_handler_caller
+         && !(get_frame_type (tmp_frame) == SIGTRAMP_FRAME)
          && !pc_in_interrupt_handler (tmp_frame->pc))
        {
-         return read_memory_integer (tmp_frame->frame, 4);
+         return read_memory_integer (tmp_frame->frame, TARGET_PTR_BIT / 8);
        }
       /* %r3 was saved somewhere in the stack.  Dig it out.  */
       else
        {
-         struct frame_saved_regs saved_regs;
-
          /* Sick.
 
             For optimization purposes many kernels don't have the
@@ -1197,20 +1306,23 @@ frame_chain (frame)
             fail miserably if the function which performs the
             system call has a variable sized stack frame.  */
 
-         get_frame_saved_regs (tmp_frame, &saved_regs);
+         if (tmp_frame != saved_regs_frame)
+           deprecated_get_frame_saved_regs (tmp_frame, &saved_regs);
 
          /* Abominable hack.  */
          if (current_target.to_has_execution == 0
              && ((saved_regs.regs[FLAGS_REGNUM]
-                  && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4)
+                  && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM],
+                                           TARGET_PTR_BIT / 8)
                       & 0x2))
                  || (saved_regs.regs[FLAGS_REGNUM] == 0
                      && read_register (FLAGS_REGNUM) & 0x2)))
            {
-             u = find_unwind_entry (FRAME_SAVED_PC (frame));
+             u = find_unwind_entry (DEPRECATED_FRAME_SAVED_PC (frame));
              if (!u)
                {
-                 return read_memory_integer (saved_regs.regs[FP_REGNUM], 4);
+                 return read_memory_integer (saved_regs.regs[FP_REGNUM],
+                                             TARGET_PTR_BIT / 8);
                }
              else
                {
@@ -1218,31 +1330,34 @@ frame_chain (frame)
                }
            }
 
-         return read_memory_integer (saved_regs.regs[FP_REGNUM], 4);
+         return read_memory_integer (saved_regs.regs[FP_REGNUM],
+                                     TARGET_PTR_BIT / 8);
        }
     }
   else
     {
-      struct frame_saved_regs saved_regs;
-
       /* Get the innermost frame.  */
       tmp_frame = frame;
       while (tmp_frame->next != NULL)
        tmp_frame = tmp_frame->next;
 
-      get_frame_saved_regs (tmp_frame, &saved_regs);
+      if (tmp_frame != saved_regs_frame)
+       deprecated_get_frame_saved_regs (tmp_frame, &saved_regs);
+
       /* Abominable hack.  See above.  */
       if (current_target.to_has_execution == 0
          && ((saved_regs.regs[FLAGS_REGNUM]
-              && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM], 4)
+              && (read_memory_integer (saved_regs.regs[FLAGS_REGNUM],
+                                       TARGET_PTR_BIT / 8)
                   & 0x2))
              || (saved_regs.regs[FLAGS_REGNUM] == 0
                  && read_register (FLAGS_REGNUM) & 0x2)))
        {
-         u = find_unwind_entry (FRAME_SAVED_PC (frame));
+         u = find_unwind_entry (DEPRECATED_FRAME_SAVED_PC (frame));
          if (!u)
            {
-             return read_memory_integer (saved_regs.regs[FP_REGNUM], 4);
+             return read_memory_integer (saved_regs.regs[FP_REGNUM],
+                                         TARGET_PTR_BIT / 8);
            }
          else
            {
@@ -1261,18 +1376,13 @@ frame_chain (frame)
    was compiled with gcc. */
 
 int
-hppa_frame_chain_valid (chain, thisframe)
-     CORE_ADDR chain;
-     struct frame_info *thisframe;
+hppa_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe)
 {
   struct minimal_symbol *msym_us;
   struct minimal_symbol *msym_start;
   struct unwind_table_entry *u, *next_u = NULL;
   struct frame_info *next;
 
-  if (!chain)
-    return 0;
-
   u = find_unwind_entry (thisframe->pc);
 
   if (u == NULL)
@@ -1284,7 +1394,7 @@ hppa_frame_chain_valid (chain, thisframe)
      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_us = lookup_minimal_symbol_by_pc (DEPRECATED_FRAME_SAVED_PC (thisframe));
   msym_start = lookup_minimal_symbol ("_start", NULL, NULL);
   if (msym_us
       && msym_start
@@ -1307,7 +1417,7 @@ hppa_frame_chain_valid (chain, thisframe)
      and doesn't "call" an interrupt routine or signal handler caller,
      then its not valid.  */
   if (u->Save_SP || u->Total_frame_size || u->stub_unwind.stub_type != 0
-      || (thisframe->next && thisframe->next->signal_handler_caller)
+      || (thisframe->next && (get_frame_type (thisframe->next) == SIGTRAMP_FRAME))
       || (next_u && next_u->HP_UX_interrupt_marker))
     return 1;
 
@@ -1317,46 +1427,28 @@ hppa_frame_chain_valid (chain, thisframe)
   return 0;
 }
 
-/*
-   These functions deal with saving and restoring register state
-   around a function call in the inferior. They keep the stack
-   double-word aligned; eventually, on an hp700, the stack will have
-   to be aligned to a 64-byte boundary. */
+/* These functions deal with saving and restoring register state
+   around a function call in the inferior.  They keep the stack
+   double-word aligned;  eventually, on an hp700, the stack will have
+   to be aligned to a 64-byte boundary.  */
 
 void
-push_dummy_frame (inf_status)
-     struct inferior_status *inf_status;
+hppa_push_dummy_frame (void)
 {
   CORE_ADDR sp, pc, pcspace;
   register int regnum;
-  int int_buffer;
+  CORE_ADDR int_buffer;
   double freg_buffer;
 
-  /* Oh, what a hack.  If we're trying to perform an inferior call
-     while the inferior is asleep, we have to make sure to clear
-     the "in system call" bit in the flag register (the call will
-     start after the syscall returns, so we're no longer in the system
-     call!)  This state is kept in "inf_status", change it there.
-
-     We also need a number of horrid hacks to deal with lossage in the
-     PC queue registers (apparently they're not valid when the in syscall
-     bit is set).  */
-  pc = target_read_pc (inferior_pid);
+  pc = hppa_target_read_pc (inferior_ptid);
   int_buffer = read_register (FLAGS_REGNUM);
   if (int_buffer & 0x2)
     {
-      unsigned int sid;
-      int_buffer &= ~0x2;
-      write_inferior_status_register (inf_status, 0, int_buffer);
-      write_inferior_status_register (inf_status, PCOQ_HEAD_REGNUM, pc + 0);
-      write_inferior_status_register (inf_status, PCOQ_TAIL_REGNUM, pc + 4);
-      sid = (pc >> 30) & 0x3;
+      const unsigned int sid = (pc >> 30) & 0x3;
       if (sid == 0)
        pcspace = read_register (SR4_REGNUM);
       else
        pcspace = read_register (SR4_REGNUM + 4 + sid);
-      write_inferior_status_register (inf_status, PCSQ_HEAD_REGNUM, pcspace);
-      write_inferior_status_register (inf_status, PCSQ_TAIL_REGNUM, pcspace);
     }
   else
     pcspace = read_register (PCSQ_HEAD_REGNUM);
@@ -1364,24 +1456,33 @@ push_dummy_frame (inf_status)
   /* Space for "arguments"; the RP goes in here. */
   sp = read_register (SP_REGNUM) + 48;
   int_buffer = read_register (RP_REGNUM) | 0x3;
-  write_memory (sp - 20, (char *) &int_buffer, 4);
+
+  /* The 32bit and 64bit ABIs save the return pointer into different
+     stack slots.  */
+  if (REGISTER_SIZE == 8)
+    write_memory (sp - 16, (char *) &int_buffer, REGISTER_SIZE);
+  else
+    write_memory (sp - 20, (char *) &int_buffer, REGISTER_SIZE);
 
   int_buffer = TARGET_READ_FP ();
-  write_memory (sp, (char *) &int_buffer, 4);
+  write_memory (sp, (char *) &int_buffer, REGISTER_SIZE);
 
   write_register (FP_REGNUM, sp);
 
-  sp += 8;
+  sp += 2 * REGISTER_SIZE;
 
   for (regnum = 1; regnum < 32; regnum++)
     if (regnum != RP_REGNUM && regnum != FP_REGNUM)
       sp = push_word (sp, read_register (regnum));
 
-  sp += 4;
+  /* This is not necessary for the 64bit ABI.  In fact it is dangerous.  */
+  if (REGISTER_SIZE != 8)
+    sp += 4;
 
   for (regnum = FP0_REGNUM; regnum < NUM_REGS; regnum++)
     {
-      read_register_bytes (REGISTER_BYTE (regnum), (char *) &freg_buffer, 8);
+      deprecated_read_register_bytes (REGISTER_BYTE (regnum),
+                                     (char *) &freg_buffer, 8);
       sp = push_bytes (sp, (char *) &freg_buffer, 8);
     }
   sp = push_word (sp, read_register (IPSW_REGNUM));
@@ -1394,40 +1495,48 @@ push_dummy_frame (inf_status)
 }
 
 static void
-find_dummy_frame_regs (frame, frame_saved_regs)
-     struct frame_info *frame;
-     struct frame_saved_regs *frame_saved_regs;
+find_dummy_frame_regs (struct frame_info *frame,
+                      struct frame_saved_regs *frame_saved_regs)
 {
   CORE_ADDR fp = frame->frame;
   int i;
 
-  frame_saved_regs->regs[RP_REGNUM] = (fp - 20) & ~0x3;
+  /* The 32bit and 64bit ABIs save RP into different locations.  */
+  if (REGISTER_SIZE == 8)
+    frame_saved_regs->regs[RP_REGNUM] = (fp - 16) & ~0x3;
+  else
+    frame_saved_regs->regs[RP_REGNUM] = (fp - 20) & ~0x3;
+
   frame_saved_regs->regs[FP_REGNUM] = fp;
-  frame_saved_regs->regs[1] = fp + 8;
 
-  for (fp += 12, i = 3; i < 32; i++)
+  frame_saved_regs->regs[1] = fp + (2 * REGISTER_SIZE);
+
+  for (fp += 3 * REGISTER_SIZE, i = 3; i < 32; i++)
     {
       if (i != FP_REGNUM)
        {
          frame_saved_regs->regs[i] = fp;
-         fp += 4;
+         fp += REGISTER_SIZE;
        }
     }
 
-  fp += 4;
+  /* This is not necessary or desirable for the 64bit ABI.  */
+  if (REGISTER_SIZE != 8)
+    fp += 4;
+
   for (i = FP0_REGNUM; i < NUM_REGS; i++, fp += 8)
     frame_saved_regs->regs[i] = fp;
 
   frame_saved_regs->regs[IPSW_REGNUM] = fp;
-  frame_saved_regs->regs[SAR_REGNUM] = fp + 4;
-  frame_saved_regs->regs[PCOQ_HEAD_REGNUM] = fp + 8;
-  frame_saved_regs->regs[PCSQ_HEAD_REGNUM] = fp + 12;
-  frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp + 16;
-  frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp + 20;
+  frame_saved_regs->regs[SAR_REGNUM] = fp + REGISTER_SIZE;
+  frame_saved_regs->regs[PCOQ_HEAD_REGNUM] = fp + 2 * REGISTER_SIZE;
+  frame_saved_regs->regs[PCSQ_HEAD_REGNUM] = fp + 3 * REGISTER_SIZE;
+  frame_saved_regs->regs[PCOQ_TAIL_REGNUM] = fp + 4 * REGISTER_SIZE;
+  frame_saved_regs->regs[PCSQ_TAIL_REGNUM] = fp + 5 * REGISTER_SIZE;
 }
 
 void
-hppa_pop_frame ()
+hppa_pop_frame (void)
 {
   register struct frame_info *frame = get_current_frame ();
   register CORE_ADDR fp, npc, target_pc;
@@ -1435,8 +1544,8 @@ hppa_pop_frame ()
   struct frame_saved_regs fsr;
   double freg_buffer;
 
-  fp = FRAME_FP (frame);
-  get_frame_saved_regs (frame, &fsr);
+  fp = get_frame_base (frame);
+  deprecated_get_frame_saved_regs (frame, &fsr);
 
 #ifndef NO_PC_SPACE_QUEUE_RESTORE
   if (fsr.regs[IPSW_REGNUM])   /* Restoring a call dummy frame */
@@ -1445,27 +1554,32 @@ hppa_pop_frame ()
 
   for (regnum = 31; regnum > 0; regnum--)
     if (fsr.regs[regnum])
-      write_register (regnum, read_memory_integer (fsr.regs[regnum], 4));
+      write_register (regnum, read_memory_integer (fsr.regs[regnum],
+                     REGISTER_SIZE));
 
   for (regnum = NUM_REGS - 1; regnum >= FP0_REGNUM; regnum--)
     if (fsr.regs[regnum])
       {
        read_memory (fsr.regs[regnum], (char *) &freg_buffer, 8);
-       write_register_bytes (REGISTER_BYTE (regnum), (char *) &freg_buffer, 8);
+       deprecated_write_register_bytes (REGISTER_BYTE (regnum),
+                                        (char *) &freg_buffer, 8);
       }
 
   if (fsr.regs[IPSW_REGNUM])
     write_register (IPSW_REGNUM,
-                   read_memory_integer (fsr.regs[IPSW_REGNUM], 4));
+                   read_memory_integer (fsr.regs[IPSW_REGNUM],
+                                        REGISTER_SIZE));
 
   if (fsr.regs[SAR_REGNUM])
     write_register (SAR_REGNUM,
-                   read_memory_integer (fsr.regs[SAR_REGNUM], 4));
+                   read_memory_integer (fsr.regs[SAR_REGNUM],
+                                        REGISTER_SIZE));
 
   /* If the PC was explicitly saved, then just restore it.  */
   if (fsr.regs[PCOQ_TAIL_REGNUM])
     {
-      npc = read_memory_integer (fsr.regs[PCOQ_TAIL_REGNUM], 4);
+      npc = read_memory_integer (fsr.regs[PCOQ_TAIL_REGNUM],
+                                REGISTER_SIZE);
       write_register (PCOQ_TAIL_REGNUM, npc);
     }
   /* Else use the value in %rp to set the new PC.  */
@@ -1475,7 +1589,7 @@ hppa_pop_frame ()
       write_pc (npc);
     }
 
-  write_register (FP_REGNUM, read_memory_integer (fp, 4));
+  write_register (FP_REGNUM, read_memory_integer (fp, REGISTER_SIZE));
 
   if (fsr.regs[IPSW_REGNUM])   /* call dummy */
     write_register (SP_REGNUM, fp - 48);
@@ -1500,16 +1614,16 @@ hppa_pop_frame ()
          for "return_command" will print the frame we returned to.  */
       sal = find_pc_line (target_pc, 0);
       sal.pc = target_pc;
-      breakpoint = set_momentary_breakpoint (sal, NULL, bp_finish);
+      breakpoint = set_momentary_breakpoint (sal, null_frame_id, bp_finish);
       breakpoint->silent = 1;
 
       /* So we can clean things up.  */
-      old_chain = make_cleanup ((make_cleanup_func) delete_breakpoint, breakpoint);
+      old_chain = make_cleanup_delete_breakpoint (breakpoint);
 
       /* Start up the inferior.  */
       clear_proceed_status ();
       proceed_to_finish = 1;
-      proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_DEFAULT, 0);
+      proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0);
 
       /* Perform our cleanups.  */
       do_cleanups (old_chain);
@@ -1521,11 +1635,11 @@ hppa_pop_frame ()
    queue space registers. */
 
 static int
-restore_pc_queue (fsr)
-     struct frame_saved_regs *fsr;
+restore_pc_queue (struct frame_saved_regs *fsr)
 {
   CORE_ADDR pc = read_pc ();
-  CORE_ADDR new_pc = read_memory_integer (fsr->regs[PCOQ_HEAD_REGNUM], 4);
+  CORE_ADDR new_pc = read_memory_integer (fsr->regs[PCOQ_HEAD_REGNUM],
+                                         TARGET_PTR_BIT / 8);
   struct target_waitstatus w;
   int insn_count;
 
@@ -1543,7 +1657,8 @@ restore_pc_queue (fsr)
      So, load up the registers and single step until we are in the
      right place. */
 
-  write_register (21, read_memory_integer (fsr->regs[PCSQ_HEAD_REGNUM], 4));
+  write_register (21, read_memory_integer (fsr->regs[PCSQ_HEAD_REGNUM],
+                                          REGISTER_SIZE));
   write_register (22, new_pc);
 
   for (insn_count = 0; insn_count < 3; insn_count++)
@@ -1554,7 +1669,7 @@ 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_ptid, &w);
 
       if (w.kind == TARGET_WAITKIND_SIGNALLED)
        {
@@ -1572,126 +1687,193 @@ restore_pc_queue (fsr)
   return 1;
 }
 
-#if 0
+
+#ifdef PA20W_CALLING_CONVENTIONS
+
+/* This function pushes a stack frame with arguments as part of the
+   inferior function calling mechanism.
+
+   This is the version for the PA64, in which later arguments appear
+   at higher addresses.  (The stack always grows towards higher
+   addresses.)
+
+   We simply allocate the appropriate amount of stack space and put
+   arguments into their proper slots.  The call dummy code will copy
+   arguments into registers as needed by the ABI.
+
+   This ABI also requires that the caller provide an argument pointer
+   to the callee, so we do that too.  */
+   
 CORE_ADDR
-hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
-     int nargs;
-     value_ptr *args;
-     CORE_ADDR sp;
-     int struct_return;
-     CORE_ADDR struct_addr;
+hppa_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+                    int struct_return, CORE_ADDR struct_addr)
 {
   /* array of arguments' offsets */
   int *offset = (int *) alloca (nargs * sizeof (int));
-  int cum = 0;
-  int i, alignment;
 
+  /* array of arguments' lengths: real lengths in bytes, not aligned to
+     word size */
+  int *lengths = (int *) alloca (nargs * sizeof (int));
+
+  /* The value of SP as it was passed into this function after
+     aligning.  */
+  CORE_ADDR orig_sp = STACK_ALIGN (sp);
+
+  /* The number of stack bytes occupied by the current argument.  */
+  int bytes_reserved;
+
+  /* The total number of bytes reserved for the arguments.  */
+  int cum_bytes_reserved = 0;
+
+  /* Similarly, but aligned.  */
+  int cum_bytes_aligned = 0;
+  int i;
+
+  /* Iterate over each argument provided by the user.  */
   for (i = 0; i < nargs; i++)
     {
-      int x = 0;
-      /* cum is the sum of the lengths in bytes of
-         the arguments seen so far */
-      cum += TYPE_LENGTH (VALUE_TYPE (args[i]));
+      struct type *arg_type = VALUE_TYPE (args[i]);
+
+      /* Integral scalar values smaller than a register are padded on
+         the left.  We do this by promoting them to full-width,
+         although the ABI says to pad them with garbage.  */
+      if (is_integral_type (arg_type)
+         && TYPE_LENGTH (arg_type) < REGISTER_SIZE)
+       {
+         args[i] = value_cast ((TYPE_UNSIGNED (arg_type)
+                                ? builtin_type_unsigned_long
+                                : builtin_type_long),
+                               args[i]);
+         arg_type = VALUE_TYPE (args[i]);
+       }
+
+      lengths[i] = TYPE_LENGTH (arg_type);
 
-      /* value must go at proper alignment. Assume alignment is a
-         power of two. */
-      alignment = hppa_alignof (VALUE_TYPE (args[i]));
+      /* Align the size of the argument to the word size for this
+        target.  */
+      bytes_reserved = (lengths[i] + REGISTER_SIZE - 1) & -REGISTER_SIZE;
 
-      if (cum % alignment)
-       cum = (cum + alignment) & -alignment;
-      offset[i] = -cum;
+      offset[i] = cum_bytes_reserved;
 
+      /* Aggregates larger than eight bytes (the only types larger
+         than eight bytes we have) are aligned on a 16-byte boundary,
+         possibly padded on the right with garbage.  This may leave an
+         empty word on the stack, and thus an unused register, as per
+         the ABI.  */
+      if (bytes_reserved > 8)
+       {
+         /* Round up the offset to a multiple of two slots.  */
+         int new_offset = ((offset[i] + 2*REGISTER_SIZE-1)
+                           & -(2*REGISTER_SIZE));
+
+         /* Note the space we've wasted, if any.  */
+         bytes_reserved += new_offset - offset[i];
+         offset[i] = new_offset;
+       }
+
+      cum_bytes_reserved += bytes_reserved;
     }
-  sp += max ((cum + 7) & -8, 16);
 
+  /* CUM_BYTES_RESERVED already accounts for all the arguments
+     passed by the user.  However, the ABIs mandate minimum stack space
+     allocations for outgoing arguments.
+
+     The ABIs also mandate minimum stack alignments which we must
+     preserve.  */
+  cum_bytes_aligned = STACK_ALIGN (cum_bytes_reserved);
+  sp += max (cum_bytes_aligned, REG_PARM_STACK_SPACE);
+
+  /* Now write each of the args at the proper offset down the stack.  */
   for (i = 0; i < nargs; i++)
-    write_memory (sp + offset[i], VALUE_CONTENTS (args[i]),
-                 TYPE_LENGTH (VALUE_TYPE (args[i])));
+    write_memory (orig_sp + offset[i], VALUE_CONTENTS (args[i]), lengths[i]);
 
+  /* If a structure has to be returned, set up register 28 to hold its
+     address */
   if (struct_return)
     write_register (28, struct_addr);
-  return sp + 32;
+
+  /* For the PA64 we must pass a pointer to the outgoing argument list.
+     The ABI mandates that the pointer should point to the first byte of
+     storage beyond the register flushback area.
+
+     However, the call dummy expects the outgoing argument pointer to
+     be passed in register %r4.  */
+  write_register (4, orig_sp + REG_PARM_STACK_SPACE);
+
+  /* ?!? This needs further work.  We need to set up the global data
+     pointer for this procedure.  This assumes the same global pointer
+     for every procedure.   The call dummy expects the dp value to
+     be passed in register %r6.  */
+  write_register (6, read_register (27));
+  
+  /* The stack will have 64 bytes of additional space for a frame marker.  */
+  return sp + 64;
 }
-#endif
 
-/* elz: I am rewriting this function, because the one above is a very 
-   obscure piece of code.
-   This function pushes the arguments on the stack. The stack grows up
-   on the PA. 
-   Each argument goes in one (or more) word (4 bytes) on the stack.
-   The first four words for the args must be allocated, even if they 
-   are not used. 
-   The 'topmost' arg is arg0, the 'bottom-most' is arg3. (if you think of 
-   them as 1 word long).
-   Below these there can be any number of arguments, as needed by the function.
-   If an arg is bigger than one word, it will be written on the stack 
-   occupying as many words as needed. Args that are bigger than 64bits
-   are not copied on the stack, a pointer is passed instead.
-
-   On top of the arg0 word there are other 8 words (32bytes) which are used
-   for other purposes */
+#else
+
+/* This function pushes a stack frame with arguments as part of the
+   inferior function calling mechanism.
 
+   This is the version of the function for the 32-bit PA machines, in
+   which later arguments appear at lower addresses.  (The stack always
+   grows towards higher addresses.)
+
+   We simply allocate the appropriate amount of stack space and put
+   arguments into their proper slots.  The call dummy code will copy
+   arguments into registers as needed by the ABI. */
+   
 CORE_ADDR
-hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
-     int nargs;
-     value_ptr *args;
-     CORE_ADDR sp;
-     int struct_return;
-     CORE_ADDR struct_addr;
+hppa_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
+                    int struct_return, CORE_ADDR struct_addr)
 {
   /* array of arguments' offsets */
   int *offset = (int *) alloca (nargs * sizeof (int));
-  /* array of arguments' lengths: real lengths in bytes, not aligned to word size */
+
+  /* array of arguments' lengths: real lengths in bytes, not aligned to
+     word size */
   int *lengths = (int *) alloca (nargs * sizeof (int));
 
-  int bytes_reserved;          /* this is the number of bytes on the stack occupied by an
-                                  argument. This will be always a multiple of 4 */
+  /* The number of stack bytes occupied by the current argument.  */
+  int bytes_reserved;
 
-  int cum_bytes_reserved = 0;  /* this is the total number of bytes reserved by the args
-                                  seen so far. It is a multiple of 4 always */
-  int cum_bytes_aligned = 0;   /* same as above, but aligned on 8 bytes */
-  int i;
+  /* The total number of bytes reserved for the arguments.  */
+  int cum_bytes_reserved = 0;
 
-  /* When an arg does not occupy a whole word, for instance in bitfields:
-     if the arg is x bits (0<x<32), it must be written
-     starting from the (x-1)-th position  down until the 0-th position. 
-     It is enough to align it to the word. */
-  /* if an arg occupies 8 bytes, it must be aligned on the 64-bits 
-     high order word in odd arg word. */
-  /* if an arg is larger than 64 bits, we need to pass a pointer to it, and
-     copy the actual value on the stack, so that the callee can play with it.
-     This is taken care of in valops.c in the call_function_by_hand function.
-     The argument that is received in this function here has already be converted
-     to a pointer to whatever is needed, so that it just can be pushed
-     as a word argument */
+  /* Similarly, but aligned.  */
+  int cum_bytes_aligned = 0;
+  int i;
 
+  /* Iterate over each argument provided by the user.  */
   for (i = 0; i < nargs; i++)
     {
-
       lengths[i] = TYPE_LENGTH (VALUE_TYPE (args[i]));
 
-      if (lengths[i] % 4)
-       bytes_reserved = (lengths[i] / 4) * 4 + 4;
-      else
-       bytes_reserved = lengths[i];
+      /* Align the size of the argument to the word size for this
+        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 ((bytes_reserved == 8) && (offset[i] % 8))    /* if 64-bit arg is not 64 bit aligned */
+      /* If the argument is a double word argument, then it needs to be
+        double word aligned.  */
+      if ((bytes_reserved == 2 * REGISTER_SIZE)
+         && (offset[i] % 2 * REGISTER_SIZE))
        {
          int new_offset = 0;
-         /* bytes_reserved is already aligned to the word, so we put it at one word
-            more down the stack. This will leave one empty word on the
-            stack, and one unused register. This is OK, see the calling
-            convention doc */
-         /* the offset may have to be moved to the corresponding position
-            one word down the stack, to maintain 
-            alignment. */
-         new_offset = (offset[i] / 8) * 8 + 8;
-         if ((new_offset - offset[i]) >= 4)
+         /* BYTES_RESERVED is already aligned to the word, so we put
+            the argument at one word more down the stack.
+
+            This will leave one empty word on the stack, and one unused
+            register as mandated by the ABI.  */
+         new_offset = ((offset[i] + 2 * REGISTER_SIZE - 1)
+                       & -(2 * REGISTER_SIZE));
+
+         if ((new_offset - offset[i]) >= 2 * REGISTER_SIZE)
            {
-             bytes_reserved += 4;
-             offset[i] += 4;
+             bytes_reserved += REGISTER_SIZE;
+             offset[i] += REGISTER_SIZE;
            }
        }
 
@@ -1699,25 +1881,31 @@ hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
 
     }
 
-  /* now move up the sp to reserve at least 4 words required for the args,
-     or more than this if needed */
-  /* wee also need to keep the sp aligned to 8 bytes */
+  /* CUM_BYTES_RESERVED already accounts for all the arguments passed
+     by the user.  However, the ABI mandates minimum stack space
+     allocations for outgoing arguments.
+
+     The ABI also mandates minimum stack alignments which we must
+     preserve.  */
   cum_bytes_aligned = STACK_ALIGN (cum_bytes_reserved);
-  sp += max (cum_bytes_aligned, 16);
+  sp += max (cum_bytes_aligned, REG_PARM_STACK_SPACE);
 
-  /* now write each of the args at the proper offset down the stack */
+  /* Now write each of the args at the proper offset down the stack.
+     ?!? We need to promote values to a full register instead of skipping
+     words in the stack.  */
   for (i = 0; i < nargs; i++)
     write_memory (sp - offset[i], VALUE_CONTENTS (args[i]), lengths[i]);
 
-
-  /* if a structure has to be returned, set up register 28 to hold its address */
+  /* If a structure has to be returned, set up register 28 to hold its
+     address */
   if (struct_return)
     write_register (28, struct_addr);
 
-  /* the stack will have other 8 words on top of the args */
+  /* The stack will have 32 bytes of additional space for a frame marker.  */
   return sp + 32;
 }
 
+#endif
 
 /* elz: this function returns a value which is built looking at the given address.
    It is called from call_function_by_hand, in case we need to return a 
@@ -1726,12 +1914,10 @@ hppa_push_arguments (nargs, args, sp, struct_return, struct_addr)
    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
-hppa_value_returned_from_stack (valtype, addr)
-     register struct type *valtype;
-     CORE_ADDR addr;
+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);
@@ -1762,29 +1948,28 @@ hppa_value_returned_from_stack (valtype, addr)
    man entry for shl_findsym */
 
 CORE_ADDR
-find_stub_with_shl_get (function, handle)
-     struct minimal_symbol *function;
-     CORE_ADDR handle;
+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);
   msymbol = lookup_minimal_symbol ("__shldp", NULL, NULL);
   symbol2 = lookup_symbol ("__shldp", NULL, VAR_NAMESPACE, NULL, NULL);
   endo_buff_addr = SYMBOL_VALUE_ADDRESS (buff_minsym);
-  namelen = strlen (SYMBOL_NAME (function));
+  namelen = strlen (DEPRECATED_SYMBOL_NAME (function));
   value_return_addr = endo_buff_addr + namelen;
   ftype = check_typedef (SYMBOL_TYPE (get_sym));
 
@@ -1797,7 +1982,7 @@ find_stub_with_shl_get (function, handle)
 
   /* set up stuff needed by __d_shl_get in buffer in end.o */
 
-  target_write_memory (endo_buff_addr, SYMBOL_NAME (function), namelen);
+  target_write_memory (endo_buff_addr, DEPRECATED_SYMBOL_NAME (function), namelen);
 
   target_write_memory (value_return_addr, (char *) &tmp, 4);
 
@@ -1809,11 +1994,11 @@ find_stub_with_shl_get (function, handle)
   /* now prepare the arguments for the call */
 
   args[0] = value_from_longest (TYPE_FIELD_TYPE (ftype, 0), 12);
-  args[1] = value_from_longest (TYPE_FIELD_TYPE (ftype, 1), SYMBOL_VALUE_ADDRESS (msymbol));
-  args[2] = value_from_longest (TYPE_FIELD_TYPE (ftype, 2), endo_buff_addr);
+  args[1] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 1), SYMBOL_VALUE_ADDRESS (msymbol));
+  args[2] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 2), endo_buff_addr);
   args[3] = value_from_longest (TYPE_FIELD_TYPE (ftype, 3), TYPE_PROCEDURE);
-  args[4] = value_from_longest (TYPE_FIELD_TYPE (ftype, 4), value_return_addr);
-  args[5] = value_from_longest (TYPE_FIELD_TYPE (ftype, 5), errno_return_addr);
+  args[4] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 4), value_return_addr);
+  args[5] = value_from_pointer (TYPE_FIELD_TYPE (ftype, 5), errno_return_addr);
 
   /* now call the function */
 
@@ -1825,14 +2010,14 @@ find_stub_with_shl_get (function, handle)
 
   target_read_memory (value_return_addr, (char *) &stub_addr, sizeof (stub_addr));
   if (stub_addr <= 0)
-    error ("call to __d_shl_get failed, error code is %d", err_value); /* purecov: deadcode */
+    error ("call to __d_shl_get failed, error code is %d", err_value);
 
   return (stub_addr);
 }
 
 /* Cover routine for find_stub_with_shl_get to pass to catch_errors */
 static int
-cover_find_stub_with_shl_get (PTR args_untyped)
+cover_find_stub_with_shl_get (void *args_untyped)
 {
   args_for_find_stub *args = args_untyped;
   args->return_val = find_stub_with_shl_get (args->msym, args->solib_handle);
@@ -1863,14 +2048,8 @@ cover_find_stub_with_shl_get (PTR args_untyped)
    Please contact Jeff Law (law@cygnus.com) before changing this code.  */
 
 CORE_ADDR
-hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
-     char *dummy;
-     CORE_ADDR pc;
-     CORE_ADDR fun;
-     int nargs;
-     value_ptr *args;
-     struct type *type;
-     int gcc_p;
+hppa_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+                    struct value **args, struct type *type, int gcc_p)
 {
   CORE_ADDR dyncall_addr;
   struct minimal_symbol *msymbol;
@@ -1881,14 +2060,111 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
   CORE_ADDR solib_handle = 0;
 
   /* Nonzero if we will use GCC's PLT call routine.  This routine must be
-     passed an import stub, not a PLABEL.  It is also necessary to set %r19     
-     (the PIC register) before performing the call. 
+     passed an import stub, not a PLABEL.  It is also necessary to set %r19
+     (the PIC register) before performing the call.
 
      If zero, then we are using __d_plt_call (HP's PLT call routine) or we
      are calling the target directly.  When using __d_plt_call we want to
      use a PLABEL instead of an import stub.  */
   int using_gcc_plt_call = 1;
 
+#ifdef GDB_TARGET_IS_HPPA_20W
+  /* We currently use completely different code for the PA2.0W inferior
+     function call sequences.  This needs to be cleaned up.  */
+  {
+    CORE_ADDR pcsqh, pcsqt, pcoqh, pcoqt, sr5;
+    struct target_waitstatus w;
+    int inst1, inst2;
+    char buf[4];
+    int status;
+    struct objfile *objfile;
+
+    /* We can not modify the PC space queues directly, so we start
+       up the inferior and execute a couple instructions to set the
+       space queues so that they point to the call dummy in the stack.  */
+    pcsqh = read_register (PCSQ_HEAD_REGNUM);
+    sr5 = read_register (SR5_REGNUM);
+    if (1)
+      {
+        pcoqh = read_register (PCOQ_HEAD_REGNUM);
+        pcoqt = read_register (PCOQ_TAIL_REGNUM);
+        if (target_read_memory (pcoqh, buf, 4) != 0)
+          error ("Couldn't modify space queue\n");
+        inst1 = extract_unsigned_integer (buf, 4);
+
+        if (target_read_memory (pcoqt, buf, 4) != 0)
+          error ("Couldn't modify space queue\n");
+        inst2 = extract_unsigned_integer (buf, 4);
+
+        /* BVE (r1) */
+        *((int *) buf) = 0xe820d000;
+        if (target_write_memory (pcoqh, buf, 4) != 0)
+          error ("Couldn't modify space queue\n");
+
+        /* NOP */
+        *((int *) buf) = 0x08000240;
+        if (target_write_memory (pcoqt, buf, 4) != 0)
+          {
+            *((int *) buf) = inst1;
+            target_write_memory (pcoqh, buf, 4);
+            error ("Couldn't modify space queue\n");
+          }
+
+        write_register (1, pc);
+
+        /* Single step twice, the BVE instruction will set the space queue
+          such that it points to the PC value written immediately above
+          (ie the call dummy).  */
+        resume (1, 0);
+        target_wait (inferior_ptid, &w);
+        resume (1, 0);
+        target_wait (inferior_ptid, &w);
+
+       /* Restore the two instructions at the old PC locations.  */
+        *((int *) buf) = inst1;
+        target_write_memory (pcoqh, buf, 4);
+        *((int *) buf) = inst2;
+        target_write_memory (pcoqt, buf, 4);
+      }
+
+    /* The call dummy wants the ultimate destination address initially
+       in register %r5.  */
+    write_register (5, fun);
+
+    /* We need to see if this objfile has a different DP value than our
+       own (it could be a shared library for example).  */
+    ALL_OBJFILES (objfile)
+      {
+       struct obj_section *s;
+       obj_private_data_t *obj_private;
+
+       /* See if FUN is in any section within this shared library.  */
+       for (s = objfile->sections; s < objfile->sections_end; s++)
+         if (s->addr <= fun && fun < s->endaddr)
+           break;
+
+        if (s >= objfile->sections_end)
+         continue;
+
+       obj_private = (obj_private_data_t *) objfile->obj_private;
+       
+       /* The DP value may be different for each objfile.  But within an
+          objfile each function uses the same dp value.  Thus we do not need
+          to grope around the opd section looking for dp values.
+
+          ?!? This is not strictly correct since we may be in a shared library
+          and want to call back into the main program.  To make that case
+          work correctly we need to set obj_private->dp for the main program's
+          objfile, then remove this conditional.  */
+       if (obj_private->dp)
+         write_register (27, obj_private->dp);
+       break;
+      }
+    return pc;
+  }
+#endif
+
+#ifndef GDB_TARGET_IS_HPPA_20W
   /* Prefer __gcc_plt_call over the HP supplied routine because
      __gcc_plt_call works for any number of arguments.  */
   trampoline = NULL;
@@ -1909,11 +2185,13 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
       /* Get the GOT/DP value for the target function.  It's
          at *(fun+4).  Note the call dummy is *NOT* allowed to
          trash %r19 before calling the target function.  */
-      write_register (19, read_memory_integer ((fun & ~0x3) + 4, 4));
+      write_register (19, read_memory_integer ((fun & ~0x3) + 4,
+                     REGISTER_SIZE));
 
       /* Now get the real address for the function we are calling, it's
          at *fun.  */
-      fun = (CORE_ADDR) read_memory_integer (fun & ~0x3, 4);
+      fun = (CORE_ADDR) read_memory_integer (fun & ~0x3,
+                                            TARGET_PTR_BIT / 8);
     }
   else
     {
@@ -1924,7 +2202,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
          stub rather than the export stub or real function for lazy binding
          to work correctly
 
-         /* If we are using the gcc PLT call routine, then we need to
+         If we are using the gcc PLT call routine, then we need to
          get the import stub for the target function.  */
       if (using_gcc_plt_call && som_solib_get_got_by_pc (fun))
        {
@@ -1934,7 +2212,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
 
          funsymbol = lookup_minimal_symbol_by_pc (fun);
          if (!funsymbol)
-           error ("Unable to find minimal symbol for target fucntion.\n");
+           error ("Unable to find minimal symbol for target function.\n");
 
          /* Search all the object files for an import symbol with the
             right name. */
@@ -1942,10 +2220,10 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
          {
            stub_symbol
              = lookup_minimal_symbol_solib_trampoline
-             (SYMBOL_NAME (funsymbol), NULL, objfile);
+             (DEPRECATED_SYMBOL_NAME (funsymbol), NULL, objfile);
 
            if (!stub_symbol)
-             stub_symbol = lookup_minimal_symbol (SYMBOL_NAME (funsymbol),
+             stub_symbol = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (funsymbol),
                                                   NULL, objfile);
 
            /* Found a symbol with the right name.  */
@@ -1958,14 +2236,34 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
 
                /* It must also be an import stub.  */
                u = find_unwind_entry (SYMBOL_VALUE (stub_symbol));
-               if (!u
-                   || (u->stub_unwind.stub_type != IMPORT)
-                   && u->stub_unwind.stub_type != IMPORT_SHLIB)
+               if (u == NULL
+                   || (u->stub_unwind.stub_type != IMPORT
+#ifdef GDB_NATIVE_HPUX_11
+                       /* Sigh.  The hpux 10.20 dynamic linker will blow
+                          chunks if we perform a call to an unbound function
+                          via the IMPORT_SHLIB stub.  The hpux 11.00 dynamic
+                          linker will blow chunks if we do not call the
+                          unbound function via the IMPORT_SHLIB stub.
+
+                          We currently have no way to select bevahior on just
+                          the target.  However, we only support HPUX/SOM in
+                          native mode.  So we conditinalize on a native
+                          #ifdef.  Ugly.  Ugly.  Ugly  */
+                       && u->stub_unwind.stub_type != IMPORT_SHLIB
+#endif
+                       ))
                  continue;
 
                /* OK.  Looks like the correct import stub.  */
                newfun = SYMBOL_VALUE (stub_symbol);
                fun = newfun;
+
+               /* If we found an IMPORT stub, then we want to stop
+                  searching now.  If we found an IMPORT_SHLIB, we want
+                  to continue the search in the hopes that we will find
+                  an IMPORT stub.  */
+               if (u->stub_unwind.stub_type == IMPORT)
+                 break;
              }
          }
 
@@ -2026,7 +2324,7 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
          new_stub = find_stub_with_shl_get (fmsymbol, solib_handle);
 
          if (new_stub == 0)
-           error ("Can't find an import stub for %s", SYMBOL_NAME (fmsymbol));
+           error ("Can't find an import stub for %s", DEPRECATED_SYMBOL_NAME (fmsymbol));
 
          /* We have to store the address of the stub in __shlib_funcptr.  */
          msymbol = lookup_minimal_symbol ("__shlib_funcptr", NULL,
@@ -2044,7 +2342,6 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
        }
     }
 
-#ifndef GDB_TARGET_IS_HPPA_20W
   /* Store upper 21 bits of function address into ldil.  fun will either be
      the final target (most cases) or __d_plt_call when calling into a shared
      library and __gcc_plt_call is not available.  */
@@ -2062,7 +2359,6 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
      deposit_14 (fun & MASK_11,
                 extract_unsigned_integer (&dummy[FUNC_LDO_OFFSET],
                                           INSTRUCTION_SIZE)));
-#endif /* GDB_TARGET_IS_HPPA_20W */
 #ifdef SR4EXPORT_LDIL_OFFSET
 
   {
@@ -2114,22 +2410,20 @@ hppa_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p)
   if (flags & 2)
     return pc;
 #ifndef GDB_TARGET_IS_PA_ELF
-  else if (som_solib_get_got_by_pc (target_read_pc (inferior_pid)))
+  else if (som_solib_get_got_by_pc (hppa_target_read_pc (inferior_ptid)))
     return pc;
 #endif
   else
     return dyncall_addr;
+#endif
 }
 
-
-
-
 /* If the pid is in a syscall, then the FP register is not readable.
    We'll return zero in that case, rather than attempting to read it
    and cause a warning. */
+
 CORE_ADDR
-target_read_fp (pid)
-     int pid;
+hppa_read_fp (int pid)
 {
   int flags = read_register (FLAGS_REGNUM);
 
@@ -2143,34 +2437,36 @@ target_read_fp (pid)
   return read_register (FP_REGNUM);
 }
 
+CORE_ADDR
+hppa_target_read_fp (void)
+{
+  return hppa_read_fp (PIDGET (inferior_ptid));
+}
 
 /* Get the PC from %r31 if currently in a syscall.  Also mask out privilege
    bits.  */
 
 CORE_ADDR
-target_read_pc (pid)
-     int pid;
+hppa_target_read_pc (ptid_t ptid)
 {
-  int flags = read_register_pid (FLAGS_REGNUM, pid);
+  int flags = read_register_pid (FLAGS_REGNUM, ptid);
 
   /* The following test does not belong here.  It is OS-specific, and belongs
      in native code.  */
   /* Test SS_INSYSCALL */
   if (flags & 2)
-    return read_register_pid (31, pid) & ~0x3;
+    return read_register_pid (31, ptid) & ~0x3;
 
-  return read_register_pid (PC_REGNUM, pid) & ~0x3;
+  return read_register_pid (PC_REGNUM, ptid) & ~0x3;
 }
 
 /* Write out the PC.  If currently in a syscall, then also write the new
    PC value into %r31.  */
 
 void
-target_write_pc (v, pid)
-     CORE_ADDR v;
-     int pid;
+hppa_target_write_pc (CORE_ADDR v, ptid_t ptid)
 {
-  int flags = read_register_pid (FLAGS_REGNUM, pid);
+  int flags = read_register_pid (FLAGS_REGNUM, ptid);
 
   /* The following test does not belong here.  It is OS-specific, and belongs
      in native code.  */
@@ -2178,18 +2474,17 @@ target_write_pc (v, pid)
      privilege bits set correctly.  */
   /* Test SS_INSYSCALL */
   if (flags & 2)
-    write_register_pid (31, v | 0x3, pid);
+    write_register_pid (31, v | 0x3, ptid);
 
-  write_register_pid (PC_REGNUM, v, pid);
-  write_register_pid (NPC_REGNUM, v + 4, pid);
+  write_register_pid (PC_REGNUM, v, ptid);
+  write_register_pid (NPC_REGNUM, v + 4, ptid);
 }
 
 /* return the alignment of a type in bytes. Structures have the maximum
    alignment required by their fields. */
 
 static int
-hppa_alignof (type)
-     struct type *type;
+hppa_alignof (struct type *type)
 {
   int max_align, align, i;
   CHECK_TYPEDEF (type);
@@ -2223,9 +2518,7 @@ hppa_alignof (type)
 /* Print the register regnum, or all registers if regnum is -1 */
 
 void
-pa_do_registers_info (regnum, fpregs)
-     int regnum;
-     int fpregs;
+pa_do_registers_info (int regnum, int fpregs)
 {
   char raw_regs[REGISTER_BYTES];
   int i;
@@ -2233,7 +2526,7 @@ pa_do_registers_info (regnum, 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 (deprecated_selected_frame, i, raw_regs + REGISTER_BYTE (i));
 
   if (regnum == -1)
     pa_print_registers (raw_regs, regnum, fpregs);
@@ -2247,15 +2540,15 @@ pa_do_registers_info (regnum, 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]);
        }
     }
@@ -2268,11 +2561,8 @@ pa_do_registers_info (regnum, fpregs)
 
 /********** new function ********************/
 void
-pa_do_strcat_registers_info (regnum, fpregs, stream, precision)
-     int regnum;
-     int fpregs;
-     GDB_FILE *stream;
-     enum precision_type precision;
+pa_do_strcat_registers_info (int regnum, int fpregs, struct ui_file *stream,
+                            enum precision_type precision)
 {
   char raw_regs[REGISTER_BYTES];
   int i;
@@ -2280,7 +2570,7 @@ pa_do_strcat_registers_info (regnum, fpregs, stream, precision)
   /* 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 (deprecated_selected_frame, i, raw_regs + REGISTER_BYTE (i));
 
   if (regnum == -1)
     pa_strcat_registers (raw_regs, regnum, fpregs, stream);
@@ -2295,16 +2585,16 @@ pa_do_strcat_registers_info (regnum, fpregs, stream, precision)
 
       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]);
        }
     }
@@ -2321,10 +2611,7 @@ pa_do_strcat_registers_info (regnum, fpregs, stream, precision)
    Note that reg_val is really expected to be an array of longs,
    with two elements. */
 static void
-pa_register_look_aside (raw_regs, regnum, raw_val)
-     char *raw_regs;
-     int regnum;
-     long *raw_val;
+pa_register_look_aside (char *raw_regs, int regnum, long *raw_val)
 {
   static int know_which = 0;   /* False */
 
@@ -2334,7 +2621,7 @@ pa_register_look_aside (raw_regs, regnum, raw_val)
   int start;
 
 
-  char buf[MAX_REGISTER_RAW_SIZE];
+  char *buf = alloca (max_register_size (current_gdbarch));
   long long reg_val;
 
   if (!know_which)
@@ -2401,7 +2688,7 @@ pa_register_look_aside (raw_regs, regnum, raw_val)
   for (i = start; i < 2; i++)
     {
       errno = 0;
-      raw_val[i] = call_ptrace (PT_RUREGS, inferior_pid,
+      raw_val[i] = call_ptrace (PT_RUREGS, PIDGET (inferior_ptid),
                                (PTRACE_ARG3_TYPE) regaddr, 0);
       if (errno != 0)
        {
@@ -2427,10 +2714,7 @@ error_exit:
 /* "Info all-reg" command */
 
 static void
-pa_print_registers (raw_regs, regnum, fpregs)
-     char *raw_regs;
-     int regnum;
-     int fpregs;
+pa_print_registers (char *raw_regs, int regnum, int fpregs)
 {
   int i, j;
   /* Alas, we are compiled so that "long long" is 32 bits */
@@ -2457,17 +2741,17 @@ pa_print_registers (raw_regs, regnum, 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]);
            }
@@ -2482,11 +2766,8 @@ pa_print_registers (raw_regs, regnum, fpregs)
 
 /************* new function ******************/
 static void
-pa_strcat_registers (raw_regs, regnum, fpregs, stream)
-     char *raw_regs;
-     int regnum;
-     int fpregs;
-     GDB_FILE *stream;
+pa_strcat_registers (char *raw_regs, int regnum, int fpregs,
+                    struct ui_file *stream)
 {
   int i, j;
   long raw_val[2];             /* Alas, we are compiled so that "long long" is 32 bits */
@@ -2511,17 +2792,19 @@ pa_strcat_registers (raw_regs, regnum, fpregs, stream)
              /* 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");
@@ -2533,14 +2816,13 @@ pa_strcat_registers (raw_regs, regnum, fpregs, stream)
 }
 
 static void
-pa_print_fp_reg (i)
-     int i;
+pa_print_fp_reg (int i)
 {
-  char raw_buffer[MAX_REGISTER_RAW_SIZE];
-  char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
+  char *raw_buffer = alloca (max_register_size (current_gdbarch));
+  char *virtual_buffer = alloca (max_register_size (current_gdbarch));
 
   /* Get 32bits of data.  */
-  read_relative_register_raw_bytes (i, raw_buffer);
+  frame_register_read (deprecated_selected_frame, i, raw_buffer);
 
   /* Put it in the buffer.  No conversions are ever necessary.  */
   memcpy (virtual_buffer, raw_buffer, REGISTER_RAW_SIZE (i));
@@ -2558,7 +2840,7 @@ pa_print_fp_reg (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 (deprecated_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,
@@ -2577,19 +2859,16 @@ pa_print_fp_reg (i)
 
 /*************** new function ***********************/
 static void
-pa_strcat_fp_reg (i, stream, precision)
-     int i;
-     GDB_FILE *stream;
-     enum precision_type precision;
+pa_strcat_fp_reg (int i, struct ui_file *stream, enum precision_type precision)
 {
-  char raw_buffer[MAX_REGISTER_RAW_SIZE];
-  char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
+  char *raw_buffer = alloca (max_register_size (current_gdbarch));
+  char *virtual_buffer = alloca (max_register_size (current_gdbarch));
 
   fputs_filtered (REGISTER_NAME (i), stream);
   print_spaces_filtered (8 - strlen (REGISTER_NAME (i)), stream);
 
   /* Get 32bits of data.  */
-  read_relative_register_raw_bytes (i, raw_buffer);
+  frame_register_read (deprecated_selected_frame, i, raw_buffer);
 
   /* Put it in the buffer.  No conversions are ever necessary.  */
   memcpy (virtual_buffer, raw_buffer, REGISTER_RAW_SIZE (i));
@@ -2597,10 +2876,10 @@ pa_strcat_fp_reg (i, stream, precision)
   if (precision == double_precision && (i % 2) == 0)
     {
 
-      char raw_buf[MAX_REGISTER_RAW_SIZE];
+      char *raw_buf = alloca (max_register_size (current_gdbarch));
 
       /* Get the data in raw format for the 2nd half.  */
-      read_relative_register_raw_bytes (i + 1, raw_buf);
+      frame_register_read (deprecated_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));
@@ -2623,17 +2902,80 @@ pa_strcat_fp_reg (i, stream, precision)
    just shared library trampolines (import, export).  */
 
 int
-in_solib_call_trampoline (pc, name)
-     CORE_ADDR pc;
-     char *name;
+hppa_in_solib_call_trampoline (CORE_ADDR pc, char *name)
 {
   struct minimal_symbol *minsym;
   struct unwind_table_entry *u;
   static CORE_ADDR dyncall = 0;
   static CORE_ADDR sr4export = 0;
 
-/* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
-   new exec file */
+#ifdef GDB_TARGET_IS_HPPA_20W
+  /* PA64 has a completely different stub/trampoline scheme.  Is it
+     better?  Maybe.  It's certainly harder to determine with any
+     certainty that we are in a stub because we can not refer to the
+     unwinders to help. 
+
+     The heuristic is simple.  Try to lookup the current PC value in th
+     minimal symbol table.  If that fails, then assume we are not in a
+     stub and return.
+
+     Then see if the PC value falls within the section bounds for the
+     section containing the minimal symbol we found in the first
+     step.  If it does, then assume we are not in a stub and return.
+
+     Finally peek at the instructions to see if they look like a stub.  */
+  {
+    struct minimal_symbol *minsym;
+    asection *sec;
+    CORE_ADDR addr;
+    int insn, i;
+
+    minsym = lookup_minimal_symbol_by_pc (pc);
+    if (! minsym)
+      return 0;
+
+    sec = SYMBOL_BFD_SECTION (minsym);
+
+    if (sec->vma <= pc
+       && sec->vma + sec->_cooked_size < pc)
+      return 0;
+
+    /* We might be in a stub.  Peek at the instructions.  Stubs are 3
+       instructions long. */
+    insn = read_memory_integer (pc, 4);
+
+    /* Find out where we think we are within the stub.  */
+    if ((insn & 0xffffc00e) == 0x53610000)
+      addr = pc;
+    else if ((insn & 0xffffffff) == 0xe820d000)
+      addr = pc - 4;
+    else if ((insn & 0xffffc00e) == 0x537b0000)
+      addr = pc - 8;
+    else
+      return 0;
+
+    /* Now verify each insn in the range looks like a stub instruction.  */
+    insn = read_memory_integer (addr, 4);
+    if ((insn & 0xffffc00e) != 0x53610000)
+      return 0;
+       
+    /* Now verify each insn in the range looks like a stub instruction.  */
+    insn = read_memory_integer (addr + 4, 4);
+    if ((insn & 0xffffffff) != 0xe820d000)
+      return 0;
+    
+    /* Now verify each insn in the range looks like a stub instruction.  */
+    insn = read_memory_integer (addr + 8, 4);
+    if ((insn & 0xffffc00e) != 0x537b0000)
+      return 0;
+
+    /* Looks like a stub.  */
+    return 1;
+  }
+#endif
+
+  /* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
+     new exec file */
 
   /* First see if PC is in one of the two C-library trampolines.  */
   if (!dyncall)
@@ -2657,6 +2999,10 @@ in_solib_call_trampoline (pc, name)
   if (pc == dyncall || pc == sr4export)
     return 1;
 
+  minsym = lookup_minimal_symbol_by_pc (pc);
+  if (minsym && strcmp (DEPRECATED_SYMBOL_NAME (minsym), ".stub") == 0)
+    return 1;
+
   /* Get the unwind descriptor corresponding to PC, return zero
      if no unwind was found.  */
   u = find_unwind_entry (pc);
@@ -2702,12 +3048,12 @@ in_solib_call_trampoline (pc, name)
        }
 
       /* Should never happen.  */
-      warning ("Unable to find branch in parameter relocation stub.\n");       /* purecov: deadcode */
-      return 0;                        /* purecov: deadcode */
+      warning ("Unable to find branch in parameter relocation stub.\n");
+      return 0;
     }
 
   /* Unknown stub type.  For now, just return zero.  */
-  return 0;                    /* purecov: deadcode */
+  return 0;
 }
 
 /* Return one if PC is in the return path of a trampoline, else return zero.
@@ -2716,9 +3062,7 @@ in_solib_call_trampoline (pc, name)
    just shared library trampolines (import, export).  */
 
 int
-in_solib_return_trampoline (pc, name)
-     CORE_ADDR pc;
-     char *name;
+hppa_in_solib_return_trampoline (CORE_ADDR pc, char *name)
 {
   struct unwind_table_entry *u;
 
@@ -2764,12 +3108,12 @@ in_solib_return_trampoline (pc, name)
        }
 
       /* Should never happen.  */
-      warning ("Unable to find branch in parameter relocation stub.\n");       /* purecov: deadcode */
-      return 0;                        /* purecov: deadcode */
+      warning ("Unable to find branch in parameter relocation stub.\n");
+      return 0;
     }
 
   /* Unknown stub type.  For now, just return zero.  */
-  return 0;                    /* purecov: deadcode */
+  return 0;
 
 }
 
@@ -2790,21 +3134,8 @@ in_solib_return_trampoline (pc, name)
    calling an argument relocation stub.  It even handles some stubs
    used in dynamic executables.  */
 
-#if 0
 CORE_ADDR
-skip_trampoline_code (pc, name)
-     CORE_ADDR pc;
-     char *name;
-{
-  return find_solib_trampoline_target (pc);
-}
-
-#endif
-
-CORE_ADDR
-skip_trampoline_code (pc, name)
-     CORE_ADDR pc;
-     char *name;
+hppa_skip_trampoline_code (CORE_ADDR pc)
 {
   long orig_pc = pc;
   long prev_inst, curr_inst, loc;
@@ -2814,9 +3145,8 @@ skip_trampoline_code (pc, name)
   struct minimal_symbol *msym;
   struct unwind_table_entry *u;
 
-
-/* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
-   new exec file */
+  /* FIXME XXX - dyncall and sr4export must be initialized whenever we get a
+     new exec file */
 
   if (!dyncall)
     {
@@ -2855,12 +3185,12 @@ skip_trampoline_code (pc, name)
          the PLT entry for this function, not the address of the function
          itself.  Bit 31 has meaning too, but only for MPE.  */
       if (pc & 0x2)
-       pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, 4);
+       pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8);
     }
   if (pc == dyncall_external)
     {
       pc = (CORE_ADDR) read_register (22);
-      pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, 4);
+      pc = (CORE_ADDR) read_memory_integer (pc & ~0x3, TARGET_PTR_BIT / 8);
     }
   else if (pc == sr4export)
     pc = (CORE_ADDR) (read_register (22));
@@ -2913,7 +3243,7 @@ skip_trampoline_code (pc, name)
          ALL_MSYMBOLS (objfile, msymbol)
          {
            if (MSYMBOL_TYPE (msymbol) == mst_text
-               && STREQ (SYMBOL_NAME (msymbol), SYMBOL_NAME (msym)))
+               && STREQ (DEPRECATED_SYMBOL_NAME (msymbol), DEPRECATED_SYMBOL_NAME (msym)))
              {
                function_found = 1;
                break;
@@ -3004,15 +3334,15 @@ skip_trampoline_code (pc, 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;
            }
 
-         libsym = lookup_minimal_symbol (SYMBOL_NAME (stubsym), NULL, NULL);
+         libsym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (stubsym), NULL, NULL);
          if (libsym == NULL)
            {
              warning ("Unable to find library symbol for %s\n",
-                      SYMBOL_NAME (stubsym));
+                      DEPRECATED_SYMBOL_NAME (stubsym));
              return orig_pc == pc ? 0 : pc & ~0x3;
            }
 
@@ -3052,7 +3382,7 @@ skip_trampoline_code (pc, name)
       else if ((curr_inst & 0xffe0f000) == 0xe840d000)
        {
          return (read_memory_integer
-                 (read_register (SP_REGNUM) - 24, 4)) & ~0x3;
+                 (read_register (SP_REGNUM) - 24, TARGET_PTR_BIT / 8)) & ~0x3;
        }
 
       /* What about be,n 0(sr0,%rp)?  It's just another way we return to
@@ -3064,7 +3394,7 @@ skip_trampoline_code (pc, name)
             I guess we could check for the previous instruction being
             mtsp %r1,%sr0 if we want to do sanity checking.  */
          return (read_memory_integer
-                 (read_register (SP_REGNUM) - 24, 4)) & ~0x3;
+                 (read_register (SP_REGNUM) - 24, TARGET_PTR_BIT / 8)) & ~0x3;
        }
 
       /* Haven't found the branch yet, but we're still in the stub.
@@ -3080,8 +3410,7 @@ skip_trampoline_code (pc, name)
    This only handles instructions commonly found in prologues.  */
 
 static int
-prologue_inst_adjust_sp (inst)
-     unsigned long inst;
+prologue_inst_adjust_sp (unsigned long inst)
 {
   /* This must persist across calls.  */
   static int save_high21;
@@ -3094,6 +3423,10 @@ prologue_inst_adjust_sp (inst)
   if ((inst & 0xffe00000) == 0x6fc00000)
     return extract_14 (inst);
 
+  /* std,ma X,D(sp) */
+  if ((inst & 0xffe00008) == 0x73c00008)
+    return (inst & 0x1 ? -1 << 13 : 0) | (((inst >> 4) & 0x3ff) << 3);
+
   /* addil high21,%r1; ldo low11,(%r1),%r30)
      save high bits in save_high21 for later use.  */
   if ((inst & 0xffe00000) == 0x28200000)
@@ -3116,8 +3449,7 @@ prologue_inst_adjust_sp (inst)
 /* Return nonzero if INST is a branch of some kind, else return zero.  */
 
 static int
-is_branch (inst)
-     unsigned long inst;
+is_branch (unsigned long inst)
 {
   switch (inst >> 26)
     {
@@ -3150,8 +3482,7 @@ is_branch (inst)
    zero it INST does not save a GR.  */
 
 static int
-inst_saves_gr (inst)
-     unsigned long inst;
+inst_saves_gr (unsigned long inst)
 {
   /* Does it look like a stw?  */
   if ((inst >> 26) == 0x1a || (inst >> 26) == 0x1b
@@ -3190,8 +3521,7 @@ inst_saves_gr (inst)
    FIXME: What about argument stores with the HP compiler in ANSI mode? */
 
 static int
-inst_saves_fr (inst)
-     unsigned long inst;
+inst_saves_fr (unsigned long inst)
 {
   /* is this an FSTD ? */
   if ((inst & 0xfc00dfc0) == 0x2c001200)
@@ -3214,8 +3544,7 @@ inst_saves_fr (inst)
 
 
 CORE_ADDR
-skip_prologue_hard_way (pc)
-     CORE_ADDR pc;
+skip_prologue_hard_way (CORE_ADDR pc)
 {
   char buf[4];
   CORE_ADDR orig_pc = pc;
@@ -3309,11 +3638,21 @@ restart:
       if (inst == 0x6bc23fd9 || inst == 0x0fc212c1)
        save_rp = 0;
 
-      /* This is the only way we save SP into the stack.  At this time
+      /* These are the only ways we save SP into the stack.  At this time
          the HP compilers never bother to save SP into the stack.  */
-      if ((inst & 0xffffc000) == 0x6fc10000)
+      if ((inst & 0xffffc000) == 0x6fc10000
+         || (inst & 0xffffc00c) == 0x73c10008)
        save_sp = 0;
 
+      /* Are we loading some register with an offset from the argument
+         pointer?  */
+      if ((inst & 0xffe00000) == 0x37a00000
+         || (inst & 0xffffffe0) == 0x081d0240)
+       {
+         pc += 4;
+         continue;
+       }
+
       /* Account for general and floating-point register saves.  */
       reg_num = inst_saves_gr (inst);
       save_gr &= ~(1 << reg_num);
@@ -3328,9 +3667,9 @@ restart:
 
          FIXME.  Can still die if we have a mix of GR and FR argument
          stores!  */
-      if (reg_num >= 23 && reg_num <= 26)
+      if (reg_num >= (TARGET_PTR_BIT == 64 ? 19 : 23) && reg_num <= 26)
        {
-         while (reg_num >= 23 && reg_num <= 26)
+         while (reg_num >= (TARGET_PTR_BIT == 64 ? 19 : 23) && reg_num <= 26)
            {
              pc += 4;
              status = target_read_memory (pc, buf, 4);
@@ -3357,7 +3696,7 @@ restart:
          save.  */
       if ((inst & 0xfc000000) == 0x34000000
          && inst_saves_fr (next_inst) >= 4
-         && inst_saves_fr (next_inst) <= 7)
+         && inst_saves_fr (next_inst) <= (TARGET_PTR_BIT == 64 ? 11 : 7))
        {
          /* So we drop into the code below in a reasonable state.  */
          reg_num = inst_saves_fr (next_inst);
@@ -3368,9 +3707,9 @@ restart:
          This is a kludge as on the HP compiler sets this bit and it
          never does prologue scheduling.  So once we see one, skip past
          all of them.  */
-      if (reg_num >= 4 && reg_num <= 7)
+      if (reg_num >= 4 && reg_num <= (TARGET_PTR_BIT == 64 ? 11 : 7))
        {
-         while (reg_num >= 4 && reg_num <= 7)
+         while (reg_num >= 4 && reg_num <= (TARGET_PTR_BIT == 64 ? 11 : 7))
            {
              pc += 8;
              status = target_read_memory (pc, buf, 4);
@@ -3437,8 +3776,7 @@ restart:
    we can determine it from the debug symbols.  Else return zero.  */
 
 static CORE_ADDR
-after_prologue (pc)
-     CORE_ADDR pc;
+after_prologue (CORE_ADDR pc)
 {
   struct symtab_and_line sal;
   CORE_ADDR func_addr, func_end;
@@ -3479,8 +3817,7 @@ after_prologue (pc)
    stuff some day.  */
 
 CORE_ADDR
-hppa_skip_prologue (pc)
-     CORE_ADDR pc;
+hppa_skip_prologue (CORE_ADDR pc)
 {
   unsigned long inst;
   int offset;
@@ -3512,9 +3849,8 @@ hppa_skip_prologue (pc)
    the address we return for it IS the sp for the next frame.  */
 
 void
-hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
-     struct frame_info *frame_info;
-     struct frame_saved_regs *frame_saved_regs;
+hppa_frame_find_saved_regs (struct frame_info *frame_info,
+                           struct frame_saved_regs *frame_saved_regs)
 {
   CORE_ADDR pc;
   struct unwind_table_entry *u;
@@ -3522,6 +3858,7 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
   int status, i, reg;
   char buf[4];
   int fp_loc = -1;
+  int final_iteration;
 
   /* Zero out everything.  */
   memset (frame_saved_regs, '\0', sizeof (struct frame_saved_regs));
@@ -3531,9 +3868,20 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
      instead, let find_dummy_frame_regs fill in the correct offsets
      for the saved registers.  */
   if ((frame_info->pc >= frame_info->frame
-       && frame_info->pc <= (frame_info->frame + CALL_DUMMY_LENGTH
-                            + 32 * 4 + (NUM_REGS - FP0_REGNUM) * 8
-                            + 6 * 4)))
+       && frame_info->pc <= (frame_info->frame
+                            /* A call dummy is sized in words, but it is
+                               actually a series of instructions.  Account
+                               for that scaling factor.  */
+                            + ((REGISTER_SIZE / INSTRUCTION_SIZE)
+                               * CALL_DUMMY_LENGTH)
+                            /* Similarly we have to account for 64bit
+                               wide register saves.  */
+                            + (32 * REGISTER_SIZE)
+                            /* We always consider FP regs 8 bytes long.  */
+                            + (NUM_REGS - FP0_REGNUM) * 8
+                            /* Similarly we have to account for 64bit
+                               wide register saves.  */
+                            + (6 * REGISTER_SIZE))))
     find_dummy_frame_regs (frame_info, frame_saved_regs);
 
   /* Interrupt handlers are special too.  They lay out the register
@@ -3545,7 +3893,8 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
          /* SP is a little special.  */
          if (i == SP_REGNUM)
            frame_saved_regs->regs[SP_REGNUM]
-             = read_memory_integer (frame_info->frame + SP_REGNUM * 4, 4);
+             = read_memory_integer (frame_info->frame + SP_REGNUM * 4,
+                                    TARGET_PTR_BIT / 8);
          else
            frame_saved_regs->regs[i] = frame_info->frame + i * 4;
        }
@@ -3554,7 +3903,7 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
 
 #ifdef FRAME_FIND_SAVED_REGS_IN_SIGTRAMP
   /* Handle signal handler callers.  */
-  if (frame_info->signal_handler_caller)
+  if ((get_frame_type (frame_info) == SIGTRAMP_FRAME))
     {
       FRAME_FIND_SAVED_REGS_IN_SIGTRAMP (frame_info, frame_saved_regs);
       return;
@@ -3612,7 +3961,9 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
      Some unexpected things are expected with debugging optimized code, so
      we allow this routine to walk past user instructions in optimized
      GCC code.  */
-  while (save_gr || save_fr || save_rp || save_sp || stack_remaining > 0)
+  final_iteration = 0;
+  while ((save_gr || save_fr || save_rp || save_sp || stack_remaining > 0)
+        && pc <= frame_info->pc)
     {
       status = target_read_memory (pc, buf, 4);
       inst = extract_unsigned_integer (buf, 4);
@@ -3624,17 +3975,27 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
       /* Note the interesting effects of this instruction.  */
       stack_remaining -= prologue_inst_adjust_sp (inst);
 
-      /* There is only one instruction used for saving RP into the stack.  */
-      if (inst == 0x6bc23fd9)
+      /* There are limited ways to store the return pointer into the
+        stack.  */
+      if (inst == 0x6bc23fd9) /* stw rp,-0x14(sr0,sp) */
        {
          save_rp = 0;
          frame_saved_regs->regs[RP_REGNUM] = frame_info->frame - 20;
        }
+      else if (inst == 0x0fc212c1) /* std rp,-0x10(sr0,sp) */
+       {
+         save_rp = 0;
+         frame_saved_regs->regs[RP_REGNUM] = frame_info->frame - 16;
+       }
 
-      /* Just note that we found the save of SP into the stack.  The
-         value for frame_saved_regs was computed above.  */
-      if ((inst & 0xffffc000) == 0x6fc10000)
-       save_sp = 0;
+      /* Note if we saved SP into the stack.  This also happens to indicate
+        the location of the saved frame pointer.  */
+      if (   (inst & 0xffffc000) == 0x6fc10000  /* stw,ma r1,N(sr0,sp) */
+          || (inst & 0xffffc00c) == 0x73c10008) /* std,ma r1,N(sr0,sp) */
+       {
+         frame_saved_regs->regs[FP_REGNUM] = frame_info->frame;
+         save_sp = 0;
+       }
 
       /* Account for general and floating-point register saves.  */
       reg = inst_saves_gr (inst);
@@ -3647,16 +4008,28 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
          if ((inst >> 26) == 0x1b
              && extract_14 (inst) >= 0)
            frame_saved_regs->regs[reg] = frame_info->frame;
+         /* A std has explicit post_modify forms.  */
+         else if ((inst & 0xfc00000c0) == 0x70000008)
+           frame_saved_regs->regs[reg] = frame_info->frame;
          else
            {
+             CORE_ADDR offset;
+
+             if ((inst >> 26) == 0x1c)
+               offset = (inst & 0x1 ? -1 << 13 : 0) | (((inst >> 4) & 0x3ff) << 3);
+             else if ((inst >> 26) == 0x03)
+               offset = low_sign_extend (inst & 0x1f, 5);
+             else
+               offset = extract_14 (inst);
+
              /* Handle code with and without frame pointers.  */
              if (u->Save_SP)
                frame_saved_regs->regs[reg]
-                 = frame_info->frame + extract_14 (inst);
+                 = frame_info->frame + offset;
              else
                frame_saved_regs->regs[reg]
-                 = frame_info->frame + (u->Total_frame_size << 3)
-                 + extract_14 (inst);
+                 = (frame_info->frame + (u->Total_frame_size << 3)
+                    + offset);
            }
        }
 
@@ -3698,11 +4071,15 @@ hppa_frame_find_saved_regs (frame_info, frame_saved_regs)
            }
        }
 
-      /* Quit if we hit any kind of branch.  This can happen if a prologue
-         instruction is in the delay slot of the first call/branch.  */
-      if (is_branch (inst))
+      /* Quit if we hit any kind of branch the previous iteration. */
+      if (final_iteration)
        break;
 
+      /* We want to look precisely one instruction beyond the branch
+        if we have not found everything yet.  */
+      if (is_branch (inst))
+       final_iteration = 1;
+
       /* Bump the PC.  */
       pc += 4;
     }
@@ -3760,7 +4137,7 @@ static struct symtab_and_line *break_callback_sal = 0;
    0 => success
    1 => failure  */
 int
-setup_d_pid_in_inferior ()
+setup_d_pid_in_inferior (void)
 {
   CORE_ADDR anaddr;
   struct minimal_symbol *msymbol;
@@ -3776,7 +4153,7 @@ setup_d_pid_in_inferior ()
     }
 
   anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
-  store_unsigned_integer (buf, 4, inferior_pid);       /* FIXME 32x64? */
+  store_unsigned_integer (buf, 4, PIDGET (inferior_ptid)); /* FIXME 32x64? */
   if (target_write_memory (anaddr, buf, 4))    /* FIXME 32x64? */
     {
       warning ("Unable to write __d_pid");
@@ -3794,7 +4171,7 @@ setup_d_pid_in_inferior ()
    1 => success          */
 
 static int
-initialize_hp_cxx_exception_support ()
+initialize_hp_cxx_exception_support (void)
 {
   struct symtabs_and_lines sals;
   struct cleanup *old_chain;
@@ -3882,6 +4259,7 @@ initialize_hp_cxx_exception_support ()
       return 0;
     }
 
+#ifndef GDB_TARGET_IS_HPPA_20W
   /* Check whether the executable is dynamically linked or archive bound */
   /* With an archive-bound executable we can use the raw addresses we find
      for the callback function, etc. without modification. For an executable
@@ -3907,7 +4285,7 @@ initialize_hp_cxx_exception_support ()
       args.return_val = 0;
 
       recurse++;
-      catch_errors (cover_find_stub_with_shl_get, (PTR) &args, message,
+      catch_errors (cover_find_stub_with_shl_get, &args, message,
                    RETURN_MASK_ALL);
       eh_notify_callback_addr = args.return_val;
       recurse--;
@@ -3917,7 +4295,7 @@ initialize_hp_cxx_exception_support ()
       if (!eh_notify_callback_addr)
        {
          /* We can get here either if there is no plabel in the export list
-            for the main image, or if something strange happened (??) */
+            for the main image, or if something strange happened (?) */
          warning ("Couldn't find a plabel (indirect function label) for the exception callback.");
          warning ("GDB will not be able to intercept exception events.");
          return 0;
@@ -3925,6 +4303,7 @@ initialize_hp_cxx_exception_support ()
     }
   else
     exception_catchpoints_are_fragile = 0;
+#endif
 
   /* Now, look for the breakpointable routine in end.o */
   /* This should also be available in the SOM symbol dict. if end.o linked in */
@@ -4013,9 +4392,7 @@ initialize_hp_cxx_exception_support ()
    address was found. */
 
 struct symtab_and_line *
-child_enable_exception_callback (kind, enable)
-     enum exception_event_kind kind;
-     int enable;
+child_enable_exception_callback (enum exception_event_kind kind, int enable)
 {
   char buf[4];
 
@@ -4046,15 +4423,15 @@ child_enable_exception_callback (kind, enable)
   if (enable)
     {
       /* Ensure that __d_pid is set up correctly -- end.c code checks this. :-( */
-      if (inferior_pid > 0)
+      if (PIDGET (inferior_ptid) > 0)
        {
          if (setup_d_pid_in_inferior ())
            return (struct symtab_and_line *) -1;
        }
       else
        {
-         warning ("Internal error: Invalid inferior pid?  Cannot intercept exception events.");        /* purecov: deadcode */
-         return (struct symtab_and_line *) -1;         /* purecov: deadcode */
+         warning ("Internal error: Invalid inferior pid?  Cannot intercept exception events.");
+         return (struct symtab_and_line *) -1;
        }
     }
 
@@ -4076,8 +4453,8 @@ child_enable_exception_callback (kind, enable)
          return (struct symtab_and_line *) -1;
        }
       break;
-    default:                   /* purecov: deadcode */
-      error ("Request to enable unknown or unsupported exception event.");     /* purecov: deadcode */
+    default:
+      error ("Request to enable unknown or unsupported exception event.");
     }
 
   /* Copy break address into new sal struct, malloc'ing if needed. */
@@ -4085,7 +4462,7 @@ child_enable_exception_callback (kind, enable)
     {
       break_callback_sal = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line));
     }
-  INIT_SAL (break_callback_sal);
+  init_sal (break_callback_sal);
   break_callback_sal->symtab = NULL;
   break_callback_sal->pc = eh_break_addr;
   break_callback_sal->line = 0;
@@ -4105,7 +4482,7 @@ static struct symtab_and_line null_symtab_and_line =
    and where it will be caught.  More information may be reported
    in the future */
 struct exception_event_record *
-child_get_current_exception_event ()
+child_get_current_exception_event (void)
 {
   CORE_ADDR event_kind;
   CORE_ADDR throw_addr;
@@ -4124,7 +4501,7 @@ child_get_current_exception_event ()
   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:
@@ -4150,11 +4527,11 @@ child_get_current_exception_event ()
   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);
@@ -4163,10 +4540,18 @@ child_get_current_exception_event ()
   return &current_ex_event;
 }
 
+/* Instead of this nasty cast, add a method pvoid() that prints out a
+   host VOID data type (remember %p isn't portable).  */
+
+static CORE_ADDR
+hppa_pointer_to_address_hack (void *ptr)
+{
+  gdb_assert (sizeof (ptr) == TYPE_LENGTH (builtin_type_void_data_ptr));
+  return POINTER_TO_ADDRESS (builtin_type_void_data_ptr, &ptr);
+}
+
 static void
-unwind_command (exp, from_tty)
-     char *exp;
-     int from_tty;
+unwind_command (char *exp, int from_tty)
 {
   CORE_ADDR address;
   struct unwind_table_entry *u;
@@ -4186,7 +4571,8 @@ unwind_command (exp, from_tty)
       return;
     }
 
-  printf_unfiltered ("unwind_table_entry (0x%x):\n", u);
+  printf_unfiltered ("unwind_table_entry (0x%s):\n",
+                    paddr_nz (hppa_pointer_to_address_hack (u)));
 
   printf_unfiltered ("\tregion_start = ");
   print_address (u->region_start, gdb_stdout);
@@ -4194,11 +4580,7 @@ unwind_command (exp, from_tty)
   printf_unfiltered ("\n\tregion_end = ");
   print_address (u->region_end, gdb_stdout);
 
-#ifdef __STDC__
 #define pif(FLD) if (u->FLD) printf_unfiltered (" "#FLD);
-#else
-#define pif(FLD) if (u->FLD) printf_unfiltered (" FLD");
-#endif
 
   printf_unfiltered ("\n\tflags =");
   pif (Cannot_unwind);
@@ -4223,11 +4605,7 @@ unwind_command (exp, from_tty)
 
   putchar_unfiltered ('\n');
 
-#ifdef __STDC__
 #define pin(FLD) printf_unfiltered ("\t"#FLD" = 0x%x\n", u->FLD);
-#else
-#define pin(FLD) printf_unfiltered ("\tFLD = 0x%x\n", u->FLD);
-#endif
 
   pin (Region_description);
   pin (Entry_FR);
@@ -4269,14 +4647,20 @@ unwind_command (exp, from_tty)
    For these reasons, we have to violate information hiding and
    call "breakpoint_here_p".  If core gdb thinks there is a bpt
    here, that's what counts, as core gdb is the one which is
-   putting the BPT instruction in and taking it out. */
+   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.
+
+   FIXME This may not support switching threads after Ctrl-C
+   correctly. The default implementation does support this. */
 int
-hppa_prepare_to_proceed ()
+hppa_prepare_to_proceed (void)
 {
   pid_t old_thread;
   pid_t current_thread;
 
-  old_thread = hppa_switched_threads (inferior_pid);
+  old_thread = hppa_switched_threads (PIDGET (inferior_ptid));
   if (old_thread != 0)
     {
       /* Switched over from "old_thread".  Try to do
@@ -4287,8 +4671,8 @@ hppa_prepare_to_proceed ()
 
       /* Yuk, shouldn't use global to specify current
          thread.  But that's how gdb does it. */
-      current_thread = inferior_pid;
-      inferior_pid = old_thread;
+      current_thread = PIDGET (inferior_ptid);
+      inferior_ptid = pid_to_ptid (old_thread);
 
       new_pc = read_pc ();
       if (new_pc != old_pc     /* If at same pc, no need */
@@ -4300,14 +4684,14 @@ hppa_prepare_to_proceed ()
          registers_changed ();
 #if 0
          printf ("---> PREPARE_TO_PROCEED (was %d, now %d)!\n",
-                 current_thread, inferior_pid);
+                 current_thread, PIDGET (inferior_ptid));
 #endif
 
          return 1;
        }
 
       /* Otherwise switch back to the user-chosen thread. */
-      inferior_pid = current_thread;
+      inferior_ptid = pid_to_ptid (current_thread);
       new_pc = read_pc ();     /* Re-prime register cache */
     }
 
@@ -4316,11 +4700,371 @@ hppa_prepare_to_proceed ()
 #endif /* PREPARE_TO_PROCEED */
 
 void
-_initialize_hppa_tdep ()
+hppa_skip_permanent_breakpoint (void)
 {
+  /* To step over a breakpoint instruction on the PA takes some
+     fiddling with the instruction address queue.
+
+     When we stop at a breakpoint, the IA queue front (the instruction
+     we're executing now) points at the breakpoint instruction, and
+     the IA queue back (the next instruction to execute) points to
+     whatever instruction we would execute after the breakpoint, if it
+     were an ordinary instruction.  This is the case even if the
+     breakpoint is in the delay slot of a branch instruction.
+
+     Clearly, to step past the breakpoint, we need to set the queue
+     front to the back.  But what do we put in the back?  What
+     instruction comes after that one?  Because of the branch delay
+     slot, the next insn is always at the back + 4.  */
+  write_register (PCOQ_HEAD_REGNUM, read_register (PCOQ_TAIL_REGNUM));
+  write_register (PCSQ_HEAD_REGNUM, read_register (PCSQ_TAIL_REGNUM));
+
+  write_register (PCOQ_TAIL_REGNUM, read_register (PCOQ_TAIL_REGNUM) + 4);
+  /* We can leave the tail's space the same, since there's no jump.  */
+}
+
+/* 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.  */
+  deprecated_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)
+    deprecated_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));
+}
+
+int
+hppa_reg_struct_has_addr (int gcc_p, struct type *type)
+{
+  /* On the PA, any pass-by-value structure > 8 bytes is actually passed
+     via a pointer regardless of its type or the compiler used.  */
+  return (TYPE_LENGTH (type) > 8);
+}
+
+int
+hppa_inner_than (CORE_ADDR lhs, CORE_ADDR rhs)
+{
+  /* Stack grows upward */
+  return (lhs > rhs);
+}
+
+CORE_ADDR
+hppa_stack_align (CORE_ADDR sp)
+{
+  /* elz: adjust the quantity to the next highest value which is
+     64-bit aligned.  This is used in valops.c, when the sp is adjusted.
+     On hppa the sp must always be kept 64-bit aligned */
+  return ((sp % 8) ? (sp + 7) & -8 : sp);
+}
+
+int
+hppa_pc_requires_run_before_use (CORE_ADDR pc)
+{
+  /* Sometimes we may pluck out a minimal symbol that has a negative address.
+  
+     An example of this occurs when an a.out is linked against a foo.sl.
+     The foo.sl defines a global bar(), and the a.out declares a signature
+     for bar().  However, the a.out doesn't directly call bar(), but passes
+     its address in another call.
+  
+     If you have this scenario and attempt to "break bar" before running,
+     gdb will find a minimal symbol for bar() in the a.out.  But that
+     symbol's address will be negative.  What this appears to denote is
+     an index backwards from the base of the procedure linkage table (PLT)
+     into the data linkage table (DLT), the end of which is contiguous
+     with the start of the PLT.  This is clearly not a valid address for
+     us to set a breakpoint on.
+  
+     Note that one must be careful in how one checks for a negative address.
+     0xc0000000 is a legitimate address of something in a shared text
+     segment, for example.  Since I don't know what the possible range
+     is of these "really, truly negative" addresses that come from the
+     minimal symbols, I'm resorting to the gross hack of checking the
+     top byte of the address for all 1's.  Sigh.  */
+
+  return (!target_has_stack && (pc & 0xFF000000));
+}
+
+int
+hppa_instruction_nullified (void)
+{
+  /* brobecker 2002/11/07: Couldn't we use a ULONGEST here? It would
+     avoid the type cast.  I'm leaving it as is for now as I'm doing
+     semi-mechanical multiarching-related changes.  */
+  const int ipsw = (int) read_register (IPSW_REGNUM);
+  const int flags = (int) read_register (FLAGS_REGNUM);
+
+  return ((ipsw & 0x00200000) && !(flags & 0x2));
+}
+
+int
+hppa_register_raw_size (int reg_nr)
+{
+  /* All registers have the same size.  */
+  return REGISTER_SIZE;
+}
+
+/* Index within the register vector of the first byte of the space i
+   used for register REG_NR.  */
+
+int
+hppa_register_byte (int reg_nr)
+{
+  return reg_nr * 4;
+}
+
+/* Return the GDB type object for the "standard" data type of data
+   in register N.  */
+
+struct type *
+hppa_register_virtual_type (int reg_nr)
+{
+   if (reg_nr < FP4_REGNUM)
+     return builtin_type_int;
+   else
+     return builtin_type_float;
+}
+
+/* Store the address of the place in which to copy the structure the
+   subroutine will return.  This is called from call_function.  */
+
+void
+hppa_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
+{
+  write_register (28, addr);
+}
+
+CORE_ADDR
+hppa_extract_struct_value_address (char *regbuf)
+{
+  /* Extract from an array REGBUF containing the (raw) register state
+     the address in which a function should return its structure value,
+     as a CORE_ADDR (or an expression that can be used as one).  */
+  /* FIXME: brobecker 2002-12-26.
+     The current implementation is historical, but we should eventually
+     implement it in a more robust manner as it relies on the fact that
+     the address size is equal to the size of an int* _on the host_...
+     One possible implementation that crossed my mind is to use
+     extract_address.  */
+  return (*(int *)(regbuf + REGISTER_BYTE (28)));
+}
+
+/* Return True if REGNUM is not a register available to the user
+   through ptrace().  */
+
+int
+hppa_cannot_store_register (int regnum)
+{
+  return (regnum == 0
+          || regnum == PCSQ_HEAD_REGNUM
+          || (regnum >= PCSQ_TAIL_REGNUM && regnum < IPSW_REGNUM)
+          || (regnum > IPSW_REGNUM && regnum < FP4_REGNUM));
+
+}
+
+CORE_ADDR
+hppa_frame_args_address (struct frame_info *fi)
+{
+  return fi->frame;
+}
+
+CORE_ADDR
+hppa_frame_locals_address (struct frame_info *fi)
+{
+  return fi->frame;
+}
+
+int
+hppa_frame_num_args (struct frame_info *frame)
+{
+  /* We can't tell how many args there are now that the C compiler delays
+     popping them.  */
+  return -1;
+}
+
+CORE_ADDR
+hppa_smash_text_address (CORE_ADDR addr)
+{
+  /* The low two bits of the PC on the PA contain the privilege level.
+     Some genius implementing a (non-GCC) compiler apparently decided
+     this means that "addresses" in a text section therefore include a
+     privilege level, and thus symbol tables should contain these bits.
+     This seems like a bonehead thing to do--anyway, it seems to work
+     for our purposes to just ignore those bits.  */
+
+  return (addr &= ~0x3);
+}
+
+static struct gdbarch *
+hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  struct gdbarch *gdbarch;
+  
+  /* Try to determine the ABI of the object we are loading.  */
+  if (info.abfd != NULL && info.osabi == GDB_OSABI_UNKNOWN)
+    {
+      /* If it's a SOM file, assume it's HP/UX SOM.  */
+      if (bfd_get_flavour (info.abfd) == bfd_target_som_flavour)
+       info.osabi = GDB_OSABI_HPUX_SOM;
+    }
+
+  /* find a candidate among the list of pre-declared architectures.  */
+  arches = gdbarch_list_lookup_by_info (arches, &info);
+  if (arches != NULL)
+    return (arches->gdbarch);
+
+  /* If none found, then allocate and initialize one.  */
+  gdbarch = gdbarch_alloc (&info, NULL);
+
+  /* Hook in ABI-specific overrides, if they have been registered.  */
+  gdbarch_init_osabi (info, gdbarch);
+
+  set_gdbarch_reg_struct_has_addr (gdbarch, hppa_reg_struct_has_addr);
+  set_gdbarch_function_start_offset (gdbarch, 0);
+  set_gdbarch_skip_prologue (gdbarch, hppa_skip_prologue);
+  set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
+  set_gdbarch_in_solib_call_trampoline (gdbarch, hppa_in_solib_call_trampoline);
+  set_gdbarch_in_solib_return_trampoline (gdbarch,
+                                          hppa_in_solib_return_trampoline);
+  set_gdbarch_saved_pc_after_call (gdbarch, hppa_saved_pc_after_call);
+  set_gdbarch_inner_than (gdbarch, hppa_inner_than);
+  set_gdbarch_stack_align (gdbarch, hppa_stack_align);
+  set_gdbarch_extra_stack_alignment_needed (gdbarch, 0);
+  set_gdbarch_decr_pc_after_break (gdbarch, 0);
+  set_gdbarch_register_size (gdbarch, 4);
+  set_gdbarch_num_regs (gdbarch, hppa_num_regs);
+  set_gdbarch_fp_regnum (gdbarch, 3);
+  set_gdbarch_sp_regnum (gdbarch, 30);
+  set_gdbarch_fp0_regnum (gdbarch, 64);
+  set_gdbarch_pc_regnum (gdbarch, PCOQ_HEAD_REGNUM);
+  set_gdbarch_npc_regnum (gdbarch, PCOQ_TAIL_REGNUM);
+  set_gdbarch_register_raw_size (gdbarch, hppa_register_raw_size);
+  set_gdbarch_register_bytes (gdbarch, hppa_num_regs * 4);
+  set_gdbarch_register_byte (gdbarch, hppa_register_byte);
+  set_gdbarch_register_virtual_size (gdbarch, hppa_register_raw_size);
+  set_gdbarch_deprecated_max_register_raw_size (gdbarch, 4);
+  set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 8);
+  set_gdbarch_register_virtual_type (gdbarch, hppa_register_virtual_type);
+  set_gdbarch_deprecated_store_struct_return (gdbarch, hppa_store_struct_return);
+  set_gdbarch_deprecated_extract_return_value (gdbarch,
+                                               hppa_extract_return_value);
+  set_gdbarch_use_struct_convention (gdbarch, hppa_use_struct_convention);
+  set_gdbarch_deprecated_store_return_value (gdbarch, hppa_store_return_value);
+  set_gdbarch_deprecated_extract_struct_value_address
+    (gdbarch, hppa_extract_struct_value_address);
+  set_gdbarch_cannot_store_register (gdbarch, hppa_cannot_store_register);
+  set_gdbarch_deprecated_init_extra_frame_info (gdbarch, hppa_init_extra_frame_info);
+  set_gdbarch_deprecated_frame_chain (gdbarch, hppa_frame_chain);
+  set_gdbarch_deprecated_frame_chain_valid (gdbarch, hppa_frame_chain_valid);
+  set_gdbarch_frameless_function_invocation
+    (gdbarch, hppa_frameless_function_invocation);
+  set_gdbarch_deprecated_frame_saved_pc (gdbarch, hppa_frame_saved_pc);
+  set_gdbarch_frame_args_address (gdbarch, hppa_frame_args_address);
+  set_gdbarch_frame_locals_address (gdbarch, hppa_frame_locals_address);
+  set_gdbarch_frame_num_args (gdbarch, hppa_frame_num_args);
+  set_gdbarch_frame_args_skip (gdbarch, 0);
+  set_gdbarch_deprecated_push_dummy_frame (gdbarch, hppa_push_dummy_frame);
+  set_gdbarch_deprecated_pop_frame (gdbarch, hppa_pop_frame);
+  set_gdbarch_call_dummy_length (gdbarch, INSTRUCTION_SIZE * 28);
+  set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+  /* set_gdbarch_fix_call_dummy (gdbarch, hppa_fix_call_dummy); */
+  set_gdbarch_push_arguments (gdbarch, hppa_push_arguments);
+  set_gdbarch_smash_text_address (gdbarch, hppa_smash_text_address);
+  set_gdbarch_believe_pcc_promotion (gdbarch, 1);
+  set_gdbarch_read_pc (gdbarch, hppa_target_read_pc);
+  set_gdbarch_write_pc (gdbarch, hppa_target_write_pc);
+  set_gdbarch_read_fp (gdbarch, hppa_target_read_fp);
+
+  return gdbarch;
+}
+
+static void
+hppa_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+   /* Nothing to print for the moment.  */
+}
+
+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);
+
+  gdbarch_register (bfd_arch_hppa, hppa_gdbarch_init, hppa_dump_tdep);
   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);
 }
+
This page took 0.065842 seconds and 4 git commands to generate.