/* Machine independent support for QNX Neutrino /proc (process file system)
for GDB. Written by Colin Burgess at QNX Software Systems Limited.
- Copyright 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
Contributed by QNX Software Systems Ltd.
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
+ 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,
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. */
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
#include <sys/procfs.h>
#include <sys/neutrino.h>
#include <sys/syspage.h>
-#include <dirent.h>
+#include "gdb_dirent.h"
#include <sys/netmgr.h>
+#include "exceptions.h"
#include "gdb_string.h"
#include "gdbcore.h"
#include "inferior.h"
#include "nto-tdep.h"
#include "command.h"
#include "regcache.h"
+#include "solib.h"
#define NULL_PID 0
#define _DEBUG_FLAG_TRACE (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\
struct mem_attrib *attrib,
struct target_ops *);
-static void procfs_fetch_registers (int);
+static void procfs_fetch_registers (struct regcache *, int);
static void notice_signals (void);
static int procfs_can_use_hw_breakpoint (int, int, int);
-static int procfs_insert_hw_breakpoint (CORE_ADDR, char *);
-
-static int procfs_remove_hw_breakpoint (CORE_ADDR addr, char *);
-
static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type);
static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type);
is required is because QNX node descriptors are transient so
we have to re-acquire them every time. */
static unsigned
-nto_node()
+nto_node (void)
{
unsigned node;
- if (ND_NODE_CMP(nto_procfs_node, ND_LOCAL_NODE) == 0)
+ if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0)
return ND_LOCAL_NODE;
- node = netmgr_strtond(nto_procfs_path,0);
+ node = netmgr_strtond (nto_procfs_path, 0);
if (node == -1)
- error ("Lost the QNX node. Debug session probably over.");
+ error (_("Lost the QNX node. Debug session probably over."));
return (node);
}
+static enum gdb_osabi
+procfs_is_nto_target (bfd *abfd)
+{
+ return GDB_OSABI_QNXNTO;
+}
+
/* This is called when we call 'target procfs <arg>' from the (gdb) prompt.
For QNX6 (nto), the only valid arg will be a QNX node string,
eg: "/net/some_node". If arg is not a valid QNX node, we will
int fd, total_size;
procfs_sysinfo *sysinfo;
+ nto_is_nto_target = procfs_is_nto_target;
+
/* Set the default node used for spawning to this one,
and only override it if there is a valid arg. */
if (errno == ENOTSUP)
printf_filtered ("QNX Net Manager not found.\n");
printf_filtered ("Invalid QNX node %s: error %d (%s).\n", nodestr,
- errno, strerror (errno));
+ errno, safe_strerror (errno));
xfree (nodestr);
nodestr = NULL;
nto_procfs_node = ND_LOCAL_NODE;
*endstr = 0;
}
}
- sprintf (nto_procfs_path, "%s%s", nodestr ? nodestr : "", "/proc");
+ snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "",
+ "/proc");
if (nodestr)
xfree (nodestr);
if (fd == -1)
{
printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
- strerror (errno));
- error ("Invalid procfs arg");
+ safe_strerror (errno));
+ error (_("Invalid procfs arg"));
}
sysinfo = (void *) buffer;
if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK)
{
printf_filtered ("Error getting size: %d (%s)\n", errno,
- strerror (errno));
+ safe_strerror (errno));
close (fd);
- error ("Devctl failed.");
+ error (_("Devctl failed."));
}
else
{
if (!sysinfo)
{
printf_filtered ("Memory error: %d (%s)\n", errno,
- strerror (errno));
+ safe_strerror (errno));
close (fd);
- error ("alloca failed.");
+ error (_("alloca failed."));
}
else
{
if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK)
{
printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
- strerror (errno));
+ safe_strerror (errno));
close (fd);
- error ("Devctl failed.");
+ error (_("Devctl failed."));
}
else
{
if (sysinfo->type !=
- nto_map_arch_to_cputype (TARGET_ARCHITECTURE->arch_name))
+ nto_map_arch_to_cputype (gdbarch_bfd_arch_info
+ (current_gdbarch)->arch_name))
{
close (fd);
- error ("Invalid target CPU.");
+ error (_("Invalid target CPU."));
}
}
}
dp = opendir (nto_procfs_path);
if (dp == NULL)
{
- printf ("failed to opendir \"%s\" - %d (%s)", nto_procfs_path, errno,
- strerror (errno));
+ fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)",
+ nto_procfs_path, errno, safe_strerror (errno));
return;
}
closedir (dp);
return;
}
- sprintf (buf, "%s/%s/as", nto_procfs_path, dirp->d_name);
+ snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name);
pid = atoi (dirp->d_name);
}
while (pid == 0);
fd = open (buf, O_RDONLY);
if (fd == -1)
{
- printf ("failed to open %s - %d (%s)\n", buf, errno,
- strerror (errno));
+ fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n",
+ buf, errno, safe_strerror (errno));
closedir (dp);
return;
}
pidinfo = (procfs_info *) buf;
if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK)
{
- printf ("devctl DCMD_PROC_INFO failed - %d (%s)\n", errno,
- strerror (errno));
+ fprintf_unfiltered (gdb_stderr,
+ "devctl DCMD_PROC_INFO failed - %d (%s)\n",
+ errno, safe_strerror (errno));
break;
}
num_threads = pidinfo->num_threads;
err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num);
if (err != EOK)
{
- printf ("failed devctl num mapinfos - %d (%s)\n", err, strerror (err));
+ printf ("failed devctl num mapinfos - %d (%s)\n", err,
+ safe_strerror (err));
return;
}
* sizeof (procfs_mapinfo), &num);
if (err != EOK)
{
- printf ("failed devctl mapinfos - %d (%s)\n", err, strerror (err));
+ printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err));
xfree (mapinfos);
return;
}
/* Mark our target-struct as eligible for stray "run" and "attach" commands. */
static int
-procfs_can_run ()
+procfs_can_run (void)
{
return 1;
}
int pid;
if (!args)
- error_no_arg ("process-id to attach");
+ error_no_arg (_("process-id to attach"));
pid = atoi (args);
if (pid == getpid ())
- error ("Attaching GDB to itself is not a good idea...");
+ error (_("Attaching GDB to itself is not a good idea..."));
if (from_tty)
{
static void
procfs_post_attach (pid_t pid)
{
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
if (exec_bfd)
- SOLIB_CREATE_INFERIOR_HOOK (pid);
-#endif
+ solib_create_inferior_hook ();
}
static ptid_t
{
procfs_status status;
struct sigevent event;
- char path[100];
+ char path[PATH_MAX];
- sprintf (path, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
+ snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, PIDGET (ptid));
ctl_fd = open (path, O_RDWR);
if (ctl_fd == -1)
- error ("Couldn't open proc file %s, error %d (%s)", path, errno,
- strerror (errno));
+ error (_("Couldn't open proc file %s, error %d (%s)"), path, errno,
+ safe_strerror (errno));
if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
- error ("Couldn't stop process");
+ error (_("Couldn't stop process"));
/* Define a sigevent for process stopped notification. */
event.sigev_notify = SIGEV_SIGNAL_THREAD;
if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK
&& status.flags & _DEBUG_FLAG_STOPPED)
- SignalKill (nto_node(), PIDGET (ptid), 0, SIGCONT, 0, 0);
+ SignalKill (nto_node (), PIDGET (ptid), 0, SIGCONT, 0, 0);
attach_flag = 1;
nto_init_solib_absolute_prefix ();
return ptid;
/* Ask the user what to do when an interrupt is received. */
static void
-interrupt_query ()
+interrupt_query (void)
{
target_terminal_ours ();
Give up (and stop debugging it)? "))
{
target_mourn_inferior ();
- throw_exception (RETURN_QUIT);
+ deprecated_throw_reason (RETURN_QUIT);
}
target_terminal_inferior ();
general register set and floating point registers (if supported)
and update gdb's idea of their current values. */
static void
-procfs_fetch_registers (int regno)
+procfs_fetch_registers (struct regcache *regcache, int regno)
{
union
{
procfs_set_thread (inferior_ptid);
if (devctl (ctl_fd, DCMD_PROC_GETGREG, ®, sizeof (reg), ®size) == EOK)
- nto_supply_gregset ((char *) ®.greg);
+ nto_supply_gregset (regcache, (char *) ®.greg);
if (devctl (ctl_fd, DCMD_PROC_GETFPREG, ®, sizeof (reg), ®size)
== EOK)
- nto_supply_fpregset ((char *) ®.fpreg);
+ nto_supply_fpregset (regcache, (char *) ®.fpreg);
if (devctl (ctl_fd, DCMD_PROC_GETALTREG, ®, sizeof (reg), ®size)
== EOK)
- nto_supply_altregset ((char *) ®.altreg);
+ nto_supply_altregset (regcache, (char *) ®.altreg);
}
/* Copy LEN bytes to/from inferior's memory starting at MEMADDR
siggnal = atoi (args);
if (siggnal)
- SignalKill (nto_node(), PIDGET (inferior_ptid), 0, siggnal, 0, 0);
+ SignalKill (nto_node (), PIDGET (inferior_ptid), 0, siggnal, 0, 0);
close (ctl_fd);
ctl_fd = -1;
}
static int
-procfs_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+procfs_insert_breakpoint (struct bp_target_info *bp_tgt)
{
- return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, 0);
+ return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0);
}
static int
-procfs_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+procfs_remove_breakpoint (struct bp_target_info *bp_tgt)
{
- return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC, -1);
+ return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1);
}
static int
-procfs_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
+procfs_insert_hw_breakpoint (struct bp_target_info *bp_tgt)
{
- return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
+ return procfs_breakpoint (bp_tgt->placed_address,
+ _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0);
}
static int
-procfs_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
+procfs_remove_hw_breakpoint (struct bp_target_info *bp_tgt)
{
- return procfs_breakpoint (addr, _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
+ return procfs_breakpoint (bp_tgt->placed_address,
+ _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
}
static void
{
if (signal_to_pass != status.info.si_signo)
{
- SignalKill (nto_node(), PIDGET (inferior_ptid), 0, signal_to_pass,
- 0, 0);
+ SignalKill (nto_node (), PIDGET (inferior_ptid), 0,
+ signal_to_pass, 0, 0);
run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
}
else /* Let it kill the program without telling us. */
}
static void
-procfs_mourn_inferior ()
+procfs_mourn_inferior (void)
{
if (!ptid_equal (inferior_ptid, null_ptid))
{
- SignalKill (nto_node(), PIDGET (inferior_ptid), 0, SIGKILL, 0, 0);
+ SignalKill (nto_node (), PIDGET (inferior_ptid), 0, SIGKILL, 0, 0);
close (ctl_fd);
}
inferior_ptid = null_ptid;
}
static void
-procfs_create_inferior (char *exec_file, char *allargs, char **env)
+procfs_create_inferior (char *exec_file, char *allargs, char **env,
+ int from_tty)
{
struct inheritance inherit;
pid_t pid;
int flags, errn;
char **argv, *args;
- char *in = "", *out = "", *err = "";
+ const char *in = "", *out = "", *err = "";
int fd, fds[3];
sigset_t set;
+ const char *inferior_io_terminal = get_inferior_io_terminal ();
argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
sizeof (*argv));
if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
{
- inherit.nd = nto_node();
+ inherit.nd = nto_node ();
inherit.flags |= SPAWN_SETND;
inherit.flags &= ~SPAWN_EXEC;
}
sigprocmask (SIG_BLOCK, &set, NULL);
if (pid == -1)
- error ("Error spawning %s: %d (%s)", argv[0], errno, strerror (errno));
+ error (_("Error spawning %s: %d (%s)"), argv[0], errno,
+ safe_strerror (errno));
if (fds[0] != STDIN_FILENO)
close (fds[0]);
push_target (&procfs_ops);
target_terminal_init ();
-#ifdef SOLIB_CREATE_INFERIOR_HOOK
if (exec_bfd != NULL
|| (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
- SOLIB_CREATE_INFERIOR_HOOK (pid);
-#endif
+ solib_create_inferior_hook ();
+ stop_soon = 0;
}
static void
-procfs_stop ()
+procfs_stop (void)
{
devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
}
static void
-procfs_kill_inferior ()
+procfs_kill_inferior (void)
{
target_mourn_inferior ();
}
/* Store register REGNO, or all registers if REGNO == -1, from the contents
of REGISTERS. */
static void
-procfs_prepare_to_store ()
+procfs_prepare_to_store (struct regcache *regcache)
{
}
}
void
-procfs_store_registers (int regno)
+procfs_store_registers (struct regcache *regcache, int regno)
{
union
{
if (dev_set == -1)
continue;
- if (nto_regset_fill (regset, (char *) ®) == -1)
+ if (nto_regset_fill (regcache, regset, (char *) ®) == -1)
continue;
err = devctl (ctl_fd, dev_set, ®, regsize, 0);
if (err != EOK)
fprintf_unfiltered (gdb_stderr,
"Warning unable to write regset %d: %s\n",
- regno, strerror (err));
+ regno, safe_strerror (err));
}
}
else
if (len < 1)
return;
- regcache_collect (regno, (char *) ® + off);
+ regcache_raw_collect (regcache, regno, (char *) ® + off);
err = devctl (ctl_fd, dev_set, ®, regsize, 0);
if (err != EOK)
fprintf_unfiltered (gdb_stderr,
"Warning unable to write regset %d: %s\n", regno,
- strerror (err));
+ safe_strerror (err));
}
}
pid = ptid_get_pid (ptid);
tid = ptid_get_tid (ptid);
- n = sprintf (buf, "process %d", pid);
+ n = snprintf (buf, 1023, "process %d", pid);
#if 0 /* NYI */
tip = procfs_thread_info (pid, tid);
if (tip != NULL)
- sprintf (&buf[n], " (state = 0x%02x)", tip->state);
+ snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state);
#endif
return buf;
}
static void
-init_procfs_ops ()
+init_procfs_ops (void)
{
procfs_ops.to_shortname = "procfs";
procfs_ops.to_longname = "QNX Neutrino procfs child process";
procfs_ops.to_fetch_registers = procfs_fetch_registers;
procfs_ops.to_store_registers = procfs_store_registers;
procfs_ops.to_prepare_to_store = procfs_prepare_to_store;
- procfs_ops.to_xfer_memory = procfs_xfer_memory;
+ procfs_ops.deprecated_xfer_memory = procfs_xfer_memory;
procfs_ops.to_files_info = procfs_files_info;
procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
#define OSTYPE_NTO 1
void
-_initialize_procfs ()
+_initialize_procfs (void)
{
sigset_t set;
/* Set up trace and fault sets, as gdb expects them. */
sigemptyset (&run.trace);
- notice_signals ();
/* Stuff some information. */
nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags;
nto_cpuinfo_valid = 1;
- add_info ("pidlist", procfs_pidlist, "pidlist");
- add_info ("meminfo", procfs_meminfo, "memory information");
+ add_info ("pidlist", procfs_pidlist, _("pidlist"));
+ add_info ("meminfo", procfs_meminfo, _("memory information"));
+
+ nto_is_nto_target = procfs_is_nto_target;
}