aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/config/i386/nto.mt4
-rw-r--r--gdb/config/i386/tm-nto.h33
-rw-r--r--gdb/config/tm-nto.h61
-rw-r--r--gdb/configure.tgt4
-rw-r--r--gdb/i386-nto-tdep.c298
-rw-r--r--gdb/nto-tdep.c341
-rw-r--r--gdb/nto-tdep.h157
7 files changed, 898 insertions, 0 deletions
diff --git a/gdb/config/i386/nto.mt b/gdb/config/i386/nto.mt
new file mode 100644
index 0000000..6655f3e
--- /dev/null
+++ b/gdb/config/i386/nto.mt
@@ -0,0 +1,4 @@
+# Target: Intel 386 running qnx6.
+TDEPFILES = i386-tdep.o i387-tdep.o corelow.o solib.o solib-svr4.o \
+ i386-nto-tdep.o nto-tdep.o remote-nto.o
+TM_FILE = tm-nto.h
diff --git a/gdb/config/i386/tm-nto.h b/gdb/config/i386/tm-nto.h
new file mode 100644
index 0000000..ff5eb78
--- /dev/null
+++ b/gdb/config/i386/tm-nto.h
@@ -0,0 +1,33 @@
+/* QNX Neutrino target header.
+
+ Copyright 2003 Free Software Foundation, Inc.
+
+ This code was donated by QNX Software Systems Ltd.
+
+ 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 TM_NTO_H
+#define TM_NTO_H 1
+
+/* Pick up most of what we need from the generic i386 target include file. */
+#include "i386/tm-i386.h"
+#include "tm-nto.h"
+
+#include "solib.h"
+
+#endif /* TM_NTO_H */
diff --git a/gdb/config/tm-nto.h b/gdb/config/tm-nto.h
new file mode 100644
index 0000000..359ff06
--- /dev/null
+++ b/gdb/config/tm-nto.h
@@ -0,0 +1,61 @@
+/* Target machine sub-description for QNX Neutrino version 6.
+ This is included by other tm-*.h files to specify nto specific
+ stuff.
+
+ Copyright 2003 Free Software Foundation, Inc.
+
+ This code was donated by QNX Software Systems Ltd.
+
+ 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 _TM_QNXNTO_H
+#define _TM_QNXNTO_H
+
+#include "tm-sysv4.h"
+
+/* Setup the valid realtime signal range. */
+#define REALTIME_LO 41
+#define REALTIME_HI 56
+
+/* Set up the undefined useable signals. */
+#define RAW_SIGNAL_LO 32
+#define RAW_SIGNAL_HI (REALTIME_LO - 1)
+
+#define TARGET_SIGNAL_RAW_VALUES \
+TARGET_SIGNAL_RAW0, \
+TARGET_SIGNAL_RAW1, \
+TARGET_SIGNAL_RAW2, \
+TARGET_SIGNAL_RAW3, \
+TARGET_SIGNAL_RAW4, \
+TARGET_SIGNAL_RAW5, \
+TARGET_SIGNAL_RAW6, \
+TARGET_SIGNAL_RAW7, \
+TARGET_SIGNAL_RAW8
+
+#define TARGET_SIGNAL_RAW_TABLE \
+{"SIGNAL32", "Signal 32"}, \
+{"SIGNAL33", "Signal 33"}, \
+{"SIGNAL34", "Signal 34"}, \
+{"SIGNAL35", "Signal 35"}, \
+{"SIGNAL36", "Signal 36"}, \
+{"SIGNAL37", "Signal 37"}, \
+{"SIGNAL38", "Signal 38"}, \
+{"SIGNAL39", "Signal 39"}, \
+{"SIGNAL40", "Signal 40"}
+
+#endif /* _TM_QNXNTO_H */
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index aeb9e271..fe4cc5d 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -51,6 +51,7 @@ arm*-*-linux*) gdb_target=linux
;;
arm*-*-netbsd*) gdb_target=nbsd
gdb_multi_arch=yes ;;
+arm-*-nto*) gdb_target=nto ;;
arm*-*-* | thumb*-*-* | strongarm*-*-*)
gdb_target=embed
configdirs="$configdirs rdi-share"
@@ -90,6 +91,7 @@ i[3456]86-*-netbsd*) gdb_target=nbsd ;;
i[3456]86-*-openbsd*) gdb_target=obsd ;;
i[3456]86-*-go32*) gdb_target=i386aout ;;
i[3456]86-*-msdosdjgpp*) gdb_target=go32 ;;
+i[3456]86-*-nto*) gdb_target=nto ;;
i[3456]86-*-lynxos*) gdb_target=i386lynx ;;
i[3456]86-*-solaris*) gdb_target=i386sol2 ;;
i[3456]86-*-sco*) gdb_target=i386v ;;
@@ -216,6 +218,7 @@ sh-*-linux*) gdb_target=linux
build_gdbserver=yes
;;
sh*-*-netbsdelf*) gdb_target=nbsd ;;
+sh-*-nto*) gdb_target=nto ;;
sh*) gdb_target=embed ;;
sparc-*-aout*) gdb_target=sparc-em ;;
@@ -280,5 +283,6 @@ esac
case "${target}" in
*-*-linux*) gdb_osabi=GDB_OSABI_LINUX ;;
*-*-gnu*) gdb_osabi=GDB_OSABI_HURD ;;
+*-*-nto*) gdb_osabi=GDB_OSABI_QNXNTO ;;
*-*-solaris*) gdb_osabi=GDB_OSABI_SOLARIS ;;
esac
diff --git a/gdb/i386-nto-tdep.c b/gdb/i386-nto-tdep.c
new file mode 100644
index 0000000..42eb9ce
--- /dev/null
+++ b/gdb/i386-nto-tdep.c
@@ -0,0 +1,298 @@
+/* i386-nto-tdep.c - i386 specific functionality for QNX Neutrino.
+
+ Copyright 2003 Free Software Foundation, Inc.
+
+ Contributed by QNX Software Systems Ltd.
+
+ 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 "gdb_string.h"
+#include "gdb_assert.h"
+#include "defs.h"
+#include "frame.h"
+#include "target.h"
+#include "regcache.h"
+#include "solib-svr4.h"
+#include "i386-tdep.h"
+#include "nto-tdep.h"
+#include "osabi.h"
+#include "i387-tdep.h"
+
+#ifndef X86_CPU_FXSR
+#define X86_CPU_FXSR (1L << 12)
+#endif
+
+/* Why 13? Look in our /usr/include/x86/context.h header at the
+ x86_cpu_registers structure and you'll see an 'exx' junk register
+ that is just filler. Don't ask me, ask the kernel guys. */
+#define NUM_GPREGS 13
+
+/* Map a GDB register number to an offset in the reg structure. */
+static int regmap[] = {
+ (7 * 4), /* eax */
+ (6 * 4), /* ecx */
+ (5 * 4), /* edx */
+ (4 * 4), /* ebx */
+ (11 * 4), /* esp */
+ (2 * 4), /* epb */
+ (1 * 4), /* esi */
+ (0 * 4), /* edi */
+ (8 * 4), /* eip */
+ (10 * 4), /* eflags */
+ (9 * 4), /* cs */
+ (12 * 4), /* ss */
+ (-1 * 4) /* filler */
+};
+
+/* Given a gdb regno, return the offset into Neutrino's register structure
+ or -1 if register is unknown. */
+static int
+nto_reg_offset (int regno)
+{
+ return (regno >= 0 && regno < NUM_GPREGS) ? regmap[regno] : -1;
+}
+
+static void
+i386nto_supply_gregset (char *gpregs)
+{
+ unsigned regno;
+ int empty = 0;
+
+ for (regno = 0; regno < FP0_REGNUM; regno++)
+ {
+ int offset = nto_reg_offset (regno);
+ if (offset == -1)
+ supply_register (regno, (char *) &empty);
+ else
+ supply_register (regno, gpregs + offset);
+ }
+}
+
+static void
+i386nto_supply_fpregset (char *fpregs)
+{
+ if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
+ i387_supply_fxsave (fpregs);
+ else
+ i387_supply_fsave (fpregs);
+}
+
+static void
+i386nto_supply_regset (int regset, char *data)
+{
+ switch (regset)
+ {
+ case NTO_REG_GENERAL: /* QNX has different ordering of GP regs than GDB. */
+ i386nto_supply_gregset (data);
+ break;
+ case NTO_REG_FLOAT:
+ i386nto_supply_fpregset (data);
+ break;
+ }
+}
+
+static int
+i386nto_regset_id (int regno)
+{
+ if (regno == -1)
+ return NTO_REG_END;
+ else if (regno < FP0_REGNUM)
+ return NTO_REG_GENERAL;
+ else if (regno < FPC_REGNUM)
+ return NTO_REG_FLOAT;
+
+ return -1; /* Error. */
+}
+
+static int
+i386nto_register_area (int regno, int regset, unsigned *off)
+{
+ int len;
+
+ *off = 0;
+ if (regset == NTO_REG_GENERAL)
+ {
+ if (regno == -1)
+ return NUM_GPREGS * 4;
+
+ *off = nto_reg_offset (regno);
+ if (*off == -1)
+ return 0;
+ return 4;
+ }
+ else if (regset == NTO_REG_FLOAT)
+ {
+ unsigned off_adjust, regsize, regset_size;
+
+ if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
+ {
+ off_adjust = 32;
+ regsize = 16;
+ regset_size = 512;
+ }
+ else
+ {
+ off_adjust = 28;
+ regsize = 10;
+ regset_size = 128;
+ }
+
+ if (regno == -1)
+ return regset_size;
+
+ *off = (regno - FP0_REGNUM) * regsize + off_adjust;
+ return 10;
+ /* Why 10 instead of regsize? GDB only stores 10 bytes per FP
+ register so if we're sending a register back to the target,
+ we only want pdebug to write 10 bytes so as not to clobber
+ the reserved 6 bytes in the fxsave structure. */
+ }
+ return -1;
+}
+
+static int
+i386nto_regset_fill (int regset, char *data)
+{
+ if (regset == NTO_REG_GENERAL)
+ {
+ int regno;
+
+ for (regno = 0; regno < NUM_GPREGS; regno++)
+ {
+ int offset = nto_reg_offset (regno);
+ if (offset != -1)
+ regcache_collect (regno, data + offset);
+ }
+ }
+ else if (regset == NTO_REG_FLOAT)
+ {
+ if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
+ i387_fill_fxsave (data, -1);
+ else
+ i387_fill_fsave (data, -1);
+ }
+ else
+ return -1;
+
+ return 0;
+}
+
+static struct link_map_offsets *
+i386nto_svr4_fetch_link_map_offsets (void)
+{
+ static struct link_map_offsets lmo;
+ static struct link_map_offsets *lmp = NULL;
+
+ if (lmp == NULL)
+ {
+ lmp = &lmo;
+
+ lmo.r_debug_size = 8; /* The actual size is 20 bytes, but
+ only 8 bytes are used. */
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 4;
+
+ lmo.link_map_size = 20; /* The actual size is 552 bytes, but
+ only 20 bytes are used. */
+ lmo.l_addr_offset = 0;
+ lmo.l_addr_size = 4;
+
+ lmo.l_name_offset = 4;
+ lmo.l_name_size = 4;
+
+ lmo.l_next_offset = 12;
+ lmo.l_next_size = 4;
+
+ lmo.l_prev_offset = 16;
+ lmo.l_prev_size = 4;
+ }
+
+ return lmp;
+}
+
+static int
+i386nto_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+ return name && strcmp ("__signalstub", name) == 0;
+}
+
+#define SIGCONTEXT_OFFSET 136
+static CORE_ADDR
+i386nto_sigcontext_addr (struct frame_info *frame)
+{
+ if (get_next_frame (frame))
+ return get_frame_base (get_next_frame (frame)) + SIGCONTEXT_OFFSET;
+
+ return read_register (SP_REGNUM) + SIGCONTEXT_OFFSET;
+}
+
+static void
+init_i386nto_ops ()
+{
+ current_nto_target.nto_regset_id = i386nto_regset_id;
+ current_nto_target.nto_supply_gregset = i386nto_supply_gregset;
+ current_nto_target.nto_supply_fpregset = i386nto_supply_fpregset;
+ current_nto_target.nto_supply_altregset = nto_dummy_supply_regset;
+ current_nto_target.nto_supply_regset = i386nto_supply_regset;
+ current_nto_target.nto_register_area = i386nto_register_area;
+ current_nto_target.nto_regset_fill = i386nto_regset_fill;
+ current_nto_target.nto_fetch_link_map_offsets =
+ i386nto_svr4_fetch_link_map_offsets;
+}
+
+static void
+i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* NTO uses ELF. */
+ i386_elf_init_abi (info, gdbarch);
+
+ /* Neutrino rewinds to look more normal. */
+ set_gdbarch_decr_pc_after_break (gdbarch, 0);
+
+ /* NTO has shared libraries. */
+ set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
+ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
+
+ set_gdbarch_pc_in_sigtramp (gdbarch, i386nto_pc_in_sigtramp);
+ tdep->sigcontext_addr = i386nto_sigcontext_addr;
+ tdep->sc_pc_offset = 56;
+ tdep->sc_sp_offset = 68;
+
+ /* Setjmp()'s return PC saved in EDX (5). */
+ tdep->jb_pc_offset = 20; /* 5x32 bit ints in. */
+
+ set_solib_svr4_fetch_link_map_offsets (gdbarch,
+ i386nto_svr4_fetch_link_map_offsets);
+
+ /* Our loader handles solib relocations slightly differently than svr4. */
+ TARGET_SO_RELOCATE_SECTION_ADDRESSES = nto_relocate_section_addresses;
+
+ /* Supply a nice function to find our solibs. */
+ TARGET_SO_FIND_AND_OPEN_SOLIB = nto_find_and_open_solib;
+
+ init_i386nto_ops ();
+}
+
+void
+_initialize_i386nto_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO,
+ i386nto_init_abi);
+}
diff --git a/gdb/nto-tdep.c b/gdb/nto-tdep.c
new file mode 100644
index 0000000..abf63b9
--- /dev/null
+++ b/gdb/nto-tdep.c
@@ -0,0 +1,341 @@
+/* nto-tdep.c - general QNX Neutrino target functionality.
+
+ Copyright 2003 Free Software Foundation, Inc.
+
+ Contributed by QNX Software Systems Ltd.
+
+ 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 <sys/stat.h>
+#include "gdb_string.h"
+#include "nto-tdep.h"
+#include "top.h"
+#include "cli/cli-decode.h"
+#include "cli/cli-cmds.h"
+#include "inferior.h"
+#include "gdbarch.h"
+#include "bfd.h"
+#include "elf-bfd.h"
+#include "solib-svr4.h"
+#include "gdbcore.h"
+
+#ifdef __CYGWIN__
+#include <sys/cygwin.h>
+#endif
+
+#ifdef __CYGWIN__
+static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6";
+#elif defined(__sun__) || defined(linux)
+static char default_nto_target[] = "/opt/QNXsdk/target/qnx6";
+#else
+static char default_nto_target[] = "";
+#endif
+
+struct nto_target_ops current_nto_target;
+
+static char *
+nto_target (void)
+{
+ char *p = getenv ("QNX_TARGET");
+
+#ifdef __CYGWIN__
+ static char buf[PATH_MAX];
+ if (p)
+ cygwin_conv_to_posix_path (p, buf);
+ else
+ cygwin_conv_to_posix_path (default_nto_target, buf);
+ return buf;
+#else
+ return p ? p : default_nto_target;
+#endif
+}
+
+/* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86,
+ CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */
+int
+nto_map_arch_to_cputype (const char *arch)
+{
+ if (!strcmp (arch, "i386") || !strcmp (arch, "x86"))
+ return CPUTYPE_X86;
+ if (!strcmp (arch, "rs6000") || !strcmp (arch, "ppc"))
+ return CPUTYPE_PPC;
+ if (!strcmp (arch, "mips"))
+ return CPUTYPE_MIPS;
+ if (!strcmp (arch, "arm"))
+ return CPUTYPE_ARM;
+ if (!strcmp (arch, "sh"))
+ return CPUTYPE_SH;
+ return CPUTYPE_UNKNOWN;
+}
+
+int
+nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
+{
+ char *buf, arch_path[PATH_MAX], *nto_root, *endian;
+ const char *arch;
+ char *path_fmt = "%s/lib:%s/usr/lib:%s/usr/photon/lib\
+:%s/usr/photon/dll:%s/lib/dll";
+
+ nto_root = nto_target ();
+ if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") == 0)
+ {
+ arch = "x86";
+ endian = "";
+ }
+ else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") == 0)
+ {
+ arch = "ppc";
+ endian = "be";
+ }
+ else
+ {
+ arch = TARGET_ARCHITECTURE->arch_name;
+ endian = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "be" : "le";
+ }
+
+ sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
+
+ buf = alloca (strlen (path_fmt) + strlen (arch_path) * 5 + 1);
+ sprintf (buf, path_fmt, arch_path, arch_path, arch_path, arch_path,
+ arch_path);
+
+ return openp (buf, 1, solib, o_flags, 0, temp_pathname);
+}
+
+void
+nto_init_solib_absolute_prefix (void)
+{
+ char buf[PATH_MAX * 2], arch_path[PATH_MAX];
+ char *nto_root, *endian;
+ const char *arch;
+
+ nto_root = nto_target ();
+ if (strcmp (TARGET_ARCHITECTURE->arch_name, "i386") == 0)
+ {
+ arch = "x86";
+ endian = "";
+ }
+ else if (strcmp (TARGET_ARCHITECTURE->arch_name, "rs6000") == 0)
+ {
+ arch = "ppc";
+ endian = "be";
+ }
+ else
+ {
+ arch = TARGET_ARCHITECTURE->arch_name;
+ endian = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? "be" : "le";
+ }
+
+ sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
+
+ sprintf (buf, "set solib-absolute-prefix %s", arch_path);
+ execute_command (buf, 0);
+}
+
+char **
+nto_parse_redirection (char *pargv[], char **pin, char **pout, char **perr)
+{
+ char **argv;
+ char *in, *out, *err, *p;
+ int argc, i, n;
+
+ for (n = 0; pargv[n]; n++);
+ if (n == 0)
+ return NULL;
+ in = "";
+ out = "";
+ err = "";
+
+ argv = xcalloc (n + 1, sizeof argv[0]);
+ argc = n;
+ for (i = 0, n = 0; n < argc; n++)
+ {
+ p = pargv[n];
+ if (*p == '>')
+ {
+ p++;
+ if (*p)
+ out = p;
+ else
+ out = pargv[++n];
+ }
+ else if (*p == '<')
+ {
+ p++;
+ if (*p)
+ in = p;
+ else
+ in = pargv[++n];
+ }
+ else if (*p++ == '2' && *p++ == '>')
+ {
+ if (*p == '&' && *(p + 1) == '1')
+ err = out;
+ else if (*p)
+ err = p;
+ else
+ err = pargv[++n];
+ }
+ else
+ argv[i++] = pargv[n];
+ }
+ *pin = in;
+ *pout = out;
+ *perr = err;
+ return argv;
+}
+
+/* The struct lm_info, LM_ADDR, and nto_truncate_ptr are copied from
+ solib-svr4.c to support nto_relocate_section_addresses
+ which is different from the svr4 version. */
+
+struct lm_info
+{
+ /* Pointer to copy of link map from inferior. The type is char *
+ rather than void *, so that we may use byte offsets to find the
+ various fields without the need for a cast. */
+ char *lm;
+};
+
+static CORE_ADDR
+LM_ADDR (struct so_list *so)
+{
+ struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
+
+ return (CORE_ADDR) extract_signed_integer (so->lm_info->lm +
+ lmo->l_addr_offset,
+ lmo->l_addr_size);
+}
+
+static CORE_ADDR
+nto_truncate_ptr (CORE_ADDR addr)
+{
+ if (TARGET_PTR_BIT == sizeof (CORE_ADDR) * 8)
+ /* We don't need to truncate anything, and the bit twiddling below
+ will fail due to overflow problems. */
+ return addr;
+ else
+ return addr & (((CORE_ADDR) 1 << TARGET_PTR_BIT) - 1);
+}
+
+Elf_Internal_Phdr *
+find_load_phdr (bfd *abfd)
+{
+ Elf_Internal_Phdr *phdr;
+ unsigned int i;
+
+ if (!elf_tdata (abfd))
+ return NULL;
+
+ phdr = elf_tdata (abfd)->phdr;
+ for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
+ {
+ if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X))
+ return phdr;
+ }
+ return NULL;
+}
+
+void
+nto_relocate_section_addresses (struct so_list *so, struct section_table *sec)
+{
+ /* Neutrino treats the l_addr base address field in link.h as different than
+ the base address in the System V ABI and so the offset needs to be
+ calculated and applied to relocations. */
+ Elf_Internal_Phdr *phdr = find_load_phdr (sec->bfd);
+ unsigned vaddr = phdr ? phdr->p_vaddr : 0;
+
+ sec->addr = nto_truncate_ptr (sec->addr + LM_ADDR (so) - vaddr);
+ sec->endaddr = nto_truncate_ptr (sec->endaddr + LM_ADDR (so) - vaddr);
+}
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+{
+ nto_regset_t regset;
+
+ nto_init_solib_absolute_prefix ();
+
+ if (which == NTO_REG_GENERAL)
+ {
+ memcpy ((char *) &regset, core_reg_sect,
+ min (core_reg_size, sizeof (regset)));
+ nto_supply_gregset ((char *) &regset);
+ }
+ else if (which == NTO_REG_FLOAT)
+ {
+ memcpy ((char *) &regset, core_reg_sect,
+ min (core_reg_size, sizeof (regset)));
+ nto_supply_fpregset ((char *) &regset);
+ }
+ else if (which == NTO_REG_ALT)
+ {
+ memcpy ((char *) &regset, core_reg_sect,
+ min (core_reg_size, sizeof (regset)));
+ nto_supply_altregset ((char *) &regset);
+ }
+}
+
+void
+nto_dummy_supply_regset (char *regs)
+{
+ /* Do nothing. */
+}
+
+/* Register that we are able to handle ELF file formats using standard
+ procfs "regset" structures. */
+static struct core_fns regset_core_fns = {
+ bfd_target_elf_flavour, /* core_flavour */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_nto_tdep ()
+{
+ add_show_from_set (add_set_cmd ("nto-debug", class_maintenance, var_zinteger, (char *) &nto_internal_debugging, "Set QNX NTO internal debugging.\n\
+When non-zero, nto specific debug info is\n\
+displayed. Different information is displayed\n\
+for different positive values.", &setdebuglist),
+ &showdebuglist);
+
+ /* We use SIG45 for pulses, or something, so nostop, noprint
+ and pass them. */
+ signal_stop_update (target_signal_from_name ("SIG45"), 0);
+ signal_print_update (target_signal_from_name ("SIG45"), 0);
+ signal_pass_update (target_signal_from_name ("SIG45"), 1);
+
+ /* By default we don't want to stop on these two, but we do want to pass. */
+#if defined(SIGSELECT)
+ signal_stop_update (SIGSELECT, 0);
+ signal_print_update (SIGSELECT, 0);
+ signal_pass_update (SIGSELECT, 1);
+#endif
+
+#if defined(SIGPHOTON)
+ signal_stop_update (SIGPHOTON, 0);
+ signal_print_update (SIGPHOTON, 0);
+ signal_pass_update (SIGPHOTON, 1);
+#endif
+
+ /* Register core file support. */
+ add_core_fns (&regset_core_fns);
+}
diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h
new file mode 100644
index 0000000..ac6f628
--- /dev/null
+++ b/gdb/nto-tdep.h
@@ -0,0 +1,157 @@
+/* nto-tdep.h - QNX Neutrino target header.
+
+ Copyright 2003 Free Software Foundation, Inc.
+
+ Contributed by QNX Software Systems Ltd.
+
+ 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 _NTO_TDEP_H
+#define _NTO_TDEP_H
+
+#include "defs.h"
+#include "solist.h"
+
+/* Generic functions in nto-tdep.c. */
+
+extern void nto_init_solib_absolute_prefix PARAMS ((void));
+
+char **nto_parse_redirection
+PARAMS ((char *start_argv[], char **in, char **out, char **err));
+
+int proc_iterate_over_mappings PARAMS ((int (*func) (int, CORE_ADDR)));
+
+void nto_relocate_section_addresses
+PARAMS ((struct so_list *, struct section_table *));
+
+int nto_map_arch_to_cputype PARAMS ((const char *));
+
+int nto_find_and_open_solib PARAMS ((char *, unsigned, char **));
+
+/* Dummy function for initializing nto_target_ops on targets which do
+ not define a particular regset. */
+void nto_dummy_supply_regset PARAMS ((char *regs));
+
+/* Target operations defined for Neutrino targets (<target>-nto-tdep.c). */
+
+struct nto_target_ops
+{
+ int nto_internal_debugging;
+ unsigned nto_cpuinfo_flags;
+ int nto_cpuinfo_valid;
+
+ int (*nto_regset_id) (int);
+ void (*nto_supply_gregset) (char *);
+ void (*nto_supply_fpregset) (char *);
+ void (*nto_supply_altregset) (char *);
+ void (*nto_supply_regset) (int, char *);
+ int (*nto_register_area) (int, int, unsigned *);
+ int (*nto_regset_fill) (int, char *);
+ struct link_map_offsets *(*nto_fetch_link_map_offsets) (void);
+};
+
+extern struct nto_target_ops current_nto_target;
+
+/* For 'maintenance debug nto-debug' command. */
+#define nto_internal_debugging \
+ (current_nto_target.nto_internal_debugging)
+
+/* The CPUINFO flags from the remote. Currently used by
+ i386 for fxsave but future proofing other hosts.
+ This is initialized in procfs_attach or nto_start_remote
+ depending on our host/target. It would only be invalid
+ if we were talking to an older pdebug which didn't support
+ the cpuinfo message. */
+#define nto_cpuinfo_flags \
+ (current_nto_target.nto_cpuinfo_flags)
+
+/* True if successfully retrieved cpuinfo from remote. */
+#define nto_cpuinfo_valid \
+ (current_nto_target.nto_cpuinfo_valid)
+
+/* Given a register, return an id that represents the Neutrino
+ regset it came from. If reg == -1 update all regsets. */
+#define nto_regset_id(reg) \
+ (*current_nto_target.nto_regset_id) (reg)
+
+#define nto_supply_gregset(regs) \
+ (*current_nto_target.nto_supply_gregset) (regs)
+
+#define nto_supply_fpregset(regs) \
+ (*current_nto_target.nto_supply_fpregset) (regs)
+
+#define nto_supply_altregset(regs) \
+ (*current_nto_target.nto_supply_altregset) (regs)
+
+/* Given a regset, tell gdb about registers stored in data. */
+#define nto_supply_regset(regset, data) \
+ (*current_nto_target.nto_supply_regset) (regset, data)
+
+/* Given a register and regset, calculate the offset into the regset
+ and stuff it into the last argument. If regno is -1, calculate the
+ size of the entire regset. Returns length of data, -1 if unknown
+ regset, 0 if unknown register. */
+#define nto_register_area(reg, regset, off) \
+ (*current_nto_target.nto_register_area) (reg, regset, off)
+
+/* Build the Neutrino register set info into the data buffer.
+ Return -1 if unknown regset, 0 otherwise. */
+#define nto_regset_fill(regset, data) \
+ (*current_nto_target.nto_regset_fill) (regset, data)
+
+/* Gives the fetch_link_map_offsets function exposure outside of
+ solib-svr4.c so that we can override relocate_section_addresses(). */
+#define nto_fetch_link_map_offsets() \
+ (*current_nto_target.nto_fetch_link_map_offsets) ()
+
+/* Keep this consistant with neutrino syspage.h. */
+enum
+{
+ CPUTYPE_X86,
+ CPUTYPE_PPC,
+ CPUTYPE_MIPS,
+ CPUTYPE_SPARE,
+ CPUTYPE_ARM,
+ CPUTYPE_SH,
+ CPUTYPE_UNKNOWN
+};
+
+enum
+{
+ OSTYPE_QNX4,
+ OSTYPE_NTO
+};
+
+/* These correspond to the DSMSG_* versions in dsmsgs.h. */
+enum
+{
+ NTO_REG_GENERAL,
+ NTO_REG_FLOAT,
+ NTO_REG_SYSTEM,
+ NTO_REG_ALT,
+ NTO_REG_END
+};
+
+typedef char qnx_reg64[8];
+
+typedef struct _debug_regs
+{
+ qnx_reg64 padding[1024];
+} nto_regset_t;
+
+#endif