Index: gdb/gdb/configure.tgt
diff -u gdb/gdb/configure.tgt:1.1.1.1 gdb/gdb/configure.tgt:1.3
--- gdb/gdb/configure.tgt:1.1.1.1       Sun May 12 12:55:55 2002
+++ gdb/gdb/configure.tgt       Tue Jun 18 12:40:15 2002
@@ -82,6 +82,7 @@
               configdirs="${configdirs} gdbserver" ;;
hppa*64*-*-linux* | parisc*64*-*-linux*)       gdb_target=pa64-linux ;;
hppa*-*-linux* | parisc*-*-linux*)             gdb_target=pa-linux ;;
+hppa*-*-netbsd*)       gdb_target=nbsd ;;

i[3456]86-sequent-bsd*)        gdb_target=symmetry ;;
i[3456]86-sequent-sysv4*) gdb_target=ptx4 ;;
Index: gdb/gdb/pa-nbsd-tdep.c
diff -u /dev/null gdb/gdb/pa-nbsd-tdep.c:1.1
--- /dev/null   Thu Nov 14 11:59:57 2002
+++ gdb/gdb/pa-nbsd-tdep.c      Mon May 13 18:16:06 2002
@@ -0,0 +1,739 @@
+/* Functions specific to gdb targetted to HPPA running NetBSD.
+   Copyright 2000, 2001 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "value.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "tm.h"
+#include "elf/common.h"
+
+static CORE_ADDR
+pa_read_pc (int pid)
+{
+  return (CORE_ADDR) read_register_pid (PA_PCOQ_HEAD_REGNUM, pid) & ~3;
+}
+
+static void
+pa_write_pc (CORE_ADDR pc, int pid)
+{
+  write_register_pid (PA_PCOQ_HEAD_REGNUM, pc, pid);
+  write_register_pid (PA_PCOQ_TAIL_REGNUM, pc + 4, pid);
+}
+
+static CORE_ADDR
+pa_read_fp (void)
+{
+  return read_register (PA_GR3_REGNUM);
+}
+
+static void
+pa_write_fp (CORE_ADDR val)
+{
+  write_register (PA_GR3_REGNUM, val);
+}
+
+static CORE_ADDR
+pa_read_sp (void)
+{
+  return read_register (PA_GR30_REGNUM);
+}
+
+static void
+pa_write_sp (CORE_ADDR val)
+{
+  write_register (PA_GR30_REGNUM, val);
+}
+
+/* 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.  */
+
+static void
+pa_push_dummy_frame (void)
+{
+  CORE_ADDR sp, pc, pcspace;
+  register int regnum;
+  char reg_buffer[8];
+  LONGEST int_buffer;
+  int reg_size = REGISTER_SIZE;
+
+  pc = TARGET_READ_PC (inferior_pid);
+  pcspace = read_register (PA_PCSQ_HEAD_REGNUM);
+
+  /* Space for "arguments"; the RP goes in here. */
+  sp = read_register (PA_GR30_REGNUM) + 48;
+  read_register_gen (PA_GR2_REGNUM, reg_buffer);
+
+  /* The 32bit and 64bit ABIs save the return pointer into different
+     stack slots.  */
+  if (reg_size == 8)
+    write_memory (sp - 16, reg_buffer, 8);
+  else
+    write_memory (sp - 20, reg_buffer, 4);
+
+  int_buffer = TARGET_READ_FP ();
+  write_register (PA_GR3_REGNUM, sp);
+
+  sp = push_word (sp, int_buffer);
+  sp += reg_size;
+
+  for (regnum = PA_GR1_REGNUM; regnum <= PA_GR31_REGNUM; regnum++)
+    if (regnum != PA_GR2_REGNUM && regnum != PA_GR3_REGNUM)
+      {
+       read_register_gen (regnum, reg_buffer);
+       sp = push_bytes (sp, reg_buffer, reg_size);
+      }
+
+  /* This is not necessary for the 64bit ABI.  In fact it is dangerous.  */
+  if (reg_size != 8)
+    sp += reg_size;
+
+  for (regnum = PA_FR0_REGNUM; regnum < NUM_REGS; regnum++)
+    {
+      read_register_gen (regnum, reg_buffer);
+      sp = push_bytes (sp, reg_buffer, 4);
+    }
+  read_register_gen (PA_IPSW_REGNUM, reg_buffer);
+  sp = push_bytes (sp, reg_buffer, reg_size);
+  read_register_gen (PA_SAR_REGNUM, reg_buffer);
+  sp = push_bytes (sp, reg_buffer, reg_size);
+  sp = push_word (sp, pc);
+  sp = push_word (sp, pcspace);
+  sp = push_word (sp, pc + 4);
+  sp = push_word (sp, pcspace);
+  write_register (PA_GR30_REGNUM, sp);
+}
+
+/* Called to determine if PC is in an interrupt handler of some
+   kind.  */
+static int
+pa_nbsd_in_interrupt_handler (CORE_ADDR pc)
+{
+  /* gdb won't get control in a kernel ISR, so no need to worry here.  */
+  return 0;
+}
+
+static CORE_ADDR
+pa_nbsd_frame_saved_pc_in_interrupt (const struct frame_info *frame)
+{
+  return 0;
+}
+
+static CORE_ADDR
+pa_hpux_frame_base_before_interrupt (const struct frame_info *frame)
+{
+  /* return r30 from the interrupt save state.  */
+  return 0;
+}
+
+static void
+pa_nbsd_frame_find_saved_regs_in_interrupt (struct frame_info *frame,
+                                            CORE_ADDR *saved_regs)
+{
+}
+
+#define        NBSD_GATEWAY_ADDR       0xC0000000
+#define END_NBSD_GATEWAY_ADDR  (NBSD_GATEWAY_ADDR + 4096)
+
+/* Called to determine if the register state indicates we are in
+   a syscall.  */
+static int
+pa_nbsd_in_syscall (const CORE_ADDR *saved_regs)
+{
+  int flags;
+  CORE_ADDR pc;
+
+  if (saved_regs && saved_regs[PA_IPSW_REGNUM])
+    flags = read_memory_integer (saved_regs[PA_IPSW_REGNUM],
+                                REGISTER_SIZE);
+  else
+    flags = read_register (PA_IPSW_REGNUM);
+
+  if ((flags & PSW_C) == 0)
+    return 1;
+
+  if (saved_regs && saved_regs[PA_PCOQ_HEAD_REGNUM])
+    pc = read_memory_integer (saved_regs[PA_PCOQ_HEAD_REGNUM],
+                             REGISTER_SIZE);
+  else
+    pc = read_register (PA_PCOQ_HEAD_REGNUM);
+  pc &= ~3;
+
+  if (pc >= NBSD_GATEWAY_ADDR && pc < END_NBSD_GATEWAY_ADDR)
+    return 1;
+
+  return 0;
+}
+
+/* XXX fredette */
+#if 1
+int
+pa_nbsd_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+  return 0;
+}
+static CORE_ADDR
+pa_nbsd_frame_saved_pc_in_sigtramp (const struct frame_info *frame)
+{
+       abort();
+}
+
+static CORE_ADDR
+pa_nbsd_frame_base_before_sigtramp (struct frame_info *frame)
+{
+       abort();
+}
+
+static void
+pa_nbsd_frame_find_saved_regs_in_sigtramp (struct frame_info *frame,
+                                           CORE_ADDR *saved_regs)
+{
+       abort();
+}
+#else  /* 0 XXX fredette */
+
+static const struct stub_struc pa_linux_sigtramp[] =
+  {
+    { 0x34190000, 0xfffffffd, 0 },     /* ldi  x,%r25 ; x=!!in_syscall   */
+    { 0x3414015a, 0xffffffff, 4 },     /* ldi  __NR_rt_sigreturn,%r20    */
+    { 0xe4008200, 0xffffffff, 8 },     /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
+    { 0x08000240, 0xffffffff, 12},     /* nop */
+
+    { (unsigned) -1, 0, -999 }         /* sentinel */
+  };
+
+int
+pa_linux_in_sigtramp (CORE_ADDR pc, const char *name)
+{
+  if (is_pa_stub (pc, pa_linux_sigtramp, NULL))
+    return 1;
+
+  if (pc >= LINUX_GATEWAY_ADDR && pc < END_LINUX_GATEWAY_ADDR
+      && read_register (PA_GR20_REGNUM) == 0xad) /* __NR_rt_sigreturn */
+    return 1;
+
+  return 0;
+}
+
+/* Where to find the start of the register save area in a signal frame.  */
+#define PA_LINUX_SIGCONTEXT(REGSIZE) \
+ (((4 * 4      /* tramp */                             \
+    + 128      /* struct siginfo */                    \
+    + ((2      /* struct ucontext.uc_flags,uc_link */  \
+        + 3)   /* struct ucontext.uc_stack */          \
+       * (REGSIZE))) + 7) & -8)
+
+#define PA_LINUX_SIGCONTEXT_GR(REGSIZE) \
+  (PA_LINUX_SIGCONTEXT (REGSIZE) + (REGSIZE))
+
+#define PA_LINUX_SIGCONTEXT_FR(REGSIZE) \
+  ((PA_LINUX_SIGCONTEXT_GR (REGSIZE) + 32 * (REGSIZE) + 7) & -8)
+
+#define PA_LINUX_SIGCONTEXT_PCSQ(REGSIZE) \
+  (PA_LINUX_SIGCONTEXT_FR(REGSIZE) + 32 * 8)
+
+#define PA_LINUX_SIGCONTEXT_PCOQ(REGSIZE) \
+  (PA_LINUX_SIGCONTEXT_PCSQ(REGSIZE) + 2 * (REGSIZE))
+
+#define PA_LINUX_SIGCONTEXT_SAR(REGSIZE) \
+  (PA_LINUX_SIGCONTEXT_PCOQ(REGSIZE) + 2 * (REGSIZE))
+
+static CORE_ADDR
+pa_linux_frame_saved_pc_in_sigtramp (const struct frame_info *frame)
+{
+  int regsize = REGISTER_SIZE;
+  CORE_ADDR addr;
+
+  /* read pcoqh in sigcontext structure */
+  addr = frame->frame + PA_LINUX_SIGCONTEXT_PCOQ (regsize);
+  return read_memory_integer (addr, regsize) & ~3;
+}
+
+static CORE_ADDR
+pa_linux_frame_base_before_sigtramp (struct frame_info *frame)
+{
+  CORE_ADDR start_pc;
+
+  if (is_pa_stub (frame->pc, pa_linux_sigtramp, &start_pc))
+    {
+      /* Fudge alert: fix up frame->frame here as pa_frame_chain gets
+        it wrong.  The problem being that linux doesn't set r3 on
+        entry to signal handlers, and find_proc_framesize returns -1
+        for the signal handler trampoline as there is no unwind info.
+        It would be possible to make a special find_proc_framesize.
+        For now, this seems to work.  */
+      frame->frame = start_pc;
+
+#if 0
+      {
+       CORE_ADDR addr;
+       int regsize = REGISTER_SIZE;
+
+       /* read r30 in sigcontext structure */
+       addr = start_pc + PA_LINUX_SIGCONTEXT_GR (regsize) + 30 * regsize;
+       return read_memory_integer (addr, regsize);
+      }
+#else
+      /* We may as well just return the start pc, as it's the same as
+        our saved r30 anyway.  */
+      return start_pc;
+#endif
+    }
+  return 0;
+}
+
+static void
+pa_linux_frame_find_saved_regs_in_sigtramp (struct frame_info *frame,
+                                           CORE_ADDR *saved_regs)
+{
+  int i;
+  int regsize = REGISTER_SIZE;
+  CORE_ADDR addr;
+
+  addr = frame->frame + PA_LINUX_SIGCONTEXT_GR (regsize);
+
+  for (i = PA_GR0_REGNUM; i <= PA_GR31_REGNUM; i++)
+    {
+      if (i == PA_GR30_REGNUM)
+       saved_regs[i] = read_memory_integer (addr, regsize);
+      else
+       saved_regs[i] = addr;
+      addr += regsize;
+    }
+  addr = (addr + 7) & -8;
+  for (i = PA_FR0_REGNUM; i < NUM_REGS; i++)
+    {
+      saved_regs[i] = addr;
+      addr += 4;
+    }
+  saved_regs[PA_PCSQ_HEAD_REGNUM] = addr; addr += regsize;
+  saved_regs[PA_PCSQ_TAIL_REGNUM] = addr; addr += regsize;
+  saved_regs[PA_PCOQ_HEAD_REGNUM] = addr; addr += regsize;
+  saved_regs[PA_PCOQ_TAIL_REGNUM] = addr; addr += regsize;
+  saved_regs[PA_SAR_REGNUM] = addr;
+}
+
+#endif /* 0 XXX fredette */
+
+/* Attempt to find (and return) the global pointer for the given file.
+
+   This code searchs for the .dynamic section in OBJFILE.  Once it finds
+   the addresses at which the .dynamic section lives in the child process,
+   it scans the Elf64_Dyn or Elf32_Dyn entries for a DT_PLTGOT tag.  If it
+   finds one of these, the corresponding d_un.d_ptr value is the global
+   pointer.  */
+
+static CORE_ADDR
+generic_elf_find_global_pointer (struct objfile *objfile)
+{
+  struct obj_section *osect;
+
+  ALL_OBJFILE_OSECTIONS (objfile, osect)
+    if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0)
+      {
+       CORE_ADDR addr;
+       int dtag_size = REGISTER_SIZE;
+
+       addr = osect->addr;
+       while (addr < osect->endaddr)
+         {
+           int status;
+           LONGEST tag;
+           char buf[8];
+
+           status = target_read_memory (addr, buf, dtag_size);
+           if (status != 0)
+             break;
+           tag = extract_signed_integer (buf, dtag_size);
+
+           if (tag == DT_PLTGOT)
+             {
+               CORE_ADDR global_pointer;
+
+               status = target_read_memory (addr + dtag_size, buf, dtag_size);
+               if (status != 0)
+                 break;
+
+               global_pointer = extract_address (buf, dtag_size);
+
+               /* The payoff... */
+               return global_pointer;
+             }
+
+           if (tag == DT_NULL)
+             break;
+
+           addr += 2 * dtag_size;
+         }
+       break;
+      }
+  return 0;
+}
+
+/* XXX fredette */
+#if 0
+
+/* This the pa-linux64 call dummy
+
+   Call stack frame has already been built by gdb. Since we could be
+   calling a varargs function, and we do not have the benefit of a stub to
+   put things in the right place, we load the first 8 word of arguments
+   into both the general and fp registers.
+
+   fldd -64(0,%r29),%fr4
+   fldd -56(0,%r29),%fr5
+   fldd -48(0,%r29),%fr6
+   fldd -40(0,%r29),%fr7
+   fldd -32(0,%r29),%fr8
+   fldd -24(0,%r29),%fr9
+   fldd -16(0,%r29),%fr10
+   fldd -8(0,%r29),%fr11
+   ldd -64(%r29), %r26
+   ldd -56(%r29), %r25
+   ldd -48(%r29), %r24
+   ldd -40(%r29), %r23
+   ldd -32(%r29), %r22
+   ldd -24(%r29), %r21
+   ldd -16(%r29), %r20
+   bve,l (%r1),%r2
+   ldd -8(%r29), %r19
+   mtsp %r21, %sr0             ; Code used when popping frame
+   ble 0(%sr0, %r22)
+   nop
+*/
+
+/* Call dummys are sized and written out in word sized hunks.  So we have
+   to pack the instructions into words.  */
+
+static const LONGEST pa_linux64_dummy[] =
+  {
+    0x53a43f8353a53f93LL, 0x53a63fa353a73fb3LL,
+    0x53a83fc353a93fd3LL, 0x2fa1100a2fb1100bLL,
+    0x53ba3f8153b93f91LL, 0x53b83fa153b73fb1LL,
+    0x53b63fc153b53fd1LL, 0x0fa110d4e820f000LL,
+    0x0fb110d300151820LL, 0xe6c0000008000240LL
+  };
+
+/* Insert the specified number of args and function address
+   into a dummy call sequence, DUMMY, stored at PC.  */
+
+static CORE_ADDR
+pa64_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+                    value_ptr *args, struct type *type, int gcc_p)
+{
+  CORE_ADDR pcoqh, pcoqt;
+  struct target_waitstatus w;
+  char buf[8];
+  int status;
+  struct objfile *objfile;
+  static const char stub[8] =
+  {
+    0xe8, 0x20, 0xd0, 0x00,    /* BVE (r1) */
+    0x08, 0x00, 0x02, 0x40     /* NOP */
+  };
+
+  /* We can not modify the instruction address queues directly, so we start
+     up the inferior and execute a couple of instructions to set them so
+     that they point to the call dummy in the stack.  */
+  pcoqh = read_register (PA_PCOQ_HEAD_REGNUM);
+  pcoqt = read_register (PA_PCOQ_TAIL_REGNUM);
+
+  if (target_read_memory (pcoqh, buf, 4) != 0)
+    error ("Couldn't modify instruction address queue\n");
+
+  if (target_read_memory (pcoqt, buf + 4, 4) != 0)
+    error ("Couldn't modify instruction address queue\n");
+
+  if (target_write_memory (pcoqh, stub, 4) != 0)
+    error ("Couldn't modify instruction address queue\n");
+
+  if (target_write_memory (pcoqt, stub + 4, 4) != 0)
+    {
+      target_write_memory (pcoqh, buf, 4);
+      error ("Couldn't modify instruction address queue\n");
+    }
+
+  write_register (PA_GR1_REGNUM, pc);
+
+  /* Single step twice, the BVE instruction will set the instruction
+     address queue such that it points to the PC value written immediately
+     above (ie the call dummy).  */
+  resume (1, 0);
+  target_wait (inferior_pid, &w);
+  resume (1, 0);
+  target_wait (inferior_pid, &w);
+
+  /* Restore the two instructions at the old PC locations.  */
+  target_write_memory (pcoqh, buf, 4);
+  target_write_memory (pcoqt, buf + 4, 4);
+
+  /* The call dummy wants the ultimate destination address in
+     register %r1.  */
+  write_register (PA_GR1_REGNUM, 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.  */
+
+      if (obj_private->dp == 0)
+       {
+         obj_private->dp = generic_elf_find_global_pointer (objfile);
+         if (obj_private->dp == 0)
+           obj_private->dp = -1;
+       }
+      if (obj_private->dp != -1)
+       write_register (PA_GR27_REGNUM, obj_private->dp);
+      break;
+    }
+  return pc;
+}
+
+#endif /* 0 XXX fredette */
+
+/* This is the pa-nbsd32 call dummy.  The function address is in r22.
+
+   Call stack frame has already been built by gdb. Since we could be
+   calling a varargs function, and we do not have the benefit of a stub to
+   put things in the right place, we load the first 4 word of arguments
+   into both the general and fp registers.
+
+   ldo -36(%sp), %r1
+   ldw -36(%sp), %arg0
+   ldw -40(%sp), %arg1
+   ldw -44(%sp), %arg2
+   ldw -48(%sp), %arg3
+   fldws 0(%r1), %fr4
+   fldds -4(%r1), %fr5
+   fldws -8(%r1), %fr6
+   fldds -12(%r1), %fr7
+   ble 0(%sr3, %r22)
+   copy %r31, %r2
+   mtsp %r21, %sr0     ; Code used when popping a dummy frame.
+   ble,n 0(%sr0, %r22)
+   nop  */
+
+static const LONGEST pa_nbsd32_dummy[] =
+  {
+    0x37c13fb9, 0x4bda3fb9, 0x4bd93fb1, 0x4bd83fa9,
+    0x4bd73fa1, 0x24201004, 0x2c391005, 0x24311006,
+    0x2c291007, 0xe6c0c000, 0x081f0242, 0x00151820,
+    0xe6c00002, 0x08000240
+  };
+
+/* Insert the specified number of args and function address
+   into a dummy call sequence, DUMMY, stored at PC.  */
+
+static CORE_ADDR
+pa_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs,
+                    value_ptr *args, struct type *type, int gcc_p)
+{
+  CORE_ADDR pcoqh, pcoqt;
+  struct target_waitstatus w;
+  char buf[8];
+  int status;
+  struct objfile *objfile;
+  static const char stub[8] =
+  {
+    0xe4, 0x20, 0xc0, 0x00,    /* ble 0(%sr3,%r1)) */
+    0x08, 0x00, 0x02, 0x40     /* nop */
+  };
+
+  /* We can not modify the instruction address queues directly, so we start
+     up the inferior and execute a couple of instructions to set them so
+     that they point to the call dummy in the stack.  */
+  pcoqh = read_register (PA_PCOQ_HEAD_REGNUM);
+  pcoqt = read_register (PA_PCOQ_TAIL_REGNUM);
+
+  if (target_read_memory (pcoqh, buf, 4) != 0)
+    error ("Couldn't modify instruction address queue\n");
+
+  if (target_read_memory (pcoqt, buf + 4, 4) != 0)
+    error ("Couldn't modify instruction address queue\n");
+
+  if (target_write_memory (pcoqh, stub, 4) != 0)
+    error ("Couldn't modify instruction address queue\n");
+
+  if (target_write_memory (pcoqt, stub + 4, 4) != 0)
+    {
+      target_write_memory (pcoqh, buf, 4);
+      error ("Couldn't modify instruction address queue\n");
+    }
+
+  write_register (PA_GR1_REGNUM, pc);
+
+  /* Single step twice, the BLE instruction will set the instruction
+     address queue such that it points to the PC value written immediately
+     above (ie the call dummy).  */
+  resume (1, 0);
+  target_wait (inferior_pid, &w);
+  resume (1, 0);
+  target_wait (inferior_pid, &w);
+
+  /* Restore the two instructions at the old PC locations.  */
+  target_write_memory (pcoqh, buf, 4);
+  target_write_memory (pcoqt, buf + 4, 4);
+
+  /* The call dummy wants the ultimate destination address in
+     register %r22.  */
+  if (fun & 2)
+    {
+      /* It's a plabel.  */
+      int gp;
+
+      fun &= ~3;
+      gp = read_memory_integer (fun + 4, 4);
+      write_register (PA_GR19_REGNUM, gp);
+      fun = read_memory_integer (fun, 4);
+      write_register (PA_GR22_REGNUM, fun);
+    }
+  else
+    {
+      write_register (PA_GR22_REGNUM, 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.  */
+
+         if (obj_private->dp == 0)
+           {
+             obj_private->dp = generic_elf_find_global_pointer (objfile);
+             if (obj_private->dp == 0)
+               obj_private->dp = -1;
+           }
+         if (obj_private->dp != -1)
+           write_register (PA_GR19_REGNUM, obj_private->dp);
+         break;
+       }
+    }
+  return pc;
+}
+
+#ifdef PA_XM_NBSD_H
+/* For native compiles, check that our defines match the kernel.  */
+#include <asm/ucontext.h>
+#include <asm/rt_sigframe.h>
+#endif
+
+void
+pa_nbsd_initialize_tdep (struct gdbarch *gdbarch, int is_elf64)
+{
+/* XXX fredette */
+#if 0
+#ifdef PA_XM_NBSD_H
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((char *) &((TYPE *)0)->MEMBER - (char *)0)
+#endif
+  if (offsetof (struct rt_sigframe, uc.uc_mcontext)
+      != PA_LINUX_SIGCONTEXT (sizeof (unsigned long))
+      || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_gr)
+         != PA_LINUX_SIGCONTEXT_GR (sizeof (unsigned long)))
+      || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_fr)
+         != PA_LINUX_SIGCONTEXT_FR (sizeof (unsigned long)))
+      || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_iasq)
+         != PA_LINUX_SIGCONTEXT_PCSQ (sizeof (unsigned long)))
+      || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_iaoq)
+         != PA_LINUX_SIGCONTEXT_PCOQ (sizeof (unsigned long)))
+      || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_sar)
+         != PA_LINUX_SIGCONTEXT_SAR (sizeof (unsigned long))))
+    internal_error (__FILE__, __LINE__,
+                   "kernel struct rt_sigframe has changed");
+#endif
+#endif /* 0 XXX fredette */
+
+  set_gdbarch_read_pc (gdbarch, pa_read_pc);
+  set_gdbarch_write_pc (gdbarch, pa_write_pc);
+  set_gdbarch_read_fp (gdbarch, pa_read_fp);
+  set_gdbarch_write_fp (gdbarch, pa_write_fp);
+  set_gdbarch_read_sp (gdbarch, pa_read_sp);
+  set_gdbarch_write_sp (gdbarch, pa_write_sp);
+  set_gdbarch_push_dummy_frame (gdbarch, pa_push_dummy_frame);
+
+  gdbarch_tdep (gdbarch)->in_interrupt_handler = pa_nbsd_in_interrupt_handler;
+  gdbarch_tdep (gdbarch)->frame_saved_pc_in_interrupt
+    = pa_nbsd_frame_saved_pc_in_interrupt;
+  gdbarch_tdep (gdbarch)->in_syscall = pa_nbsd_in_syscall;
+  gdbarch_tdep (gdbarch)->in_sigtramp = pa_nbsd_in_sigtramp;
+  gdbarch_tdep (gdbarch)->frame_saved_pc_in_sigtramp
+    = pa_nbsd_frame_saved_pc_in_sigtramp;
+  gdbarch_tdep (gdbarch)->frame_base_before_sigtramp
+    = pa_nbsd_frame_base_before_sigtramp;
+  gdbarch_tdep (gdbarch)->frame_find_saved_regs_in_sigtramp
+    = pa_nbsd_frame_find_saved_regs_in_sigtramp;
+
+  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
+  /* call_dummy_address only needed for AT_ENTRY_POINT call dummies.  */
+  set_gdbarch_call_dummy_start_offset (gdbarch, 0);
+  set_gdbarch_call_dummy_breakpoint_offset (gdbarch, is_elf64 ? 0x44 : 0x2c);
+  set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
+  set_gdbarch_call_dummy_length (gdbarch, is_elf64 ? 0x50 : 0x38);
+  set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack);
+  set_gdbarch_call_dummy_p (gdbarch, 1);
+  set_gdbarch_call_dummy_words (gdbarch, (is_elf64
+                                         ? NULL
+                                         : pa_nbsd32_dummy));
+  set_gdbarch_sizeof_call_dummy_words (gdbarch, (is_elf64
+                                                ? 0
+                                                : sizeof (pa_nbsd32_dummy)));
+  /* call_dummy_stack_adjust unused.  */
+  set_gdbarch_call_dummy_stack_adjust_p  (gdbarch, 0);
+  set_gdbarch_fix_call_dummy (gdbarch, (is_elf64
+                                       ? NULL
+                                       : pa_fix_call_dummy));
+}
+
Index: gdb/gdb/pa-tdep.c
diff -u gdb/gdb/pa-tdep.c:1.1.1.1 gdb/gdb/pa-tdep.c:1.2
--- gdb/gdb/pa-tdep.c:1.1.1.1   Sun May 12 12:55:56 2002
+++ gdb/gdb/pa-tdep.c   Mon May 13 18:13:55 2002
@@ -765,8 +765,15 @@
      if (pc_in_linker_call_stub (pc))
       /* This is the so-called RP'.  */
       return -24;
-      else
+      else {
+       if (DEBUG_PA_FRAME)
+         printf("  no unwind and not call stub\n");
+#ifdef PA_NBSD_TARGET
+       return -20;
+#else
       return 0;
+#endif
+      }
    }

  if (u->Save_RP)
@@ -780,6 +787,8 @@
    case PARAMETER_RELOCATION:
      return -8;
    }
+  if (DEBUG_PA_FRAME)
+    printf("  unknown unwind stub type\n");
  return 0;
}

@@ -3308,7 +3317,7 @@
static unsigned char *
pa_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
-  static unsigned char breakpoint[4] = {0x00, 0x01, 0x00, 0x04};
+  static unsigned char breakpoint[4] = {0x00, 0x01, 0x00, 0x00};
  *lenptr = sizeof (breakpoint);
  return breakpoint;
}
@@ -3597,7 +3606,7 @@
#if 0
  if (os_ident == ELFOSABI_LINUX)
#endif
-    pa_linux_initialize_tdep (gdbarch, is_elf64);
+    pa_nbsd_initialize_tdep (gdbarch, is_elf64);
#if 0
  /* Disable hpux support as som stuff only compiles native.  Sheesh.  */
  else
Index: gdb/gdb/solib-svr4.c
diff -u gdb/gdb/solib-svr4.c:1.1.1.1 gdb/gdb/solib-svr4.c:1.2
--- gdb/gdb/solib-svr4.c:1.1.1.1        Sun May 12 12:55:56 2002
+++ gdb/gdb/solib-svr4.c        Mon May 13 18:14:30 2002
@@ -36,6 +36,7 @@
#include <a.out.h>
#else
#include "elf/external.h"
+#include "elf/common.h"
#endif

#ifdef HAVE_LINK_H
Index: gdb/gdb/config/pa/nbsd.mt
diff -u /dev/null gdb/gdb/config/pa/nbsd.mt:1.1
--- /dev/null   Thu Nov 14 12:00:01 2002
+++ gdb/gdb/config/pa/nbsd.mt   Mon May 13 18:16:11 2002
@@ -0,0 +1,3 @@
+# Target: HP PA-RISC running NetBSD
+TDEPFILES= pa-tdep.o pa-nbsd-tdep.o solib.o solib-svr4.o
+TM_FILE= tm-nbsd.h
Index: gdb/gdb/config/pa/tm-hppa.h
diff -u gdb/gdb/config/pa/tm-hppa.h:1.1.1.1 gdb/gdb/config/pa/tm-hppa.h:1.2
--- gdb/gdb/config/pa/tm-hppa.h:1.1.1.1 Sun May 12 12:55:59 2002
+++ gdb/gdb/config/pa/tm-hppa.h Mon May 13 18:15:11 2002
@@ -111,8 +111,8 @@

/* Sequence of bytes for breakpoint instruction.  */

-#define BREAKPOINT {0x00, 0x01, 0x00, 0x04}
-#define BREAKPOINT32 0x10004
+#define BREAKPOINT {0x00, 0x01, 0x00, 0x00}
+#define BREAKPOINT32 0x10000

/* Amount PC must be decremented by after a breakpoint.
   This is often the number of bytes in BREAKPOINT
Index: gdb/gdb/config/pa/tm-nbsd.h
diff -u /dev/null gdb/gdb/config/pa/tm-nbsd.h:1.1
--- /dev/null   Thu Nov 14 12:00:01 2002
+++ gdb/gdb/config/pa/tm-nbsd.h Mon May 13 18:16:11 2002
@@ -0,0 +1,37 @@
+/* Definitions to target GDB to NetBSD on HPPA.
+   Copyright 2000, 2001 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef PA_TM_NBSD_H
+#define PA_TM_NBSD_H
+
+#define SVR4_SHARED_LIBS
+
+#include "tm-nbsd.h"
+#include "pa/tm-pa.h"
+#include "pa/tm-pa32.h"
+
+/* XXX fredette - this used to define PA_LINUX_TARGET, used in
+   the linux gdbserver support. */
+#define PA_NBSD_TARGET
+
+struct gdbarch;
+void pa_nbsd_initialize_tdep (struct gdbarch *, int);
+
+#endif