gdb: remove QNX Neutrino support

Remove the support for the QNX Neutrino OS (tdep and native bits).  This
has been unmaintained for years, and we don't have a way to see if it
works (or even builds, for the native parts).  Without somebody actively
maintaining it, this is just a burden for developers, especially that
this port does a few weird unique things that require reasoning about
when doing big change.

Support for GDBserver was removed in 2020, commit 613f149a90
("gdbserver: remove support for Neutrino").

Change-Id: I4e25ec26ab06636629adebd02ceb161ee31c232d
Approved-by: Kevin Buettner <kevinb@redhat.com>
This commit is contained in:
Simon Marchi 2024-07-25 13:41:35 -04:00 committed by Simon Marchi
parent 7ee8372bdb
commit 36fb20fa93
13 changed files with 2 additions and 2741 deletions

View File

@ -832,7 +832,6 @@ ALL_TARGET_OBS = \
i386-go32-tdep.o \
i386-linux-tdep.o \
i386-netbsd-tdep.o \
i386-nto-tdep.o \
i386-obsd-tdep.o \
i386-sol2-tdep.o \
i386-tdep.o \
@ -860,7 +859,6 @@ ALL_TARGET_OBS = \
nds32-tdep.o \
nios2-linux-tdep.o \
nios2-tdep.o \
nto-tdep.o \
obsd-tdep.o \
or1k-linux-tdep.o \
or1k-tdep.o \
@ -1444,7 +1442,6 @@ HFILES_NO_SRCDIR = \
nds32-tdep.h \
nios2-tdep.h \
elf-none-tdep.h \
nto-tdep.h \
objc-lang.h \
objfiles.h \
obsd-nat.h \
@ -1581,7 +1578,6 @@ HFILES_NO_SRCDIR = \
compile/gcc-c-plugin.h \
compile/gcc-cp-plugin.h \
config/nm-linux.h \
config/nm-nto.h \
config/djgpp/langinfo.h \
config/djgpp/nl_types.h \
config/i386/nm-i386gnu.h \

View File

@ -1,29 +0,0 @@
/* Native support for QNX Neutrino version 6.
Copyright (C) 2003-2024 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 3 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, see <http://www.gnu.org/licenses/>. */
#ifndef CONFIG_NM_NTO_H
#define CONFIG_NM_NTO_H
/* Setup the valid realtime signal range. */
#define REALTIME_LO 41
#define REALTIME_HI 56
#endif /* CONFIG_NM_NTO_H */

View File

@ -110,7 +110,6 @@ i[34567]86-*-mingw32*) gdb_host=mingw
i[34567]86-*-msdosdjgpp*) gdb_host=go32 ;;
i[34567]86-*-linux*) gdb_host=linux ;;
i[34567]86-*-gnu*) gdb_host=i386gnu ;;
i[3456]86-*-nto*) gdb_host=nto ;;
i[34567]86-*-openbsd*) gdb_host=obsd ;;
i[34567]86-*-solaris2* | x86_64-*-solaris2*)
gdb_host=sol2 ;;

View File

@ -426,15 +426,6 @@ case ${gdb_host} in
esac
;;
nto)
case ${gdb_host_cpu} in
i386)
# Host: Intel 386 running QNX.
NATDEPFILES='nto-procfs.o'
NAT_FILE='config/nm-nto.h'
;;
esac
;;
obsd)
case ${gdb_host_cpu} in
i386)

View File

@ -305,11 +305,6 @@ i[34567]86-*-openbsd*)
# Target: OpenBSD/i386
gdb_target_obs="i386-bsd-tdep.o i386-obsd-tdep.o bsd-uthread.o"
;;
i[34567]86-*-nto*)
# Target: Intel 386 running qnx6.
gdb_target_obs="solib-svr4.o \
i386-nto-tdep.o nto-tdep.o"
;;
i[34567]86-*-solaris2* | x86_64-*-solaris2*)
# Target: Solaris x86_64
gdb_target_obs="${i386_tobjs} ${amd64_tobjs} \
@ -809,7 +804,6 @@ case "${targ}" in
gdb_osabi=GDB_OSABI_FREEBSD ;;
*-*-linux* | *-*-uclinux*)
gdb_osabi=GDB_OSABI_LINUX ;;
*-*-nto*) gdb_osabi=GDB_OSABI_QNXNTO ;;
m68*-*-openbsd* | m88*-*-openbsd* | vax-*-openbsd*) ;;
*-*-openbsd*) gdb_osabi=GDB_OSABI_OPENBSD ;;
*-*-solaris*) gdb_osabi=GDB_OSABI_SOLARIS ;;

View File

@ -2742,7 +2742,7 @@ environment:
@end smallexample
This command is available when debugging locally on most targets, excluding
@sc{djgpp}, Cygwin, MS Windows, and QNX Neutrino.
@sc{djgpp}, Cygwin, and MS Windows.
@kindex set startup-with-shell
@anchor{set startup-with-shell}
@ -22011,7 +22011,7 @@ name and remembers it that way.
@cindex shared libraries
@anchor{Shared Libraries}
@value{GDBN} supports @sc{gnu}/Linux, MS-Windows, SunOS,
Darwin/Mach-O, SVr4, IBM RS/6000 AIX, QNX Neutrino, FDPIC (FR-V), and
Darwin/Mach-O, SVr4, IBM RS/6000 AIX, FDPIC (FR-V), and
DSBT (TIC6X) shared libraries.
On MS-Windows @value{GDBN} must be linked with the Expat library to support
@ -25207,16 +25207,6 @@ Show the file to which @code{procfs} API trace is written.
These commands enable and disable tracing of entries into and exits
from the @code{syscall} interface.
@item info pidlist
@kindex info pidlist
@cindex process list, QNX Neutrino
For QNX Neutrino only, this command displays the list of all the
processes and all the threads within each process.
@item info meminfo
@kindex info meminfo
@cindex mapinfo list, QNX Neutrino
For QNX Neutrino only, this command displays the list of all mapinfos.
@end table
@node DJGPP Native

View File

@ -1,379 +0,0 @@
/* Target-dependent code for QNX Neutrino x86.
Copyright (C) 2003-2024 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 3 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, see <http://www.gnu.org/licenses/>. */
#include "extract-store-integer.h"
#include "frame.h"
#include "osabi.h"
#include "regcache.h"
#include "target.h"
#include "i386-tdep.h"
#include "i387-tdep.h"
#include "nto-tdep.h"
#include "solib.h"
#include "solib-svr4.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
/* Mapping between the general-purpose registers in `struct xxx'
format and GDB's register cache layout. */
/* From <x86/context.h>. */
static int i386nto_gregset_reg_offset[] =
{
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 /* filler */
};
/* Given a GDB register number REGNUM, return the offset into
Neutrino's register structure or -1 if the register is unknown. */
static int
nto_reg_offset (int regnum)
{
if (regnum >= 0 && regnum < ARRAY_SIZE (i386nto_gregset_reg_offset))
return i386nto_gregset_reg_offset[regnum];
return -1;
}
static void
i386nto_supply_gregset (struct regcache *regcache, char *gpregs)
{
struct gdbarch *gdbarch = regcache->arch ();
i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
gdb_assert (tdep->gregset_reg_offset == i386nto_gregset_reg_offset);
i386_gregset.supply_regset (&i386_gregset, regcache, -1,
gpregs, NUM_GPREGS * 4);
}
static void
i386nto_supply_fpregset (struct regcache *regcache, char *fpregs)
{
if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
i387_supply_fxsave (regcache, -1, fpregs);
else
i387_supply_fsave (regcache, -1, fpregs);
}
static void
i386nto_supply_regset (struct regcache *regcache, int regset, char *data)
{
switch (regset)
{
case NTO_REG_GENERAL:
i386nto_supply_gregset (regcache, data);
break;
case NTO_REG_FLOAT:
i386nto_supply_fpregset (regcache, data);
break;
}
}
static int
i386nto_regset_id (int regno)
{
if (regno == -1)
return NTO_REG_END;
else if (regno < I386_NUM_GREGS)
return NTO_REG_GENERAL;
else if (regno < I386_NUM_GREGS + I387_NUM_REGS)
return NTO_REG_FLOAT;
else if (regno < I386_SSE_NUM_REGS)
return NTO_REG_FLOAT; /* We store xmm registers in fxsave_area. */
return -1; /* Error. */
}
static int
i386nto_register_area (struct gdbarch *gdbarch,
int regno, int regset, unsigned *off)
{
i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
*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, regno_base;
/* The following are flags indicating number in our fxsave_area. */
int first_four = (regno >= I387_FCTRL_REGNUM (tdep)
&& regno <= I387_FISEG_REGNUM (tdep));
int second_four = (regno > I387_FISEG_REGNUM (tdep)
&& regno <= I387_FOP_REGNUM (tdep));
int st_reg = (regno >= I387_ST0_REGNUM (tdep)
&& regno < I387_ST0_REGNUM (tdep) + 8);
int xmm_reg = (regno >= I387_XMM0_REGNUM (tdep)
&& regno < I387_MXCSR_REGNUM (tdep));
if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
{
off_adjust = 32;
regsize = 16;
regset_size = 512;
/* fxsave_area structure. */
if (first_four)
{
/* fpu_control_word, fpu_status_word, fpu_tag_word, fpu_operand
registers. */
regsize = 2; /* Two bytes each. */
off_adjust = 0;
regno_base = I387_FCTRL_REGNUM (tdep);
}
else if (second_four)
{
/* fpu_ip, fpu_cs, fpu_op, fpu_ds registers. */
regsize = 4;
off_adjust = 8;
regno_base = I387_FISEG_REGNUM (tdep) + 1;
}
else if (st_reg)
{
/* ST registers. */
regsize = 16;
off_adjust = 32;
regno_base = I387_ST0_REGNUM (tdep);
}
else if (xmm_reg)
{
/* XMM registers. */
regsize = 16;
off_adjust = 160;
regno_base = I387_XMM0_REGNUM (tdep);
}
else if (regno == I387_MXCSR_REGNUM (tdep))
{
regsize = 4;
off_adjust = 24;
regno_base = I387_MXCSR_REGNUM (tdep);
}
else
{
/* Whole regset. */
gdb_assert (regno == -1);
off_adjust = 0;
regno_base = 0;
regsize = regset_size;
}
}
else
{
regset_size = 108;
/* fsave_area structure. */
if (first_four || second_four)
{
/* fpu_control_word, ... , fpu_ds registers. */
regsize = 4;
off_adjust = 0;
regno_base = I387_FCTRL_REGNUM (tdep);
}
else if (st_reg)
{
/* One of ST registers. */
regsize = 10;
off_adjust = 7 * 4;
regno_base = I387_ST0_REGNUM (tdep);
}
else
{
/* Whole regset. */
gdb_assert (regno == -1);
off_adjust = 0;
regno_base = 0;
regsize = regset_size;
}
}
if (regno != -1)
*off = off_adjust + (regno - regno_base) * regsize;
else
*off = 0;
return regsize;
}
return -1;
}
static int
i386nto_regset_fill (const struct regcache *regcache, 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->raw_collect (regno, data + offset);
}
}
else if (regset == NTO_REG_FLOAT)
{
if (nto_cpuinfo_valid && nto_cpuinfo_flags | X86_CPU_FXSR)
i387_collect_fxsave (regcache, -1, data);
else
i387_collect_fsave (regcache, -1, data);
}
else
return -1;
return 0;
}
/* Return whether THIS_FRAME corresponds to a QNX Neutrino sigtramp
routine. */
static int
i386nto_sigtramp_p (const frame_info_ptr &this_frame)
{
CORE_ADDR pc = get_frame_pc (this_frame);
const char *name;
find_pc_partial_function (pc, &name, NULL, NULL);
return name && strcmp ("__signalstub", name) == 0;
}
/* Assuming THIS_FRAME is a QNX Neutrino sigtramp routine, return the
address of the associated sigcontext structure. */
static CORE_ADDR
i386nto_sigcontext_addr (const frame_info_ptr &this_frame)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[4];
CORE_ADDR ptrctx;
/* We store __ucontext_t addr in EDI register. */
get_frame_register (this_frame, I386_EDI_REGNUM, buf);
ptrctx = extract_unsigned_integer (buf, 4, byte_order);
ptrctx += 24 /* Context pointer is at this offset. */;
return ptrctx;
}
static void
init_i386nto_ops (void)
{
nto_regset_id = i386nto_regset_id;
nto_supply_gregset = i386nto_supply_gregset;
nto_supply_fpregset = i386nto_supply_fpregset;
nto_supply_altregset = nto_dummy_supply_regset;
nto_supply_regset = i386nto_supply_regset;
nto_register_area = i386nto_register_area;
nto_regset_fill = i386nto_regset_fill;
nto_fetch_link_map_offsets =
svr4_ilp32_fetch_link_map_offsets;
}
static void
i386nto_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
static solib_ops nto_svr4_so_ops;
/* Deal with our strange signals. */
nto_initialize_signals ();
/* NTO uses ELF. */
i386_elf_init_abi (info, gdbarch);
/* Neutrino rewinds to look more normal. Need to override the i386
default which is [unfortunately] to decrement the PC. */
set_gdbarch_decr_pc_after_break (gdbarch, 0);
tdep->gregset_reg_offset = i386nto_gregset_reg_offset;
tdep->gregset_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset);
tdep->sizeof_gregset = NUM_GPREGS * 4;
tdep->sigtramp_p = i386nto_sigtramp_p;
tdep->sigcontext_addr = i386nto_sigcontext_addr;
tdep->sc_reg_offset = i386nto_gregset_reg_offset;
tdep->sc_num_regs = ARRAY_SIZE (i386nto_gregset_reg_offset);
/* 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, svr4_ilp32_fetch_link_map_offsets);
/* Initialize this lazily, to avoid an initialization order
dependency on solib-svr4.c's _initialize routine. */
if (nto_svr4_so_ops.in_dynsym_resolve_code == NULL)
{
nto_svr4_so_ops = svr4_so_ops;
/* Our loader handles solib relocations differently than svr4. */
nto_svr4_so_ops.relocate_section_addresses
= nto_relocate_section_addresses;
/* Supply a nice function to find our solibs. */
nto_svr4_so_ops.find_and_open_solib
= nto_find_and_open_solib;
/* Our linker code is in libc. */
nto_svr4_so_ops.in_dynsym_resolve_code
= nto_in_dynsym_resolve_code;
}
set_gdbarch_so_ops (gdbarch, &nto_svr4_so_ops);
set_gdbarch_wchar_bit (gdbarch, 32);
set_gdbarch_wchar_signed (gdbarch, 0);
}
void _initialize_i386nto_tdep ();
void
_initialize_i386nto_tdep ()
{
init_i386nto_ops ();
gdbarch_register_osabi (bfd_arch_i386, 0, GDB_OSABI_QNXNTO,
i386nto_init_abi);
gdbarch_register_osabi_sniffer (bfd_arch_i386, bfd_target_elf_flavour,
nto_elf_osabi_sniffer);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,521 +0,0 @@
/* nto-tdep.c - general QNX Neutrino target functionality.
Copyright (C) 2003-2024 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 3 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, see <http://www.gnu.org/licenses/>. */
#include <sys/stat.h>
#include "nto-tdep.h"
#include "extract-store-integer.h"
#include "top.h"
#include "inferior.h"
#include "infrun.h"
#include "gdbarch.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "solib-svr4.h"
#include "gdbcore.h"
#include "objfiles.h"
#include "source.h"
#include "gdbsupport/pathstuff.h"
#define QNX_NOTE_NAME "QNX"
#define QNX_INFO_SECT_NAME "QNX_info"
#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 const registry<inferior>::key<struct nto_inferior_data>
nto_inferior_data_reg;
static char *
nto_target (void)
{
char *p = getenv ("QNX_TARGET");
#ifdef __CYGWIN__
static char buf[PATH_MAX];
if (p)
cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX);
else
cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX);
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, "powerpc"))
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 (const char *solib, unsigned o_flags,
gdb::unique_xmalloc_ptr<char> *temp_pathname)
{
char *buf, *arch_path, *nto_root;
const char *endian;
const char *base;
const char *arch;
int arch_len, len, ret;
#define PATH_FMT \
"%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
nto_root = nto_target ();
gdbarch *gdbarch = current_inferior ()->arch ();
if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "i386") == 0)
{
arch = "x86";
endian = "";
}
else if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name,
"rs6000") == 0
|| strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name,
"powerpc") == 0)
{
arch = "ppc";
endian = "be";
}
else
{
arch = gdbarch_bfd_arch_info (gdbarch)->arch_name;
endian = gdbarch_byte_order (gdbarch)
== BFD_ENDIAN_BIG ? "be" : "le";
}
/* In case nto_root is short, add strlen(solib)
so we can reuse arch_path below. */
arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2
+ strlen (solib));
arch_path = (char *) alloca (arch_len);
xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian);
len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1;
buf = (char *) alloca (len);
xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path,
arch_path);
base = lbasename (solib);
ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags,
temp_pathname);
if (ret < 0 && base != solib)
{
xsnprintf (arch_path, arch_len, "/%s", solib);
ret = open (arch_path, o_flags, 0);
if (temp_pathname)
{
if (ret >= 0)
*temp_pathname = gdb_realpath (arch_path);
else
temp_pathname->reset (NULL);
}
}
return ret;
}
void
nto_init_solib_absolute_prefix (void)
{
char buf[PATH_MAX * 2], arch_path[PATH_MAX];
char *nto_root;
const char *endian;
const char *arch;
nto_root = nto_target ();
gdbarch *gdbarch = current_inferior ()->arch ();
if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name, "i386") == 0)
{
arch = "x86";
endian = "";
}
else if (strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name,
"rs6000") == 0
|| strcmp (gdbarch_bfd_arch_info (gdbarch)->arch_name,
"powerpc") == 0)
{
arch = "ppc";
endian = "be";
}
else
{
arch = gdbarch_bfd_arch_info (gdbarch)->arch_name;
endian = gdbarch_byte_order (gdbarch)
== BFD_ENDIAN_BIG ? "be" : "le";
}
xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian);
xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path);
execute_command (buf, 0);
}
char **
nto_parse_redirection (char *pargv[], const char **pin, const char **pout,
const char **perr)
{
char **argv;
const char *in, *out, *err, *p;
int argc, i, n;
for (n = 0; pargv[n]; n++);
if (n == 0)
return NULL;
in = "";
out = "";
err = "";
argv = XCNEWVEC (char *, n + 1);
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;
}
static CORE_ADDR
lm_addr (const solib &so)
{
auto *li = gdb::checked_static_cast<const lm_info_svr4 *> (so.lm_info.get ());
return li->l_addr;
}
static CORE_ADDR
nto_truncate_ptr (CORE_ADDR addr)
{
gdbarch *gdbarch = current_inferior ()->arch ();
if (gdbarch_ptr_bit (gdbarch) == 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 << gdbarch_ptr_bit (gdbarch)) - 1);
}
static 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 (solib &so, target_section *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->the_bfd_section->owner);
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);
}
/* This is cheating a bit because our linker code is in libc.so. If we
ever implement lazy linking, this may need to be re-examined. */
int
nto_in_dynsym_resolve_code (CORE_ADDR pc)
{
if (in_plt_section (pc))
return 1;
return 0;
}
void
nto_dummy_supply_regset (struct regcache *regcache, char *regs)
{
/* Do nothing. */
}
static void
nto_sniff_abi_note_section (bfd *abfd, asection *sect, void *obj)
{
const char *sectname;
unsigned int sectsize;
/* Buffer holding the section contents. */
char *note;
unsigned int namelen;
const char *name;
const unsigned sizeof_Elf_Nhdr = 12;
sectname = bfd_section_name (sect);
sectsize = bfd_section_size (sect);
if (sectsize > 128)
sectsize = 128;
if (sectname != NULL && strstr (sectname, QNX_INFO_SECT_NAME) != NULL)
*(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO;
else if (sectname != NULL && strstr (sectname, "note") != NULL
&& sectsize > sizeof_Elf_Nhdr)
{
note = XNEWVEC (char, sectsize);
bfd_get_section_contents (abfd, sect, note, 0, sectsize);
namelen = (unsigned int) bfd_h_get_32 (abfd, note);
name = note + sizeof_Elf_Nhdr;
if (sectsize >= namelen + sizeof_Elf_Nhdr
&& namelen == sizeof (QNX_NOTE_NAME)
&& 0 == strcmp (name, QNX_NOTE_NAME))
*(enum gdb_osabi *) obj = GDB_OSABI_QNXNTO;
XDELETEVEC (note);
}
}
enum gdb_osabi
nto_elf_osabi_sniffer (bfd *abfd)
{
enum gdb_osabi osabi = GDB_OSABI_UNKNOWN;
bfd_map_over_sections (abfd,
nto_sniff_abi_note_section,
&osabi);
return osabi;
}
static const char * const nto_thread_state_str[] =
{
"DEAD", /* 0 0x00 */
"RUNNING", /* 1 0x01 */
"READY", /* 2 0x02 */
"STOPPED", /* 3 0x03 */
"SEND", /* 4 0x04 */
"RECEIVE", /* 5 0x05 */
"REPLY", /* 6 0x06 */
"STACK", /* 7 0x07 */
"WAITTHREAD", /* 8 0x08 */
"WAITPAGE", /* 9 0x09 */
"SIGSUSPEND", /* 10 0x0a */
"SIGWAITINFO", /* 11 0x0b */
"NANOSLEEP", /* 12 0x0c */
"MUTEX", /* 13 0x0d */
"CONDVAR", /* 14 0x0e */
"JOIN", /* 15 0x0f */
"INTR", /* 16 0x10 */
"SEM", /* 17 0x11 */
"WAITCTX", /* 18 0x12 */
"NET_SEND", /* 19 0x13 */
"NET_REPLY" /* 20 0x14 */
};
const char *
nto_extra_thread_info (struct target_ops *self, struct thread_info *ti)
{
if (ti != NULL && ti->priv != NULL)
{
nto_thread_info *priv = get_nto_thread_info (ti);
if (priv->state < ARRAY_SIZE (nto_thread_state_str))
return nto_thread_state_str [priv->state];
}
return "";
}
void
nto_initialize_signals (void)
{
/* We use SIG45 for pulses, or something, so nostop, noprint
and pass them. */
signal_stop_update (gdb_signal_from_name ("SIG45"), 0);
signal_print_update (gdb_signal_from_name ("SIG45"), 0);
signal_pass_update (gdb_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
}
/* Read AUXV from initial_stack. */
LONGEST
nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, gdb_byte *readbuf,
LONGEST len, size_t sizeof_auxv_t)
{
gdb_byte targ32[4]; /* For 32 bit target values. */
gdb_byte targ64[8]; /* For 64 bit target values. */
CORE_ADDR data_ofs = 0;
ULONGEST anint;
LONGEST len_read = 0;
gdb_byte *buff;
enum bfd_endian byte_order;
int ptr_size;
if (sizeof_auxv_t == 16)
ptr_size = 8;
else
ptr_size = 4;
/* Skip over argc, argv and envp... Comment from ldd.c:
The startup frame is set-up so that we have:
auxv
NULL
...
envp2
envp1 <----- void *frame + (argc + 2) * sizeof(char *)
NULL
...
argv2
argv1
argc <------ void * frame
On entry to ldd, frame gives the address of argc on the stack. */
/* Read argc. 4 bytes on both 64 and 32 bit arches and luckily little
* endian. So we just read first 4 bytes. */
if (target_read_memory (initial_stack + data_ofs, targ32, 4) != 0)
return 0;
byte_order = gdbarch_byte_order (current_inferior ()->arch ());
anint = extract_unsigned_integer (targ32, sizeof (targ32), byte_order);
/* Size of pointer is assumed to be 4 bytes (32 bit arch.) */
data_ofs += (anint + 2) * ptr_size; /* + 2 comes from argc itself and
NULL terminating pointer in
argv. */
/* Now loop over env table: */
anint = 0;
while (target_read_memory (initial_stack + data_ofs, targ64, ptr_size)
== 0)
{
if (extract_unsigned_integer (targ64, ptr_size, byte_order) == 0)
anint = 1; /* Keep looping until non-null entry is found. */
else if (anint)
break;
data_ofs += ptr_size;
}
initial_stack += data_ofs;
memset (readbuf, 0, len);
buff = readbuf;
while (len_read <= len-sizeof_auxv_t)
{
if (target_read_memory (initial_stack + len_read, buff, sizeof_auxv_t)
== 0)
{
/* Both 32 and 64 bit structures have int as the first field. */
const ULONGEST a_type
= extract_unsigned_integer (buff, sizeof (targ32), byte_order);
if (a_type == AT_NULL)
break;
buff += sizeof_auxv_t;
len_read += sizeof_auxv_t;
}
else
break;
}
return len_read;
}
/* Return nto_inferior_data for the given INFERIOR. If not yet created,
construct it. */
struct nto_inferior_data *
nto_inferior_data (struct inferior *const inferior)
{
struct inferior *const inf = inferior ? inferior : current_inferior ();
struct nto_inferior_data *inf_data;
gdb_assert (inf != NULL);
inf_data = nto_inferior_data_reg.get (inf);
if (inf_data == NULL)
inf_data = nto_inferior_data_reg.emplace (inf);
return inf_data;
}

View File

@ -1,194 +0,0 @@
/* nto-tdep.h - QNX Neutrino target header.
Copyright (C) 2003-2024 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 3 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, see <http://www.gnu.org/licenses/>. */
#ifndef NTO_TDEP_H
#define NTO_TDEP_H
#include "solist.h"
#include "osabi.h"
#include "regset.h"
#include "gdbthread.h"
#include "gdbsupport/gdb-checked-static-cast.h"
/* Target operations defined for Neutrino targets (<target>-nto-tdep.c). */
struct nto_target_ops
{
/* 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. */
unsigned cpuinfo_flags;
/* True if successfully retrieved cpuinfo from remote. */
int cpuinfo_valid;
/* Given a register, return an id that represents the Neutrino
regset it came from. If reg == -1 update all regsets. */
int (*regset_id) (int);
void (*supply_gregset) (struct regcache *, char *);
void (*supply_fpregset) (struct regcache *, char *);
void (*supply_altregset) (struct regcache *, char *);
/* Given a regset, tell gdb about registers stored in data. */
void (*supply_regset) (struct regcache *, int, char *);
/* 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. */
int (*register_area) (struct gdbarch *, int, int, unsigned *);
/* Build the Neutrino register set info into the data buffer.
Return -1 if unknown regset, 0 otherwise. */
int (*regset_fill) (const struct regcache *, int, char *);
/* 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 *(*fetch_link_map_offsets) (void);
/* Used by nto_elf_osabi_sniffer to determine if we're connected to an
Neutrino target. */
enum gdb_osabi (*is_nto_target) (bfd *abfd);
};
extern struct nto_target_ops current_nto_target;
#define nto_cpuinfo_flags (current_nto_target.cpuinfo_flags)
#define nto_cpuinfo_valid (current_nto_target.cpuinfo_valid)
#define nto_regset_id (current_nto_target.regset_id)
#define nto_supply_gregset (current_nto_target.supply_gregset)
#define nto_supply_fpregset (current_nto_target.supply_fpregset)
#define nto_supply_altregset (current_nto_target.supply_altregset)
#define nto_supply_regset (current_nto_target.supply_regset)
#define nto_register_area (current_nto_target.register_area)
#define nto_regset_fill (current_nto_target.regset_fill)
#define nto_fetch_link_map_offsets \
(current_nto_target.fetch_link_map_offsets)
#define nto_is_nto_target (current_nto_target.is_nto_target)
/* 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;
struct nto_thread_info : public private_thread_info
{
short tid = 0;
unsigned char state = 0;
unsigned char flags = 0;
std::string name;
};
static inline nto_thread_info *
get_nto_thread_info (thread_info *thread)
{
return gdb::checked_static_cast<nto_thread_info *> (thread->priv.get ());
}
/* Per-inferior data, common for both procfs and remote. */
struct nto_inferior_data
{
/* Last stopped flags result from wait function */
unsigned int stopped_flags = 0;
/* Last known stopped PC */
CORE_ADDR stopped_pc = 0;
};
/* Generic functions in nto-tdep.c. */
void nto_init_solib_absolute_prefix (void);
char **nto_parse_redirection (char *start_argv[], const char **in,
const char **out, const char **err);
void nto_relocate_section_addresses (solib &, target_section *);
int nto_map_arch_to_cputype (const char *);
int nto_find_and_open_solib (const char *, unsigned,
gdb::unique_xmalloc_ptr<char> *);
enum gdb_osabi nto_elf_osabi_sniffer (bfd *abfd);
void nto_initialize_signals (void);
/* Dummy function for initializing nto_target_ops on targets which do
not define a particular regset. */
void nto_dummy_supply_regset (struct regcache *regcache, char *regs);
int nto_in_dynsym_resolve_code (CORE_ADDR pc);
const char *nto_extra_thread_info (struct target_ops *self, struct thread_info *);
LONGEST nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack,
gdb_byte *readbuf,
LONGEST len, size_t sizeof_auxv_t);
struct nto_inferior_data *nto_inferior_data (struct inferior *inf);
#endif /* NTO_TDEP_H */

View File

@ -70,7 +70,6 @@ static const struct osabi_names gdb_osabi_names[] =
{ "OpenBSD", NULL },
{ "WindowsCE", NULL },
{ "DJGPP", NULL },
{ "QNX-Neutrino", NULL },
{ "Cygwin", NULL },
{ "Windows", NULL },
{ "AIX", NULL },

View File

@ -35,7 +35,6 @@ enum gdb_osabi
GDB_OSABI_OPENBSD,
GDB_OSABI_WINCE,
GDB_OSABI_GO32,
GDB_OSABI_QNXNTO,
GDB_OSABI_CYGWIN,
GDB_OSABI_WINDOWS,
GDB_OSABI_AIX,

View File

@ -8113,7 +8113,6 @@ gdb_caching_proc gdb_has_argv0 {} {
|| [istarget *-wince-pe] || [istarget *-*-mingw32ce*]
|| [istarget *-*-osf*]
|| [istarget *-*-dicos*]
|| [istarget *-*-nto*]
|| [istarget *-*-*vms*]
|| [istarget *-*-lynx*178]) } {
fail "argv\[0\] should be available on this target"