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