This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [patch] nto target update
- From: Aleksandar Ristovski <aristovski at qnx dot com>
- To: Ulrich Weigand <uweigand at de dot ibm dot com>
- Cc: gdb-patches at sourceware dot org, Ryan Mansfield <RMansfield at qnx dot com>, aristovski at qnx dot com
- Date: Fri, 25 Jan 2008 17:14:29 -0500
- Subject: Re: [patch] nto target update
- References: <200711082051.lA8KpEL8016249@d12av02.megacenter.de.ibm.com>
Ulrich Weigand wrote:
Aleksandar Ristovski wrote:
Nto target has been maintained in our private branch and hasn't been
synchronized with mainstream for a while.
As a result, nto target does not compile. This patch brings it up-to
date.
Thank you very much for working on getting nto support in GDB mainline
up to date. Unfortunately, this patch introduces a number of coding
style violations that I'd ask you to fix before this can be applied.
Also, the patch introduces a number of functions and macros that are
apparently not used anywhere, neither in the patch nor in the existing
nto code. Is this something to support some other out-of-mainline code?
It would be better if we only add functions as they are actually needed
in mainline.
Hello Ulrich,
Sorry for the long delay. I have cleaned up the code and am resubmitting the patch.
Please review.
Thank you,
Aleksandar
2008-01-25 Aleksandar Ristovski <aristovski@qnx.com>
* Makefile.in (nto_tdep_h, i386-nto-tdep.o, nto-tdep.o): Added
dependency.
* nto.mh (NAT_FILE): Removed.
* nm-nto.h: Removed file.
* nto-procfs.c (procfs_xfer_memory): Changed argument type.
(notice_signals): Removed function.
(procfs_notice_signals): New function.
(procfs_thread_alive): Changed to use DCMD_PROC_TIDSTATUS and
properly interpret thread's status.
(procfs_wait): Print error if sigwaitinfo fails. Get status properly
(ufltset): New union, to workaround aliasing rules violation
warnings in newer gcc versions.
(procfs_resume): Use union ufltset to workaround aliasing rules
violation, call new function procfs_notice_signals instead of
notice_signals. Added new case for the inferior's status when
we want to pass signal. Comments formatting.
* nto-tdep.c: New includes. Removed hard-coded default target path.
(nto_set_target): Use new nto_generic_svr4_fetch_link_map_offsets
functions unless overriden.
(PATH_FMT): Reformat macro to fit in.
(nto_find_and_open_solib): Make sure not to dereference NULL ptr.
(nto_init_solib_absolute_prefix): Add set solib-search-path.
(nto_parse_redirection): Changed argument type.
(nto_generic_svr4_fetch_link_map_offsets): New function.
(LM_ADDR, LM_ADDR_FROM_LINK_MAP): Renamed.
(nto_relocate_section_addresses): Use LM_ADDR_FROM_LINK_MAP.
(nto_target_extra_thread_info): New function.
(nto_initialize_signals): Make sure signals are correct in case
host is different from the target.
(show_nto_debug): New function.
(nto_print_tidinfo_callback): New function.
(nto_info_tidinfo_command): New function.
* nto-tdep.h: New include.
(private_thread_info): New struct for extra thread information.
(nto_parse_redirection): Changed argument type.
(nto_target_extra_thread_info): New declaration.
(nto_generic_svr4_fetch_link_map_offsets): New declaration.
diff -U 5 -p -r -N -X DIFFXPATT clean/src/gdb/Makefile.in changed/src/gdb/Makefile.in
--- clean/src/gdb/Makefile.in 2008-01-19 10:03:49.000000000 -0500
+++ changed/src/gdb/Makefile.in 2008-01-25 15:13:57.000000000 -0500
@@ -837,11 +837,12 @@ mips_tdep_h = mips-tdep.h
memory_map_h = memory-map.h $(memattr_h)
mn10300_tdep_h = mn10300-tdep.h
monitor_h = monitor.h
nbsd_nat_h = nbsd-nat.h
nbsd_tdep_h = nbsd-tdep.h
-nto_tdep_h = nto-tdep.h $(defs_h) $(solist_h) $(osabi_h) $(regset_h)
+nto_tdep_h = nto-tdep.h $(defs_h) $(solist_h) $(osabi_h) $(regset_h) \
+ $(gdbthread_h)
objc_lang_h = objc-lang.h
objfiles_h = objfiles.h $(gdb_obstack_h) $(symfile_h)
obsd_tdep_h = obsd-tdep.h
osabi_h = osabi.h
parser_defs_h = parser-defs.h $(doublest_h)
@@ -2237,11 +2238,11 @@ i386nbsd-tdep.o: i386nbsd-tdep.c $(defs_
$(gdb_assert_h) $(gdb_string_h) $(i386_tdep_h) $(i387_tdep_h) \
$(nbsd_tdep_h) $(solib_svr4_h) $(trad_frame_h) $(tramp_frame_h)
i386-nto-tdep.o: i386-nto-tdep.c $(defs_h) $(frame_h) $(osabi_h) \
$(regcache_h) $(target_h) $(gdb_assert_h) $(gdb_string_h) \
$(i386_tdep_h) $(i387_tdep_h) $(nto_tdep_h) $(solib_h) \
- $(solib_svr4_h)
+ $(solib_svr4_h) $(gdb_stat_h) $(top_h)
i386obsd-nat.o: i386obsd-nat.c $(defs_h) $(gdbcore_h) $(regcache_h) \
$(target_h) $(i386_tdep_h) $(i386bsd_nat_h) $(bsd_kvm_h)
i386obsd-tdep.o: i386obsd-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \
$(frame_unwind_h) $(gdbcore_h) $(regcache_h) $(regset_h) $(symtab_h) \
$(objfiles_h) $(osabi_h) $(target_h) $(trad_frame_h) $(gdb_assert_h) \
@@ -2518,11 +2519,12 @@ nbsd-tdep.o: nbsd-tdep.c $(defs_h) $(gdb
nto-procfs.o: nto-procfs.c $(defs_h) $(gdb_dirent_h) $(exceptions_h) \
$(gdb_string_h) $(gdbcore_h) $(inferior_h) $(target_h) $(objfiles_h) \
$(gdbthread_h) $(nto_tdep_h) $(command_h) $(regcache_h) $(solib_h)
nto-tdep.o: nto-tdep.c $(gdb_stat_h) $(gdb_string_h) $(nto_tdep_h) $(top_h) \
$(cli_decode_h) $(cli_cmds_h) $(inferior_h) $(gdbarch_h) $(bfd_h) \
- $(elf_bfd_h) $(solib_svr4_h) $(gdbcore_h) $(objfiles_h)
+ $(elf_bfd_h) $(solib_svr4_h) $(gdbcore_h) $(objfiles_h) \
+ $(filenames_h) $(gdbcmd_h) $(safe_ctype_h) $(gdb_assert_h)
objc-exp.o: objc-exp.c $(defs_h) $(gdb_string_h) $(expression_h) \
$(objc_lang_h) $(value_h) $(parser_defs_h) $(language_h) $(c_lang_h) \
$(bfd_h) $(symfile_h) $(objfiles_h) $(top_h) $(completer_h) \
$(block_h)
objc-lang.o: objc-lang.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(expression_h) \
diff -U 5 -p -r -N -X DIFFXPATT clean/src/gdb/config/i386/nto.mh changed/src/gdb/config/i386/nto.mh
--- clean/src/gdb/config/i386/nto.mh 2006-11-28 14:07:50.000000000 -0500
+++ changed/src/gdb/config/i386/nto.mh 2008-01-25 15:13:58.000000000 -0500
@@ -1,4 +1,3 @@
# Host: Intel 386 running QNX.
NATDEPFILES= nto-procfs.o
-NAT_FILE= config/nm-nto.h
diff -U 5 -p -r -N -X DIFFXPATT clean/src/gdb/config/nm-nto.h changed/src/gdb/config/nm-nto.h
--- clean/src/gdb/config/nm-nto.h 2008-01-01 17:53:14.000000000 -0500
+++ changed/src/gdb/config/nm-nto.h 1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-/* Native support for QNX Neutrino version 6.
-
- Copyright 2003,2006,2007,2008 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 NM_NTO_H
-#define NM_NTO_H
-
-/* Setup the valid realtime signal range. */
-#define REALTIME_LO 41
-#define REALTIME_HI 56
-
-#endif /* NM_NTO_H */
diff -U 5 -p -r -N -X DIFFXPATT clean/src/gdb/nto-procfs.c changed/src/gdb/nto-procfs.c
--- clean/src/gdb/nto-procfs.c 2008-01-01 17:53:12.000000000 -0500
+++ changed/src/gdb/nto-procfs.c 2008-01-25 15:13:57.000000000 -0500
@@ -59,18 +59,16 @@ static void procfs_open (char *, int);
static int procfs_can_run (void);
static ptid_t procfs_wait (ptid_t, struct target_waitstatus *);
-static int procfs_xfer_memory (CORE_ADDR, char *, int, int,
+static int procfs_xfer_memory (CORE_ADDR, gdb_byte *, int, int,
struct mem_attrib *attrib,
struct target_ops *);
static void procfs_fetch_registers (struct regcache *, int);
-static void notice_signals (void);
-
static void init_procfs_ops (void);
static ptid_t do_attach (ptid_t ptid);
static int procfs_can_use_hw_breakpoint (int, int, int);
@@ -79,10 +77,12 @@ static int procfs_insert_hw_watchpoint (
static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type);
static int procfs_stopped_by_watchpoint (void);
+static void procfs_notice_signals (ptid_t ptid);
+
/* These two globals are only ever set in procfs_open(), but are
referenced elsewhere. 'nto_procfs_node' is a flag used to say
whether we are local, or we should get the current node descriptor
for the remote QNX node. */
static char nto_procfs_path[PATH_MAX] = { "/proc" };
@@ -226,15 +226,32 @@ procfs_set_thread (ptid_t ptid)
/* Return nonzero if the thread TH is still alive. */
static int
procfs_thread_alive (ptid_t ptid)
{
pid_t tid;
+ pid_t pid;
+ procfs_status status;
+ int err;
tid = ptid_get_tid (ptid);
- if (devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0) == EOK)
- return 1;
- return 0;
+ pid = ptid_get_pid (ptid);
+
+ if (kill (pid, 0) == -1)
+ return 0;
+
+ status.tid = tid;
+ if ((err = devctl (ctl_fd, DCMD_PROC_TIDSTATUS,
+ &status, sizeof (status), 0)) != EOK)
+ return 0;
+
+ /* Thread is alive or dead but not yet joined,
+ or dead and there is an alive (or dead unjoined) thread with
+ higher tid. We return tidinfo.
+
+ Client should check if the tid is the same as
+ requested; if not, requested tid is dead. */
+ return (status.tid == tid) && (status.state != STATE_DEAD);
}
void
procfs_find_new_threads (void)
{
@@ -632,12 +649,15 @@ procfs_wait (ptid_t ptid, struct target_
sigaddset (&set, SIGUSR1);
devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
while (!(status.flags & _DEBUG_FLAG_ISTOP))
{
+ int sigwaitres;
ofunc = (void (*)()) signal (SIGINT, nto_interrupt);
- sigwaitinfo (&set, &info);
+ sigwaitres = sigwaitinfo (&set, &info);
+ if (sigwaitres == -1)
+ perror_with_name (__FILE__);
signal (SIGINT, ofunc);
devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
}
if (status.flags & _DEBUG_FLAG_SSTEP)
@@ -676,24 +696,21 @@ procfs_wait (ptid_t ptid, struct target_
}
break;
case _DEBUG_WHY_TERMINATED:
{
- int waitval = 0;
-
- waitpid (PIDGET (inferior_ptid), &waitval, WNOHANG);
if (exit_signo)
{
/* Abnormal death. */
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = exit_signo;
}
else
{
/* Normal death. */
ourstatus->kind = TARGET_WAITKIND_EXITED;
- ourstatus->value.integer = WEXITSTATUS (waitval);
+ ourstatus->value.integer = status.what;
}
exit_signo = 0;
break;
}
@@ -742,11 +759,11 @@ procfs_fetch_registers (struct regcache
Returns the length copied, which is either the LEN argument or
zero. This xfer function does not do partial moves, since procfs_ops
doesn't allow memory operations to cross below us in the target stack
anyway. */
static int
-procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int dowrite,
+procfs_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int dowrite,
struct mem_attrib *attrib, struct target_ops *target)
{
int nbytes = 0;
if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
@@ -831,15 +848,27 @@ procfs_remove_hw_breakpoint (struct bp_t
{
return procfs_breakpoint (bp_tgt->placed_address,
_DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1);
}
+/* Workaround for aliasing rules violation. In our case,
+ violation is o.k. We use sigaddset on fltset_t which is
+ equivalent to sigset_t in nto. */
+
+typedef union
+ {
+ sigset_t *ps;
+ fltset_t *pflt;
+ } ufltset;
+
static void
procfs_resume (ptid_t ptid, int step, enum target_signal signo)
{
int signal_to_pass;
procfs_status status;
+ /* Workaround for aliasing rules violation. */
+ ufltset psigset;
if (ptid_equal (inferior_ptid, null_ptid))
return;
procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid :
@@ -847,41 +876,43 @@ procfs_resume (ptid_t ptid, int step, en
run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
if (step)
run.flags |= _DEBUG_RUN_STEP;
- sigemptyset ((sigset_t *) &run.fault);
- sigaddset ((sigset_t *) &run.fault, FLTBPT);
- sigaddset ((sigset_t *) &run.fault, FLTTRACE);
- sigaddset ((sigset_t *) &run.fault, FLTILL);
- sigaddset ((sigset_t *) &run.fault, FLTPRIV);
- sigaddset ((sigset_t *) &run.fault, FLTBOUNDS);
- sigaddset ((sigset_t *) &run.fault, FLTIOVF);
- sigaddset ((sigset_t *) &run.fault, FLTIZDIV);
- sigaddset ((sigset_t *) &run.fault, FLTFPE);
- /* Peter V will be changing this at some point. */
- sigaddset ((sigset_t *) &run.fault, FLTPAGE);
+ psigset.pflt = &run.fault;
+
+ sigemptyset (psigset.ps);
+ sigaddset (psigset.ps, FLTBPT);
+ sigaddset (psigset.ps, FLTTRACE);
+ sigaddset (psigset.ps, FLTILL);
+ sigaddset (psigset.ps, FLTPRIV);
+ sigaddset (psigset.ps, FLTBOUNDS);
+ sigaddset (psigset.ps, FLTIOVF);
+ sigaddset (psigset.ps, FLTIZDIV);
+ sigaddset (psigset.ps, FLTFPE);
+ sigaddset (psigset.ps, FLTPAGE);
run.flags |= _DEBUG_RUN_ARM;
- sigemptyset (&run.trace);
- notice_signals ();
+ procfs_notice_signals (inferior_ptid);
signal_to_pass = target_signal_to_host (signo);
if (signal_to_pass)
{
devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
signal_to_pass = target_signal_to_host (signo);
- if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
+
+ if ((status.why == _DEBUG_WHY_REQUESTED) ||
+ (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED)))
{
if (signal_to_pass != status.info.si_signo)
{
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. */
+ else /* Let it kill the program without telling us. */
sigdelset (&run.trace, signal_to_pass);
}
}
else
run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
@@ -1040,16 +1071,17 @@ procfs_create_inferior (char *exec_file,
}
/* Clear any pending SIGUSR1's but keep the behavior the same. */
signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
- sigemptyset (&set);
- sigaddset (&set, SIGUSR1);
- sigprocmask (SIG_UNBLOCK, &set, NULL);
-
+
memset (&inherit, 0, sizeof (inherit));
-
+ inherit.flags |= SPAWN_SETSIGDEF;
+ sigemptyset (&inherit.sigdefault);
+ sigaddset (&inherit.sigdefault, SIGHUP);
+ sigaddset (&inherit.sigdefault, SIGPIPE);
+ sigaddset (&inherit.sigdefault, SIGINT);
if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
{
inherit.nd = nto_node ();
inherit.flags |= SPAWN_SETND;
inherit.flags &= ~SPAWN_EXEC;
@@ -1057,16 +1089,20 @@ procfs_create_inferior (char *exec_file,
inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
inherit.pgroup = SPAWN_NEWPGROUP;
pid = spawnp (argv[0], 3, fds, &inherit, argv,
ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0);
xfree (args);
-
- sigprocmask (SIG_BLOCK, &set, NULL);
-
+
if (pid == -1)
error (_("Error spawning %s: %d (%s)"), argv[0], errno,
safe_strerror (errno));
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGUSR1);
+ sigprocmask (SIG_UNBLOCK, &set, NULL);
+
+ sigprocmask (SIG_BLOCK, &set, NULL);
if (fds[0] != STDIN_FILENO)
close (fds[0]);
if (fds[1] != STDOUT_FILENO)
close (fds[1]);
@@ -1205,38 +1241,32 @@ procfs_store_registers (struct regcache
"Warning unable to write regset %d: %s\n", regno,
safe_strerror (err));
}
}
+/* When the user changes the state of gdb's signal handling via the
+ "handle" command, this function gets called to see if any change
+ in the /proc interface is required. It is also called internally
+ by other /proc interface functions to initialize the state of
+ the traced signal set. */
static void
-notice_signals (void)
+procfs_notice_signals (ptid_t ptid)
{
int signo;
+ sigemptyset (&run.trace);
- for (signo = 1; signo < NSIG; signo++)
+ for (signo = 0; signo < NSIG; signo++)
{
if (signal_stop_state (target_signal_from_host (signo)) == 0
&& signal_print_state (target_signal_from_host (signo)) == 0
&& signal_pass_state (target_signal_from_host (signo)) == 1)
sigdelset (&run.trace, signo);
else
sigaddset (&run.trace, signo);
}
}
-/* When the user changes the state of gdb's signal handling via the
- "handle" command, this function gets called to see if any change
- in the /proc interface is required. It is also called internally
- by other /proc interface functions to initialize the state of
- the traced signal set. */
-static void
-procfs_notice_signals (ptid_t ptid)
-{
- sigemptyset (&run.trace);
- notice_signals ();
-}
-
static struct tidinfo *
procfs_thread_info (pid_t pid, short tid)
{
/* NYI */
return NULL;
@@ -1264,10 +1294,11 @@ procfs_pid_to_str (ptid_t ptid)
}
static void
init_procfs_ops (void)
{
+ memset (&procfs_ops, 0, sizeof (procfs_ops));
procfs_ops.to_shortname = "procfs";
procfs_ops.to_longname = "QNX Neutrino procfs child process";
procfs_ops.to_doc =
"QNX Neutrino procfs child process (started by the \"run\" command).\n\
target procfs <node>";
diff -U 5 -p -r -N -X DIFFXPATT clean/src/gdb/nto-tdep.c changed/src/gdb/nto-tdep.c
--- clean/src/gdb/nto-tdep.c 2008-01-01 17:53:12.000000000 -0500
+++ changed/src/gdb/nto-tdep.c 2008-01-25 15:13:57.000000000 -0500
@@ -17,10 +17,11 @@
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 "gdb_assert.h"
#include "gdb_stat.h"
#include "gdb_string.h"
#include "nto-tdep.h"
#include "top.h"
#include "cli/cli-decode.h"
@@ -30,24 +31,20 @@
#include "bfd.h"
#include "elf-bfd.h"
#include "solib-svr4.h"
#include "gdbcore.h"
#include "objfiles.h"
+#include "filenames.h"
-#include <string.h>
+#include "gdbcmd.h"
+#include "safe-ctype.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)
@@ -74,11 +71,14 @@ nto_set_target (struct nto_target_ops *t
nto_supply_fpregset = targ->supply_fpregset;
nto_supply_altregset = targ->supply_altregset;
nto_supply_regset = targ->supply_regset;
nto_register_area = targ->register_area;
nto_regset_fill = targ->regset_fill;
- nto_fetch_link_map_offsets = targ->fetch_link_map_offsets;
+ if (targ->fetch_link_map_offsets)
+ nto_fetch_link_map_offsets = targ->fetch_link_map_offsets;
+ else
+ nto_fetch_link_map_offsets = nto_generic_svr4_fetch_link_map_offsets;
}
/* 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
@@ -101,11 +101,12 @@ int
nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
{
char *buf, *arch_path, *nto_root, *endian, *base;
const char *arch;
int ret;
-#define PATH_FMT "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll"
+#define PATH_FMT "%s/lib:%s/usr/lib:%s/usr/photon/lib:" \
+ "%s/usr/photon/dll:%s/lib/dll"
nto_root = nto_target ();
if (strcmp (gdbarch_bfd_arch_info (current_gdbarch)->arch_name, "i386") == 0)
{
arch = "x86";
@@ -152,11 +153,16 @@ nto_find_and_open_solib (char *solib, un
if (temp_pathname)
{
if (ret >= 0)
*temp_pathname = gdb_realpath (arch_path);
else
- **temp_pathname = '\0';
+ {
+ if (*temp_pathname)
+ **temp_pathname = '\0';
+ else
+ *temp_pathname = "";
+ }
}
}
return ret;
}
@@ -190,14 +196,23 @@ nto_init_solib_absolute_prefix (void)
sprintf (arch_path, "%s/%s%s", nto_root, arch, endian);
sprintf (buf, "set solib-absolute-prefix %s", arch_path);
execute_command (buf, 0);
+
+#if defined (__MINGW32__)
+#define PATH_SEP ";"
+#else
+#define PATH_SEP ":"
+#endif
+
+ sprintf (buf, "set solib-search-path %s/%s" PATH_SEP "%s/%s", arch_path, "lib", arch_path, "usr/lib");
+ execute_command (buf, 0);
}
char **
-nto_parse_redirection (char *pargv[], char **pin, char **pout, char **perr)
+nto_parse_redirection (char *pargv[], const char **pin, const char **pout, const char **perr)
{
char **argv;
char *in, *out, *err, *p;
int argc, i, n;
@@ -245,10 +260,36 @@ nto_parse_redirection (char *pargv[], ch
*pout = out;
*perr = err;
return argv;
}
+struct link_map_offsets *
+nto_generic_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_map_offset = 4;
+
+ lmo.link_map_size = 20; /* The actual size is 552 bytes, but
+ this is all we need. */
+ lmo.l_addr_offset = 0;
+
+ lmo.l_name_offset = 4;
+
+ lmo.l_next_offset = 12;
+
+ lmo.l_prev_offset = 16;
+ }
+
+ return lmp;
+}
+
/* 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
@@ -258,16 +299,19 @@ struct lm_info
various fields without the need for a cast. */
char *lm;
};
static CORE_ADDR
-LM_ADDR (struct so_list *so)
+LM_ADDR_FROM_LINK_MAP (struct so_list *so)
{
struct link_map_offsets *lmo = nto_fetch_link_map_offsets ();
+ gdb_byte *buf = so->lm_info->lm + lmo->l_addr_offset;
+ if (NULL == buf)
+ return 0;
return extract_typed_address (so->lm_info->lm + lmo->l_addr_offset,
- builtin_type_void_data_ptr);
+ builtin_type_void_data_ptr);
}
static CORE_ADDR
nto_truncate_ptr (CORE_ADDR addr)
{
@@ -304,21 +348,23 @@ nto_relocate_section_addresses (struct s
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);
+ sec->addr = nto_truncate_ptr (sec->addr + LM_ADDR_FROM_LINK_MAP (so) - vaddr);
+ sec->endaddr = nto_truncate_ptr (sec->endaddr + LM_ADDR_FROM_LINK_MAP (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, NULL))
- return 1;
+ if (in_plt_section (pc, NULL))
+ {
+ return 1;
+ }
return 0;
}
void
nto_generic_supply_gpregset (const struct regset *regset,
@@ -353,10 +399,18 @@ nto_elf_osabi_sniffer (bfd *abfd)
if (nto_is_nto_target)
return nto_is_nto_target (abfd);
return GDB_OSABI_UNKNOWN;
}
+char *
+nto_target_extra_thread_info (struct thread_info *ti)
+{
+ if (ti && ti->private && ti->private->name[0])
+ return ti->private->name;
+ return "";
+}
+
void
nto_initialize_signals (void)
{
/* We use SIG45 for pulses, or something, so nostop, noprint
and pass them. */
@@ -364,31 +418,58 @@ nto_initialize_signals (void)
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);
+ signal_stop_update (target_signal_from_host (SIGSELECT), 0);
+ signal_print_update (target_signal_from_host (SIGSELECT), 0);
+ signal_pass_update (target_signal_from_host (SIGSELECT), 1);
#endif
#if defined(SIGPHOTON)
- signal_stop_update (SIGPHOTON, 0);
- signal_print_update (SIGPHOTON, 0);
- signal_pass_update (SIGPHOTON, 1);
+ signal_stop_update (target_signal_from_host (SIGPHOTON), 0);
+ signal_print_update (target_signal_from_host (SIGPHOTON), 0);
+ signal_pass_update (target_signal_from_host (SIGPHOTON), 1);
#endif
}
+static void
+show_nto_debug (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("QNX NTO debug level is %d.\n"), nto_internal_debugging);
+}
+
+static int
+nto_print_tidinfo_callback (struct thread_info *tp, void *data)
+{
+ printf_filtered("%c%d\t%d\t%d\n", ptid_equal (tp->ptid, inferior_ptid) ? '*' : ' ', tp->private->tid, tp->private->state, tp->private->flags );
+ return 0;
+}
+
+static void
+nto_info_tidinfo_command (char *args, int from_tty)
+{
+ target_find_new_threads ();
+ printf_filtered("Threads for pid %d (%s)\nTid:\tState:\tFlags:\n", ptid_get_pid (inferior_ptid), get_exec_file (0));
+
+ iterate_over_threads (nto_print_tidinfo_callback, NULL);
+}
+
+
void
_initialize_nto_tdep (void)
{
add_setshow_zinteger_cmd ("nto-debug", class_maintenance,
&nto_internal_debugging, _("\
-Set QNX NTO internal debugging."), _("\
-Show QNX NTO internal debugging."), _("\
+Set QNX NTO debug level."), _("\
+Show QNX NTO debug level."), _("\
When non-zero, nto specific debug info is\n\
displayed. Different information is displayed\n\
for different positive values."),
NULL,
- NULL, /* FIXME: i18n: QNX NTO internal debugging is %s. */
- &setdebuglist, &showdebuglist);
+ show_nto_debug,
+ &maintenance_set_cmdlist,
+ &maintenance_show_cmdlist);
+
+ add_info ("tidinfo", nto_info_tidinfo_command, "List threads for current process." );
}
diff -U 5 -p -r -N -X DIFFXPATT clean/src/gdb/nto-tdep.h changed/src/gdb/nto-tdep.h
--- clean/src/gdb/nto-tdep.h 2008-01-01 17:53:12.000000000 -0500
+++ changed/src/gdb/nto-tdep.h 2008-01-25 15:13:57.000000000 -0500
@@ -24,10 +24,11 @@
#include "defs.h"
#include "solist.h"
#include "osabi.h"
#include "regset.h"
+#include "gdbthread.h"
/* Target operations defined for Neutrino targets (<target>-nto-tdep.c). */
struct nto_target_ops
{
@@ -137,18 +138,26 @@ typedef char qnx_reg64[8];
typedef struct _debug_regs
{
qnx_reg64 padding[1024];
} nto_regset_t;
+/* Used by gdbthread.h. Same as struct tidinfo in pdebug protocol */
+struct private_thread_info {
+ short tid;
+ unsigned char state;
+ unsigned char flags;
+ char name[1];
+};
+
/* Generic functions in nto-tdep.c. */
void nto_init_solib_absolute_prefix (void);
void nto_set_target(struct nto_target_ops *);
-char **nto_parse_redirection (char *start_argv[], char **in,
- char **out, char **err);
+char **nto_parse_redirection (char *start_argv[], const char **in,
+ const char **out, const char **err);
int proc_iterate_over_mappings (int (*func) (int, CORE_ADDR));
void nto_relocate_section_addresses (struct so_list *,
struct section_table *);
@@ -174,6 +183,10 @@ void nto_generic_supply_altregset (const
not define a particular regset. */
void nto_dummy_supply_regset (struct regcache *regcache, char *regs);
int nto_in_dynsym_resolve_code (CORE_ADDR pc);
+char *nto_target_extra_thread_info (struct thread_info *);
+
+struct link_map_offsets* nto_generic_svr4_fetch_link_map_offsets (void);
+
#endif