From 1b883d351364d8b9e00021462e06d5dba0d61460 Mon Sep 17 00:00:00 2001 From: Kris Warkentin Date: Mon, 5 May 2003 13:57:21 +0000 Subject: [PATCH] Added i386 QNX Neutrino support. --- gdb/config/i386/nto.mt | 4 + gdb/config/i386/tm-nto.h | 33 ++++ gdb/config/tm-nto.h | 61 +++++++ gdb/configure.tgt | 4 + gdb/i386-nto-tdep.c | 298 ++++++++++++++++++++++++++++++++++ gdb/nto-tdep.c | 341 +++++++++++++++++++++++++++++++++++++++ gdb/nto-tdep.h | 157 ++++++++++++++++++ 7 files changed, 898 insertions(+) create mode 100644 gdb/config/i386/nto.mt create mode 100644 gdb/config/i386/tm-nto.h create mode 100644 gdb/config/tm-nto.h create mode 100644 gdb/i386-nto-tdep.c create mode 100644 gdb/nto-tdep.c create mode 100644 gdb/nto-tdep.h diff --git a/gdb/config/i386/nto.mt b/gdb/config/i386/nto.mt new file mode 100644 index 0000000000..6655f3eee7 --- /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 0000000000..ff5eb7837e --- /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 0000000000..359ff068b7 --- /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 aeb9e2718e..fe4cc5d485 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 0000000000..42eb9cefa6 --- /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 0000000000..abf63b9129 --- /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 +#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 +#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 *) ®set, core_reg_sect, + min (core_reg_size, sizeof (regset))); + nto_supply_gregset ((char *) ®set); + } + else if (which == NTO_REG_FLOAT) + { + memcpy ((char *) ®set, core_reg_sect, + min (core_reg_size, sizeof (regset))); + nto_supply_fpregset ((char *) ®set); + } + else if (which == NTO_REG_ALT) + { + memcpy ((char *) ®set, core_reg_sect, + min (core_reg_size, sizeof (regset))); + nto_supply_altregset ((char *) ®set); + } +} + +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 (®set_core_fns); +} diff --git a/gdb/nto-tdep.h b/gdb/nto-tdep.h new file mode 100644 index 0000000000..ac6f6280cb --- /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 (-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 -- 2.34.1