Added i386 QNX Neutrino support.

This commit is contained in:
Kris Warkentin 2003-05-05 13:57:21 +00:00
parent 4bc6e03a51
commit 1b883d3513
7 changed files with 898 additions and 0 deletions

4
gdb/config/i386/nto.mt Normal file
View File

@ -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

33
gdb/config/i386/tm-nto.h Normal file
View File

@ -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 */

61
gdb/config/tm-nto.h Normal file
View File

@ -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 */

View File

@ -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

298
gdb/i386-nto-tdep.c Normal file
View File

@ -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);
}

341
gdb/nto-tdep.c Normal file
View File

@ -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);
}

157
gdb/nto-tdep.h Normal file
View File

@ -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