[patch] i386-nto (QNX Neutrino) support

Kris Warkentin
2003-04-23T18:48:21Z

[-- Attachment #1: Type: text/plain, Size: 938 bytes --]

In the interest of expediency, I removed the non-i386 things from debug.h
which I believe eliminates the portability issues. These can be re-examined
later when I'm doing the mips/powerpc ports.

Most of this stuff has been gone over by Mark Kettenis fairly extensively (I
ran indent again Mark) and I hope that the debug.h issue was the last of
them. I've attached a diff of the config files as well as all the
individual files. I also included a tarball that can be extracted in the
gdb directory.

Thanks

Kris

ChangeLog

* configure.tgt: Add i386nto target
* i386-nto-tdep.c: New file. i386 specific support for QNX Neutrino.
* nto-tdep.c: New file. Neutrino target support routines.
* nto-tdep.h: New file. Neutrino target header.
* config/tm-qnxnto.h: New file.
* config/i386/i386nto.mt: New file.
* config/i386/tm-i386nto.h: New file.
* nto-share/debug.h: New file. Neutrino procfs interface.

[-- Attachment #2: config.diff --]
[-- Type: application/octet-stream, Size: 291 bytes --]

Index: configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.102
diff -r1.102 configure.tgt
92a93
> i[3456]86-*-nto*) gdb_target=i386nto;;
282a285
> *-*-nto*) gdb_osabi=GDB_OSABI_QNXNTO ;;

[-- Attachment #3: nto.tgz --]
[-- Type: application/x-compressed, Size: 9677 bytes --]

[-- Attachment #4: i386-nto-tdep.c --]
[-- Type: application/octet-stream, Size: 9571 bytes --]

/* 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 "nto-share/debug.h"
#include "i387-tdep.h"

#ifndef X86_CPU_FXSR
#define X86_CPU_FXSR (1L << 12)
#endif

enum QNX_REGS
{
QNX_REGS_GP = 0,
QNX_REGS_FP = 1,
QNX_REGS_END = 2
};

/* Why 13? Look in our debug.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 */
};

/* Perform mapping of gdb registers onto Neutrino registers.
Actually works in reverse too which is why we make sure to
return -1 if we're out of range. */
int
gdb_to_os (int regno)
{
return (regno >= 0 && regno < NUM_GPREGS) ? regmap[regno] >> 2 : -1;
}

void
nto_supply_gregset (char *gpregs)
{
unsigned regno;

for (regno = 0; regno < NUM_GPREGS - 1; regno++)
{
supply_register (regno, gpregs + regmap[regno]);
}
}

int
nto_get_regset_id (int regno)
{
if (regno == -1)
return QNX_REGS_END;
else if (regno < FP0_REGNUM)
return QNX_REGS_GP;
else if (regno < FPC_REGNUM)
return QNX_REGS_FP;

return -1; /* Error. */
}

void
nto_cpu_supply_regset (int endian, int regset, void *data)
{
endian = endian; /* For i386, we don't care about endian. */

switch (regset)
{
case QNX_REGS_GP: /* QNX has different ordering of GP regs than GDB. */
nto_supply_gregset (data);
break;
case QNX_REGS_FP:
nto_supply_fpregset (data);
break;
}
}

unsigned
nto_get_regset_area (unsigned regset, char *subcmd)
{
unsigned length = 0;
switch (regset)
{
case QNX_REGS_GP:
*subcmd = NTO_REG_GENERAL;
length = NUM_GPREGS * sizeof (unsigned);
break;
case QNX_REGS_FP:
*subcmd = NTO_REG_FLOAT;
/* FIXME: Should we calculate based on fxsave/fsave? */
length = 512;
break;
default:
length = 0;
}
return length;
}

unsigned
nto_cpu_register_area (unsigned first_regno, unsigned last_regno,
unsigned char *subcmd, unsigned *off, unsigned *len)
{
int regno = -1;

if (first_regno < FP0_REGNUM)
{
if (last_regno >= FP0_REGNUM)
last_regno = FP0_REGNUM - 1;
*subcmd = NTO_REG_GENERAL;
regno = gdb_to_os (first_regno);
*off = regno * sizeof (unsigned);
if (regno == -1)
*len = 0;
else
*len = (last_regno - first_regno + 1) * sizeof (unsigned);
}
else if (first_regno == FP_REGNUM)
{
/* Frame Pointer Psuedo-register. */
*off = SP_REGNUM * sizeof (unsigned);
*len = sizeof (unsigned);
return FP_REGNUM;
}
else if (first_regno >= FP0_REGNUM && first_regno < FPC_REGNUM)
{
unsigned off_adjust, regsize;

if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
{
off_adjust = 32;
regsize = 16;
}
else
{
off_adjust = 28;
regsize = 10;
}

if (last_regno >= FPC_REGNUM)
last_regno = FPC_REGNUM - 1;
*subcmd = NTO_REG_FLOAT;
*off = (first_regno - FP0_REGNUM) * regsize + off_adjust;
*len = (last_regno - first_regno + 1) * 10;
/* Why 10? 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. The astute reader will note that this will fail if we
try to send a range of fpregs rather than 1 at a time but, as far
as I know, there is no way to send more than one fpreg at a time
anyway. If this turns out to be wrong, we may need to put more code
in pdebug to deal with this - perhaps by masking off part of the
register when it writes it in. Put assertion to this effect so
that we'll catch it here rather than get mysterious failures. */
gdb_assert (last_regno == first_regno);
}
else
{
*len = 0;
return last_regno;
}
return last_regno;
}

int
nto_cpu_register_store (int endian, unsigned first_regno,
unsigned last_regno, void *data)
{
/* Mostly (always?) you're only storing one at a time. */
if (first_regno == last_regno)
{
regcache_collect (first_regno, data);
return 1;
}
/* Floating point is the same for gdb and target. */
if (first_regno >= FP0_REGNUM)
{
for (; first_regno <= last_regno; first_regno++)
{
regcache_collect (first_regno, data);
(char *) data += REGISTER_RAW_SIZE (first_regno);
}
return 1;
}
/* GP registers are mapped differently for NTO than GDB. */
for (; first_regno <= last_regno; first_regno++)
{
int regnum = gdb_to_os (first_regno);
if (regnum == -1)
continue;
regcache_collect (first_regno,
(char *) data + sizeof (unsigned) * regnum);
}
return 1;
}

void
nto_supply_fpregset (char *fpregs)
{
if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
i387_supply_fxsave (fpregs);
else
i387_supply_fsave (fpregs);
}

/* Fetch (and possibly build) an appropriate link_map_offsets
structure for native x86 targets using the struct offsets
defined in link.h (but without actual reference to that file).

This makes it possible to access x86 shared libraries from a GDB
that was not built on an x86 host (for cross debugging). */
static struct link_map_offsets *
i386_nto_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;
}

struct link_map_offsets *
nto_fetch_link_map_offsets (void)
{
return i386_nto_svr4_fetch_link_map_offsets ();
}

static int
i386_nto_pc_in_sigtramp (CORE_ADDR pc, char *name)
{
return name && strcmp ("__signalstub", name) == 0;
}

#define SIGCONTEXT_OFFSET 136
static CORE_ADDR
i386_nto_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
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, i386_nto_pc_in_sigtramp);
tdep->sigcontext_addr = i386_nto_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,
i386_nto_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;
}

void
_initialize_i386nto_tdep (void)
{
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO,
i386nto_init_abi);
}

[-- Attachment #5: nto-tdep.h --]
[-- Type: application/octet-stream, Size: 3412 bytes --]

/* 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 "nto-share/debug.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_source_extra_gdbinit PARAMS ((char *));

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 **));

/* Functions exported from all Neutrino targets (<target>-nto-tdep.c). */

/* Given a register, return an id that represents the Neutrino
regset it came from. If reg == -1 update all regsets. */
int nto_get_regset_id PARAMS ((int regno));

/* Tell gdb about registers stored in data, based on regset. */
void nto_cpu_supply_regset PARAMS ((int endian, int regset, void *data));

/* Get regset characteristics. Returns the length of the regset,
or 0 if regset is unknown. */
unsigned nto_get_regset_area PARAMS ((unsigned regset, char *subcmd));

/* Given the first and last register number, figure out the size/len
of the Neutrino register save area to ask for/tell about. Also set
the register set that's being dealt with in *subcmd. Watch out for
the range crossing a register set boundry. */
unsigned nto_cpu_register_area
PARAMS ((unsigned first_regno, unsigned last_regno, unsigned char *subcmd,
unsigned *off, unsigned *len));

/* Build the Neutrino register set info into the 'data' buffer. */
int nto_cpu_register_store
PARAMS ((int endian, unsigned first_regno, unsigned last_regno, void *data));

void nto_supply_gregset PARAMS ((char *regs));

void nto_supply_fpregset PARAMS ((char *regs));

/* Gives the fetch_link_map_offsets function exposure outside of
solib-svr4.c so that we can override relocate_section_addresses(). */
struct link_map_offsets *nto_fetch_link_map_offsets PARAMS ((void));

/* Globals. */

/* For 'maintenance debug nto-debug' command. */
extern int nto_internal_debugging;

/* The CPUINFO flags from the remote. Currently used by
i386 for fxsave but future proofing other hosts. */
extern unsigned nto_cpuinfo_flags;

/* True if successfully retrieved cpuinfo from remote. */
extern int nto_cpuinfo_valid;

#endif

[-- Attachment #6: nto-tdep.c --]
[-- Type: application/octet-stream, Size: 9637 bytes --]

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

/* Maintenance debugging flag. */
int nto_internal_debugging;

/* Filled in cpu info structure and flag to indicate its validity.
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. */
unsigned nto_cpuinfo_flags;
int nto_cpuinfo_valid;

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

void
nto_source_extra_gdbinit (char *file)
{
char *homedir, *homeinit;
struct stat statbuf;

homedir = getenv ("HOME");

if (homedir && !inhibit_gdbinit)
{
homeinit = (char *) alloca (strlen (homedir) + strlen (file) + 10);
sprintf (homeinit, "%s/%s", homedir, file);
if (stat (homeinit, &statbuf) == 0)
catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);
}
}

/* 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_gregset_t gregset;
nto_fpregset_t fpregset;

nto_init_solib_absolute_prefix ();

if (which == 0)
{
memcpy ((char *) &gregset, core_reg_sect,
min (core_reg_size, sizeof (gregset)));
nto_supply_gregset ((char *) &gregset);
}
else if (which == 2)
{
memcpy ((char *) &fpregset, core_reg_sect,
min (core_reg_size, sizeof (fpregset)));
nto_supply_fpregset ((char *) &fpregset);
}
}

/* 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);
}

[-- Attachment #7: debug.h --]
[-- Type: application/octet-stream, Size: 7717 bytes --]

/* QNX Neutrino debug interface.

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 _DEBUG_H
#define _DEBUG_H

/* __DEBUG_H_INCLUDED is Neutrino's native debug.h header. We don't want
these duplicate definitions if we're compiling natively and have already
included it. */
#ifndef __DEBUG_H_INCLUDED
#define __DEBUG_H_INCLUDED

#define QNX_NOTE_NAME "QNX"

typedef char qnx_reg64[8];

enum Elf_nto_note_types
{
QNT_NULL = 0,
QNT_DEBUG_FULLPATH,
QNT_DEBUG_RELOC,
QNT_STACK,
QNT_GENERATOR,
QNT_DEFAULT_LIB,
QNT_CORE_SYSINFO,
QNT_CORE_INFO,
QNT_CORE_STATUS,
QNT_CORE_GREG,
QNT_CORE_FPREG,
QNT_NUM
};

typedef struct
{
long bits[2];
} nto_sigset_t;

union nto_sigval
{
int sival_int;
void *sival_ptr;
};

typedef struct nto_siginfo
{
int si_signo;
int si_code;
void (*si_handler) ();
union
{
int _pad[6];
struct
{
pid_t _pid;
union
{
struct
{
union nto_sigval _value;
uid_t _uid;
} _kill;
struct
{
int _status;
clock_t _utime;
clock_t _stime;
} _chld;
} _pdata;
} _proc;
struct
{
int _fltno;
void *_addr;
void *_fltip;
} _fault;
} _data;
} nto_siginfo_t;

typedef struct x86_cpu_registers
{
#ifdef __SEGMENTS__
unsigned gs, fs;
unsigned es, ds;
#endif
unsigned edi, esi, ebp, exx, ebx, edx, ecx, eax;
unsigned eip, cs, efl;
unsigned esp, ss;
} X86_CPU_REGISTERS;

typedef struct fsave_area
{
unsigned fpu_control_word;
unsigned fpu_status_word;
unsigned fpu_tag_word;
unsigned fpu_ip;
unsigned fpu_cs;
unsigned fpu_op;
unsigned fpu_ds;
unsigned char st_regs[80]; /* Each register is 10 bytes. */
} X86_FSAVE_REGISTERS;

typedef struct fxsave_area
{
unsigned short fpu_control_word;
unsigned short fpu_status_word;
unsigned short fpu_tag_word;
unsigned short fpu_operand;
unsigned fpu_ip;
unsigned fpu_cs;
unsigned fpu_op;
unsigned fpu_ds;
unsigned mxcsr;
unsigned reserved;
unsigned char st_regs[128];
unsigned char xmm_regs[128];
unsigned char reserved2[224];
} X86_FXSAVE_REGISTERS;

typedef union x86_fpu_registers
{
X86_FSAVE_REGISTERS fsave_area;
X86_FXSAVE_REGISTERS fxsave_area;
unsigned char data[512]; /* Needs to be this big for the emulator. */
} X86_FPU_REGISTERS;

#ifdef __QNX__
__BEGIN_DECLS
#include <_pack64.h>
#endif
#define _DEBUG_FLAG_STOPPED 0x00000001 /* Thread is not running. */
#define DEBUG_FLAG_ISTOP 0x00000002 /* Stopped at point of interest. */
#define _DEBUG_FLAG_IPINVAL 0x00000010 /* IP is not valid. */
#define _DEBUG_FLAG_ISSYS 0x00000020 /* System process. */
#define _DEBUG_FLAG_SSTEP 0x00000040 /* Stopped because of single step. */
#define _DEBUG_FLAG_CURTID 0x00000080 /* Thread is current thread. */
#define DEBUG_FLAG_TRACE_EXEC 0x00000100 /* Stopped because of breakpoint. */
#define _DEBUG_FLAG_TRACE_RD 0x00000200 /* Stopped because of read access. */
#define _DEBUG_FLAG_TRACE_WR 0x00000400 /* Stopped because of write access. */
#define _DEBUG_FLAG_TRACE_MODIFY 0x00000800 /* Stopped because of modified memory. */
#define _DEBUG_FLAG_RLC 0x00010000 /* Run-on-Last-Close flag is set. */
#define _DEBUG_FLAG_KLC 0x00020000 /* Kill-on-Last-Close flag is set. */
#define _DEBUG_FLAG_FORK 0x00040000 /* Child inherits flags (Stop on fork/spawn). */
#define _DEBUG_FLAG_MASK 0x000f0000 /* Flags that can be changed. */
enum
{
_DEBUG_WHY_REQUESTED,
_DEBUG_WHY_SIGNALLED,
_DEBUG_WHY_FAULTED,
_DEBUG_WHY_JOBCONTROL,
_DEBUG_WHY_TERMINATED,
_DEBUG_WHY_CHILD,
_DEBUG_WHY_EXEC
};

#define _DEBUG_RUN_CLRSIG 0x00000001 /* Clear pending signal */
#define _DEBUG_RUN_CLRFLT 0x00000002 /* Clear pending fault */
#define DEBUG_RUN_TRACE 0x00000004 /* Trace mask flags interesting signals */
#define DEBUG_RUN_HOLD 0x00000008 /* Hold mask flags interesting signals */
#define DEBUG_RUN_FAULT 0x00000010 /* Fault mask flags interesting faults */
#define _DEBUG_RUN_VADDR 0x00000020 /* Change ip before running */
#define _DEBUG_RUN_STEP 0x00000040 /* Single step only one thread */
#define _DEBUG_RUN_STEP_ALL 0x00000080 /* Single step one thread, other threads run */
#define _DEBUG_RUN_CURTID 0x00000100 /* Change current thread (target thread) */
#define DEBUG_RUN_ARM 0x00000200 /* Deliver event at point of interest */

typedef struct _debug_process_info
{
pid_t pid;
pid_t parent;
unsigned flags;
unsigned umask;
pid_t child;
pid_t sibling;
pid_t pgrp;
pid_t sid;
int base_address;
int initial_stack;
uid_t uid;
gid_t gid;
uid_t euid;
gid_t egid;
uid_t suid;
gid_t sgid;
nto_sigset_t sig_ignore;
nto_sigset_t sig_queue;
nto_sigset_t sig_pending;
unsigned num_chancons;
unsigned num_fdcons;
unsigned num_threads;
unsigned num_timers;
qnx_reg64 reserved[20];
} nto_procfs_info;

typedef struct _debug_thread_info
{
pid_t pid;
unsigned tid;
unsigned flags;
unsigned short why;
unsigned short what;
int ip;
int sp;
int stkbase;
int tls;
unsigned stksize;
unsigned tid_flags;
unsigned char priority;
unsigned char real_priority;
unsigned char policy;
unsigned char state;
short syscall;
unsigned short last_cpu;
unsigned timeout;
int last_chid;
nto_sigset_t sig_blocked;
nto_sigset_t sig_pending;
nto_siginfo_t info;
unsigned reserved1;
union
{
struct
{
unsigned tid;
} join;
struct
{
int id;
int sync;
} sync;
struct
{
unsigned nid;
pid_t pid;
int coid;
int chid;
int scoid;
} connect;
struct
{
int chid;
} channel;
struct
{
pid_t pid;
int vaddr;
unsigned flags;
} waitpage;
struct
{
unsigned size;
} stack;
qnx_reg64 filler[4];
} blocked;
qnx_reg64 reserved2[8];
} nto_procfs_status;

typedef union _debug_gregs
{
X86_CPU_REGISTERS x86;
qnx_reg64 padding[1024];
} nto_gregset_t;

typedef union _debug_fpregs
{
X86_FPU_REGISTERS x86;
qnx_reg64 padding[1024];
} nto_fpregset_t;

typedef union _debug_altregs
{
qnx_reg64 padding[1024];
} debug_altreg_t;

/* 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
};

#ifdef __QNX__
#include <_packpop.h>

__END_DECLS
#endif
#endif /* __DEBUG_H_INCLUDED */
/* These correspond to the DSMSG_* versions in dsmsgs.h. */
enum
{
NTO_REG_GENERAL,
NTO_REG_FLOAT,
NTO_REG_SYSTEM,
NTO_REG_ALT
};

#endif /* _DEBUG_H */

[-- Attachment #8: tm-qnxnto.h --]
[-- Type: application/octet-stream, Size: 1874 bytes --]

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

[-- Attachment #9: tm-i386nto.h --]
[-- Type: application/octet-stream, Size: 1139 bytes --]

/* 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_I386NTO_H
#define TM_I386NTO_H 1

/* Pick up most of what we need from the generic i386 target include file. */
#include "i386/tm-i386.h"
#include "tm-qnxnto.h"

#include "solib.h"

#endif /* TM_I386NTO_H */

[-- Attachment #10: i386nto.mt --]
[-- Type: application/octet-stream, Size: 169 bytes --]

# 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-i386nto.h