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
