* patch to add QNX NTO i386 support
@ 2003-02-03 20:19 Kris Warkentin
2003-02-04 7:23 ` Eli Zaretskii
` (2 more replies)
0 siblings, 3 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-03 20:19 UTC (permalink / raw)
To: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2117 bytes --]
I am submitting, on behalf of my employer QNX Software Systems Ltd., a patch
against the current HEAD branch of gdb (as of Feb.3/2003 - see attachment).
We already have copywrite assignment paperwork on file with the FSF.
Now that I've said what the lawyer told me to say ;-), the readline patch
deserves some explanation. I didn't get any response from the readline or
bash mailing lists about the fact that if the test for wcwidth fails, no
action is taken. Oddly, this test fails on other targets (ie Cygwin) but
there is no problem since wcwidth seems to resolve anyway. Self hosted
Neutrino is actually missing it however so we had to conditionally compile
it in. Hence the changes to Makefile.in. I would have changed Makefile.am
but it doesn't seem to be in your sources.
Please let me know if the patch and these ChangeLog entries are
satisfactory.
cheers,
Kris
Top Level ChangeLog entry:
2003-03-02 Kris Warkentin kewarken@qnx.com
* config/mh-qnxnto: New file
* config.sub: Add nto i386 and multi-arch support
* configure.in: add host_makefile_frag
bfd/ChangeLog entry:
2003-03-02 Kris Warkentin kewarken@qnx.com
* elf.c: Add qnx corefile support
gdb/ChangeLog entry:
2003-03-02 Kris Warkentin kewarken@qnx.com
* config/i386/i386nto.mt: New file
* config/i386/nm-nto.h: New file
* config/i386/nto.mh: New file
* config/i386/tm-i386nto.h: New file
* config/i386/xm-nto.h: New file
* config/tm-qnxnto.h: New file
* configure.host: add gdb_host=nto
* configure.tgt: add gdb_target=i386nto
* nto-procfs.c: New file
* nto-share/debug.h: New file
* nto-share/dsmsgs.h: New file
* remote-nto-i386.c: New file
* remote-nto.c: New file
* ser-ntopty.c: New file
readline/ChangeLog entry:
2003-03-02 Kris Warkentin kewarken@qnx.com
* Makefile.in: Check HAVE_WCWIDTH variable for conditionally compiling
support/wcwidth.c
* shlib/Makefile.in: Likewise
* aclocal.m4: If we don't have wcwidth, define HAVE_WCWIDTH=no for
Makefile
generation
[-- Attachment #2: qnxnto.diff --]
[-- Type: application/octet-stream, Size: 233635 bytes --]
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/bfd/elf.c src/bfd/elf.c
*** src.orig/bfd/elf.c Thu Jan 23 06:51:32 2003
--- src/bfd/elf.c Fri Jan 31 11:53:58 2003
*************** static bfd_boolean elfcore_grok_netbsd_p
*** 97,102 ****
--- 97,108 ----
PARAMS ((bfd *, Elf_Internal_Note *));
static bfd_boolean elfcore_grok_netbsd_note
PARAMS ((bfd *, Elf_Internal_Note *));
+ static bfd_boolean elfcore_grok_nto_gregs
+ PARAMS ((bfd *, Elf_Internal_Note *, pid_t));
+ static bfd_boolean elfcore_grok_nto_status
+ PARAMS ((bfd *, Elf_Internal_Note *, pid_t *));
+ static bfd_boolean elfcore_grok_nto_note
+ PARAMS ((bfd *, Elf_Internal_Note *));
/* Swap version information in and out. The version information is
currently size independent. If that ever changes, this code will
*************** elfcore_read_notes (abfd, offset, size)
*** 7189,7194 ****
--- 7195,7205 ----
if (! elfcore_grok_netbsd_note (abfd, &in))
goto error;
}
+ else if (strncmp (in.namedata, "QNX", 3) == 0)
+ {
+ if (! elfcore_grok_nto_note (abfd, &in))
+ goto error;
+ }
else
{
if (! elfcore_grok_note (abfd, &in))
*************** _bfd_elf_section_offset (abfd, info, sec
*** 7391,7393 ****
--- 7402,7505 ----
return offset;
}
}
+
+ static bfd_boolean
+ elfcore_grok_nto_status(abfd, note, tid)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+ pid_t *tid;
+ {
+ void *ddata = note->descdata;
+ char buf[100];
+ char *name;
+ asection *sect;
+
+ /* nto_procfs_status 'pid' field is at offset 0 */
+ elf_tdata (abfd)->core_pid = bfd_get_32( abfd, (bfd_byte *)ddata);
+
+ /* nto_procfs_status 'tid' field is at offset 4 */
+ elf_tdata (abfd)->core_lwpid = bfd_get_32( abfd, (bfd_byte *)ddata + 4);
+
+ /* nto_procfs_status 'what' field is at offset 14 */
+ elf_tdata (abfd)->core_signal = bfd_get_16( abfd, (bfd_byte *)ddata + 14);
+
+ /* pass tid back */
+ *tid = elf_tdata (abfd)->core_lwpid;
+
+ /* Make a ".qnx_core_status/%d" section. */
+ sprintf (buf, ".qnx_core_status/%d", *tid);
+
+ name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
+ if (name == NULL)
+ return FALSE;
+ strcpy (name, buf);
+
+ sect = bfd_make_section (abfd, name);
+ if (sect == NULL)
+ return FALSE;
+
+ sect->_raw_size = note->descsz;
+ sect->filepos = note->descpos;
+
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 2;
+
+ return (elfcore_maybe_make_sect (abfd, ".qnx_core_status", sect));
+ }
+
+
+ static bfd_boolean
+ elfcore_grok_nto_gregs(abfd, note, tid)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+ pid_t tid;
+ {
+ char buf[100];
+ char *name;
+ asection *sect;
+
+ /* Make a ".reg/%d" section. */
+ sprintf (buf, ".reg/%d", tid);
+
+ name = bfd_alloc (abfd, (bfd_size_type) strlen (buf) + 1);
+ if (name == NULL)
+ return FALSE;
+ strcpy (name, buf);
+
+ sect = bfd_make_section (abfd, name);
+ if (sect == NULL)
+ return FALSE;
+
+ sect->_raw_size = note->descsz;
+ sect->filepos = note->descpos;
+
+ sect->flags = SEC_HAS_CONTENTS;
+ sect->alignment_power = 2;
+
+ return elfcore_maybe_make_sect (abfd, ".reg", sect);
+ }
+
+ static bfd_boolean
+ elfcore_grok_nto_note (abfd, note)
+ bfd *abfd;
+ Elf_Internal_Note *note;
+ {
+ /* Every GREG section has a STATUS section before it. Store the
+ * tid from the previous call to pass down to the next gregs
+ * function. */
+ static pid_t tid = 1;
+ switch (note->type)
+ {
+ default:
+ return TRUE;
+ case 7: //QNT_CORE_INFO
+ return elfcore_make_note_pseudosection (abfd, ".qnx_core_info", note);
+ case 8: //QNT_CORE_STATUS
+ return elfcore_grok_nto_status (abfd, note, &tid);
+ case 9: //QNT_CORE_GREG
+ return elfcore_grok_nto_gregs (abfd, note, tid);
+ case 10: //QNT_CORE_FPREG
+ return elfcore_grok_prfpreg (abfd, note);
+ }
+ /* NOTREACHED */
+ }
Binary files src.orig/bfd/po/da.gmo and src/bfd/po/da.gmo differ
Binary files src.orig/bfd/po/es.gmo and src/bfd/po/es.gmo differ
Binary files src.orig/bfd/po/fr.gmo and src/bfd/po/fr.gmo differ
Binary files src.orig/bfd/po/ja.gmo and src/bfd/po/ja.gmo differ
Binary files src.orig/bfd/po/sv.gmo and src/bfd/po/sv.gmo differ
Binary files src.orig/bfd/po/tr.gmo and src/bfd/po/tr.gmo differ
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/config/mh-qnxnto src/config/mh-qnxnto
*** src.orig/config/mh-qnxnto Wed Dec 31 19:00:00 1969
--- src/config/mh-qnxnto Mon Jan 13 12:12:04 2003
***************
*** 0 ****
--- 1 ----
+ LIBCFLAGS += -DNEED_sys_siglist=1 -DNO_SYS_FILE_H
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/config.sub src/config.sub
*** src.orig/config.sub Wed Jan 8 17:09:30 2003
--- src/config.sub Mon Jan 13 16:22:24 2003
*************** case $basic_machine in
*** 727,732 ****
--- 727,740 ----
nsr-tandem)
basic_machine=nsr-tandem
;;
+ ntox86)
+ basic_machine=i386${os:--unknown}
+ os=-nto
+ ;;
+ ntomulti)
+ basic_machine=i686${os:--unknown}
+ os=-cygwin32
+ ;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/configure.in src/configure.in
*** src.orig/configure.in Mon Jan 27 14:47:23 2003
--- src/configure.in Tue Jan 28 13:50:28 2003
*************** case "${host}" in
*** 1089,1094 ****
--- 1089,1097 ----
tentative_cc="/usr/ccs/ATT/cc"
host_makefile_frag="config/mh-ncr3000"
;;
+ i[3456]86-*-nto*)
+ host_makefile_frag="config/mh-qnxnto"
+ ;;
i[[3456]]86-*-sco3.2v5*)
;;
i[[3456]]86-*-sco*)
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/config/i386/i386nto.mt src/gdb/config/i386/i386nto.mt
*** src.orig/gdb/config/i386/i386nto.mt Wed Dec 31 19:00:00 1969
--- src/gdb/config/i386/i386nto.mt Tue Jan 21 14:19:26 2003
***************
*** 0 ****
--- 1,4 ----
+ # Target: Intel 386 running qnx6
+ TDEPFILES= i386-tdep.o i387-tdep.o corelow.o solib.o solib-svr4.o \
+ remote-nto.o remote-nto-i386.o
+ TM_FILE= tm-i386nto.h
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/config/i386/nm-nto.h src/gdb/config/i386/nm-nto.h
*** src.orig/gdb/config/i386/nm-nto.h Wed Dec 31 19:00:00 1969
--- src/gdb/config/i386/nm-nto.h Fri Jan 31 12:24:06 2003
***************
*** 0 ****
--- 1 ----
+ #define __QNXNTO_USE_PROCFS__
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/config/i386/nto.mh src/gdb/config/i386/nto.mh
*** src.orig/gdb/config/i386/nto.mh Wed Dec 31 19:00:00 1969
--- src/gdb/config/i386/nto.mh Mon Jan 27 17:06:58 2003
***************
*** 0 ****
--- 1,9 ----
+ # Host: Intel 386 running QNX
+
+ MH_CFLAGS=-DNEED_SYS_SELECT_H
+
+ XM_FILE= xm-nto.h
+
+ NAT_FILE= nm-nto.h
+
+ NATDEPFILES= nto-procfs.o ser-ntopty.o
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/config/i386/tm-i386nto.h src/gdb/config/i386/tm-i386nto.h
*** src.orig/gdb/config/i386/tm-i386nto.h Wed Dec 31 19:00:00 1969
--- src/gdb/config/i386/tm-i386nto.h Fri Jan 31 12:24:06 2003
***************
*** 0 ****
--- 1,114 ----
+ /*-
+ QNX Debug Protocol, i386
+ */
+
+ #ifndef TM_I386QNX_H
+ #define TM_I386QNX_H 1
+
+ #define HAVE_I387_REGS
+
+ /* Pick up most of what we need from the generic i386 target include file. */
+
+ #include "i386/tm-i386.h"
+ #include "tm-qnxnto.h"
+
+ #define __QNXTARGET__
+ #define QNX_TARGET_CPUTYPE CPUTYPE_X86
+
+ /* Used in solib.c */
+ #define EBX_REGNUM 3
+
+ #undef DECR_PC_AFTER_BREAK
+ #define DECR_PC_AFTER_BREAK 0 /* neutrino rewinds to look more normal */
+
+ /* Offsets (in target ints) into jmp_buf. Not defined in any system header
+ file, so we have to step through setjmp/longjmp with a debugger and figure
+ them out. Note that <setjmp> defines _JBLEN as 10, which is the default
+ if no specific machine is selected, even though we only use 6 slots. */
+
+ #define JB_ELEMENT_SIZE sizeof(int) /* jmp_buf[_JBLEN] is array of ints */
+
+ #define JB_EBX 0
+ #define JB_ESI 1
+ #define JB_EDI 2
+ #define JB_EBP 3
+ #define JB_ESP 4
+ #define JB_EDX 5
+
+ #define JB_PC JB_EDX /* Setjmp()'s return PC saved in EDX */
+
+ /* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc (JB_PC) that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+ #if 0
+ extern int i386_get_longjmp_target PARAMS ((CORE_ADDR *));
+
+ #define GET_LONGJMP_TARGET(ADDR) i386_get_longjmp_target(ADDR)
+ #endif
+
+ /* The following redefines make backtracing through sigtramp work.
+ They manufacture a fake sigtramp frame and obtain the saved pc in sigtramp
+ from the ucontext structure which is pushed by the kernel on the
+ user stack. Unfortunately there are three variants of sigtramp handlers. */
+
+ #define I386V4_SIGTRAMP_SAVED_PC
+ #define IN_SIGTRAMP(pc, name) ((name) \
+ && (STREQ ("_sigreturn", name) \
+ || STREQ ("_sigacthandler", name) \
+ || STREQ ("sigvechandler", name)))
+
+ /* Saved Pc. Get it from ucontext if within sigtramp. */
+
+ #define sigtramp_saved_pc i386v4_sigtramp_saved_pc
+ extern CORE_ADDR i386v4_sigtramp_saved_pc PARAMS ((struct frame_info *));
+
+ /* Neutrino supports the 386 hardware debugging registers. */
+
+ #define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+ #define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) 1
+
+ /* After a watchpoint trap, the PC points to the instruction after
+ the one that caused the trap. Therefore we don't need to step over it.
+ But we do need to reset the status register to avoid another trap. */
+ #define HAVE_CONTINUABLE_WATCHPOINT
+
+ #define STOPPED_BY_WATCHPOINT(W) \
+ qnx_stopped_by_watchpoint()
+
+ /* Use these macros for watchpoint insertion/removal. */
+
+ #define target_insert_watchpoint(addr, len, type) \
+ qnx_insert_hw_watchpoint ( addr, len, type)
+
+ #define target_remove_watchpoint(addr, len, type) \
+ qnx_remove_hw_watchpoint ( addr, len, type)
+
+ /* Use these macros for watchpoint insertion/removal. */
+
+ #define target_remove_hw_breakpoint(ADDR,SHADOW) \
+ qnx_remove_hw_breakpoint(ADDR,SHADOW)
+
+ #define target_insert_hw_breakpoint(ADDR,SHADOW) \
+ qnx_insert_hw_breakpoint(ADDR,SHADOW)
+
+ #define FIND_NEW_THREADS qnx_find_new_threads
+ void qnx_find_new_threads PARAMS ((void));
+
+ /* default processor for search path for libs */
+ #define SOLIB_PROCESSOR "x86"
+
+ /* Use target_specific function to define link map offsets. */
+ extern struct link_map_offsets *i386_qnx_svr4_fetch_link_map_offsets (void);
+ #define SVR4_FETCH_LINK_MAP_OFFSETS() i386_qnx_svr4_fetch_link_map_offsets ()
+
+ #define HANDLE_SVR4_EXEC_EMULATORS 1
+ #include "solib.h" /* Support for shared libraries. */
+
+ #define NO_PTRACE_H
+
+ /* Use .ntox86-gdbinit */
+ #define EXTRA_GDBINIT_FILENAME ".ntox86-gdbinit"
+
+ #endif /* ifndef TM_I386QNX_H */
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/config/i386/xm-nto.h src/gdb/config/i386/xm-nto.h
*** src.orig/gdb/config/i386/xm-nto.h Wed Dec 31 19:00:00 1969
--- src/gdb/config/i386/xm-nto.h Fri Jan 31 12:24:06 2003
***************
*** 0 ****
--- 1,46 ----
+ /* Host support for i386.
+ Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
+ Changes for 80386 by Pace Willisson (pace@prep.ai.mit.edu), July 1988.
+
+ 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. */
+
+ #define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+ /* I'm running gdb 3.4 under 386/ix 2.0.2, which is a derivative of AT&T's
+ Sys V/386 3.2.
+
+ On some machines, gdb crashes when it's starting up while calling the
+ vendor's termio tgetent() routine. It always works when run under
+ itself (actually, under 3.2, it's not an infinitely recursive bug.)
+ After some poking around, it appears that depending on the environment
+ size, or whether you're running YP, or the phase of the moon or something,
+ the stack is not always long-aligned when main() is called, and tgetent()
+ takes strong offense at that. On some machines this bug never appears, but
+ on those where it does, it occurs quite reliably. */
+ #define ALIGN_STACK_ON_STARTUP
+
+ /* define USG if you are using sys5 /usr/include's */
+ #define USG
+
+ #ifndef HAVE_TERMIOS_H
+ #define HAVE_TERMIO
+ #endif
+
+ /* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+ #define KERNEL_U_ADDR 0xe0000000
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/config/tm-qnxnto.h src/gdb/config/tm-qnxnto.h
*** src.orig/gdb/config/tm-qnxnto.h Wed Dec 31 19:00:00 1969
--- src/gdb/config/tm-qnxnto.h Fri Jan 31 12:24:06 2003
***************
*** 0 ****
--- 1,69 ----
+ /* Target machine sub-description for QNX Neutrino version 6.
+ This is included by other tm-*.h files to specify nto specific
+ stuff. Copyright 2002 Free Software Foundation, Inc.
+
+ 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. */
+
+ #define __QNXTARGET__
+ #include "tm-sysv4.h"
+
+ #define FIND_NEW_THREADS qnx_find_new_threads
+ void qnx_find_new_threads PARAMS ((void));
+
+ #define target_pid_to_str(PTID) \
+ qnx_pid_to_str(PTID)
+ extern char *qnx_pid_to_str PARAMS ((ptid_t ptid));
+
+ /* 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"}
+
+ /* See solib-svr4.c
+ * This works around a problem with static binaries. An internal breakpoint
+ * is set on _start but for whatever reason, gdb doesn't handle it properly
+ * and claims a SIGTRAP has been raised on the inferior. If we move the
+ * shlib_event breakpoint ahead to main (this already happened by default
+ * on sh for some reason), then it works. FIXME: we need to discover why
+ * gdb isn't handling breakpoints properly at the early stages of execution. */
+ #define SOLIB_BKPT_NAME "main"
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/configure.host src/gdb/configure.host
*** src.orig/gdb/configure.host Sat Feb 1 07:28:00 2003
--- src/gdb/configure.host Mon Feb 3 14:15:16 2003
*************** i[3456]86-*-msdosdjgpp*) gdb_host=go32 ;
*** 64,69 ****
--- 64,70 ----
i[3456]86-*-linux*) gdb_host=linux ;;
i[3456]86-*-lynxos*) gdb_host=i386lynx ;;
i[3456]86-*-gnu*) gdb_host=i386gnu ;;
+ i[3456]86-*-nto* | x86-*-nto*) gdb_host=nto ;;
i[3456]86-*-openbsd*) gdb_host=obsd ;;
i[3456]86-*-sco3.2v5*) gdb_host=i386sco5 ;;
i[3456]86-*-sco3.2v4*) gdb_host=i386sco4 ;;
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/configure.tgt src/gdb/configure.tgt
*** src.orig/gdb/configure.tgt Fri Jan 31 11:32:44 2003
--- src/gdb/configure.tgt Mon Feb 3 14:15:16 2003
*************** i[3456]86-*-netbsd*) gdb_target=nbsd ;;
*** 90,95 ****
--- 90,96 ----
i[3456]86-*-openbsd*) gdb_target=obsd ;;
i[3456]86-*-go32*) gdb_target=i386aout ;;
i[3456]86-*-msdosdjgpp*) gdb_target=go32 ;;
+ i[3456]86-*-nto*) gdb_target=i386nto;;
i[3456]86-*-lynxos*) gdb_target=i386lynx ;;
i[3456]86-*-solaris*) gdb_target=i386sol2 ;;
i[3456]86-*-sysv4.2*) gdb_target=i386v42mp ;;
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/nto-procfs.c src/gdb/nto-procfs.c
*** src.orig/gdb/nto-procfs.c Wed Dec 31 19:00:00 1969
--- src/gdb/nto-procfs.c Mon Feb 3 11:36:20 2003
***************
*** 0 ****
--- 1,1450 ----
+ /* Machine independent support for QNX Neutrino /proc (process file system) for GDB.
+ Copyright 1991, 1992-99, 2000 Free Software Foundation, Inc.
+ Written by Colin Burgess at QNX Software Systems Limited.
+
+ 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 "defs.h"
+
+ #include <errno.h>
+ #include <string.h>
+ #include <fcntl.h>
+ #include <spawn.h>
+ #include <sys/debug.h>
+ #include <sys/procfs.h>
+ #include <sys/neutrino.h>
+ #include <sys/types.h>
+ #include <sys/syspage.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <dirent.h>
+ #include <sys/netmgr.h>
+
+ #include "defs.h"
+ #include "gdb_string.h"
+ #include "gdbcore.h"
+ #include "frame.h"
+ #include "inferior.h"
+ #include "bfd.h"
+ #include "symfile.h"
+ #include "target.h"
+ #include "gdb_wait.h"
+ #include "gdbcmd.h"
+ #include "objfiles.h"
+ #include "gdb-stabs.h"
+ #include "gdbthread.h"
+ #include "nto-share/dsmsgs.h"
+ #include "dcache.h"
+ #include "gdb_stat.h"
+ #include "command.h"
+
+ #define NULL_PID 0
+ #define _DEBUG_FLAG_TRACE (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|_DEBUG_FLAG_TRACE_WR|_DEBUG_FLAG_TRACE_MODIFY)
+
+ static struct target_ops procfs_ops;
+ int ctl_fd;
+ static void (*ofunc) ();
+ static procfs_run run;
+
+ static void procfs_open PARAMS ((char *, int));
+ static int procfs_can_run PARAMS ((void));
+ static ptid_t procfs_wait PARAMS ((ptid_t, struct target_waitstatus *));
+ static int procfs_xfer_memory
+ PARAMS ((CORE_ADDR, char *, int, int, struct mem_attrib * attrib,
+ struct target_ops *));
+ static void procfs_fetch_registers PARAMS ((int));
+ static void notice_signals (void);
+
+ static void init_procfs_ops PARAMS ((void));
+ static ptid_t do_attach PARAMS ((ptid_t ptid));
+
+ extern char **qnx_parse_redirection
+ PARAMS ((char *start_argv[], char **in, char **out, char **err));
+ extern short int qnx_swap16 PARAMS ((int val));
+ extern void qnx_init_solib_search_path ();
+ extern unsigned qnx_cpu_register_area
+ PARAMS ((unsigned first_regno, unsigned last_regno, unsigned char *subcmd,
+ unsigned *off, unsigned *len));
+ extern int qnx_cpu_register_store
+ PARAMS ((int endian, unsigned first_regno, unsigned last_regno, void *data));
+
+ /*
+ 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" };
+ static unsigned nto_procfs_node = ND_LOCAL_NODE;
+
+ /*
+ This is a simple wrapper for the netmgr_strtond() function. It is
+ only called from the QNX_NODE macro declared below. The reason for
+ the macro and function are because QNX node descriptors are transient,
+ so we have to re-acquire them every time.
+ */
+ static unsigned
+ procfs_qnx_node (unsigned node)
+ {
+ if (node == -1)
+ {
+ error ("Lost the QNX node. Debug session probably over.");
+ /* NOTREACHED */
+ }
+ return (node);
+ }
+
+ /*
+ This define returns the current QNX Node, or -1 on error. It calls the above
+ function which is a simple wrapper for the error() call.
+ */
+ #define QNX_NODE (ND_NODE_CMP(nto_procfs_node, ND_LOCAL_NODE) == 0 ? ND_LOCAL_NODE : \
+ procfs_qnx_node(netmgr_strtond(nto_procfs_path, 0)))
+
+ /*
+ 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/gp". If arg is not a valid QNX node, we will default to local.
+ */
+ static void
+ procfs_open (arg, from_tty)
+ char *arg;
+ int from_tty;
+ {
+ char *nodestr;
+ char *endstr;
+ char buffer[50];
+ int fd, total_size;
+ procfs_sysinfo *sysinfo;
+
+ // Set the default node used for spawning to this one, and only override it
+ // if there is a valid arg.
+
+ nto_procfs_node = ND_LOCAL_NODE;
+ nodestr = arg ? strdup (arg) : arg;
+
+ init_thread_list ();
+
+ if (nodestr)
+ {
+ nto_procfs_node = netmgr_strtond (nodestr, &endstr);
+ if (nto_procfs_node == -1)
+ {
+ 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));
+ xfree (nodestr);
+ nodestr = NULL;
+ nto_procfs_node = ND_LOCAL_NODE;
+ }
+ else if (*endstr)
+ {
+ if (*(endstr - 1) == '/')
+ *(endstr - 1) = 0;
+ else
+ *endstr = 0;
+ }
+ }
+ sprintf (nto_procfs_path, "%s%s", nodestr ? nodestr : "", "/proc");
+ if (nodestr)
+ xfree (nodestr);
+
+ fd = open (nto_procfs_path, O_RDONLY);
+ if (fd == -1)
+ {
+ printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno,
+ strerror (errno));
+ error ("Invalid procfs arg");
+ /* NOTREACHED */
+ }
+
+ 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));
+ close (fd);
+ error ("Devctl failed.");
+ /* NOTREACHED */
+ }
+ else
+ {
+ total_size = sysinfo->total_size;
+ if (!(sysinfo = alloca (total_size)))
+ {
+ printf_filtered ("Memory error: %d (%s)\n", errno,
+ strerror (errno));
+ close (fd);
+ error ("alloca failed.");
+ /* NOTREACHED */
+ }
+ else
+ {
+ if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK)
+ {
+ printf_filtered ("Error getting sysinfo: %d (%s)\n", errno,
+ strerror (errno));
+ close (fd);
+ error ("Devctl failed.");
+ /* NOTREACHED */
+ }
+ else
+ {
+ if (sysinfo->type != QNX_TARGET_CPUTYPE)
+ {
+ close (fd);
+ error ("Invalid target CPU.");
+ /* NOTREACHED */
+ }
+ }
+ }
+ }
+ close (fd);
+ printf_filtered ("Debugging using %s\n", nto_procfs_path);
+
+ }
+
+ static void
+ procfs_set_thread (ptid)
+ ptid_t ptid;
+ {
+ pid_t tid;
+
+ tid = ptid_get_tid (inferior_ptid);
+ devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0);
+ }
+
+ /* Return nonzero if the thread TH is still alive. */
+ static int
+ procfs_thread_alive (ptid_t ptid)
+ {
+ pid_t tid;
+
+ tid = ptid_get_tid (ptid);
+ if (devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0) == EOK)
+ return 1;
+ return 0;
+ }
+
+
+ void
+ procfs_find_new_threads (void)
+ {
+ procfs_status status;
+ pid_t pid;
+ ptid_t ptid;
+
+ if (ctl_fd == -1)
+ return;
+
+ pid = ptid_get_pid (inferior_ptid);
+
+ for (status.tid = 1;; ++status.tid)
+ {
+ if (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0) !=
+ EOK && status.tid != 0)
+ {
+ break;
+ }
+ ptid = ptid_build (pid, 0, qnx_swap16 (status.tid));
+ if (!in_thread_list (ptid))
+ add_thread (ptid);
+ }
+ return;
+ }
+
+ void
+ procfs_pidlist (char *args, int from_tty)
+ {
+ static DIR *dp = NULL;
+ struct dirent *dirp = NULL;
+ int fd = -1;
+ char buf[512];
+ procfs_info *pidinfo = NULL;
+ procfs_debuginfo *info = NULL;
+ procfs_status *status = NULL;
+ pid_t num_threads = 0;
+ pid_t pid;
+ char name[512];
+
+ dp = opendir (nto_procfs_path);
+ if (dp == NULL)
+ {
+ printf ("failed to opendir \"%s\" - %d (%s)", nto_procfs_path, errno,
+ strerror (errno));
+ return;
+ }
+
+ // start scan at first pid
+ rewinddir (dp);
+
+ do
+ {
+ // Get the right pid and procfs path for the pid
+ do
+ {
+ if ((dirp = readdir (dp)) == NULL)
+ {
+ closedir (dp);
+ return;
+ }
+ strcat (strcat
+ (strcat (strcpy (buf, nto_procfs_path), "/"), dirp->d_name),
+ "/as");
+ }
+ while ((pid = atoi (dirp->d_name)) == 0);
+
+ // open the procfs path
+ if ((fd = open (buf, O_RDONLY)) == -1)
+ {
+ printf ("failed to open %s - %d (%s)\n", buf, errno,
+ 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));
+ break;
+ }
+ num_threads = pidinfo->num_threads;
+
+ info = (procfs_debuginfo *) buf;
+ if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) != EOK)
+ strcpy (name, "unavailable");
+ else
+ strcpy (name, info->path);
+
+ //
+ // Collect state info on all the threads.
+ //
+ status = (procfs_status *) buf;
+ for (status->tid = 1; status->tid <= num_threads; status->tid++)
+ {
+ if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) != EOK
+ && status->tid != 0)
+ break;
+ if (status->tid != 0)
+ printf_filtered ("%s - %d/%d\n", name, pid, status->tid);
+ }
+ close (fd);
+ }
+ while (dirp != NULL);
+
+ close (fd);
+ closedir (dp);
+ return;
+ }
+
+
+ void
+ procfs_meminfo (char *args, int from_tty)
+ {
+ procfs_mapinfo *mapinfos = NULL;
+ static int num_mapinfos = 0;
+ procfs_mapinfo *mapinfo_p, *mapinfo_p2;
+ int flags = ~0, err, num, i, j;
+
+ struct
+ {
+ procfs_debuginfo info;
+ char buff[_POSIX_PATH_MAX];
+ } map;
+
+ struct info
+ {
+ unsigned addr;
+ unsigned size;
+ unsigned flags;
+ unsigned debug_vaddr;
+ unsigned long long offset;
+ };
+
+ struct printinfo
+ {
+ unsigned long long ino;
+ unsigned dev;
+ struct info text;
+ struct info data;
+ char name[256];
+ } printme;
+
+
+ // Get the number of map entrys
+ if ((err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num)) != EOK)
+ {
+ printf ("failed devctl num mapinfos - %d (%s)\n", err, strerror (err));
+ return;
+ }
+
+ mapinfos = xmalloc (num * sizeof (procfs_mapinfo));
+
+ num_mapinfos = num;
+ mapinfo_p = mapinfos;
+
+ // fill the map entrys
+ if ((err =
+ devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p,
+ num * sizeof (procfs_mapinfo), &num)) != EOK)
+ {
+ printf ("failed devctl mapinfos - %d (%s)\n", err, strerror (err));
+ xfree (mapinfos);
+ return;
+ }
+
+ num = min (num, num_mapinfos);
+
+ //
+ // Run through the list of mapinfo's, and store the data and text info
+ // so we can print it at the bottom of the loop.
+ //
+ for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++)
+ {
+ if (!(mapinfo_p->flags & flags))
+ mapinfo_p->ino = 0;
+
+ if (mapinfo_p->ino == 0) /* already visited */
+ continue;
+
+ map.info.vaddr = mapinfo_p->vaddr;
+
+ if ((err =
+ devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0)) != EOK)
+ continue;
+
+ memset (&printme, 0, sizeof printme);
+ printme.dev = mapinfo_p->dev;
+ printme.ino = mapinfo_p->ino;
+ printme.text.addr = mapinfo_p->vaddr;
+ printme.text.size = mapinfo_p->size;
+ printme.text.flags = mapinfo_p->flags;
+ printme.text.offset = mapinfo_p->offset;
+ printme.text.debug_vaddr = map.info.vaddr;
+ strcpy (printme.name, map.info.path);
+
+ /* check for matching data */
+ for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++)
+ {
+ if (mapinfo_p2->vaddr != mapinfo_p->vaddr &&
+ mapinfo_p2->ino == mapinfo_p->ino
+ && mapinfo_p2->dev == mapinfo_p->dev)
+ {
+ map.info.vaddr = mapinfo_p2->vaddr;
+ if ((err =
+ devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map),
+ 0)) != EOK)
+ continue;
+
+ if (strcmp (map.info.path, printme.name))
+ {
+ continue;
+ }
+
+ /*
+ * lower debug_vaddr is always text, if nessessary, swap
+ */
+ if ((int) map.info.vaddr < (int) printme.text.debug_vaddr)
+ {
+ memcpy (&(printme.data), &(printme.text),
+ sizeof (printme.data));
+ printme.text.addr = mapinfo_p2->vaddr;
+ printme.text.size = mapinfo_p2->size;
+ printme.text.flags = mapinfo_p2->flags;
+ printme.text.offset = mapinfo_p2->offset;
+ printme.text.debug_vaddr = map.info.vaddr;
+ }
+ else
+ {
+ printme.data.addr = mapinfo_p2->vaddr;
+ printme.data.size = mapinfo_p2->size;
+ printme.data.flags = mapinfo_p2->flags;
+ printme.data.offset = mapinfo_p2->offset;
+ printme.data.debug_vaddr = map.info.vaddr;
+ }
+ mapinfo_p2->ino = 0;
+ }
+ }
+ mapinfo_p->ino = 0;
+
+ printf_filtered ("%s\n", printme.name);
+ printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size,
+ printme.text.addr);
+ printf_filtered ("\t\tflags=%08x\n", printme.text.flags);
+ printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr);
+ printf_filtered ("\t\toffset=%016llx\n", printme.text.offset);
+ if (printme.data.size)
+ {
+ printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size,
+ printme.data.addr);
+ printf_filtered ("\t\tflags=%08x\n", printme.data.flags);
+ printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr);
+ printf_filtered ("\t\toffset=%016llx\n", printme.data.offset);
+ }
+ printf_filtered ("\tdev=0x%x\n", printme.dev);
+ printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino);
+ }
+ xfree (mapinfos);
+ return;
+ }
+
+ /* Print status information about what we're accessing. */
+
+ static void
+ procfs_files_info (ignore)
+ struct target_ops *ignore;
+ {
+ printf_unfiltered ("\tUsing the running image of %s %s via %s.\n",
+ attach_flag ? "attached" : "child",
+ target_pid_to_str (inferior_ptid), nto_procfs_path);
+ }
+
+ /* Mark our target-struct as eligible for stray "run" and "attach" commands. */
+ static int
+ procfs_can_run ()
+ {
+ return 1;
+ }
+
+ /* Attach to process PID, then initialize for debugging it */
+ static void
+ procfs_attach (args, from_tty)
+ char *args;
+ int from_tty;
+ {
+ char *exec_file;
+ int pid;
+
+ if (!args)
+ error_no_arg ("process-id to attach");
+
+ pid = atoi (args);
+
+ if (pid == getpid ())
+ error ("Attaching GDB to itself is not a good idea...");
+
+ if (from_tty)
+ {
+ exec_file = (char *) get_exec_file (0);
+
+ if (exec_file)
+ printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
+ target_pid_to_str (pid_to_ptid (pid)));
+ else
+ printf_unfiltered ("Attaching to %s\n",
+ target_pid_to_str (pid_to_ptid (pid)));
+
+ gdb_flush (gdb_stdout);
+ }
+ inferior_ptid = do_attach (pid_to_ptid (pid));
+ push_target (&procfs_ops);
+ }
+
+ static ptid_t
+ do_attach (ptid_t ptid)
+ {
+ procfs_status status;
+ struct sigevent event;
+ char path[100];
+
+ sprintf (path, "%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));
+ /* NOTREACHED */
+ }
+ if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK)
+ {
+ error ("Couldn't stop process");
+ /* NOTREACHED */
+ }
+
+ // Define a sigevent for process stopped notification.
+ event.sigev_notify = SIGEV_SIGNAL_THREAD;
+ event.sigev_signo = SIGUSR1;
+ event.sigev_code = 0;
+ event.sigev_value.sival_ptr = NULL;
+ event.sigev_priority = -1;
+ devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0);
+
+ if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK)
+ {
+ if (status.flags & _DEBUG_FLAG_STOPPED)
+ {
+ SignalKill (QNX_NODE, PIDGET (ptid), 0, SIGCONT, 0, 0);
+ }
+ }
+ attach_flag = 1;
+ qnx_init_solib_search_path ();
+ return ptid;
+ }
+
+ /* Ask the user what to do when an interrupt is received. */
+
+ static void
+ interrupt_query ()
+ {
+ target_terminal_ours ();
+
+ if (query ("Interrupted while waiting for the program.\n\
+ Give up (and stop debugging it)? "))
+ {
+ target_mourn_inferior ();
+ throw_exception (RETURN_QUIT);
+ }
+
+ target_terminal_inferior ();
+ }
+
+ /* The user typed ^C twice. */
+ static void
+ qnx_interrupt_twice (signo)
+ int signo;
+ {
+ signal (signo, ofunc);
+ interrupt_query ();
+ signal (signo, qnx_interrupt_twice);
+ }
+
+ static void
+ qnx_interrupt (int signo)
+ {
+ /* If this doesn't work, try more severe steps. */
+ signal (signo, qnx_interrupt_twice);
+
+ target_stop ();
+ }
+
+ static ptid_t
+ procfs_wait (ptid, ourstatus)
+ ptid_t ptid;
+ struct target_waitstatus *ourstatus;
+ {
+ sigset_t set;
+ siginfo_t info;
+ procfs_status status;
+ static int exit_signo = 0; //used to track signals that cause termination
+
+ ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ {
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ ourstatus->value.sig = TARGET_SIGNAL_0;
+ exit_signo = 0;
+ return null_ptid;
+ }
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGUSR1);
+
+ devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
+ while (!(status.flags & _DEBUG_FLAG_ISTOP))
+ {
+ ofunc = (void (*)()) signal (SIGINT, qnx_interrupt);
+ sigwaitinfo (&set, &info);
+ signal (SIGINT, ofunc);
+ devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0);
+ }
+
+ if (status.flags & _DEBUG_FLAG_SSTEP)
+ {
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ }
+ // Was it a breakpoint?
+ else if (status.flags & _DEBUG_FLAG_TRACE)
+ {
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ ourstatus->value.sig = TARGET_SIGNAL_TRAP;
+ }
+ else if (status.flags & _DEBUG_FLAG_ISTOP)
+ {
+ switch (status.why)
+ {
+ case _DEBUG_WHY_SIGNALLED:
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ ourstatus->value.sig =
+ target_signal_from_host (status.info.si_signo);
+ exit_signo = 0;
+ break;
+ case _DEBUG_WHY_FAULTED:
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ if (status.info.si_signo == SIGTRAP)
+ {
+ ourstatus->value.sig = 0;
+ exit_signo = 0;
+ }
+ else
+ {
+ ourstatus->value.sig =
+ target_signal_from_host (status.info.si_signo);
+ exit_signo = ourstatus->value.sig;
+ }
+ break;
+
+ case _DEBUG_WHY_TERMINATED:
+ {
+ int waitval = 0;
+
+ waitpid (PIDGET (inferior_ptid), &waitval, WNOHANG);
+ if (exit_signo)
+ {
+ ourstatus->kind = TARGET_WAITKIND_SIGNALLED; //abnormal death
+ ourstatus->value.sig = exit_signo;
+ }
+ else
+ {
+ ourstatus->kind = TARGET_WAITKIND_EXITED; //normal death
+ ourstatus->value.integer = WEXITSTATUS (waitval); //status.what;
+ }
+ exit_signo = 0;
+ break;
+ }
+
+ case _DEBUG_WHY_REQUESTED:
+ // we are assuming a requested stop is due to a SIGINT
+ ourstatus->kind = TARGET_WAITKIND_STOPPED;
+ ourstatus->value.sig = TARGET_SIGNAL_INT;
+ exit_signo = 0;
+ break;
+ }
+ }
+
+ return inferior_ptid;
+ }
+
+ /*
+
+ LOCAL FUNCTION
+
+ procfs_fetch_registers -- fetch current registers from inferior
+
+ SYNOPSIS
+
+ void procfs_fetch_registers (int regno)
+
+ DESCRIPTION
+
+ Read the current values of the inferior's registers, both the
+ general register set and floating point registers (if supported)
+ and update gdb's idea of their current values.
+
+ */
+
+ extern void nto_supply_gregset (procfs_greg * gregsetp);
+ extern void nto_supply_fpregset (procfs_fpreg * fpregsetp);
+
+ static void
+ procfs_fetch_registers (regno)
+ int regno;
+ {
+ union
+ {
+ procfs_greg greg;
+ procfs_fpreg fpreg;
+ }
+ reg;
+ int regsize;
+
+ procfs_set_thread (inferior_ptid);
+ if (devctl (ctl_fd, DCMD_PROC_GETGREG, ®, sizeof (reg), ®size) == EOK)
+ {
+ nto_supply_gregset (®.greg);
+ }
+ if (devctl (ctl_fd, DCMD_PROC_GETFPREG, ®, sizeof (reg), ®size) ==
+ EOK)
+ {
+ nto_supply_fpregset (®.fpreg);
+ }
+ }
+
+ /*
+
+ LOCAL FUNCTION
+
+ procfs_xfer_memory -- copy data to or from inferior memory space
+
+ SYNOPSIS
+
+ int procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int dowrite, struct target_ops target)
+
+ DESCRIPTION
+
+ Copy LEN bytes to/from inferior's memory starting at MEMADDR
+ from/to debugger memory starting at MYADDR. Copy from inferior
+ if DOWRITE is zero or to inferior if DOWRITE is nonzero.
+
+ 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.
+
+ NOTES
+
+ The /proc interface makes this an almost trivial task.
+ */
+
+ static int
+ procfs_xfer_memory (memaddr, myaddr, len, dowrite, attrib, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int dowrite;
+ struct mem_attrib *attrib; /* ignored */
+ struct target_ops *target; /* ignored */
+ {
+ int nbytes = 0;
+
+ if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr)
+ {
+ if (dowrite)
+ {
+ nbytes = write (ctl_fd, myaddr, len);
+ }
+ else
+ {
+ nbytes = read (ctl_fd, myaddr, len);
+ }
+ if (nbytes < 0)
+ {
+ nbytes = 0;
+ }
+ }
+ return (nbytes);
+ }
+
+ /* Take a program previously attached to and detaches it.
+ The program resumes execution and will no longer stop
+ on signals, etc. We'd better not have left any breakpoints
+ in the program or it'll die when it hits one. For this
+ to work, it may be necessary for the process to have been
+ previously attached. It *might* work if the program was
+ started via the normal ptrace (PTRACE_TRACEME). */
+
+ static void
+ procfs_detach (args, from_tty)
+ char *args;
+ int from_tty;
+ {
+ int siggnal = 0;
+
+ if (from_tty)
+ {
+ char *exec_file = get_exec_file (0);
+ if (exec_file == 0)
+ exec_file = "";
+ printf_unfiltered ("Detaching from program: %s %s\n",
+ exec_file, target_pid_to_str (inferior_ptid));
+ gdb_flush (gdb_stdout);
+ }
+ if (args)
+ siggnal = atoi (args);
+
+ if (siggnal)
+ SignalKill (QNX_NODE, PIDGET (inferior_ptid), 0, siggnal, 0, 0);
+
+ close (ctl_fd);
+ ctl_fd = -1;
+ init_thread_list ();
+ inferior_ptid = null_ptid;
+ attach_flag = 0;
+ unpush_target (&procfs_ops); /* Pop out of handling an inferior */
+ }
+
+ static int
+ nto_breakpoint (addr, type, size)
+ CORE_ADDR addr;
+ int type;
+ int size;
+ {
+ procfs_break brk;
+
+ brk.type = type;
+ brk.addr = addr;
+ brk.size = size;
+ if ((errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0)) !=
+ EOK)
+ {
+ return 1;
+ }
+ return 0;
+ }
+
+ static int
+ procfs_insert_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+ {
+ return nto_breakpoint (addr, _DEBUG_BREAK_EXEC, 0);
+ }
+
+ static int
+ procfs_remove_breakpoint (addr, contents_cache)
+ CORE_ADDR addr;
+ char *contents_cache;
+ {
+ return nto_breakpoint (addr, _DEBUG_BREAK_EXEC, -1);
+ }
+
+
+ static void
+ procfs_resume (ptid_t ptid, int step, enum target_signal signo)
+ {
+ int signal_to_pass;
+ procfs_status status;
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return;
+
+ procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid :
+ ptid);
+
+
+ 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);
+
+ run.flags |= _DEBUG_RUN_ARM;
+
+ sigemptyset (&run.trace);
+ notice_signals ();
+ 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 (signal_to_pass != status.info.si_signo)
+ {
+ SignalKill (QNX_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 */
+ sigdelset (&run.trace, signal_to_pass);
+ }
+ }
+ }
+ else
+ {
+ run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
+ }
+ if ((errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0)) != EOK)
+ {
+ perror ("run error!\n");
+ return;
+ }
+ }
+
+ static void
+ procfs_mourn_inferior ()
+ {
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ {
+ SignalKill (QNX_NODE, PIDGET (inferior_ptid), 0, SIGKILL, 0, 0);
+ close (ctl_fd);
+ }
+ inferior_ptid = null_ptid;
+ init_thread_list ();
+ unpush_target (&procfs_ops);
+ generic_mourn_inferior ();
+ attach_flag = 0;
+ }
+
+ /* This function breaks up an argument string into an argument
+ * vector suitable for passing to execvp().
+ * E.g., on "run a b c d" this routine would get as input
+ * the string "a b c d", and as output it would fill in argv with
+ * the four arguments "a", "b", "c", "d". The only additional
+ * functionality is simple quoting. The gdb command:
+ * run a "b c d" f
+ * will fill in argv with the three args "a", "b c d", "e".
+ */
+ static void
+ breakup_args (scratch, argv)
+ char *scratch;
+ char **argv;
+ {
+ char *pp, *cp = scratch;
+ char quoting = 0;
+
+ for (;;)
+ {
+
+ /* Scan past leading separators */
+ quoting = 0;
+ while (*cp == ' ' || *cp == '\t' || *cp == '\n')
+ {
+ cp++;
+ }
+
+ /* Break if at end of string */
+ if (*cp == '\0')
+ break;
+
+ /* Take an arg */
+ if (*cp == '"')
+ {
+ cp++;
+ quoting = strchr (cp, '"') ? 1 : 0;
+ }
+
+ *argv++ = cp;
+
+ /* Scan for next arg separator */
+ pp = cp;
+ if (quoting)
+ cp = strchr (pp, '"');
+ if ((cp == NULL) || (!quoting))
+ cp = strchr (pp, ' ');
+ if (cp == NULL)
+ cp = strchr (pp, '\t');
+ if (cp == NULL)
+ cp = strchr (pp, '\n');
+
+ /* No separators => end of string => break */
+ if (cp == NULL)
+ {
+ pp = cp;
+ break;
+ }
+
+ /* Replace the separator with a terminator */
+ *cp++ = '\0';
+ }
+
+ /* execv requires a null-terminated arg vector */
+ *argv = NULL;
+
+ }
+
+ static void
+ procfs_create_inferior (exec_file, allargs, env)
+ char *exec_file;
+ char *allargs;
+ char **env;
+ {
+ struct inheritance inherit;
+ pid_t pid;
+ int flags, errn;
+ char **argv, *args;
+ char *in = "", *out = "", *err = "";
+ int fd, fds[3];
+ sigset_t set;
+
+ argv =
+ (char **) xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) *
+ sizeof (*argv));
+ argv[0] = get_exec_file (1);
+ if (!argv[0])
+ {
+ if (exec_file)
+ argv[0] = exec_file;
+ else
+ return;
+ }
+
+ args = strdup (allargs);
+ breakup_args (args, exec_file ? &argv[1] : &argv[0]);
+
+ argv = qnx_parse_redirection (argv, &in, &out, &err);
+
+ fds[0] = STDIN_FILENO;
+ fds[1] = STDOUT_FILENO;
+ fds[2] = STDERR_FILENO;
+
+ /* If the user specified I/O via gdb's --tty= arg, use it, but only
+ if the i/o is not also being specified via redirection. */
+ if (inferior_io_terminal)
+ {
+ if (!in[0])
+ in = inferior_io_terminal;
+ if (!out[0])
+ out = inferior_io_terminal;
+ if (!err[0])
+ err = inferior_io_terminal;
+ }
+
+ if (in[0])
+ {
+ if ((fd = open (in, O_RDONLY)) == -1)
+ {
+ perror (in);
+ }
+ else
+ fds[0] = fd;
+ }
+ if (out[0])
+ {
+ if ((fd = open (out, O_WRONLY)) == -1)
+ {
+ perror (out);
+ }
+ else
+ fds[1] = fd;
+ }
+ if (err[0])
+ {
+ if ((fd = open (err, O_WRONLY)) == -1)
+ {
+ perror (err);
+ }
+ else
+ fds[2] = fd;
+ }
+
+ /* 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));
+
+ if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0)
+ {
+ inherit.nd = QNX_NODE;
+ inherit.flags |= SPAWN_SETND;
+ inherit.flags &= ~SPAWN_EXEC;
+ }
+ 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, strerror (errno));
+
+ if (fds[0] != STDIN_FILENO)
+ close (fds[0]);
+ if (fds[1] != STDOUT_FILENO)
+ close (fds[1]);
+ if (fds[2] != STDERR_FILENO)
+ close (fds[2]);
+
+ inferior_ptid = do_attach (pid_to_ptid (pid));
+
+ attach_flag = 0;
+ flags = _DEBUG_FLAG_KLC; // Kill-on-Last-Close flag
+ if ((errn =
+ devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0)) != EOK)
+ {
+ // warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n", errn, strerror(errn) );
+ }
+ push_target (&procfs_ops);
+ target_terminal_init ();
+
+ /* NYI: add the symbol info somewhere? */
+ #ifdef SOLIB_CREATE_INFERIOR_HOOK
+ if (exec_bfd != NULL
+ || (symfile_objfile != NULL && symfile_objfile->obfd != NULL))
+ SOLIB_CREATE_INFERIOR_HOOK (pid);
+ #endif
+ }
+
+ static void
+ procfs_stop ()
+ {
+ devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0);
+ }
+
+ static void
+ procfs_kill_inferior ()
+ {
+ target_mourn_inferior ();
+ }
+
+ /* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. */
+
+ static void
+ procfs_prepare_to_store ()
+ {
+ }
+
+ void
+ procfs_store_registers (regno)
+ int regno;
+ {
+ union
+ {
+ procfs_greg greg;
+ procfs_fpreg fpreg;
+ }
+ reg;
+ unsigned first;
+ unsigned last;
+ unsigned end;
+ unsigned off;
+ unsigned len;
+ unsigned char subcmd;
+ char *data;
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return;
+ procfs_set_thread (inferior_ptid);
+
+ if (regno == -1)
+ {
+ first = 0;
+ last = NUM_REGS - 1;
+ }
+ else
+ {
+ first = regno;
+ last = regno;
+ }
+ while (first <= last)
+ {
+ end = qnx_cpu_register_area (first, last, &subcmd, &off, &len);
+ switch (subcmd)
+ {
+ case DSMSG_REG_GENERAL:
+ if (devctl
+ (ctl_fd, DCMD_PROC_GETGREG, ®.greg, sizeof (reg.greg),
+ 0) != EOK)
+ {
+ printf ("error fetching general registers\n");
+ break;
+ }
+ data = (char *) ®.greg + off;
+ if (qnx_cpu_register_store (0, first, end, data))
+ {
+ devctl (ctl_fd, DCMD_PROC_SETGREG, ®.greg,
+ sizeof (reg.greg), 0);
+ }
+ break;
+ case DSMSG_REG_FLOAT:
+ if (devctl
+ (ctl_fd, DCMD_PROC_GETFPREG, ®.fpreg,
+ sizeof (reg.fpreg), 0) != EOK)
+ {
+ /* Do not print a warning. Not all inferiors
+ have fpregs. */
+ break;
+ }
+ data = (char *) ®.fpreg + off;
+ if (qnx_cpu_register_store (0, first, end, data))
+ {
+ devctl (ctl_fd, DCMD_PROC_SETFPREG, ®.fpreg,
+ sizeof (reg.fpreg), 0);
+ }
+ break;
+ case DSMSG_REG_SYSTEM:
+ break;
+ default:
+ break;
+ }
+ first = end + 1;
+ }
+ }
+
+ static void
+ notice_signals (void)
+ {
+ int signo;
+
+ for (signo = 1; 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);
+ }
+ }
+ }
+
+ /*
+
+ GLOBAL FUNCTION
+
+ procfs_notice_signals
+
+ SYNOPSIS
+
+ static void procfs_notice_signals (int pid);
+
+ DESCRIPTION
+
+ 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.
+
+ One thing it does is that signals for which the state is "nostop",
+ "noprint", and "pass", have their trace bits reset in the pr_trace
+ field, so that they are no longer traced. This allows them to be
+ delivered directly to the inferior without the debugger ever being
+ involved.
+ */
+
+ static void
+ procfs_notice_signals (pid)
+ int pid;
+ {
+ sigemptyset (&run.trace);
+ notice_signals ();
+ }
+
+ static void
+ init_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>";
+ procfs_ops.to_open = procfs_open;
+ procfs_ops.to_attach = procfs_attach;
+ procfs_ops.to_detach = procfs_detach;
+ procfs_ops.to_resume = procfs_resume;
+ procfs_ops.to_wait = procfs_wait;
+ 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.to_files_info = procfs_files_info;
+ procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint;
+ procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint;
+ procfs_ops.to_terminal_init = terminal_init_inferior;
+ procfs_ops.to_terminal_inferior = terminal_inferior;
+ procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output;
+ procfs_ops.to_terminal_ours = terminal_ours;
+ procfs_ops.to_terminal_info = child_terminal_info;
+ procfs_ops.to_kill = procfs_kill_inferior;
+ procfs_ops.to_create_inferior = procfs_create_inferior;
+ procfs_ops.to_mourn_inferior = procfs_mourn_inferior;
+ procfs_ops.to_can_run = procfs_can_run;
+ procfs_ops.to_notice_signals = procfs_notice_signals;
+ procfs_ops.to_thread_alive = procfs_thread_alive;
+ procfs_ops.to_find_new_threads = procfs_find_new_threads;
+ procfs_ops.to_pid_to_str = qnx_pid_to_str;
+ procfs_ops.to_stop = procfs_stop;
+ procfs_ops.to_stratum = process_stratum;
+ procfs_ops.to_has_all_memory = 1;
+ procfs_ops.to_has_memory = 1;
+ procfs_ops.to_has_stack = 1;
+ procfs_ops.to_has_registers = 1;
+ procfs_ops.to_has_execution = 1;
+ procfs_ops.to_magic = OPS_MAGIC;
+ }
+
+ extern int qnx_ostype;
+
+ void
+ _initialize_procfs ()
+ {
+ sigset_t set;
+ extern struct dscpuinfo qnx_cpuinfo;
+ extern int qnx_cpuinfo_valid;
+
+ init_procfs_ops ();
+ add_target (&procfs_ops);
+ qnx_ostype = OSTYPE_NTO;
+
+ //
+ // We use SIGUSR1 to gain control after we block waiting for a process.
+ // We use sigwaitevent to wait.
+ //
+ sigemptyset (&set);
+ sigaddset (&set, SIGUSR1);
+ sigprocmask (SIG_BLOCK, &set, NULL);
+
+ /* Set up trace and fault sets, as gdb expects them. */
+ sigemptyset (&run.trace);
+ notice_signals ();
+
+ /* Stuff some information */
+ qnx_cpuinfo.cpuflags = SYSPAGE_ENTRY (cpuinfo)->flags;
+ qnx_cpuinfo_valid = 1;
+ }
+
+
+ int
+ procfs_hw_watchpoint (int addr, int len, int type)
+ {
+ procfs_break brk;
+ int err;
+
+ switch (type)
+ {
+ case 1: /* Read */
+ brk.type = _DEBUG_BREAK_RD;
+ break;
+ case 2: /* Read/Write */
+ brk.type = _DEBUG_BREAK_RW;
+ break;
+ default: /* Modify */
+ /* brk.type = _DEBUG_BREAK_RWM; This should work, shouldn't it? I get EINVAL */
+ brk.type = _DEBUG_BREAK_RW;
+ }
+ brk.type |= _DEBUG_BREAK_HW; /* always ask for HW */
+ brk.addr = addr;
+ brk.size = len;
+
+ if ((err = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0)) != EOK)
+ {
+ errno = err;
+ perror ("Failed to set hardware watchpoint");
+ return -1;
+ }
+ return 0;
+ }
+
+ CORE_ADDR
+ procfs_getbase (void)
+ {
+ procfs_info procinfo;
+
+ if (devctl (ctl_fd, DCMD_PROC_INFO, &procinfo, sizeof procinfo, 0) != EOK)
+ return (CORE_ADDR) NULL;
+ return procinfo.base_address;
+ }
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/nto-share/debug.h src/gdb/nto-share/debug.h
*** src.orig/gdb/nto-share/debug.h Wed Dec 31 19:00:00 1969
--- src/gdb/nto-share/debug.h Fri Jan 31 12:28:10 2003
***************
*** 0 ****
--- 1,429 ----
+ #ifndef __DEBUG_H_INCLUDED
+ #define __DEBUG_H_INCLUDED
+
+ #include <time.h>
+ #include <sys/time.h>
+ #include <sys/types.h>
+
+ #define QNX_NOTE_NAME "QNX"
+
+ enum Elf_qnx_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; /* if SI_NOINFO, only si_signo is valid */
+ void (*si_handler) ();
+ union
+ {
+ int _pad[6];
+ struct
+ {
+ pid_t _pid;
+ union
+ {
+ struct
+ {
+ union nto_sigval _value;
+ uid_t _uid;
+ } _kill; /* si_code <= 0 SI_FROMUSER */
+ struct
+ {
+ int _status; /* CLD_EXITED status, else signo */
+ clock_t _utime;
+ clock_t _stime;
+ } _chld; /* si_signo=SIGCHLD si_code=CLD_* */
+ } _pdata;
+ } _proc;
+ struct
+ {
+ int _fltno;
+ void *_addr;
+ void *_fltip;
+ } _fault; /* si_signo=SIGSEGV,ILL,FPE,TRAP,BUS */
+ } _data;
+ } nto_siginfo_t;
+
+ typedef struct arm_cpu_registers
+ {
+ unsigned gpr[16];
+ unsigned spsr;
+ } ARM_CPU_REGISTERS;
+
+ typedef struct arm_fpu_registers
+ {
+ /*
+ * There is no architecturally defined FPU
+ */
+ unsigned __dummy;
+ } ARM_FPU_REGISTERS;
+
+ typedef struct arm_alt_registers
+ {
+ union
+ {
+ struct xscale_cp0
+ {
+ unsigned acc0_lo;
+ unsigned acc0_hi;
+ } xscale;
+ } un;
+ } ARM_ALT_REGISTERS;
+
+ typedef union
+ {
+ unsigned long long u64;
+ double f;
+ } mipsfloat;
+
+ typedef struct mips_cpu_registers
+ {
+ unsigned regs[74];
+ unsigned long long regs_alignment;
+ } MIPS_CPU_REGISTERS;
+
+ typedef struct mips_fpu_registers
+ {
+ mipsfloat fpr[32];
+ unsigned fpcr31;
+ } MIPS_FPU_REGISTERS;
+
+ typedef struct mips_alt_registers
+ {
+ union
+ {
+ struct mips_tx79
+ {
+ unsigned long long gpr_hi[32];
+ unsigned long long lo1;
+ unsigned long long hi1;
+ unsigned sa;
+ } tx79;
+ } un;
+ } MIPS_ALT_REGISTERS;
+
+ #ifdef __BIGREGS__
+ typedef unsigned long long ppcint;
+ #else
+ typedef unsigned ppcint;
+ #endif
+
+ typedef union
+ {
+ unsigned long long u64;
+ double f;
+ } ppcfloat;
+
+ typedef union
+ {
+ unsigned long long u64[2];
+ unsigned u32[4];
+ unsigned char u8[16];
+ float f32[4];
+ } ppcvmx;
+
+ typedef struct ppc_cpu_registers
+ {
+ ppcint gpr[32];
+ ppcint ctr;
+ ppcint lr;
+ ppcint msr;
+ ppcint iar;
+ unsigned cr;
+ unsigned xer;
+ unsigned ear; /* not present on all chips */
+ unsigned mq; /* only on the 601 */
+ unsigned vrsave; /* on Altivec CPU's, SPR256 */
+ } PPC_CPU_REGISTERS;
+
+ typedef struct ppc_fpu_registers
+ {
+ ppcfloat fpr[32];
+ unsigned fpscr;
+ unsigned fpscr_val;
+ /* load/store of fpscr is done through fprs, the real value is in [32,63] of a fpr.
+ fpscr is the address for lfd, stfd. fpscr_val is the real value of fpscr */
+ } PPC_FPU_REGISTERS;
+
+ typedef struct ppc_vmx_registers
+ {
+ ppcvmx vmxr[32];
+ ppcvmx vscr;
+ } PPC_VMX_REGISTERS;
+
+ typedef struct ppc_alt_registers
+ {
+ PPC_VMX_REGISTERS vmx;
+ } PPC_ALT_REGISTERS;
+
+ typedef unsigned shint;
+
+ typedef unsigned shfloat;
+
+ typedef struct sh_cpu_registers
+ {
+ shint gr[16];
+ shint sr;
+ shint pc;
+ /* shint dbr; */
+ shint gbr;
+ shint mach;
+ shint macl;
+ shint pr;
+ } SH_CPU_REGISTERS;
+
+ typedef struct sh_fpu_registers
+ {
+ shfloat fpr_bank0[16];
+ shfloat fpr_bank1[16];
+ unsigned fpul;
+ unsigned fpscr;
+ } SH_FPU_REGISTERS;
+
+ typedef struct sh_alt_registers
+ {
+ /*
+ * There are no architecturally defined alt regs
+ */
+ unsigned __dummy;
+ } SH_ALT_REGISTERS;
+
+ 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;
+ unsigned long long 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;
+ unsigned long long filler[4];
+ } blocked;
+ unsigned long long reserved2[8];
+ } nto_procfs_status;
+
+ typedef union _debug_gregs
+ {
+ ARM_CPU_REGISTERS arm;
+ MIPS_CPU_REGISTERS mips;
+ PPC_CPU_REGISTERS ppc;
+ SH_CPU_REGISTERS sh;
+ X86_CPU_REGISTERS x86;
+ unsigned long long padding[1024];
+ } nto_gregset_t;
+
+ typedef union _debug_fpregs
+ {
+ /* ARM_FPU_REGISTERS arm; */
+ MIPS_FPU_REGISTERS mips;
+ PPC_FPU_REGISTERS ppc;
+ SH_FPU_REGISTERS sh;
+ X86_FPU_REGISTERS x86;
+ unsigned long long padding[1024];
+ } nto_fpregset_t;
+
+ typedef union _debug_altregs
+ {
+ ARM_ALT_REGISTERS arm;
+ MIPS_ALT_REGISTERS mips;
+ PPC_ALT_REGISTERS ppc;
+ /* SH_ALT_REGISTERS sh; */
+ /* X86_ALT_REGISTERS x86; */
+ unsigned long long padding[1024];
+ } debug_altreg_t;
+
+ #ifdef __QNX__
+ #include <_packpop.h>
+
+ __END_DECLS
+ #endif
+ #endif
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/nto-share/dsmsgs.h src/gdb/nto-share/dsmsgs.h
*** src.orig/gdb/nto-share/dsmsgs.h Wed Dec 31 19:00:00 1969
--- src/gdb/nto-share/dsmsgs.h Fri Jan 31 12:28:10 2003
***************
*** 0 ****
--- 1,819 ----
+ #ifndef __DSMSGS_H__
+ #define __DSMSGS_H__
+
+ //
+ // These are the protocol versioning numbers
+ // Update them with changes that introduce potential
+ // compatibility issues
+ //
+ #define PDEBUG_PROTOVER_MAJOR 0x00000000
+ #define PDEBUG_PROTOVER_MINOR 0x00000003
+
+ #include <stddef.h>
+
+ //
+ // These are pdebug specific errors, sent sometimes with the errno after
+ // an action failed. Simply provides additional info on the reason for the
+ // error. Sent in the DSrMsg_err_t.hdr.subcmd byte.
+ //
+
+ #define PDEBUG_ENOERR 0 /* No error */
+ #define PDEBUG_ENOPTY 1 /* No Pseudo Terminals found */
+ #define PDEBUG_ETHREAD 2 /* Thread Create error */
+ #define PDEBUG_ECONINV 3 /* Invalid Console number */
+ #define PDEBUG_ESPAWN 4 /* Spawn error */
+ #define PDEBUG_EPROCFS 5 /* NTO Proc File System error */
+ #define PDEBUG_EPROCSTOP 6 /* NTO Process Stop error */
+ #define PDEBUG_EQPSINFO 7 /* QNX4 PSINFO error */
+ #define PDEBUG_EQMEMMODEL 8 /* QNX4 - Flat Memory Model only supported */
+ #define PDEBUG_EQPROXY 9 /* QNX4 Proxy error */
+ #define PDEBUG_EQDBG 10 /* QNX4 qnx_debug_* error */
+
+ //
+ // There is room for pdebugerrnos up to sizeof(unsigned char)
+ //
+
+
+ // We are moving away from the channel commands - only the RESET
+ // and NAK are required. The DEBUG and TEXT channels are now part
+ // of the DShdr and TShdr structs, 4th byte. GP June 1 1999.
+ // They are still supported, but not required.
+ //
+ // A packet containg a single byte is a set channel command.
+ // IE: 7e xx chksum 7e
+ //
+ // After a set channel all following packets are in the format
+ // for the specified channel. Currently three channels are defined.
+ // The raw channel has no structure. The other channels are all framed.
+ // The contents of each channel is defined by structures below.
+ //
+ // 0 - Reset channel. Used when either end starts.
+ //
+ // 1 - Debug channel with the structure which follows below.
+ // Uses DS (Debug Services) prefix.
+ //
+ // 2 - Text channel with the structure which follows below.
+ // Uses TS (Text Services) prefix.
+ //
+ // 0xff - Negative acknowledgment of a packet transmission.
+ //
+
+
+ #define SET_CHANNEL_RESET 0
+ #define SET_CHANNEL_DEBUG 1
+ #define SET_CHANNEL_TEXT 2
+ #define SET_CHANNEL_NAK 0xff
+
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // Debug channel Messages: DS - Debug services
+ //
+
+ //
+ // Defines and structures for the debug channel.
+ //
+ #define DS_DATA_MAX_SIZE 1024
+ #define DS_DATA_RCV_SIZE(msg, total) ((total) - (sizeof(*(msg)) - DS_DATA_MAX_SIZE))
+ #define DS_MSG_OKSTATUS_FLAG 0x20000000
+ #define DS_MSG_OKDATA_FLAG 0x40000000
+ #define DS_MSG_NO_RESPONSE 0x80000000
+
+ #define QNXNTO_NSIG 57 // from signals.h NSIG
+
+ //
+ // Common message header. It must be 32 or 64 bit aligned.
+ // The top bit of cmd is 1 for BIG endian data format.
+ //
+ #define DSHDR_MSG_BIG_ENDIAN 0x80
+ struct DShdr
+ {
+ unsigned char cmd;
+ unsigned char subcmd;
+ unsigned char mid;
+ unsigned char channel;
+ };
+
+ //
+ // Command types
+ //
+ enum
+ {
+ DStMsg_connect, // 0 0x0
+ DStMsg_disconnect, // 1 0x1
+ DStMsg_select, // 2 0x2
+ DStMsg_mapinfo, // 3 0x3
+ DStMsg_load, // 4 0x4
+ DStMsg_attach, // 5 0x5
+ DStMsg_detach, // 6 0x6
+ DStMsg_kill, // 7 0x7
+ DStMsg_stop, // 8 0x8
+ DStMsg_memrd, // 9 0x9
+ DStMsg_memwr, // 10 0xA
+ DStMsg_regrd, // 11 0xB
+ DStMsg_regwr, // 12 0xC
+ DStMsg_run, // 13 0xD
+ DStMsg_brk, // 14 0xE
+ DStMsg_fileopen, // 15 0xF
+ DStMsg_filerd, // 16 0x10
+ DStMsg_filewr, // 17 0x11
+ DStMsg_fileclose, // 18 0x12
+ DStMsg_pidlist, // 19 0x13
+ DStMsg_cwd, // 20 0x14
+ DStMsg_env, // 21 0x15
+ DStMsg_base_address, // 22 0x16
+ DStMsg_protover, // 23 0x17
+ DStMsg_handlesig, // 24 0x18
+ DStMsg_cpuinfo, // 25 0x19
+ // Room for new codes here
+ DSrMsg_err = 32, // 32 0x20
+ DSrMsg_ok, // 33 0x21
+ DSrMsg_okstatus, // 34 0x22
+ DSrMsg_okdata, // 35 0x23
+ // Room for new codes here
+ DShMsg_notify = 64 // 64 0x40
+ };
+
+
+ //
+ // Subcommand types
+ //
+ enum
+ {
+ DSMSG_LOAD_DEBUG,
+ DSMSG_LOAD_RUN,
+ DSMSG_LOAD_RUN_PERSIST,
+ DSMSG_LOAD_INHERIT_ENV = 0x80
+ };
+
+ enum
+ {
+ DSMSG_ENV_CLEARARGV,
+ DSMSG_ENV_ADDARG,
+ DSMSG_ENV_CLEARENV,
+ DSMSG_ENV_SETENV,
+ DSMSG_ENV_SETENV_MORE
+ };
+
+ enum
+ {
+ DSMSG_STOP_PID,
+ DSMSG_STOP_PIDS
+ };
+
+ enum
+ {
+ DSMSG_SELECT_SET,
+ DSMSG_SELECT_QUERY
+ };
+
+ enum
+ {
+ DSMSG_KILL_PIDTID,
+ DSMSG_KILL_PID,
+ DSMSG_KILL_PIDS
+ };
+
+ enum
+ {
+ DSMSG_MEM_VIRTUAL,
+ DSMSG_MEM_PHYSICAL,
+ DSMSG_MEM_IO,
+ DSMSG_MEM_BASEREL
+ };
+
+ enum
+ {
+ DSMSG_REG_GENERAL,
+ DSMSG_REG_FLOAT,
+ DSMSG_REG_SYSTEM,
+ DSMSG_REG_ALT
+ };
+
+ enum
+ {
+ DSMSG_RUN,
+ DSMSG_RUN_COUNT,
+ DSMSG_RUN_RANGE,
+ };
+
+ enum
+ {
+ DSMSG_PIDLIST_BEGIN,
+ DSMSG_PIDLIST_NEXT,
+ DSMSG_PIDLIST_SPECIFIC,
+ DSMSG_PIDLIST_SPECIFIC_TID, // *_TID - send starting tid for the request,
+ }; // and the response will have total to be sent
+
+ enum
+ {
+ DSMSG_CWD_QUERY,
+ DSMSG_CWD_SET,
+ };
+
+ enum
+ {
+ DSMSG_MAPINFO_BEGIN = 0x01,
+ DSMSG_MAPINFO_NEXT = 0x02,
+ DSMSG_MAPINFO_SPECIFIC = 0x04,
+ DSMSG_MAPINFO_ELF = 0x80,
+ };
+
+ enum
+ {
+ DSMSG_PROTOVER_MINOR = 0x000000FF, // bit field (status & DSMSG_PROTOVER_MAJOR)
+ DSMSG_PROTOVER_MAJOR = 0x0000FF00, // bit field (status & DSMSG_PROTOVER_MINOR)
+ };
+
+ enum
+ {
+ DSMSG_BRK_EXEC = 0x0001, // execution breakpoint
+ DSMSG_BRK_RD = 0x0002, // read access (fail if not supported)
+ DSMSG_BRK_WR = 0x0004, // write access (fail if not supported)
+ DSMSG_BRK_RW = 0x0006, // read or write access (fail if not supported)
+ DSMSG_BRK_MODIFY = 0x0008, // memory modified
+ DSMSG_BRK_RDM = 0x000a, // read access if suported otherwise modified
+ DSMSG_BRK_WRM = 0x000c, // write access if suported otherwise modified
+ DSMSG_BRK_RWM = 0x000e, // read or write access if suported otherwise modified
+ DSMSG_BRK_HW = 0x0010, // only use hardware debugging (i.e. no singlestep)
+ };
+
+ enum
+ {
+ DSMSG_NOTIFY_PIDLOAD, /* 0 */
+ DSMSG_NOTIFY_TIDLOAD, /* 1 */
+ DSMSG_NOTIFY_DLLLOAD, /* 2 */
+ DSMSG_NOTIFY_PIDUNLOAD, /* 3 */
+ DSMSG_NOTIFY_TIDUNLOAD, /* 4 */
+ DSMSG_NOTIFY_DLLUNLOAD, /* 5 */
+ DSMSG_NOTIFY_BRK, /* 6 */
+ DSMSG_NOTIFY_STEP, /* 7 */
+ DSMSG_NOTIFY_SIGEV, /* 8 */
+ DSMSG_NOTIFY_STOPPED /* 9 */
+ };
+
+
+
+ //
+ // Messages sent to the target. DStMsg_* (t - for target messages)
+ //
+
+
+ //
+ // Connect to the agent running on the target
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned char major;
+ unsigned char minor;
+ unsigned char spare[2];
+ } DStMsg_connect_t;
+
+
+ //
+ // Disconnect from the agent running on the target
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ } DStMsg_disconnect_t;
+
+
+ //
+ // Select a pid, tid for subsequent messages or query their validity
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int pid;
+ int tid;
+ } DStMsg_select_t;
+
+
+ //
+ // Return information on what is at the specified virtual address.
+ // If nothing is there we return info on the next thing in the address.
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int pid;
+ int addr;
+ } DStMsg_mapinfo_t;
+
+
+ //
+ // Load a new process into memory for a filesystem
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int argc;
+ int envc;
+ char cmdline[DS_DATA_MAX_SIZE];
+ } DStMsg_load_t;
+
+
+ //
+ // Attach to an already running process
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int pid;
+ } DStMsg_attach_t;
+
+
+ //
+ // Detach from a running process which was attached to or loaded
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int pid;
+ } DStMsg_detach_t;
+
+
+ //
+ // Set a signal on a process
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int signo;
+ } DStMsg_kill_t;
+
+
+ //
+ // Stop one or more processes/threads
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ } DStMsg_stop_t;
+
+
+ //
+ // Memory read request
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned spare0;
+ unsigned long long addr;
+ unsigned short size;
+ } DStMsg_memrd_t;
+
+
+ //
+ // Memory write request
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned spare0;
+ unsigned long long addr;
+ unsigned char data[DS_DATA_MAX_SIZE];
+ } DStMsg_memwr_t;
+
+
+ //
+ // Register read request
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned short offset;
+ unsigned short size;
+ } DStMsg_regrd_t;
+
+
+ //
+ // Register write request
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned short offset;
+ unsigned char data[DS_DATA_MAX_SIZE];
+ } DStMsg_regwr_t;
+
+
+ //
+ // Run
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ union
+ {
+ unsigned count;
+ unsigned addr[2];
+ } step;
+ } DStMsg_run_t;
+
+
+ //
+ // Break
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned addr;
+ unsigned size;
+ } DStMsg_brk_t;
+
+
+ //
+ // Open a file on the target
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int mode;
+ int perms;
+ char pathname[DS_DATA_MAX_SIZE];
+ } DStMsg_fileopen_t;
+
+
+ //
+ // Read a file on the target
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned short size;
+ } DStMsg_filerd_t;
+
+
+ //
+ // Write a file on the target
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned char data[DS_DATA_MAX_SIZE];
+ } DStMsg_filewr_t;
+
+
+ //
+ // Close a file on the target
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int mtime;
+ } DStMsg_fileclose_t;
+
+
+ //
+ // Get pids and process names in the system
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int pid; // Only valid for type subtype SPECIFIC
+ int tid; // tid to start reading from
+ } DStMsg_pidlist_t;
+
+
+ // Set current working directory of process
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned char path[DS_DATA_MAX_SIZE];
+ } DStMsg_cwd_t;
+
+
+ //
+ // clear, set, get environment for new process
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ char data[DS_DATA_MAX_SIZE];
+ } DStMsg_env_t;
+
+
+ //
+ // Get the base address of a process
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ } DStMsg_baseaddr_t;
+
+
+ //
+ // Send pdebug protocol version info, get the same in response_ok_status
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned char major;
+ unsigned char minor;
+ } DStMsg_protover_t;
+
+
+ //
+ // Handle signal message.
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned char signals[QNXNTO_NSIG];
+ unsigned sig_to_pass;
+ } DStMsg_handlesig_t;
+
+
+ //
+ // Get some cpu info
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned spare;
+ } DStMsg_cpuinfo_t;
+
+
+ //
+ // Messages sent to the host. DStMsg_* (h - for host messages)
+ //
+
+
+ //
+ // Notify host that something happened it needs to know about
+ //
+ #define NOTIFY_HDR_SIZE offsetof(DShMsg_notify_t, un)
+ #define NOTIFY_MEMBER_SIZE(member) sizeof(member)
+
+ // Keep this consistant with neutrino syspage.h
+ enum
+ {
+ CPUTYPE_X86,
+ CPUTYPE_PPC,
+ CPUTYPE_MIPS,
+ CPUTYPE_SPARE,
+ CPUTYPE_ARM,
+ CPUTYPE_SH
+ };
+
+ enum
+ {
+ OSTYPE_QNX4,
+ OSTYPE_NTO
+ };
+
+ typedef struct aaa
+ {
+ struct DShdr hdr;
+ int pid;
+ int tid;
+ union
+ {
+ struct
+ {
+ unsigned codeoff;
+ unsigned dataoff;
+ unsigned short ostype;
+ unsigned short cputype;
+ unsigned cpuid; // CPU dependant value
+ char name[DS_DATA_MAX_SIZE];
+ } pidload;
+ struct
+ {
+ int status;
+ } pidunload;
+ struct
+ {
+ int status;
+ unsigned char faulted;
+ unsigned char reserved[3];
+ } pidunload_v3;
+ struct
+ {
+ unsigned ip;
+ unsigned dp;
+ unsigned flags; // defined in <sys/debug.h>
+ } brk;
+ struct
+ {
+ unsigned ip;
+ unsigned lastip;
+ } step;
+ struct
+ {
+ int signo;
+ int code;
+ int value;
+ } sigev;
+ } un;
+ } DShMsg_notify_t;
+
+
+
+ //
+ // Responses to a message. DSrMsg_* (r - for response messages)
+ //
+
+ //
+ // Error response packet
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int err;
+ } DSrMsg_err_t;
+
+ //
+ // Simple OK response.
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ } DSrMsg_ok_t;
+
+
+ //
+ // Simple OK response with a result. Used where limited data needs
+ // to be returned. For example, if the number of bytes which were
+ // successfully written was less than requested on any write cmd the
+ // status will be the number actually written.
+ // The 'subcmd' will always be zero.
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ int status;
+ } DSrMsg_okstatus_t;
+
+
+ //
+ // The following structures overlay data[..] on a DSrMsg_okdata_t
+ //
+
+ struct dslinkmap
+ {
+ unsigned addr;
+ unsigned size;
+ unsigned flags;
+ unsigned debug_vaddr;
+ unsigned long long offset;
+ };
+
+ struct dsmapinfo
+ {
+ struct dsmapinfo *next;
+ unsigned spare0;
+ unsigned long long ino;
+ unsigned dev;
+ unsigned spare1;
+ struct dslinkmap text;
+ struct dslinkmap data;
+ char name[256];
+ };
+
+ struct dspidlist
+ {
+ int pid;
+ int num_tids; // num of threads this pid has
+ int spare[6];
+ struct tidinfo
+ {
+ short tid;
+ unsigned char state;
+ unsigned char flags;
+ } tids[1]; // Variable length terminated by tid==0
+ char name[1]; // Variable length terminated by \0
+ };
+
+ struct dscpuinfo
+ {
+ unsigned cpuflags;
+ unsigned spare1;
+ unsigned spare2;
+ unsigned spare3;
+ };
+
+ //
+ // Long OK response with 0..DS_DATA_MAX_SIZE data.
+ // The 'subcmd' will always be zero.
+ //
+ typedef struct
+ {
+ struct DShdr hdr;
+ unsigned char data[DS_DATA_MAX_SIZE];
+ } DSrMsg_okdata_t;
+
+
+ //
+ // A union of all possible messages and responses.
+ //
+ typedef union
+ {
+ struct DShdr hdr;
+ DStMsg_connect_t connect;
+ DStMsg_disconnect_t disconnect;
+ DStMsg_select_t select;
+ DStMsg_load_t load;
+ DStMsg_attach_t attach;
+ DStMsg_detach_t detach;
+ DStMsg_kill_t kill;
+ DStMsg_stop_t stop;
+ DStMsg_memrd_t memrd;
+ DStMsg_memwr_t memwr;
+ DStMsg_regrd_t regrd;
+ DStMsg_regwr_t regwr;
+ DStMsg_run_t run;
+ DStMsg_brk_t brk;
+ DStMsg_fileopen_t fileopen;
+ DStMsg_filerd_t filerd;
+ DStMsg_filewr_t filewr;
+ DStMsg_fileclose_t fileclose;
+ DStMsg_pidlist_t pidlist;
+ DStMsg_mapinfo_t mapinfo;
+ DStMsg_cwd_t cwd;
+ DStMsg_env_t env;
+ DStMsg_baseaddr_t baseaddr;
+ DStMsg_protover_t protover;
+ DStMsg_handlesig_t handlesig;
+ DStMsg_cpuinfo_t cpuinfo;
+ DShMsg_notify_t notify;
+ DSrMsg_err_t err;
+ DSrMsg_ok_t ok;
+ DSrMsg_okstatus_t okstatus;
+ DSrMsg_okdata_t okdata;
+ } DSMsg_union_t;
+
+
+
+
+
+ ///////////////////////////////////////////////////////////////////////////////
+ // Text channel Messages: TS - Text services
+ //
+
+ #define TS_TEXT_MAX_SIZE 100
+
+ //
+ // Command types
+ //
+ enum
+ {
+ TSMsg_text, /* 0 */
+ TSMsg_done, /* 1 */
+ TSMsg_start, /* 2 */
+ TSMsg_stop, /* 3 */
+ TSMsg_ack, /* 4 */
+ };
+
+
+ struct TShdr
+ {
+ unsigned char cmd;
+ unsigned char console;
+ unsigned char spare1;
+ unsigned char channel;
+ };
+
+
+ //
+ // Deliver text. This message can be sent by either side.
+ // The debugger displays it in a window. The agent gives it to a pty
+ // which a program may be listening on.
+ //
+
+ typedef struct
+ {
+ struct TShdr hdr;
+ char text[TS_TEXT_MAX_SIZE];
+ } TSMsg_text_t;
+
+
+ //
+ // There is no longer a program connected to this console.
+ //
+ typedef struct
+ {
+ struct TShdr hdr;
+ } TSMsg_done_t;
+
+
+ //
+ // TextStart or TextStop flow controlÿ
+ //
+ typedef struct
+ {
+ struct TShdr hdr;
+ } TSMsg_flowctl_t;
+
+
+ //
+ // Ack a flowctl message
+ //
+ typedef struct
+ {
+ struct TShdr hdr;
+ } TSMsg_ack_t;
+
+ #endif
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/remote-nto-i386.c src/gdb/remote-nto-i386.c
*** src.orig/gdb/remote-nto-i386.c Wed Dec 31 19:00:00 1969
--- src/gdb/remote-nto-i386.c Fri Jan 31 12:24:06 2003
***************
*** 0 ****
--- 1,393 ----
+ /* Remote target communications for serial-line targets in custom GDB protocol
+ Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Contributed by QNX Software Systems Limited.
+
+ 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. */
+
+ /* This file was derived from remote.c. It implements the MIPS specific
+ portion of the Neutrino remote debug proctocol (see remote-nto.c for
+ the CPU independent portion). */
+
+ #include "defs.h"
+ #include "gdb_string.h"
+ #include <fcntl.h>
+ #include "frame.h"
+ #include "inferior.h"
+ #include "bfd.h"
+ #include "symfile.h"
+ #include "target.h"
+ #include "gdb_wait.h"
+ #include "gdbcmd.h"
+ #include "objfiles.h"
+ #include "gdb-stabs.h"
+ #include "gdbthread.h"
+ #include "nto-share/dsmsgs.h"
+ #include "regcache.h"
+ #include "solib-svr4.h"
+ #include "dcache.h"
+
+ #ifdef USG
+ #include <sys/types.h>
+ #endif
+
+ #include <signal.h>
+ #include "serial.h"
+
+ #include "nto-share/debug.h"
+
+ /* Prototypes for i387_supply_fsave etc. */
+ #include "i387-tdep.h"
+
+ #ifndef FPC_REGNUM
+ #define FPC_REGNUM (FP0_REGNUM + 8)
+ #endif
+
+ #define NUM_GPREGS 13
+ static int gdb_to_nto[NUM_GPREGS] =
+ { 7, 6, 5, 4, 11, 2, 1, 0, 8, 10, 9, 12, -1 };
+
+ #define GDB_TO_OS(x) ((x >= 0 && x < NUM_GPREGS) ? gdb_to_nto[x] : -1)
+
+ #ifndef X86_CPU_FXSR
+ #define X86_CPU_FXSR (1L << 12)
+ #endif
+
+ extern struct dscpuinfo qnx_cpuinfo;
+ extern int qnx_cpuinfo_valid;
+ extern int qnx_ostype, qnx_cputype;
+ /*
+ Given a register return an id that represents the Neutrino regset it came from
+ if reg == -1 update all regsets
+ $MJC
+ */
+
+ enum QNX_REGS
+ {
+ QNX_REGS_GP = 0,
+ QNX_REGS_FP = 1,
+ QNX_REGS_END = 2
+ };
+ unsigned
+ qnx_get_regset_id (int regno)
+ {
+ unsigned regset;
+ if (regno == -1)
+ { /* return size so we can enumerate */
+ regset = 2;
+ }
+ else if (regno < FP0_REGNUM)
+ {
+ regset = 0;
+ }
+ else if (regno < FPC_REGNUM)
+ {
+ regset = 1;
+ }
+ else
+ {
+ regset = -1; /* error */
+ }
+ return regset;
+ }
+
+ /* Tell GDB about the regset contained in the 'data' buffer */
+ static void
+ gp_regset_fetch (char *data)
+ {
+ unsigned first_regno;
+ for (first_regno = 0; first_regno < FP0_REGNUM; first_regno++)
+ {
+ int regno = GDB_TO_OS (first_regno);
+ int const minusone = -1;
+
+ if (data == NULL || regno == -1)
+ {
+ supply_register (first_regno, (char *) &minusone);
+ }
+ else
+ {
+ supply_register (first_regno, &data[regno * 4]);
+ }
+ }
+ }
+
+ // get 8087 data
+ static void
+ fp_regset_fetch (char *data)
+ {
+ if (qnx_cpuinfo_valid && qnx_cpuinfo.cpuflags | X86_CPU_FXSR)
+ i387_supply_fxsave (data);
+ else
+ i387_supply_fsave (data);
+ }
+
+ void
+ qnx_cpu_regset_fetch (int endian, int regset, void *data)
+ {
+ endian = endian; /* x86, don't care about endian */
+
+ switch (regset)
+ {
+ case QNX_REGS_GP: /* QNX has different ordering of GP regs GDB */
+ gp_regset_fetch ((char *) data);
+ break;
+ case QNX_REGS_FP:
+ fp_regset_fetch ((char *) data);
+ break;
+ }
+ }
+
+ /* get regset characteristics */
+ unsigned
+ qnx_get_regset_area (unsigned regset, char *subcmd)
+ {
+ unsigned length = 0;
+ switch (regset)
+ {
+ case QNX_REGS_GP:
+ *subcmd = DSMSG_REG_GENERAL;
+ length = NUM_GPREGS * sizeof (unsigned);
+ break;
+ case QNX_REGS_FP:
+ *subcmd = DSMSG_REG_FLOAT;
+ /* FIXME: should we calculate based on fxsave/fsave? */
+ length = 512;
+ break;
+ default:
+ length = 0;
+ }
+ return length;
+ }
+
+ /*-
+ 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
+ qnx_cpu_register_area (first_regno, last_regno, subcmd, off, len)
+ 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 = DSMSG_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 (qnx_cpuinfo_valid && qnx_cpuinfo.cpuflags | 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 = DSMSG_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.*/
+ }
+ else
+ {
+ *len = 0;
+ return last_regno;
+ }
+ return last_regno;
+ }
+
+ /* Tell GDB about the registers contained in the 'data' buffer */
+
+ void
+ qnx_cpu_register_fetch (endian, first_regno, last_regno, data)
+ int endian;
+ unsigned first_regno;
+ unsigned last_regno;
+ void *data;
+ {
+ fprintf_unfiltered (gdb_stderr, "warning: qnx_cpu_register_fetch called \
+ in remote-qnx-i386.c. This shouldn't happen\n");
+ /* If remote-qnx-i386.c calls qnx_supply_register in remote-qnx.c,
+ * then remote-qnx.c calls qnx_cpu_register_fetch. Since this never
+ * happens, this function is left unimplemented. */
+ }
+
+ /* Build the Neutrino register set info into the 'data' buffer */
+
+ int
+ qnx_cpu_register_store (endian, first_regno, last_regno, data)
+ 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;
+ }
+
+ /* nto_supply_* are used by nto_procfs.c and qnx_core-regset.c */
+ void
+ nto_supply_gregset (gregsetp)
+ nto_gregset_t *gregsetp;
+ {
+ register int regi, i = 0;
+ register unsigned *regp = (unsigned *) gregsetp;
+
+ for (regi = 0; regi < (NUM_REGS - FP0_REGNUM); regi++)
+ {
+ i = GDB_TO_OS (regi);
+ supply_register (regi, (char *) ®p[i]);
+ }
+ }
+
+ void
+ nto_supply_fpregset (fpregsetp)
+ nto_fpregset_t *fpregsetp;
+ {
+ if (qnx_cpuinfo_valid && qnx_cpuinfo.cpuflags | X86_CPU_FXSR)
+ i387_supply_fxsave ((char *) fpregsetp);
+ else
+ i387_supply_fsave ((char *) fpregsetp);
+ }
+
+ extern void qnx_read_ioport_8 PARAMS ((char *, int));
+ extern void qnx_read_ioport_16 PARAMS ((char *, int));
+ extern void qnx_read_ioport_32 PARAMS ((char *, int));
+ extern void qnx_write_ioport_8 PARAMS ((char *, int));
+ extern void qnx_write_ioport_16 PARAMS ((char *, int));
+ extern void qnx_write_ioport_32 PARAMS ((char *, int));
+
+ void
+ _initialize_nto_i386 ()
+ {
+ #define IO_PORT_HACKS
+ #ifdef IO_PORT_HACKS
+ add_com ("in8", class_maintenance, qnx_read_ioport_8,
+ "read a 8 bit value from an ioport");
+ add_com ("in16", class_maintenance, qnx_read_ioport_16,
+ "read a 16 bit value from an ioport");
+ add_com ("in32", class_maintenance, qnx_read_ioport_32,
+ "read a 32 bit value from an ioport");
+ add_com ("out8", class_maintenance, qnx_write_ioport_8,
+ "write a 8 bit value to an ioport");
+ add_com ("out16", class_maintenance, qnx_write_ioport_16,
+ "write a 16 bit value to an ioport");
+ add_com ("out32", class_maintenance, qnx_write_ioport_32,
+ "write a 32 bit value to an ioport");
+ #endif
+ }
+
+ /* 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). */
+
+ struct link_map_offsets *
+ i386_qnx_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
+ this is all we need. */
+ lmo.r_map_offset = 4;
+ lmo.r_map_size = 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_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;
+ }
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/remote-nto.c src/gdb/remote-nto.c
*** src.orig/gdb/remote-nto.c Wed Dec 31 19:00:00 1969
--- src/gdb/remote-nto.c Mon Feb 3 12:50:30 2003
***************
*** 0 ****
--- 1,3679 ----
+ /* Remote target communications for serial-line targets in Neutrino Pdebug protocol
+ Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Contributed by QNX Software Systems Limited.
+
+ 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. */
+
+ /* This file was derived from remote.c. It communicates with a
+ box talking the QNX Software Systems Limited's Neutrino remote debug
+ protocol. See dsmsgs.h for details. */
+
+ #include "defs.h"
+ #include "gdb_string.h"
+ #include "gdbcore.h"
+ #include <fcntl.h>
+ #include <sys/stat.h>
+ #include "frame.h"
+ #include "inferior.h"
+ #include "bfd.h"
+ #include "symfile.h"
+ #include "target.h"
+ #include "gdb_wait.h"
+ #include "gdbcmd.h"
+ #include "objfiles.h"
+ #include "gdb-stabs.h"
+ #include "gdbthread.h"
+ #include "nto-share/dsmsgs.h"
+ #include "dcache.h"
+ #include "cli/cli-decode.h"
+ #include "completer.h"
+ #include "solist.h"
+ #include "solib-svr4.h"
+ #include "top.h"
+ #include "regcache.h"
+
+ #ifdef USG
+ #include <sys/types.h>
+ #endif
+
+ #include "nto-share/debug.h"
+
+ #include <sys/stat.h>
+ #include <signal.h>
+ #include "serial.h"
+ #include <termios.h>
+
+ #ifdef __CYGWIN__
+ #include <sys/cygwin.h>
+ #endif
+
+ #ifndef EOK
+ #define EOK 0
+ #endif
+
+ #define QNX_READ_MODE 0x0
+ #define QNX_WRITE_MODE 0x301
+ #define QNX_WRITE_PERMS 0x1ff
+
+ #if defined(_WIN32) || defined(__CYGWIN__)
+ #define HOST_READ_MODE O_RDONLY|O_BINARY
+ #define HOST_WRITE_MODE O_WRONLY|O_CREAT|O_TRUNC|O_BINARY
+ #else
+ #define HOST_READ_MODE O_RDONLY
+ #define HOST_WRITE_MODE O_WRONLY|O_CREAT|O_TRUNC
+ #endif
+
+ /* Prototypes in the appropriate remote-nto<CPU>.c file */
+
+ int (*target_created_hook) (pid_t);
+ CORE_ADDR qnx_getbase (void);
+ extern unsigned qnx_get_regset_id (int regno);
+ extern void qnx_cpu_regset_fetch (int endian, int regset, void *data);
+ extern unsigned qnx_get_regset_area (unsigned regset, char *subcmd);
+ extern unsigned qnx_cpu_register_area
+ PARAMS ((unsigned first_regno, unsigned last_regno, unsigned char *subcmd,
+ unsigned *off, unsigned *len));
+ extern void qnx_cpu_register_fetch
+ PARAMS ((int endian, unsigned first_regno, unsigned last_regno, void *data));
+ extern int qnx_cpu_register_store
+ PARAMS ((int endian, unsigned first_regno, unsigned last_regno, void *data));
+
+ /* Prototypes for local functions */
+
+ static void init_qnx_ops PARAMS ((void));
+ static int putpkt PARAMS ((unsigned));
+ static int readchar PARAMS ((int timeout));
+ static int getpkt PARAMS ((int forever));
+ static unsigned qnx_send PARAMS ((unsigned, int));
+ static int qnx_write_bytes
+ PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+ static int qnx_read_bytes PARAMS ((CORE_ADDR memaddr, char *myaddr, int len));
+ static void qnx_files_info PARAMS ((struct target_ops * ignore));
+ static void qnx_parse_notify PARAMS ((struct target_waitstatus * status));
+ static int qnx_xfer_memory
+ PARAMS ((CORE_ADDR memaddr, char *myaddr, int len, int should_write,
+ struct mem_attrib * attrib, struct target_ops * target));
+ static int qnx_incoming_text PARAMS ((int len));
+ void qnx_outgoing_text (char *buf, int nbytes);
+ void qnx_fetch_registers PARAMS ((int regno));
+ static void qnx_prepare_to_store PARAMS ((void));
+ static void qnx_store_registers PARAMS ((int regno));
+ static void qnx_resume
+ PARAMS ((ptid_t ptid, int step, enum target_signal sig));
+ static int qnx_start_remote PARAMS ((char *dummy));
+ static void qnx_open PARAMS ((char *name, int from_tty));
+ static void qnx_close PARAMS ((int quitting));
+ static void qnx_mourn PARAMS ((void));
+ static ptid_t qnx_wait
+ PARAMS ((ptid_t ptid, struct target_waitstatus * status));
+ static void qnx_kill PARAMS ((void));
+ static void qnx_detach PARAMS ((char *args, int from_tty));
+ static void qnx_interrupt PARAMS ((int signo));
+ static void qnx_interrupt_twice PARAMS ((int signo));
+ static void interrupt_query PARAMS ((void));
+ static void qnx_upload PARAMS ((char *args, int from_tty));
+ static void qnx_download PARAMS ((char *args, int from_tty));
+ static void qnx_add_commands PARAMS ((void));
+ static void qnx_remove_commands PARAMS ((void));
+ static int qnx_fileopen PARAMS ((char *fname, int mode, int perms));
+ static void qnx_fileclose PARAMS ((int));
+ static int qnx_fileread PARAMS ((char *buf, int size));
+ static int qnx_filewrite PARAMS ((char *buf, int size));
+ char *qnx_pid_to_str (ptid_t ptid);
+ char **qnx_parse_redirection
+ PARAMS ((char *start_argv[], char **in, char **out, char **err));
+ enum target_signal target_signal_from_qnx PARAMS ((int sig));
+ enum target_signal target_signal_to_qnx PARAMS ((int sig));
+ static struct target_ops qnx_ops;
+
+ /* This was 5 seconds, which is a long time to sit and wait.
+ Unless this is going though some terminal server or multiplexer or
+ other form of hairy serial connection, I would think 2 seconds would
+ be plenty. */
+
+ /*-
+ 2 seconds is way too short considering commands load across the
+ network
+ */
+ static int qnx_timeout = 10;
+ static int qnx_inherit_env = 1;
+ int qnx_target_has_stack_frame = 0;
+ static char *qnx_remote_cwd = NULL;
+
+ /* Descriptor for I/O to remote machine. Initialize it to NULL so that
+ qnx_open knows that we don't have a file open when the program
+ starts. */
+ struct serial *qnx_desc = NULL;
+ int qnx_ostype = -1, qnx_cputype = -1;
+ unsigned qnx_cpuid = 0;
+
+ /* Filled in cpu info structure and flag to indicate its validity.
+ * This is initialized in procfs_attach or qnx_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. */
+ struct dscpuinfo qnx_cpuinfo;
+ int qnx_cpuinfo_valid;
+
+ struct qnx_process
+ {
+ int pid;
+ int tid;
+ };
+
+ static struct qnx_process curr_proc;
+
+ static int host_endian;
+ static unsigned channelrd = SET_CHANNEL_DEBUG; // Set in getpkt()
+ static unsigned channelwr = SET_CHANNEL_DEBUG; // Set in putpkt()
+
+ /* Maintenance debugging flag */
+ int nto_internal_debugging;
+
+ /*
+ * These store the version of the protocol used by the pdebug we connect to
+ */
+ static int TargetQNXProtoverMajor = 0; // Set in qnx_start_remote()
+ static int TargetQNXProtoverMinor = 0; // Set in qnx_start_remote()
+
+ /*
+ * These define the version of the protocol implemented here.
+ */
+ #define HOST_QNX_PROTOVER_MAJOR 0
+ #define HOST_QNX_PROTOVER_MINOR 3
+
+ static union
+ {
+ unsigned char buf[DS_DATA_MAX_SIZE];
+ DSMsg_union_t pkt;
+ } tran, recv;
+
+ #define SWAP64( val ) ( \
+ (((val) >> 56) & 0x00000000000000ff) \
+ | (((val) >> 40) & 0x000000000000ff00) \
+ | (((val) >> 24) & 0x0000000000ff0000) \
+ | (((val) >> 8) & 0x00000000ff000000) \
+ | (((val) << 8) & 0x000000ff00000000) \
+ | (((val) << 24) & 0x0000ff0000000000) \
+ | (((val) << 40) & 0x00ff000000000000) \
+ | (((val) << 56) & 0xff00000000000000) )
+
+ #define SWAP32( val ) ( (((val) >> 24) & 0x000000ff) \
+ | (((val) >> 8) & 0x0000ff00)\
+ | (((val) << 8) & 0x00ff0000)\
+ | (((val) << 24) & 0xff000000) )
+
+ #define SWAP16( val ) ( (((val) >> 8) & 0xff) | (((val) << 8) & 0xff00) )
+
+
+ short int
+ qnx_swap16 (int val)
+ {
+ return (host_endian != TARGET_BYTE_ORDER ? SWAP16 (val) : val);
+ }
+
+
+ long int
+ qnx_swap32 (long int val)
+ {
+ return (host_endian != TARGET_BYTE_ORDER ? SWAP32 (val) : val);
+ }
+
+ long long int
+ qnx_swap64 (long long int val)
+ {
+ return (host_endian != TARGET_BYTE_ORDER ? SWAP64 (val) : val);
+ }
+
+ /* Stuff for dealing with the packets which are part of this protocol. */
+
+ #define MAX_TRAN_TRIES 3
+ #define MAX_RECV_TRIES 3
+
+ #define FRAME_CHAR 0x7e
+ #define ESC_CHAR 0x7d
+
+ static unsigned char nak_packet[] =
+ { FRAME_CHAR, SET_CHANNEL_NAK, 0, FRAME_CHAR };
+ static unsigned char ch_reset_packet[] =
+ { FRAME_CHAR, SET_CHANNEL_RESET, 0xff, FRAME_CHAR };
+ static unsigned char ch_debug_packet[] =
+ { FRAME_CHAR, SET_CHANNEL_DEBUG, 0xfe, FRAME_CHAR };
+ static unsigned char ch_text_packet[] =
+ { FRAME_CHAR, SET_CHANNEL_TEXT, 0xfd, FRAME_CHAR };
+
+ #define SEND_NAK serial_write(qnx_desc,nak_packet,sizeof(nak_packet))
+ #define SEND_CH_RESET serial_write(qnx_desc,ch_reset_packet,sizeof(ch_reset_packet))
+ #define SEND_CH_DEBUG serial_write(qnx_desc,ch_debug_packet,sizeof(ch_debug_packet))
+ #define SEND_CH_TEXT serial_write(qnx_desc,ch_text_packet,sizeof(ch_text_packet))
+
+ /* Send a packet to the remote machine. Also sets channelwr and informs
+ target if channelwr has changed. */
+
+ static int
+ putpkt (unsigned len)
+ {
+ int i;
+ unsigned char csum = 0;
+ unsigned char buf2[DS_DATA_MAX_SIZE * 2];
+ unsigned char *p;
+
+ /* Copy the packet into buffer BUF2, encapsulating it
+ and giving it a checksum. */
+
+ p = buf2;
+ *p++ = FRAME_CHAR;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("putpkt() - cmd %d, subcmd %d, mid %d\n",
+ tran.pkt.hdr.cmd, tran.pkt.hdr.subcmd,
+ tran.pkt.hdr.mid);
+ }
+
+ if (remote_debug)
+ printf_unfiltered ("Sending packet (len %d): ", len);
+
+ for (i = 0; i < len; i++)
+ {
+ unsigned char c = tran.buf[i];
+
+ if (remote_debug)
+ printf_unfiltered ("%2.2x", c);
+ csum += c;
+
+ switch (c)
+ {
+ case FRAME_CHAR:
+ case ESC_CHAR:
+ if (remote_debug)
+ printf_unfiltered ("[escape]");
+ *p++ = ESC_CHAR;
+ c ^= 0x20;
+ break;
+ }
+ *p++ = c;
+ }
+
+ csum ^= 0xff;
+
+ if (remote_debug)
+ {
+ printf_unfiltered ("%2.2x\n", csum);
+ gdb_flush (gdb_stdout);
+ }
+ switch (csum)
+ {
+ case FRAME_CHAR:
+ case ESC_CHAR:
+ *p++ = ESC_CHAR;
+ csum ^= 0x20;
+ break;
+ }
+ *p++ = csum;
+ *p++ = FRAME_CHAR;
+
+ /*
+ * GP added - June 17, 1999. There used to be only 'channel'. now channelwr
+ * and channelrd keep track of the state better.
+ * If channelwr is not in the right state, notify target and set channelwr
+ */
+
+ if (channelwr != tran.pkt.hdr.channel)
+ {
+ switch (tran.pkt.hdr.channel)
+ {
+ case SET_CHANNEL_TEXT:
+ SEND_CH_TEXT;
+ break;
+ case SET_CHANNEL_DEBUG:
+ SEND_CH_DEBUG;
+ break;
+ }
+ channelwr = tran.pkt.hdr.channel;
+ }
+
+ if (serial_write (qnx_desc, buf2, p - buf2))
+ perror_with_name ("putpkt: write failed");
+
+ return len;
+ }
+
+ /* Read a single character from the remote end, masking it down to 8 bits. */
+
+ static int
+ readchar (int timeout)
+ {
+ int ch;
+
+ ch = serial_readchar (qnx_desc, timeout);
+
+ switch (ch)
+ {
+ case SERIAL_EOF:
+ error ("Remote connection closed");
+ case SERIAL_ERROR:
+ perror_with_name ("Remote communication error");
+ case SERIAL_TIMEOUT:
+ return ch;
+ default:
+ return ch & 0xff;
+ }
+ }
+
+ /* Come here after finding the start of the frame. Collect the rest into BUF,
+ verifying the checksum, length, and handling run-length compression.
+ Returns 0 on any error, 1 on success. */
+
+ static int
+ read_frame ()
+ {
+ unsigned char csum;
+ unsigned char *bp;
+ unsigned char modifier = 0;
+ int c;
+
+ if (remote_debug)
+ printf_filtered ("Receiving data: ");
+
+ csum = 0;
+ bp = recv.buf;
+
+ memset (bp, -1, sizeof recv.buf);
+ for (;;)
+ {
+ c = readchar (qnx_timeout);
+
+ switch (c)
+ {
+ case SERIAL_TIMEOUT:
+ puts_filtered ("Timeout in mid-packet, retrying\n");
+ return -1;
+ case ESC_CHAR:
+ modifier = 0x20;
+ continue;
+ case FRAME_CHAR:
+ if (bp == recv.buf)
+ continue; /* Ignore multiple start frames */
+ if (csum != 0xff) /* Checksum error */
+ return -1;
+ return bp - recv.buf - 1;
+ default:
+ c ^= modifier;
+ if (remote_debug)
+ printf_filtered ("%2.2x", c);
+ csum += c;
+ *bp++ = c;
+ break;
+ }
+ modifier = 0;
+ }
+ }
+
+ /* Read a packet from the remote machine, with error checking,
+ and store it in recv.buf.
+ If FOREVER, wait forever rather than timing out; this is used
+ while the target is executing user code. */
+
+ static int
+ getpkt (int forever)
+ {
+ int c;
+ int tries;
+ int timeout;
+ unsigned len;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("getpkt(%d)\n", forever);
+ }
+
+ if (forever)
+ {
+ #ifdef MAINTENANCE_CMDS
+ timeout = watchdog > 0 ? watchdog : -1;
+ #else
+ timeout = -1;
+ #endif
+ }
+ else
+ {
+ timeout = qnx_timeout;
+ }
+
+ for (tries = 0; tries < MAX_RECV_TRIES; tries++)
+ {
+ /* This can loop forever if the remote side sends us characters
+ continuously, but if it pauses, we'll get a zero from readchar
+ because of timeout. Then we'll count that as a retry. */
+
+ /* Note that we will only wait forever prior to the start of a packet.
+ After that, we expect characters to arrive at a brisk pace. They
+ should show up within qnx_timeout intervals. */
+
+ do
+ {
+ c = readchar (timeout);
+
+ if (c == SERIAL_TIMEOUT)
+ {
+ #ifdef MAINTENANCE_CMDS
+ if (forever) /* Watchdog went off. Kill the target. */
+ {
+ target_mourn_inferior ();
+ error ("Watchdog has expired. Target detached.");
+ }
+ #endif
+ puts_filtered ("Timed out.\n");
+ return -1;
+ }
+ }
+ while (c != FRAME_CHAR);
+
+ /* We've found the start of a packet, now collect the data. */
+
+ len = read_frame ();
+
+ if (remote_debug)
+ printf_filtered ("\n");
+
+ if (len >= sizeof (struct DShdr))
+ {
+ if (recv.pkt.hdr.channel) // if hdr.channel is not 0, then hdr.channel is supported
+ channelrd = recv.pkt.hdr.channel;
+
+ if (nto_internal_debugging == 2)
+ {
+ printf_unfiltered ("getpkt() - len %d, channelrd %d,", len,
+ channelrd);
+ switch (channelrd)
+ {
+ case SET_CHANNEL_DEBUG:
+ printf_unfiltered (" cmd = %d, subcmd = %d, mid = %d\n",
+ recv.pkt.hdr.cmd, recv.pkt.hdr.subcmd,
+ recv.pkt.hdr.mid);
+ break;
+ case SET_CHANNEL_TEXT:
+ printf_unfiltered (" text message\n");
+ break;
+ case SET_CHANNEL_RESET:
+ printf_unfiltered (" set_channel_reset\n");
+ break;
+ default:
+ printf_unfiltered (" unknown channel!\n");
+ break;
+ }
+ }
+ return len;
+ }
+ if (len >= 1)
+ {
+ /* Packet too small to be part of the debug protocol,
+ must be a transport level command */
+ if (recv.buf[0] == SET_CHANNEL_NAK)
+ {
+ /* Our last transmission didn't make it - send it again. */
+ channelrd = SET_CHANNEL_NAK;
+ return -1;
+ }
+ if (recv.buf[0] <= SET_CHANNEL_TEXT)
+ channelrd = recv.buf[0];
+
+ if (nto_internal_debugging == 2)
+ {
+ printf_unfiltered ("set channelrd to %d\n", channelrd);
+ }
+ --tries; /* doesn't count as a retry */
+ continue;
+ }
+ SEND_NAK;
+ }
+
+ /* We have tried hard enough, and just can't receive the packet. Give up. */
+ printf_unfiltered ("Ignoring packet error, continuing...");
+ return 0;
+ }
+
+ void
+ qnx_send_init (unsigned cmd, unsigned subcmd, unsigned chan)
+ {
+ static unsigned char mid;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered (" qnx_send_init(cmd %d, subcmd %d)\n", cmd,
+ subcmd);
+ }
+
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ cmd |= DSHDR_MSG_BIG_ENDIAN;
+
+ tran.pkt.hdr.cmd = cmd; //TShdr.cmd
+ tran.pkt.hdr.subcmd = subcmd; //TShdr.console
+ tran.pkt.hdr.mid = ((chan == SET_CHANNEL_DEBUG) ? mid++ : 0); //TShdr.spare1
+ tran.pkt.hdr.channel = chan; //TShdr.channel
+ }
+
+
+ /* Send text to remote debug daemon - Pdebug */
+ void
+ qnx_outgoing_text (char *buf, int nbytes)
+ {
+ TSMsg_text_t *msg;
+
+ msg = (TSMsg_text_t *) & tran;
+
+ msg->hdr.cmd = TSMsg_text;
+ msg->hdr.console = 0;
+ msg->hdr.spare1 = 0;
+ msg->hdr.channel = SET_CHANNEL_TEXT;
+
+ memcpy (msg->text, buf, nbytes);
+
+ putpkt (nbytes + offsetof (TSMsg_text_t, text));
+ }
+
+
+ /* Display some text that came back across the text channel */
+
+ static int
+ qnx_incoming_text (int len)
+ {
+ int textlen;
+ TSMsg_text_t *text;
+ char fmt[20];
+ char buf[TS_TEXT_MAX_SIZE];
+
+ text = (void *) &recv.buf[0];
+ textlen = len - offsetof (TSMsg_text_t, text);
+
+ switch (text->hdr.cmd)
+ {
+ case TSMsg_text:
+ sprintf (fmt, "%%%d.%ds", textlen, textlen);
+ sprintf (buf, fmt, text->text);
+ ui_file_write (gdb_stdtarg, buf, textlen);
+ return 0;
+ default:
+ return -1;
+ }
+ }
+
+ /* Send the command in tran.buf to the remote machine,
+ and read the reply into recv.buf. */
+
+ static unsigned
+ qnx_send (unsigned len, int report_errors)
+ {
+ int rlen;
+ unsigned tries;
+
+ if (qnx_desc == NULL)
+ {
+ errno = ENOTCONN;
+ return 0;
+ }
+
+ for (tries = 0;; tries++)
+ {
+ if (tries >= MAX_TRAN_TRIES)
+ {
+ unsigned char err = DSrMsg_err;
+
+ printf_unfiltered ("Remote exhausted %d retries.\n", tries);
+ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+ err |= DSHDR_MSG_BIG_ENDIAN;
+ recv.pkt.hdr.cmd = err;
+ recv.pkt.err.err = qnx_swap32 (EIO);
+ rlen = sizeof (recv.pkt.err);
+ break;
+ }
+ putpkt (len);
+ for (;;)
+ {
+ rlen = getpkt (0);
+ if ((channelrd != SET_CHANNEL_TEXT) || (rlen == -1))
+ break;
+ qnx_incoming_text (rlen);
+ }
+ if (rlen == -1) // getpkt returns -1 if MsgNAK received.
+ {
+ printf_unfiltered ("MsgNak received - resending\n");
+ continue;
+ }
+ if ((rlen >= 0) && (recv.pkt.hdr.mid == tran.pkt.hdr.mid))
+ break;
+
+ if (nto_internal_debugging == 2)
+ {
+ printf_unfiltered ("mid mismatch!\n");
+ }
+ }
+ /*
+ * getpkt() sets channelrd to indicate where the message came from.
+ * now we switch on the channel (/type of message) and then deal
+ * with it.
+ */
+ switch (channelrd)
+ {
+ case SET_CHANNEL_DEBUG:
+ if (((recv.pkt.hdr.cmd & DSHDR_MSG_BIG_ENDIAN) != 0))
+ {
+ sprintf (tran.buf, "set endian big");
+ if (TARGET_BYTE_ORDER != BFD_ENDIAN_BIG)
+ execute_command (tran.buf, 0);
+ }
+ else
+ {
+ sprintf (tran.buf, "set endian little");
+ if (TARGET_BYTE_ORDER != BFD_ENDIAN_LITTLE)
+ execute_command (tran.buf, 0);
+ }
+ recv.pkt.hdr.cmd &= ~DSHDR_MSG_BIG_ENDIAN;
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ errno = qnx_swap32 (recv.pkt.err.err);
+ if (report_errors)
+ {
+ switch (recv.pkt.hdr.subcmd)
+ {
+ case PDEBUG_ENOERR:
+ break;
+ case PDEBUG_ENOPTY:
+ perror_with_name ("Remote (no ptys available)");
+ break;
+ case PDEBUG_ETHREAD:
+ perror_with_name ("Remote (thread start error)");
+ break;
+ case PDEBUG_ECONINV:
+ perror_with_name ("Remote (invalid console number)");
+ break;
+ case PDEBUG_ESPAWN:
+ perror_with_name ("Remote (spawn error)");
+ break;
+ case PDEBUG_EPROCFS:
+ perror_with_name ("Remote (procfs [/proc] error)");
+ break;
+ case PDEBUG_EPROCSTOP:
+ perror_with_name ("Remote (devctl PROC_STOP error)");
+ break;
+ case PDEBUG_EQPSINFO:
+ perror_with_name ("Remote (psinfo error)");
+ break;
+ case PDEBUG_EQMEMMODEL:
+ perror_with_name
+ ("Remote (invalid memory model [not flat] )");
+ break;
+ case PDEBUG_EQPROXY:
+ perror_with_name ("Remote (proxy error)");
+ break;
+ case PDEBUG_EQDBG:
+ perror_with_name ("Remote (__qnx_debug_* error)");
+ break;
+ default:
+ perror_with_name ("Remote");
+ }
+ }
+ }
+ break;
+ case SET_CHANNEL_TEXT:
+ case SET_CHANNEL_RESET: /* no-ops */
+ break;
+ }
+ return rlen;
+ }
+
+ /* FIXME: should we be ignoring th? */
+ static void
+ set_thread (int th)
+ {
+ int new_pid;
+ int new_tid;
+
+ new_pid = ptid_get_pid (inferior_ptid);
+ new_tid = ptid_get_tid (inferior_ptid);
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered
+ ("set_thread(th %d) -- th is unused (using pid %d, tid %d)\n", th,
+ new_pid, new_tid);
+ }
+
+ if (new_pid != curr_proc.pid || new_tid != curr_proc.tid)
+ {
+ curr_proc.pid = new_pid;
+ curr_proc.tid = new_tid;
+ qnx_send_init (DStMsg_select, DSMSG_SELECT_SET, SET_CHANNEL_DEBUG);
+ tran.pkt.select.pid = qnx_swap32 (new_pid);
+ tran.pkt.select.tid = qnx_swap32 (new_tid);
+ qnx_send (sizeof (tran.pkt.select), 1);
+ }
+ }
+
+
+ /* Return nonzero if the thread TH is still alive on the remote system. */
+
+ static int
+ qnx_thread_alive (ptid_t th)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_thread_alive -- pid %d, tid %ld\n",
+ ptid_get_pid (th), ptid_get_tid (th));
+ }
+
+ qnx_send_init (DStMsg_select, DSMSG_SELECT_QUERY, SET_CHANNEL_DEBUG);
+ tran.pkt.select.pid = qnx_swap32 (ptid_get_pid (th));
+ tran.pkt.select.tid = qnx_swap32 (ptid_get_tid (th));
+ qnx_send (sizeof (tran.pkt.select), 0);
+ return recv.pkt.hdr.cmd != DSrMsg_err;
+ }
+
+ /* Clean up connection to a remote debugger. */
+
+ /* ARGSUSED */
+ static int
+ qnx_close_1 (char *dummy)
+ {
+ qnx_send_init (DStMsg_disconnect, 0, SET_CHANNEL_DEBUG);
+ qnx_send (sizeof (tran.pkt.disconnect), 0);
+ serial_close (qnx_desc);
+
+ return 0;
+ }
+
+ /* ARGSUSED */
+ static void
+ qnx_close (int quitting)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_close(quitting %d)\n", quitting);
+ }
+
+ if (qnx_desc)
+ {
+ catch_errors ((catch_errors_ftype *) qnx_close_1, NULL, "",
+ RETURN_MASK_ALL);
+ qnx_desc = NULL;
+ qnx_remove_commands ();
+ }
+ }
+
+ /* Stub for catch_errors. */
+
+ extern void qnx_init_solib_search_path ();
+
+ static int
+ qnx_start_remote (char *dummy)
+ {
+ int orig_target_endian;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered
+ ("qnx_start_remote, recv.pkt.hdr.cmd %d, (dummy %s)\n",
+ recv.pkt.hdr.cmd, dummy);
+ }
+
+ immediate_quit = 1; /* Allow user to interrupt it */
+ for (;;)
+ {
+ orig_target_endian = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
+
+ /* reset remote pdebug */
+ SEND_CH_RESET;
+
+ /*
+ * This is the first significant backward incompatible change made to
+ * pdebug. We used to handle a notifyhost/ctl-c race condition by dropping
+ * the out of order debug message in pdebug. Now we handle the message.
+ * The new pdebug will know this by checking against the minor version,
+ * which is now being set to 1, as opposed to 0. We then have to query
+ * the remote agent for their protover, so we can behave accordingly.
+ */
+
+ qnx_send_init (DStMsg_connect, 0, SET_CHANNEL_DEBUG);
+
+ tran.pkt.connect.major = HOST_QNX_PROTOVER_MAJOR;
+ tran.pkt.connect.minor = HOST_QNX_PROTOVER_MINOR;
+
+ qnx_send (sizeof (tran.pkt.connect), 0);
+
+ if (recv.pkt.hdr.cmd != DSrMsg_err)
+ break;
+ if (orig_target_endian == (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG))
+ break;
+ /* Send packet again, with opposite endianness */
+ }
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ error ("Connection failed: %ld.", qnx_swap32 (recv.pkt.err.err));
+ }
+ /* NYI: need to size transmit/receive buffers to allowed size in connect response */
+ immediate_quit = 0;
+
+ #ifdef TARGET_BYTE_ORDER_SELECTABLE
+ printf_unfiltered ("Remote target is %s-endian\n",
+ (TARGET_BYTE_ORDER ==
+ BFD_ENDIAN_BIG) ? "big" : "little");
+ /* if ( t_endian )
+ TARGET_BYTE_ORDER = BFD_ENDIAN_BIG;
+ else
+ TARGET_BYTE_ORDER = BFD_ENDIAN_LITTLE; */
+ target_byte_order_auto = 1;
+ #endif
+ qnx_init_solib_search_path ();
+
+ /*
+ * Try to query pdebug for their version of the protocol
+ */
+
+ qnx_send_init (DStMsg_protover, 0, SET_CHANNEL_DEBUG);
+ tran.pkt.protover.major = HOST_QNX_PROTOVER_MAJOR;
+ tran.pkt.protover.minor = HOST_QNX_PROTOVER_MINOR;
+ qnx_send (sizeof (tran.pkt.protover), 0);
+ if ((recv.pkt.hdr.cmd == DSrMsg_err) && (qnx_swap32 (recv.pkt.err.err) == EINVAL)) // old pdebug protocol version 0.0
+ {
+ TargetQNXProtoverMajor = 0;
+ TargetQNXProtoverMinor = 0;
+ }
+ else if (recv.pkt.hdr.cmd == DSrMsg_okstatus)
+ {
+ TargetQNXProtoverMajor = qnx_swap32 (recv.pkt.okstatus.status);
+ TargetQNXProtoverMinor = qnx_swap32 (recv.pkt.okstatus.status);
+ TargetQNXProtoverMajor =
+ (TargetQNXProtoverMajor >> 8) & DSMSG_PROTOVER_MAJOR;
+ TargetQNXProtoverMinor = TargetQNXProtoverMinor & DSMSG_PROTOVER_MINOR;
+ }
+ else
+ {
+ error ("Connection failed (Protocol Version Query): %ld.",
+ qnx_swap32 (recv.pkt.err.err));
+ }
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("Pdebug protover %d.%d, GDB protover %d.%d\n",
+ TargetQNXProtoverMajor, TargetQNXProtoverMinor,
+ HOST_QNX_PROTOVER_MAJOR, HOST_QNX_PROTOVER_MINOR);
+ }
+
+ target_has_execution = 0;
+ target_has_stack = 0;
+ qnx_target_has_stack_frame = 0;
+ start_remote (); /* Initialize gdb process mechanisms */
+
+ qnx_send_init (DStMsg_cpuinfo, 0, SET_CHANNEL_DEBUG);
+ qnx_send (sizeof (tran.pkt.cpuinfo), 1);
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ qnx_cpuinfo_valid = 0;
+ }
+ else
+ {
+ memcpy (&qnx_cpuinfo, recv.pkt.okdata.data, sizeof (struct dscpuinfo));
+ qnx_cpuinfo.cpuflags = qnx_swap32 (qnx_cpuinfo.cpuflags);
+ qnx_cpuinfo_valid = 1;
+ }
+
+ return 1;
+ }
+
+ /* Open a connection to a remote debugger.
+ NAME is the filename used for communication. */
+
+ static void
+ qnx_semi_init (void)
+ {
+ qnx_send_init (DStMsg_disconnect, 0, SET_CHANNEL_DEBUG);
+ qnx_send (sizeof (tran.pkt.disconnect), 0);
+
+ curr_proc.pid = 0;
+ curr_proc.tid = 0;
+
+ /* Without this, some commands which require an active target (such as kill)
+ won't work. This variable serves (at least) double duty as both the pid
+ of the target process (if it has such), and as a flag indicating that a
+ target is active. These functions should be split out into seperate
+ variables, especially since GDB will someday have a notion of debugging
+ several processes. */
+
+ inferior_ptid = null_ptid;
+ init_thread_list ();
+
+ if (!catch_errors ((catch_errors_ftype *) qnx_start_remote, (char *) 0,
+ "Couldn't establish connection to remote target\n",
+ RETURN_MASK_ALL))
+ {
+ flush_cached_frames ();
+ pop_target ();
+ if (nto_internal_debugging == 3)
+ {
+ printf_unfiltered ("qnx_semi_init() - pop_target\n");
+ }
+ }
+ }
+
+ static void
+ qnx_open (char *name, int from_tty)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_open(name '%s', from_tty %d)\n", name,
+ from_tty);
+ }
+
+ if (name == 0)
+ error
+ ("To open a remote debug connection, you need to specify what serial\ndevice is attached to the remote system (e.g. /dev/ttya).");
+
+ immediate_quit = 1; /* Allow user to interrupt it */
+
+ target_preopen (from_tty);
+ unpush_target (&qnx_ops);
+
+ if (nto_internal_debugging == 3)
+ {
+ printf_unfiltered ("qnx_open() - unpush_target\n");
+ }
+
+ qnx_desc = serial_open (name);
+
+ if (!qnx_desc)
+ {
+ immediate_quit = 0;
+ perror_with_name (name);
+ }
+
+ if (baud_rate != -1)
+ {
+ if (serial_setbaudrate (qnx_desc, baud_rate))
+ {
+ immediate_quit = 0;
+ serial_close (qnx_desc);
+ perror_with_name (name);
+ }
+ }
+
+ serial_raw (qnx_desc);
+
+ /* If there is something sitting in the buffer we might take it as a
+ response to a command, which would be bad. */
+ serial_flush_input (qnx_desc);
+
+ if (from_tty)
+ {
+ puts_filtered ("Remote debugging using ");
+ puts_filtered (name);
+ puts_filtered ("\n");
+ }
+ push_target (&qnx_ops); /* Switch to using remote target now */
+ qnx_add_commands ();
+ if (nto_internal_debugging == 3)
+ {
+ printf_unfiltered ("qnx_open() - push_target\n");
+ }
+
+ curr_proc.pid = 0;
+ curr_proc.tid = 0;
+
+ /* Without this, some commands which require an active target (such as kill)
+ won't work. This variable serves (at least) double duty as both the pid
+ of the target process (if it has such), and as a flag indicating that a
+ target is active. These functions should be split out into seperate
+ variables, especially since GDB will someday have a notion of debugging
+ several processes. */
+
+ inferior_ptid = null_ptid;
+ init_thread_list ();
+
+ /* Start the remote connection; if error (0), discard this target.
+ In particular, if the user quits, be sure to discard it
+ (we'd be in an inconsistent state otherwise). */
+
+ if (!catch_errors ((catch_errors_ftype *) qnx_start_remote, (char *) 0,
+ "Couldn't establish connection to remote target\n",
+ RETURN_MASK_ALL))
+ {
+ immediate_quit = 0;
+ pop_target ();
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_open() - pop_target\n");
+ }
+ }
+ immediate_quit = 0;
+ }
+
+ /* Attaches to a process on the target side. Arguments are as passed
+ to the `attach' command by the user. This routine can be called
+ when the target is not on the target-stack, if the target_can_run
+ routine returns 1; in that case, it must push itself onto the stack.
+ Upon exit, the target should be ready for normal operations, and
+ should be ready to deliver the status of the process immediately
+ (without waiting) to an upcoming target_wait call. */
+
+ static void
+ qnx_attach (char *args, int from_tty)
+ {
+ ptid_t ptid;
+
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ qnx_semi_init ();
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_attach(args '%s', from_tty %d)\n",
+ args ? args : "(null)", from_tty);
+ }
+
+ if (!args)
+ error_no_arg ("process-id to attach");
+
+ ptid = pid_to_ptid (atoi (args));
+
+ if (from_tty)
+ {
+ printf_unfiltered ("Attaching to %s\n", target_pid_to_str (ptid));
+ gdb_flush (gdb_stdout);
+ }
+
+ qnx_send_init (DStMsg_attach, 0, SET_CHANNEL_DEBUG);
+ tran.pkt.attach.pid = qnx_swap32 (PIDGET (ptid));
+ qnx_send (sizeof (tran.pkt.attach), 1);
+
+ /* NYI: add symbol information for process */
+ /*
+ * Turn the PIDLOAD into a STOPPED notification so that when gdb
+ * calls qnx_wait, we won't cycle around.
+ */
+ recv.pkt.hdr.cmd = DShMsg_notify;
+ recv.pkt.hdr.subcmd = DSMSG_NOTIFY_STOPPED;
+
+ /* hack this in here, since we will bypass the notify */
+ qnx_ostype = qnx_swap16 (recv.pkt.notify.un.pidload.ostype);
+ qnx_cputype = qnx_swap16 (recv.pkt.notify.un.pidload.cputype);
+ qnx_cpuid = qnx_swap32 (recv.pkt.notify.un.pidload.cpuid);
+ #ifdef QNX_SET_PROCESSOR_TYPE
+ QNX_SET_PROCESSOR_TYPE (qnx_cpuid); // for mips
+ #endif
+ inferior_ptid = ptid;
+ target_has_execution = 1;
+ target_has_stack = 1;
+ target_has_registers = 1;
+ qnx_target_has_stack_frame = 1;
+ if (target_created_hook)
+ target_created_hook (curr_proc.pid);
+ attach_flag = 1;
+ }
+
+ /* This takes a program previously attached to and detaches it. After
+ this is done, GDB can be used to debug some other program. We
+ better not have left any breakpoints in the target program or it'll
+ die when it hits one. */
+
+ static void
+ qnx_detach (char *args, int from_tty)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_detach(args '%s', from_tty %d)\n",
+ args ? args : "(null)", from_tty);
+ }
+ if (from_tty)
+ {
+ char *exec_file = get_exec_file (0);
+ if (exec_file == 0)
+ exec_file = "";
+
+ printf_unfiltered ("Detaching from program: %s %d\n", exec_file,
+ PIDGET (inferior_ptid));
+ gdb_flush (gdb_stdout);
+ }
+ if (args)
+ {
+ int sig = target_signal_to_qnx (atoi (args));
+
+ qnx_send_init (DStMsg_kill, 0, SET_CHANNEL_DEBUG);
+ tran.pkt.kill.signo = qnx_swap32 (sig);
+ qnx_send (sizeof (tran.pkt.kill), 1);
+ }
+
+ qnx_send_init (DStMsg_detach, 0, SET_CHANNEL_DEBUG);
+ tran.pkt.detach.pid = qnx_swap32 (PIDGET (inferior_ptid));
+ qnx_send (sizeof (tran.pkt.detach), 1);
+ inferior_ptid = null_ptid;
+ init_thread_list ();
+ target_has_execution = 0;
+ target_has_stack = 0;
+ target_has_registers = 0;
+ qnx_target_has_stack_frame = 0;
+
+ attach_flag = 0;
+ }
+
+
+ /* Tell the remote machine to resume. */
+
+ static void
+ qnx_resume (ptid_t ptid, int step, enum target_signal sig)
+ {
+ int signo;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_resume(pid %d, step %d, sig %d)\n",
+ PIDGET (ptid), step, target_signal_to_qnx (sig));
+ }
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return;
+
+ set_thread (ptid_equal (ptid, minus_one_ptid) ? ptid_get_tid (inferior_ptid)
+ : ptid_get_tid (ptid));
+
+ // The HandleSig stuff is part of the new protover 0.1, but has not
+ // been implemented in all pdebugs that reflect that version. If
+ // the HandleSig comes back with an error, then revert to protover 0.0
+ // behaviour, regardless of actual protover.
+ // The handlesig msg sends the signal to pass, and a char array
+ // 'signals', which is the list of signals to notice.
+
+ qnx_send_init (DStMsg_handlesig, 0, SET_CHANNEL_DEBUG);
+ tran.pkt.handlesig.sig_to_pass = qnx_swap32 (target_signal_to_qnx (sig));
+ for (signo = 0; signo < QNXNTO_NSIG; signo++)
+ {
+ if (signal_stop_state (target_signal_from_qnx (signo)) == 0 &&
+ signal_print_state (target_signal_from_qnx (signo)) == 0 &&
+ signal_pass_state (target_signal_from_qnx (signo)) == 1)
+ {
+ tran.pkt.handlesig.signals[signo] = 0;
+ }
+ else
+ {
+ tran.pkt.handlesig.signals[signo] = 1;
+ }
+ }
+ qnx_send (sizeof (tran.pkt.handlesig), 0);
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ if (sig != TARGET_SIGNAL_0)
+ {
+ qnx_send_init (DStMsg_kill, 0, SET_CHANNEL_DEBUG);
+ tran.pkt.kill.signo = qnx_swap32 (target_signal_to_qnx (sig));
+ qnx_send (sizeof (tran.pkt.kill), 1);
+ }
+
+ qnx_send_init (DStMsg_run, step ? DSMSG_RUN_COUNT : DSMSG_RUN,
+ SET_CHANNEL_DEBUG);
+ tran.pkt.run.step.count = qnx_swap32 (1);
+ qnx_send (sizeof (tran.pkt.run), 1);
+ }
+
+ static void (*ofunc) ();
+ static void (*ofunc_alrm) ();
+
+ //
+ // Yucky but necessary globals used to track state in qnx_wait() as a result of
+ // things done in qnx_interrupt(), qnx_interrupt_twice(), and qnx_interrupt_retry();
+ //
+ static sig_atomic_t SignalCount = 0; // used to track ctl-c retransmits
+ static sig_atomic_t InterruptedTwice = 0; // Set in qnx_interrupt_twice()
+ static sig_atomic_t WaitingForStopResponse = 0; // Set in qnx_interrupt(), cleared in qnx_wait()
+
+ #define QNX_TIMER_TIMEOUT 5
+ #define QNX_CTL_C_RETRIES 3
+
+ static void
+ qnx_interrupt_retry (signo)
+ {
+ SignalCount++;
+ if (SignalCount >= QNX_CTL_C_RETRIES) // retry QNX_CTL_C_RETRIES times after original tranmission
+ {
+ printf_unfiltered
+ ("CTL-C transmit - 3 retries exhausted. Ending debug session.\n");
+ WaitingForStopResponse = 0;
+ SignalCount = 0;
+ target_mourn_inferior ();
+ throw_exception (RETURN_QUIT);
+ }
+ else
+ {
+ qnx_interrupt (SIGINT);
+ }
+ }
+
+
+ /* Ask the user what to do when an interrupt is received. */
+
+ static void
+ interrupt_query ()
+ {
+ alarm (0);
+ signal (SIGINT, ofunc);
+ signal (SIGALRM, ofunc_alrm);
+ target_terminal_ours ();
+ InterruptedTwice = 0;
+
+ if (query
+ ("Interrupted while waiting for the program.\n Give up (and stop debugging it)? "))
+ {
+ SignalCount = 0;
+ target_mourn_inferior ();
+ throw_exception (RETURN_QUIT);
+ }
+ target_terminal_inferior ();
+ signal (SIGALRM, qnx_interrupt_retry);
+ signal (SIGINT, qnx_interrupt_twice);
+ alarm (QNX_TIMER_TIMEOUT);
+ }
+
+
+ /* The user typed ^C twice. */
+ static void
+ qnx_interrupt_twice (signo)
+ int signo;
+ {
+ InterruptedTwice = 1;
+ }
+
+ /* Send ^C to target to halt it. Target will respond, and send us a
+ packet. */
+
+ //
+ // GP - Dec 21, 2000. If the target sends a NotifyHost at the same time as
+ // GDB sends a DStMsg_stop, then we would get into problems as both ends
+ // would be waiting for a response, and not the sent messages. Now, we put
+ // the pkt and set the global flag 'WaitingForStopResponse', and return.
+ // This then goes back to the the main loop in qnx_wait() below where we
+ // now check against the debug message received, and handle both.
+ // All retries of the DStMsg_stop are handled via SIGALRM and alarm(timeout);
+ //
+
+ static void
+ qnx_interrupt (int signo)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_interrupt(signo %d)\n", signo);
+ }
+
+ /* If this doesn't work, try more severe steps. */
+ signal (signo, qnx_interrupt_twice);
+ signal (SIGALRM, qnx_interrupt_retry);
+
+ WaitingForStopResponse = 1;
+
+ qnx_send_init (DStMsg_stop, DSMSG_STOP_PIDS, SET_CHANNEL_DEBUG);
+ putpkt (sizeof (tran.pkt.stop));
+
+ // Set timeout
+ alarm (QNX_TIMER_TIMEOUT);
+ }
+
+ /* Wait until the remote machine stops, then return,
+ storing status in STATUS just as `wait' would.
+ Returns "pid". */
+
+ static ptid_t
+ qnx_wait (ptid_t ptid, struct target_waitstatus *status)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_wait pid %d, inferior pid %d\n",
+ ptid_get_pid (ptid), ptid_get_pid (inferior_ptid));
+ }
+
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_0;
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return null_ptid;
+
+ if (recv.pkt.hdr.cmd != DShMsg_notify)
+ {
+ int len;
+ char waiting_for_notify;
+
+ waiting_for_notify = 1;
+ SignalCount = 0;
+ InterruptedTwice = 0;
+
+ ofunc = (void (*)()) signal (SIGINT, qnx_interrupt);
+ ofunc_alrm = (void (*)()) signal (SIGALRM, qnx_interrupt_retry);
+ for (;;)
+ {
+ len = getpkt (1);
+ if (len < 0) // error - probably received MSG_NAK
+ {
+ if (WaitingForStopResponse)
+ {
+ // we do not want to get SIGALRM while calling it's handler
+ // the timer is reset in the handler
+ alarm (0);
+ qnx_interrupt_retry (SIGALRM);
+ continue;
+ }
+ else
+ {
+ // turn off the alarm, and reset the signals, and return
+ alarm (0);
+ signal (SIGINT, ofunc);
+ signal (SIGALRM, ofunc_alrm);
+ return null_ptid;
+ }
+ }
+ if (channelrd == SET_CHANNEL_TEXT)
+ qnx_incoming_text (len);
+ else // DEBUG CHANNEL
+ {
+ recv.pkt.hdr.cmd &= ~DSHDR_MSG_BIG_ENDIAN;
+ // If we have sent the DStMsg_stop due to a ^C, we expect
+ // to get the response, so check and clear the flag
+ // also turn off the alarm - no need to retry, we did not lose the packet.
+ if ((WaitingForStopResponse) && (recv.pkt.hdr.cmd == DSrMsg_ok))
+ {
+ WaitingForStopResponse = 0;
+ status->value.sig = TARGET_SIGNAL_INT;
+ alarm (0);
+ if (!waiting_for_notify)
+ break;
+ }
+ else // else we get the Notify we are waiting for
+ if (recv.pkt.hdr.cmd == DShMsg_notify)
+ {
+ waiting_for_notify = 0;
+ // Send an OK packet to acknowledge the notify.
+ tran.pkt.hdr.cmd = DSrMsg_ok;
+ if ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG))
+ tran.pkt.hdr.cmd |= DSHDR_MSG_BIG_ENDIAN;
+ tran.pkt.hdr.channel = SET_CHANNEL_DEBUG;
+ tran.pkt.hdr.mid = recv.pkt.hdr.mid;
+ SEND_CH_DEBUG;
+ putpkt (sizeof (tran.pkt.ok));
+ // Handle old pdebug protocol behavior, where out of order msgs get dropped
+ // version 0.0 does this, so we must resend after a notify.
+ if ((TargetQNXProtoverMajor == 0)
+ && (TargetQNXProtoverMinor == 0))
+ {
+ if (WaitingForStopResponse)
+ {
+ alarm (0);
+ // change the command to something other than notify
+ // so we don't loop in here again - leave the rest of
+ // the packet alone for qnx_parse_notify() below!!!
+ recv.pkt.hdr.cmd = DSrMsg_ok;
+ qnx_interrupt (SIGINT);
+ }
+ }
+ qnx_parse_notify (status);
+
+ if (!WaitingForStopResponse)
+ break;
+ }
+ }
+ }
+ alarm (0);
+
+ //
+ // Hitting Ctl-C sends a stop request, a second ctl-c means quit,
+ // so query here, after handling the results of the first ctl-c
+ // We know we were interrupted twice because the yucky global flag
+ // 'InterruptedTwice' is set in the handler, and cleared in interrupt_query()
+ //
+ if (InterruptedTwice)
+ interrupt_query ();
+
+ signal (SIGINT, ofunc);
+ signal (SIGALRM, ofunc_alrm);
+ }
+
+ recv.pkt.hdr.cmd = DSrMsg_ok; /* to make us wait the next time */
+ return inferior_ptid;
+ }
+
+ static void
+ qnx_parse_notify (struct target_waitstatus *status)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_parse_notify(status) - subcmd %d\n",
+ recv.pkt.hdr.subcmd);
+ }
+ curr_proc.pid = qnx_swap32 (recv.pkt.notify.pid);
+ curr_proc.tid = qnx_swap32 (recv.pkt.notify.tid);
+ if (curr_proc.tid == 0)
+ curr_proc.tid = 1;
+
+ // This was added for arm. See arm_init_extra_frame_info()
+ // in arm-tdep.c. arm_scan_prologue() causes a memory_error()
+ // if there is not a valid stack frame, and when the inferior
+ // is loaded, but has not started executing, the stack frame
+ // is invalid. The default is to assume a stack frame, and
+ // this is set to 0 if we have a DSMSG_NOTIFY_PIDLOAD
+ // GP July 5, 2001.
+
+ qnx_target_has_stack_frame = 1;
+
+ switch (recv.pkt.hdr.subcmd)
+ {
+ case DSMSG_NOTIFY_PIDUNLOAD:
+ /*
+ * Added a new struct pidunload_v3 to the notify.un. This includes a
+ * faulted flag so we can tell if the status value is a signo or an
+ * exit value. See dsmsgs.h, protoverminor bumped to 3. GP Oct 31 2002.
+ */
+ if ((TargetQNXProtoverMajor == 0) && (TargetQNXProtoverMinor >= 3))
+ {
+ if (recv.pkt.notify.un.pidunload_v3.faulted)
+ {
+ status->value.integer =
+ target_signal_from_qnx (qnx_swap32
+ (recv.pkt.notify.un.pidunload_v3.
+ status));
+ if (status->value.integer)
+ status->kind = TARGET_WAITKIND_SIGNALLED; //abnormal death
+ else
+ status->kind = TARGET_WAITKIND_EXITED; //normal death
+ }
+ else
+ {
+ status->value.integer =
+ qnx_swap32 (recv.pkt.notify.un.pidunload_v3.status);
+ status->kind = TARGET_WAITKIND_EXITED; //normal death, possibly with exit value
+ }
+ }
+ else
+ {
+ status->value.integer =
+ target_signal_from_qnx (qnx_swap32
+ (recv.pkt.notify.un.pidunload.status));
+ if (status->value.integer)
+ status->kind = TARGET_WAITKIND_SIGNALLED; //abnormal death
+ else
+ status->kind = TARGET_WAITKIND_EXITED; //normal death
+ }
+ target_has_execution = 0;
+ target_has_stack = 0;
+ target_has_registers = 0;
+ qnx_target_has_stack_frame = 0;
+ break;
+ case DSMSG_NOTIFY_BRK:
+ case DSMSG_NOTIFY_STEP:
+ /* NYI: could update the CPU's IP register here. */
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig = TARGET_SIGNAL_TRAP;
+ break;
+ case DSMSG_NOTIFY_SIGEV:
+ status->kind = TARGET_WAITKIND_STOPPED;
+ status->value.sig =
+ target_signal_from_qnx (qnx_swap32 (recv.pkt.notify.un.sigev.signo));
+ break;
+ case DSMSG_NOTIFY_PIDLOAD:
+ qnx_ostype = qnx_swap16 (recv.pkt.notify.un.pidload.ostype);
+ qnx_cputype = qnx_swap16 (recv.pkt.notify.un.pidload.cputype);
+ qnx_cpuid = qnx_swap32 (recv.pkt.notify.un.pidload.cpuid);
+ #ifdef QNX_SET_PROCESSOR_TYPE
+ QNX_SET_PROCESSOR_TYPE (qnx_cpuid); // for mips
+ #endif
+ target_has_execution = 1;
+ target_has_stack = 1;
+ target_has_registers = 1;
+ qnx_target_has_stack_frame = 0;
+ if (target_created_hook)
+ target_created_hook (curr_proc.pid);
+ status->kind = TARGET_WAITKIND_LOADED;
+ break;
+ case DSMSG_NOTIFY_DLLLOAD:
+ case DSMSG_NOTIFY_TIDLOAD:
+ case DSMSG_NOTIFY_TIDUNLOAD:
+ case DSMSG_NOTIFY_DLLUNLOAD:
+ status->kind = TARGET_WAITKIND_SPURIOUS;
+ break;
+ case DSMSG_NOTIFY_STOPPED:
+ status->kind = TARGET_WAITKIND_STOPPED;
+ break;
+ default:
+ warning ("Unexpected notify type %d", recv.pkt.hdr.subcmd);
+ break;
+ }
+ inferior_ptid = ptid_build (curr_proc.pid, 0, curr_proc.tid);
+ }
+
+ /* Read register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. */
+ void
+ qnx_fetch_registers (int regno)
+ {
+ unsigned first;
+ unsigned last;
+ int len;
+ int minusone = -1;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_fetch_registers(regno %d)\n", regno);
+ }
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return;
+
+ set_thread (ptid_get_tid (inferior_ptid));
+
+ if (regno == -1)
+ { /* get all regsets */
+ first = 0;
+ last = qnx_get_regset_id (-1);
+ }
+ else
+ { /* get regset regno is in */
+ first = qnx_get_regset_id (regno);
+ last = first + 1;
+ if (first == -1)
+ { /* don't support reg */
+ supply_register (regno, (char *) &minusone);
+ return;
+ }
+ }
+ for (; first < last; ++first)
+ {
+ qnx_send_init (DStMsg_regrd, 0, SET_CHANNEL_DEBUG);
+ len = qnx_get_regset_area (first, &tran.pkt.hdr.subcmd);
+ if (len > 0)
+ {
+ void *data;
+ #ifdef TM_I386QNX_H
+ /* FIXME: these ifdefs should be taken out once we move to the new proc which
+ * has a long enough structure to hold floating point registers */
+ int rlen;
+ #endif
+
+ tran.pkt.regrd.offset = qnx_swap16 (0); /* Always get whole set */
+ tran.pkt.regrd.size = qnx_swap16 (len);
+ #ifdef TM_I386QNX_H
+ rlen = qnx_send (sizeof (tran.pkt.regrd), 0);
+ #else
+ qnx_send (sizeof (tran.pkt.regrd), 0);
+ #endif
+ if (recv.pkt.hdr.cmd != DSrMsg_err)
+ {
+ data = recv.pkt.okdata.data;
+ }
+ else
+ {
+ data = NULL;
+ return;
+ }
+ #ifdef TM_I386QNX_H
+ if (first == 1 && rlen <= 128)
+ return; //trying to get fpregs from an old proc
+
+ #endif
+ qnx_cpu_regset_fetch ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG), first,
+ data);
+ }
+ }
+ }
+
+ /* Prepare to store registers. Don't have to do anything. */
+
+ static void
+ qnx_prepare_to_store ()
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_prepare_to_store()\n");
+ }
+ }
+
+
+ /* Store register REGNO, or all registers if REGNO == -1, from the contents
+ of REGISTERS. */
+
+ void
+ qnx_store_registers (int regno)
+ {
+ unsigned first;
+ unsigned last;
+ unsigned end;
+ unsigned off;
+ unsigned len;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_store_registers(regno %d)\n", regno);
+ }
+
+ if (ptid_equal (inferior_ptid, null_ptid))
+ return;
+
+ set_thread (ptid_get_tid (inferior_ptid));
+
+ if (regno == -1)
+ {
+ first = 0;
+ last = NUM_REGS - 1;
+ }
+ else
+ {
+ first = regno;
+ last = regno;
+ }
+
+ while (first <= last)
+ {
+ qnx_send_init (DStMsg_regwr, 0, SET_CHANNEL_DEBUG);
+ end = qnx_cpu_register_area (first, last,
+ &tran.pkt.hdr.subcmd, &off, &len);
+ if (len > 0)
+ {
+ tran.pkt.regwr.offset = qnx_swap16 (off);
+ if (qnx_cpu_register_store
+ ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG), first, end,
+ tran.pkt.regwr.data))
+ qnx_send (offsetof (DStMsg_regwr_t, data) + len, 1);
+ }
+ first = end + 1;
+ }
+ }
+
+ /*
+ Use of the data cache *used* to be disabled because it loses for looking at
+ and changing hardware I/O ports and the like. Accepting `volatile'
+ would perhaps be one way to fix it. Another idea would be to use the
+ executable file for the text segment (for all SEC_CODE sections?
+ For all SEC_READONLY sections?). This has problems if you want to
+ actually see what the memory contains (e.g. self-modifying code,
+ clobbered memory, user downloaded the wrong thing).
+
+ Because it speeds so much up, it's now enabled, if you're playing
+ with registers you turn it off (set remotecache 0)
+ */
+
+
+ /* Write memory data directly to the remote machine.
+ This does not inform the data cache; the data cache uses this.
+ MEMADDR is the address in the remote memory space.
+ MYADDR is the address of the buffer in our space.
+ LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+ static int
+ qnx_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+ {
+ long long addr;
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_write_bytes(to %lx, from %p, len %d)\n",
+ memaddr, myaddr, len);
+ }
+
+ /* NYI: need to handle requests bigger than largest allowed packet */
+ qnx_send_init (DStMsg_memwr, 0, SET_CHANNEL_DEBUG);
+ addr = memaddr;
+ tran.pkt.memwr.addr = qnx_swap64 (addr);
+ memcpy (tran.pkt.memwr.data, myaddr, len);
+ qnx_send (offsetof (DStMsg_memwr_t, data) + len, 0);
+
+ switch (recv.pkt.hdr.cmd)
+ {
+ case DSrMsg_ok:
+ return len;
+ case DSrMsg_okstatus:
+ return qnx_swap32 (recv.pkt.okstatus.status);
+ }
+ return 0;
+ }
+
+ /* Read memory data directly from the remote machine.
+ This does not use the data cache; the data cache uses this.
+ MEMADDR is the address in the remote memory space.
+ MYADDR is the address of the buffer in our space.
+ LEN is the number of bytes.
+
+ Returns number of bytes transferred, or 0 for error. */
+
+ static int
+ qnx_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
+ {
+ int rcv_len, tot_len, ask_len;
+ long long addr;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_read_bytes(from %lx, to %p, len %d)\n", memaddr,
+ myaddr, len);
+ }
+
+ tot_len = rcv_len = ask_len = 0;
+
+ /* GP, Jan 27,2000 - need to handle requests bigger than largest allowed packet */
+ do
+ {
+ qnx_send_init (DStMsg_memrd, 0, SET_CHANNEL_DEBUG);
+ addr = memaddr + tot_len;
+ tran.pkt.memrd.addr = qnx_swap64 (addr);
+ ask_len =
+ ((len - tot_len) >
+ DS_DATA_MAX_SIZE) ? DS_DATA_MAX_SIZE : (len - tot_len);
+ tran.pkt.memrd.size = qnx_swap16 (ask_len);
+ rcv_len = qnx_send (sizeof (tran.pkt.memrd), 0) - sizeof (recv.pkt.hdr);
+ if (rcv_len <= 0)
+ break;
+ if (recv.pkt.hdr.cmd == DSrMsg_okdata)
+ {
+ memcpy (myaddr + tot_len, recv.pkt.okdata.data, rcv_len);
+ tot_len += rcv_len;
+ }
+ else
+ break;
+ }
+ while (tot_len != len);
+
+ return (tot_len);
+ }
+
+ /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
+ to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
+ nonzero. Returns length of data written or read; 0 for error. */
+
+ /* ARGSUSED */
+ static int
+ qnx_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int should_write,
+ struct mem_attrib *attrib, struct target_ops *ignore)
+ {
+ int res;
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered
+ ("qnx_xfer_memory(memaddr %lx, myaddr %p, len %d, should_write %d, target %p)\n",
+ memaddr, myaddr, len, should_write, ignore);
+ }
+ if (ptid_equal (inferior_ptid, null_ptid))
+ {
+ /* pretend to read if no inferior but fail on write */
+ if (should_write)
+ return 0;
+ memset (myaddr, 0, len);
+ return len;
+ }
+ if (should_write)
+ res = qnx_write_bytes (memaddr, myaddr, len);
+ else
+ res = qnx_read_bytes (memaddr, myaddr, len);
+ return res;
+ }
+
+
+ static void
+ qnx_files_info (struct target_ops *ignore)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_files_info(ignore %p)\n", ignore);
+ }
+ puts_filtered ("Debugging a target over a serial line.\n");
+ }
+
+
+ static int
+ qnx_kill_1 (char *dummy)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_kill_1(dummy %p)\n", dummy);
+ }
+
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ {
+ qnx_send_init (DStMsg_kill, DSMSG_KILL_PID, SET_CHANNEL_DEBUG);
+ tran.pkt.kill.signo = qnx_swap32 (9); /* SIGKILL */
+ qnx_send (sizeof (tran.pkt.kill), 0);
+ }
+ return 0;
+ }
+
+ static void
+ qnx_kill ()
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_kill()\n");
+ }
+
+ /* Use catch_errors so the user can quit from gdb even when we aren't on
+ speaking terms with the remote system. */
+ if (catch_errors
+ ((catch_errors_ftype *) qnx_kill_1, (char *) 0, "", RETURN_MASK_ERROR))
+ target_mourn_inferior ();
+ }
+
+ static void
+ qnx_mourn ()
+ {
+ extern int show_breakpoint_hit_counts;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_mourn()\n");
+ }
+
+ init_thread_list ();
+
+ attach_flag = 0;
+ breakpoint_init_inferior (inf_exited);
+ registers_changed ();
+
+ #ifdef CLEAR_DEFERRED_STORES
+ /* Delete any pending stores to the inferior... */
+ CLEAR_DEFERRED_STORES;
+ #endif
+
+ inferior_ptid = null_ptid;
+
+ reopen_exec_file ();
+ reinit_frame_cache ();
+
+ /* It is confusing to the user for ignore counts to stick around
+ from previous runs of the inferior. So clear them. */
+ /* However, it is more confusing for the ignore counts to disappear when
+ using hit counts. So don't clear them if we're counting hits. */
+
+ if (!show_breakpoint_hit_counts)
+ breakpoint_clear_ignore_counts ();
+
+ }
+
+ int
+ qnx_fd_raw (int fd)
+ {
+ struct termios termios_p;
+
+ if (tcgetattr (fd, &termios_p))
+ return (-1);
+
+ termios_p.c_cc[VMIN] = 1;
+ termios_p.c_cc[VTIME] = 0;
+ termios_p.c_lflag &= ~(ECHO | ICANON | ISIG | ECHOE | ECHOK | ECHONL);
+ termios_p.c_oflag &= ~(OPOST);
+ return (tcsetattr (fd, TCSADRAIN, &termios_p));
+ }
+
+ static void
+ qnx_create (char *exec_file, char *args, char **env)
+ {
+ unsigned argc;
+ unsigned envc;
+ char **start_argv;
+ char **argv;
+ char *p;
+ int fd;
+ struct target_waitstatus status;
+ char *in, *out, *err;
+ int len = 0;
+ int totlen = 0;
+
+ if (qnx_desc == NULL)
+ qnx_open ("pty", 0);
+
+ if (!ptid_equal (inferior_ptid, null_ptid))
+ qnx_semi_init ();
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_create(exec_file '%s', args '%s', environ)\n",
+ exec_file ? exec_file : "(null)",
+ args ? args : "(null)");
+ }
+
+ qnx_send_init (DStMsg_env, DSMSG_ENV_CLEARENV, SET_CHANNEL_DEBUG);
+ qnx_send (sizeof (DStMsg_env_t), 1);
+
+ if (!qnx_inherit_env)
+ {
+ for (envc = 0; *env; env++, envc++)
+ {
+ len = strlen (*env);
+ totlen = 0;
+ if (TargetQNXProtoverMinor >= 2) /* HOST_QNX_PROTOVER_MINOR == 2 */
+ {
+ if (len > DS_DATA_MAX_SIZE)
+ {
+ while (len > DS_DATA_MAX_SIZE)
+ {
+ qnx_send_init (DStMsg_env, DSMSG_ENV_SETENV_MORE,
+ SET_CHANNEL_DEBUG);
+ memcpy (tran.pkt.env.data, *env + totlen,
+ DS_DATA_MAX_SIZE);
+ qnx_send (offsetof (DStMsg_env_t, data) +
+ DS_DATA_MAX_SIZE, 1);
+ len -= DS_DATA_MAX_SIZE;
+ totlen += DS_DATA_MAX_SIZE;
+ }
+ }
+ }
+ else if (len > DS_DATA_MAX_SIZE)
+ {
+ printf_unfiltered
+ ("** Skipping env var \"%.40s .....\" <cont>\n", *env);
+ printf_unfiltered
+ ("** Protovers under 0.2 do not handle env vars longer than %d\n",
+ DS_DATA_MAX_SIZE);
+ continue;
+ }
+ qnx_send_init (DStMsg_env, DSMSG_ENV_SETENV, SET_CHANNEL_DEBUG);
+ strcpy (tran.pkt.env.data, *env + totlen);
+ qnx_send (offsetof (DStMsg_env_t, data) +
+ strlen (tran.pkt.env.data) + 1, 1);
+ }
+ }
+
+ if (qnx_remote_cwd != NULL)
+ {
+ qnx_send_init (DStMsg_cwd, DSMSG_CWD_SET, SET_CHANNEL_DEBUG);
+ strcpy (tran.pkt.cwd.path, qnx_remote_cwd);
+ qnx_send (offsetof (DStMsg_cwd_t, path) + strlen (tran.pkt.cwd.path) +
+ 1, 1);
+ }
+
+ qnx_send_init (DStMsg_env, DSMSG_ENV_CLEARARGV, SET_CHANNEL_DEBUG);
+ qnx_send (sizeof (DStMsg_env_t), 1);
+
+ start_argv = buildargv (args);
+ if (start_argv == NULL)
+ nomem (0);
+ start_argv = qnx_parse_redirection (start_argv, &in, &out, &err);
+ // printf("stdin=%s, stdout=%s, stderr=%s\n", in, out, err );
+
+ if (in[0])
+ {
+ if ((fd = open (in, O_RDONLY)) == -1)
+ perror (in);
+ else
+ qnx_fd_raw (fd);
+ }
+
+ if (out[0])
+ {
+ if ((fd = open (out, O_WRONLY)) == -1)
+ perror (out);
+ else
+ qnx_fd_raw (fd);
+ }
+
+ if (err[0])
+ {
+ if ((fd = open (err, O_WRONLY)) == -1)
+ perror (err);
+ else
+ qnx_fd_raw (fd);
+ }
+
+ in = "";
+ out = "";
+ err = "";
+ argc = 0;
+ if (exec_file != NULL)
+ {
+ qnx_send_init (DStMsg_env, DSMSG_ENV_ADDARG, SET_CHANNEL_DEBUG);
+ strcpy (tran.pkt.env.data, exec_file);
+ /* send it twice - first as cmd, second as argv[0] */
+ qnx_send (offsetof (DStMsg_env_t, data) + strlen (tran.pkt.env.data) +
+ 1, 1);
+ qnx_send_init (DStMsg_env, DSMSG_ENV_ADDARG, SET_CHANNEL_DEBUG);
+ strcpy (tran.pkt.env.data, exec_file);
+ qnx_send (offsetof (DStMsg_env_t, data) + strlen (tran.pkt.env.data) +
+ 1, 1);
+ }
+ else if (*start_argv == NULL)
+ {
+ error ("No executable specified.");
+ freeargv (start_argv);
+ return;
+ }
+ else
+ {
+ exec_file = *start_argv;
+ qnx_send_init (DStMsg_env, DSMSG_ENV_ADDARG, SET_CHANNEL_DEBUG);
+ strcpy (tran.pkt.env.data, *start_argv);
+ qnx_send (offsetof (DStMsg_env_t, data) + strlen (tran.pkt.env.data) +
+ 1, 1);
+ }
+
+ for (argv = start_argv; *argv && **argv; argv++, argc++)
+ {
+ qnx_send_init (DStMsg_env, DSMSG_ENV_ADDARG, SET_CHANNEL_DEBUG);
+ strcpy (tran.pkt.env.data, *argv);
+ qnx_send (offsetof (DStMsg_env_t, data) + strlen (tran.pkt.env.data) +
+ 1, 1);
+ }
+ freeargv (start_argv);
+
+ /* NYI: msg too big for buffer */
+ if (qnx_inherit_env)
+ qnx_send_init (DStMsg_load, DSMSG_LOAD_DEBUG | DSMSG_LOAD_INHERIT_ENV,
+ SET_CHANNEL_DEBUG);
+ else
+ qnx_send_init (DStMsg_load, DSMSG_LOAD_DEBUG, SET_CHANNEL_DEBUG);
+
+ p = tran.pkt.load.cmdline;
+
+ tran.pkt.load.envc = 0;
+ tran.pkt.load.argc = 0;
+
+ strcpy (p, exec_file);
+ p += strlen (p);
+ *p++ = '\0'; /* load_file */
+
+ strcpy (p, in);
+ p += strlen (p);
+ *p++ = '\0'; /* stdin */
+
+ strcpy (p, out);
+ p += strlen (p);
+ *p++ = '\0'; /* stdout */
+
+ strcpy (p, err);
+ p += strlen (p);
+ *p++ = '\0'; /* stderr */
+
+ qnx_send (offsetof (DStMsg_load_t, cmdline) + p - tran.pkt.load.cmdline + 1,
+ 1);
+ /* comes back as an DSrMsg_okdata, but it's really a DShMsg_notify */
+ if (recv.pkt.hdr.cmd == DSrMsg_okdata)
+ {
+ qnx_parse_notify (&status);
+ add_thread (inferior_ptid);
+ }
+ /* NYI: add the symbol info somewhere? */
+ #ifdef SOLIB_CREATE_INFERIOR_HOOK
+ if (exec_bfd)
+ SOLIB_CREATE_INFERIOR_HOOK (pid);
+ #endif
+ attach_flag = 0;
+ }
+
+ static int
+ qnx_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered
+ ("qnx_insert_breakpoint(addr %lx, contents_cache %p)\n", addr,
+ contents_cache);
+ }
+
+ qnx_send_init (DStMsg_brk, DSMSG_BRK_EXEC, SET_CHANNEL_DEBUG);
+ tran.pkt.brk.addr = qnx_swap32 (addr);
+ tran.pkt.brk.size = 0;
+ qnx_send (sizeof (tran.pkt.brk), 0);
+ return recv.pkt.hdr.cmd == DSrMsg_err;
+ }
+
+ static int
+ qnx_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered
+ ("qnx_remove_breakpoint(addr %lx, contents_cache %p)\n", addr,
+ contents_cache);
+ }
+
+ /* This got changed to send DSMSG_BRK_EXEC with a size of -1
+ * qnx_send_init(DStMsg_brk, DSMSG_BRK_REMOVE, SET_CHANNEL_DEBUG);
+ */
+ qnx_send_init (DStMsg_brk, DSMSG_BRK_EXEC, SET_CHANNEL_DEBUG);
+ tran.pkt.brk.addr = qnx_swap32 (addr);
+ tran.pkt.brk.size = qnx_swap32 (-1);
+ qnx_send (sizeof (tran.pkt.brk), 0);
+ return recv.pkt.hdr.cmd == DSrMsg_err;
+ }
+
+ #ifdef __CYGWIN__
+ void
+ slashify (char *buf)
+ {
+ int i = 0;
+ while (buf[i])
+ {
+ /* Not sure why we would want to leave an escaped '\', but seems
+ safer. */
+ if (buf[i] == '\\')
+ {
+ if (buf[i + 1] == '\\')
+ i++;
+ else
+ buf[i] = '/';
+ }
+ i++;
+ }
+ }
+ #endif
+
+ static void
+ qnx_upload (char *args, int fromtty)
+ {
+ #ifdef __CYGWIN__
+ char cygbuf[PATH_MAX];
+ #endif
+ int fd;
+ int len;
+ char buf[DS_DATA_MAX_SIZE];
+ char *from, *to;
+ char **argv;
+
+ if (args == 0)
+ {
+ printf_unfiltered ("You must specify a filename to send.\n");
+ return;
+ }
+
+ #ifdef __CYGWIN__
+ /*
+ * We need to convert back slashes to forward slashes for DOS
+ * style paths, else buildargv will remove them.
+ */
+ slashify (args);
+ #endif
+ argv = buildargv (args);
+
+ if (argv == NULL)
+ nomem (0);
+
+ #ifdef __CYGWIN__
+ cygwin_conv_to_posix_path (argv[0], cygbuf);
+ from = cygbuf;
+ #else
+ from = argv[0];
+ #endif
+ to = argv[1] ? argv[1] : from;
+
+ if ((fd = open (from, HOST_READ_MODE)) == -1)
+ {
+ printf_unfiltered ("Unable to open '%s': %s\n", from, strerror (errno));
+ return;
+ }
+
+ if (qnx_fileopen (to, QNX_WRITE_MODE, QNX_WRITE_PERMS) == -1)
+ {
+ printf_unfiltered ("Remote was unable to open '%s': %s\n", to,
+ strerror (errno));
+ close (fd);
+ return;
+ }
+
+ while ((len = read (fd, buf, sizeof buf)) > 0)
+ {
+ if (qnx_filewrite (buf, len) == -1)
+ {
+ printf_unfiltered ("Remote was unable to complete write: %s\n",
+ strerror (errno));
+ close (fd);
+ return;
+ }
+ }
+ if (len == -1)
+ printf_unfiltered ("Local read failed: %s\n", strerror (errno));
+ qnx_fileclose (fd);
+ close (fd);
+ }
+
+ static void
+ qnx_download (char *args, int fromtty)
+ {
+ #ifdef __CYGWIN__
+ char cygbuf[PATH_MAX];
+ #endif
+ int fd;
+ int len;
+ char buf[DS_DATA_MAX_SIZE];
+ char *from, *to;
+ char **argv;
+
+ if (args == 0)
+ {
+ printf_unfiltered ("You must specify a filename to get.\n");
+ return;
+ }
+
+ #ifdef __CYGWIN__
+ /*
+ * We need to convert back slashes to forward slashes for DOS
+ * style paths, else buildargv will remove them.
+ */
+ slashify (args);
+ #endif
+
+ argv = buildargv (args);
+ if (argv == NULL)
+ nomem (0);
+
+ from = argv[0];
+ #ifdef __CYGWIN__
+ if (argv[1])
+ {
+ cygwin_conv_to_posix_path (argv[1], cygbuf);
+ to = cygbuf;
+ }
+ else
+ to = from;
+ #else
+ to = argv[1] ? argv[1] : from;
+ #endif
+
+ if ((fd = open (to, HOST_WRITE_MODE, 0666)) == -1)
+ {
+ printf_unfiltered ("Unable to open '%s': %s\n", to, strerror (errno));
+ return;
+ }
+
+ if (qnx_fileopen (from, QNX_READ_MODE, 0) == -1)
+ {
+ printf_unfiltered ("Remote was unable to open '%s': %s\n", from,
+ strerror (errno));
+ close (fd);
+ return;
+ }
+
+ while ((len = qnx_fileread (buf, sizeof buf)) > 0)
+ {
+ if (write (fd, buf, len) == -1)
+ {
+ printf_unfiltered ("Local write failed: %s\n", strerror (errno));
+ close (fd);
+ return;
+ }
+ }
+
+ if (len == -1)
+ printf_unfiltered ("Remote read failed: %s\n", strerror (errno));
+ qnx_fileclose (fd);
+ close (fd);
+ }
+
+ static void
+ qnx_add_commands ()
+ {
+ struct cmd_list_element *c;
+
+ c =
+ add_com ("upload", class_obscure, qnx_upload,
+ "Send a file to the target (upload {local} [{remote}])");
+ c->completer = filename_completer;
+ add_com ("download", class_obscure, qnx_download,
+ "Get a file from the target (download {remote} [{local}])");
+ }
+
+ static void
+ qnx_remove_commands ()
+ {
+ extern struct cmd_list_element *cmdlist;
+
+ delete_cmd ("upload", &cmdlist);
+ delete_cmd ("download", &cmdlist);
+ }
+
+ static int qnx_remote_fd = -1;
+
+ static int
+ qnx_fileopen (char *fname, int mode, int perms)
+ {
+ if (qnx_remote_fd != -1)
+ {
+ printf_unfiltered
+ ("Remote file currently open, it must be closed before you can open another.\n");
+ errno = EAGAIN;
+ return -1;
+ }
+
+ qnx_send_init (DStMsg_fileopen, 0, SET_CHANNEL_DEBUG);
+ strcpy (tran.pkt.fileopen.pathname, fname);
+ tran.pkt.fileopen.mode = qnx_swap32 (mode);
+ tran.pkt.fileopen.perms = qnx_swap32 (perms);
+ qnx_send (sizeof tran.pkt.fileopen, 0);
+
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ errno = qnx_swap32 (recv.pkt.err.err);
+ return -1;
+ }
+ return qnx_remote_fd = 0;
+ }
+
+ static void
+ qnx_fileclose (int fd)
+ {
+ if (qnx_remote_fd == -1)
+ return;
+
+ qnx_send_init (DStMsg_fileclose, 0, SET_CHANNEL_DEBUG);
+ tran.pkt.fileclose.mtime = 0;
+ qnx_send (sizeof tran.pkt.fileclose, 1);
+ qnx_remote_fd = -1;
+ }
+
+ static int
+ qnx_fileread (char *buf, int size)
+ {
+ int len;
+
+ qnx_send_init (DStMsg_filerd, 0, SET_CHANNEL_DEBUG);
+ tran.pkt.filerd.size = qnx_swap16 (size);
+ len = qnx_send (sizeof tran.pkt.filerd, 0);
+
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ errno = recv.pkt.err.err;
+ return -1;
+ }
+
+ len -= sizeof recv.pkt.okdata.hdr;
+ memcpy (buf, recv.pkt.okdata.data, len);
+ return len;
+ }
+
+ static int
+ qnx_filewrite (char *buf, int size)
+ {
+ int len, siz;
+
+ for (siz = size; siz > 0; siz -= len, buf += len)
+ {
+ len =
+ siz < sizeof tran.pkt.filewr.data ? siz : sizeof tran.pkt.filewr.data;
+ qnx_send_init (DStMsg_filewr, 0, SET_CHANNEL_DEBUG);
+ memcpy (tran.pkt.filewr.data, buf, len);
+ qnx_send (sizeof (tran.pkt.filewr.hdr) + len, 0);
+
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ errno = recv.pkt.err.err;
+ return size - siz;
+ }
+ }
+ return size;
+ }
+
+ static int
+ qnx_can_run (void)
+ {
+ return 0;
+ }
+
+ static void
+ init_qnx_ops ()
+ {
+ qnx_ops.to_shortname = "qnx";
+ qnx_ops.to_longname =
+ "Remote serial target using the QNX Debugging Protocol";
+ qnx_ops.to_doc =
+ "Debug a remote machine using the QNX Debugging Protocol.\n\
+ Specify the device it is connected to (e.g. /dev/ser1, <rmt_host>:<port>)\n\
+ or `pty' to launch `pdebug' for debugging.";
+ qnx_ops.to_open = qnx_open;
+ qnx_ops.to_close = qnx_close;
+ qnx_ops.to_attach = qnx_attach;
+ qnx_ops.to_detach = qnx_detach;
+ qnx_ops.to_resume = qnx_resume;
+ qnx_ops.to_wait = qnx_wait;
+ qnx_ops.to_fetch_registers = qnx_fetch_registers;
+ qnx_ops.to_store_registers = qnx_store_registers;
+ qnx_ops.to_prepare_to_store = qnx_prepare_to_store;
+ qnx_ops.to_xfer_memory = qnx_xfer_memory;
+ qnx_ops.to_files_info = qnx_files_info;
+ qnx_ops.to_insert_breakpoint = qnx_insert_breakpoint;
+ qnx_ops.to_remove_breakpoint = qnx_remove_breakpoint;
+ qnx_ops.to_kill = qnx_kill;
+ qnx_ops.to_load = generic_load;
+ qnx_ops.to_create_inferior = qnx_create;
+ qnx_ops.to_mourn_inferior = qnx_mourn;
+ qnx_ops.to_can_run = qnx_can_run;
+ qnx_ops.to_thread_alive = qnx_thread_alive;
+ qnx_ops.to_find_new_threads = qnx_find_new_threads;
+ qnx_ops.to_stop = 0;
+ // qnx_ops.to_query = qnx_query;
+ qnx_ops.to_stratum = process_stratum;
+ qnx_ops.to_has_all_memory = 1;
+ qnx_ops.to_has_memory = 1;
+ qnx_ops.to_has_stack = 0; // 1;
+ qnx_ops.to_has_registers = 1;
+ qnx_ops.to_has_execution = 0;
+ qnx_ops.to_pid_to_str = qnx_pid_to_str;
+ // qnx_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
+ qnx_ops.to_magic = OPS_MAGIC;
+ }
+
+
+ void
+ qnx_find_new_threads (void)
+ {
+ pid_t pid, start_tid, total_tid;
+ ptid_t ptid;
+ struct dspidlist *pidlist = (void *) recv.pkt.okdata.data;
+ struct tidinfo *tip;
+ char subcmd;
+
+ pid = ptid_get_pid (inferior_ptid);
+ start_tid = 1;
+ total_tid = 1;
+ subcmd = DSMSG_PIDLIST_SPECIFIC_TID;
+
+ do
+ {
+ tran.pkt.pidlist.tid = qnx_swap32 (start_tid);
+ qnx_send_init (DStMsg_pidlist, subcmd, SET_CHANNEL_DEBUG);
+ tran.pkt.pidlist.pid = qnx_swap32 (pid);
+ qnx_send (sizeof (tran.pkt.pidlist), 0);
+
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ if (subcmd == DSMSG_PIDLIST_SPECIFIC_TID)
+ {
+ subcmd = DSMSG_PIDLIST_SPECIFIC;
+ start_tid = 0;
+ tran.pkt.pidlist.tid = qnx_swap32 (start_tid);
+ qnx_send_init (DStMsg_pidlist, subcmd, SET_CHANNEL_DEBUG);
+ tran.pkt.pidlist.pid = qnx_swap32 (pid);
+ qnx_send (sizeof (tran.pkt.pidlist), 1); //no need to check error, as '1' means no return on error
+ }
+ else
+ {
+ errno = recv.pkt.err.err;
+ return;
+ }
+ }
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("pid = %ld\n", qnx_swap32 (pidlist->pid));
+ printf_unfiltered ("start tid = %ld, total tid = %ld\n",
+ qnx_swap32 (start_tid),
+ qnx_swap32 (pidlist->num_tids));
+ printf_unfiltered ("name = %s\n", pidlist->name);
+ }
+
+ for (tip =
+ (void *) &pidlist->name[(strlen (pidlist->name) + 1 + 3) & ~3];
+ tip->tid != 0; tip++)
+ {
+ total_tid++;
+ ptid = ptid_build (pid, 0, qnx_swap16 (tip->tid));
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("%s - %d/%d\n", pidlist->name, pid,
+ qnx_swap16 (tip->tid));
+ }
+ if (!in_thread_list (ptid))
+ add_thread (ptid);
+ }
+ start_tid = total_tid + 1;
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("total_tids = %x, pidlist->num_tids = %lx\n",
+ total_tid, qnx_swap32 (pidlist->num_tids));
+ }
+ }
+ while ((total_tid < qnx_swap32 (pidlist->num_tids))
+ && (subcmd == DSMSG_PIDLIST_SPECIFIC_TID));
+
+ return;
+ }
+
+
+ void
+ qnx_pidlist (char *args, int from_tty)
+ {
+ struct dspidlist *pidlist = (void *) recv.pkt.okdata.data;
+ struct tidinfo *tip;
+ char specific_tid_supported = 0;
+ pid_t pid, start_tid, total_tid;
+ char subcmd;
+
+ #if defined(__QNXNTO__) && defined(__QNXNTO_USE_PROCFS__)
+ extern void procfs_pidlist (char *args, int from_tty);
+ if (qnx_desc == NULL)
+ return procfs_pidlist (args, from_tty);
+ #endif
+ start_tid = 1;
+ total_tid = 0;
+ pid = 1;
+ subcmd = DSMSG_PIDLIST_BEGIN;
+
+ //
+ // Send a DSMSG_PIDLIST_SPECIFIC_TID to see if it is supported
+ //
+ qnx_send_init (DStMsg_pidlist, DSMSG_PIDLIST_SPECIFIC_TID,
+ SET_CHANNEL_DEBUG);
+ tran.pkt.pidlist.pid = qnx_swap32 (pid);
+ tran.pkt.pidlist.tid = qnx_swap32 (start_tid);
+ qnx_send (sizeof (tran.pkt.pidlist), 0);
+
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ specific_tid_supported = 0;
+ else
+ specific_tid_supported = 1;
+
+ while (1)
+ {
+ qnx_send_init (DStMsg_pidlist, subcmd, SET_CHANNEL_DEBUG);
+ tran.pkt.pidlist.pid = qnx_swap32 (pid);
+ tran.pkt.pidlist.tid = qnx_swap32 (start_tid);
+ qnx_send (sizeof (tran.pkt.pidlist), 0);
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ errno = qnx_swap32 (recv.pkt.err.err);
+ return;
+ }
+ if (recv.pkt.hdr.cmd != DSrMsg_okdata)
+ {
+ errno = EOK;
+ return;
+ }
+
+ for (tip =
+ (void *) &pidlist->name[(strlen (pidlist->name) + 1 + 3) & ~3];
+ tip->tid != 0; tip++)
+ {
+ printf_filtered ("%s - %ld/%d\n", pidlist->name,
+ qnx_swap32 (pidlist->pid), qnx_swap16 (tip->tid));
+ total_tid++;
+ }
+ pid = qnx_swap32 (pidlist->pid);
+ if (specific_tid_supported)
+ {
+ if (total_tid < qnx_swap32 (pidlist->num_tids))
+ {
+ subcmd = DSMSG_PIDLIST_SPECIFIC_TID;
+ start_tid = total_tid + 1;
+ continue;
+ }
+ }
+ start_tid = 1;
+ total_tid = 0;
+ subcmd = DSMSG_PIDLIST_NEXT;
+ }
+ return;
+ }
+
+ struct dsmapinfo *
+ qnx_mapinfo (unsigned addr, int first, int elfonly)
+ {
+ //struct dsmapinfo *map = (void *)recv.pkt.okdata.data;
+ struct dsmapinfo map;
+ static struct dsmapinfo dmap;
+ DStMsg_mapinfo_t *mapinfo = (DStMsg_mapinfo_t *) & tran.pkt;
+ char subcmd;
+
+ if (core_bfd != NULL)
+ { /* have to implement corefile mapinfo */
+ errno = EOK;
+ return NULL;
+ }
+
+ subcmd = addr ? DSMSG_MAPINFO_SPECIFIC :
+ first ? DSMSG_MAPINFO_BEGIN : DSMSG_MAPINFO_NEXT;
+ if (elfonly)
+ subcmd |= DSMSG_MAPINFO_ELF;
+
+ qnx_send_init (DStMsg_mapinfo, subcmd, SET_CHANNEL_DEBUG);
+ mapinfo->addr = qnx_swap32 (addr);
+ qnx_send (sizeof (*mapinfo), 0);
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ errno = qnx_swap32 (recv.pkt.err.err);
+ return NULL;
+ }
+ if (recv.pkt.hdr.cmd != DSrMsg_okdata)
+ {
+ errno = EOK;
+ return NULL;
+ }
+
+ memset (&dmap, 0, sizeof (dmap));
+ memcpy (&map, &recv.pkt.okdata.data[0], sizeof (map));
+ dmap.ino = qnx_swap64 (map.ino);
+ dmap.dev = qnx_swap32 (map.dev);
+
+ dmap.text.addr = qnx_swap32 (map.text.addr);
+ dmap.text.size = qnx_swap32 (map.text.size);
+ dmap.text.flags = qnx_swap32 (map.text.flags);
+ dmap.text.debug_vaddr = qnx_swap32 (map.text.debug_vaddr);
+ dmap.text.offset = qnx_swap64 (map.text.offset);
+
+ dmap.data.addr = qnx_swap32 (map.data.addr);
+ dmap.data.size = qnx_swap32 (map.data.size);
+ dmap.data.flags = qnx_swap32 (map.data.flags);
+ dmap.data.debug_vaddr = qnx_swap32 (map.data.debug_vaddr);
+ dmap.data.offset = qnx_swap64 (map.data.offset);
+
+ strcpy (dmap.name, map.name);
+
+ return &dmap;
+ }
+
+ void
+ qnx_meminfo (char *args, int from_tty)
+ {
+ struct dsmapinfo *dmp;
+ int first = 1;
+
+ #if defined(__QNXNTO__) && defined(__QNXNTO_USE_PROCFS__)
+ extern void procfs_meminfo (char *args, int from_tty);
+ if (qnx_desc == NULL)
+ return procfs_meminfo (args, from_tty);
+ #endif
+
+ while ((dmp = qnx_mapinfo (0, first, 0)) != NULL)
+ {
+ first = 0;
+ printf_filtered ("%s\n", dmp->name);
+ printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", dmp->text.size,
+ dmp->text.addr);
+ printf_filtered ("\t\tflags=%08x\n", dmp->text.flags);
+ printf_filtered ("\t\tdebug=%08x\n", dmp->text.debug_vaddr);
+ printf_filtered ("\t\toffset=%016llx\n", dmp->text.offset);
+ if (dmp->data.size)
+ {
+ printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", dmp->data.size,
+ dmp->data.addr);
+ printf_filtered ("\t\tflags=%08x\n", dmp->data.flags);
+ printf_filtered ("\t\tdebug=%08x\n", dmp->data.debug_vaddr);
+ printf_filtered ("\t\toffset=%016llx\n", dmp->data.offset);
+ }
+ printf_filtered ("\tdev=0x%x\n", dmp->dev);
+ printf_filtered ("\tino=0x%llx\n", dmp->ino);
+ }
+ }
+
+ /*
+
+ GLOBAL FUNCTION
+
+ fetch_core_registers -- fetch current registers from core file
+
+ SYNOPSIS
+
+ void fetch_core_registers (char *core_reg_sect,
+ unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+
+ DESCRIPTION
+
+ Read the values of either the general register set (WHICH equals 0)
+ or the floating point register set (WHICH equals 2) from the core
+ file data (pointed to by CORE_REG_SECT), and update gdb's idea of
+ their current values. The CORE_REG_SIZE parameter is ignored.
+
+ NOTES
+
+ Use the indicated sizes to validate the gregset and fpregset
+ structures.
+ */
+
+ extern void nto_supply_gregset PARAMS ((nto_gregset_t *));
+ extern void nto_supply_fpregset PARAMS ((nto_fpregset_t *));
+ void qnx_init_solib_search_path ();
+
+ static void
+ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
+ char *core_reg_sect;
+ unsigned core_reg_size;
+ int which;
+ CORE_ADDR reg_addr; /* Unused in this version */
+ {
+ nto_gregset_t gregset;
+ nto_fpregset_t fpregset;
+
+ qnx_init_solib_search_path ();
+
+ if (which == 0)
+ {
+ memcpy ((char *) &gregset, core_reg_sect,
+ min (core_reg_size, sizeof (gregset)));
+ nto_supply_gregset (&gregset);
+ }
+ else if (which == 2)
+ {
+ memcpy ((char *) &fpregset, core_reg_sect,
+ min (core_reg_size, sizeof (fpregset)));
+ nto_supply_fpregset (&fpregset);
+ }
+ }
+
+ /* struct lm_info, LM_ADDR and qnx_truncate_ptr are copied from
+ solib-svr4.c to support qnx_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 = SVR4_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
+ qnx_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);
+ }
+
+ #include "elf-bfd.h"
+ 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;
+ }
+
+ static void
+ qnx_relocate_section_addresses (struct so_list *so, struct section_table *sec)
+ {
+ /* On some platforms, (ie. QNXnto, NetBSD) LM_ADDR is the assigned
+ address, not the offset.
+ The addresses are formed as follows:
+ LM_ADDR is the target address where the shared library file
+ is mapped, so the actual section start address is LM_ADDR plus
+ the section offset within the shared library file. The end
+ address is that plus the section length. Note that we pay no
+ attention to the section start address as recorded in the
+ library header.
+ */
+ Elf_Internal_Phdr *phdr = find_load_phdr (sec->bfd);
+ unsigned vaddr = phdr ? phdr->p_vaddr : 0;
+
+ sec->addr = qnx_truncate_ptr (sec->addr + LM_ADDR (so) - vaddr);
+ sec->endaddr = qnx_truncate_ptr (sec->endaddr + LM_ADDR (so) - vaddr);
+ }
+
+ /* 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 ()
+ {
+ int endian = 1;
+ #ifdef EXTRA_GDBINIT_FILENAME
+ char *homedir, *homeinit, *extra_gdbinit;
+ struct stat statbuf;
+ #endif
+
+ if (*(char *) &endian != 1)
+ host_endian = BFD_ENDIAN_BIG;
+ else
+ host_endian = BFD_ENDIAN_LITTLE;
+
+ #ifdef __QNXNTO__
+ munlockall ();
+ #endif
+
+ init_qnx_ops ();
+ add_target (&qnx_ops);
+ add_show_from_set (add_set_cmd ("qnxtimeout", no_class,
+ var_integer, (char *) &qnx_timeout,
+ "Set timeout value for remote read.\n",
+ &setlist), &showlist);
+
+ add_show_from_set (add_set_cmd ("qnxinheritenv", no_class,
+ var_boolean, (char *) &qnx_inherit_env,
+ "Set where remote process inherits env from pdebug, or has it set by gdb\n",
+ &setlist), &showlist);
+
+ add_show_from_set (add_set_cmd ("qnxremotecwd", class_support, var_string,
+ (char *) &qnx_remote_cwd,
+ "Set the working directory for the remote process",
+ &setlist), &showlist);
+
+ 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);
+ add_info ("pidlist", qnx_pidlist, "pidlist");
+ add_info ("meminfo", qnx_meminfo, "memory information");
+
+ //
+ // 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);
+
+ #if defined(SIGSELECT)
+ /* by default we don't want to stop on these two, but we do want to pass */
+ 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 (®set_core_fns);
+
+ /* Our loader handles solib relocations slightly differently than svr4 */
+ current_target_so_ops->relocate_section_addresses =
+ qnx_relocate_section_addresses;
+
+ #ifdef EXTRA_GDBINIT_FILENAME
+ homedir = getenv ("HOME");
+ extra_gdbinit = EXTRA_GDBINIT_FILENAME;
+
+ if (homedir && !inhibit_gdbinit)
+ {
+ homeinit = (char *) alloca (strlen (homedir) +
+ strlen (extra_gdbinit) + 10);
+ sprintf (homeinit, "%s/%s", homedir, extra_gdbinit);
+ if (stat (homeinit, &statbuf) == 0)
+ catch_command_errors (source_command, homeinit, 0, RETURN_MASK_ALL);
+ }
+ #endif
+ }
+
+ int
+ qnx_insert_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
+ {
+ if (qnx_desc == NULL)
+ return -1;
+
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered
+ ("qnx_insert_hw_breakpoint(addr %lx, contents_cache %p)\n", addr,
+ contents_cache);
+ }
+
+ qnx_send_init (DStMsg_brk, DSMSG_BRK_EXEC | DSMSG_BRK_HW,
+ SET_CHANNEL_DEBUG);
+ tran.pkt.brk.addr = qnx_swap32 (addr);
+ qnx_send (sizeof (tran.pkt.brk), 0);
+ return recv.pkt.hdr.cmd == DSrMsg_err;
+ }
+
+ int
+ qnx_remove_hw_breakpoint (CORE_ADDR addr, char *contents_cache)
+ {
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered
+ ("qnx_remove_hw_breakpoint(addr %lx, contents_cache %p)\n", addr,
+ contents_cache);
+ }
+
+ return qnx_remove_breakpoint (addr, contents_cache);
+ }
+
+ int
+ qnx_stopped_by_watchpoint (void)
+ {
+ return 0;
+ }
+
+
+ int
+ qnx_hw_watchpoint (addr, len, type)
+ {
+ unsigned subcmd;
+
+ #if defined(__QNXNTO__) && defined(__QNXNTO_USE_PROCFS__)
+ extern int procfs_hw_watchpoint (int, int, int);
+
+ if (qnx_desc == NULL)
+ {
+ return procfs_hw_watchpoint (addr, type, len);
+ }
+ #endif
+ if (nto_internal_debugging == 1)
+ {
+ printf_unfiltered ("qnx_hw_watchpoint(addr %x, len %x, type %x)\n",
+ addr, len, type);
+ }
+
+ switch (type)
+ {
+ case 1: /* Read */
+ subcmd = DSMSG_BRK_RD;
+ break;
+ case 2: /* Read/Write */
+ subcmd = DSMSG_BRK_WR;
+ break;
+ default: /* Modify */
+ subcmd = DSMSG_BRK_MODIFY;
+ }
+ subcmd |= DSMSG_BRK_HW;
+
+ qnx_send_init (DStMsg_brk, subcmd, SET_CHANNEL_DEBUG);
+ tran.pkt.brk.addr = qnx_swap32 (addr);
+ tran.pkt.brk.size = qnx_swap32 (len);
+ qnx_send (sizeof (tran.pkt.brk), 0);
+ return recv.pkt.hdr.cmd == DSrMsg_err ? -1 : 0;
+ }
+
+ int
+ qnx_remove_hw_watchpoint (addr, len, type)
+ {
+ return qnx_hw_watchpoint (addr, -1, type);
+ }
+
+ int
+ qnx_insert_hw_watchpoint (addr, len, type)
+ {
+ return qnx_hw_watchpoint (addr, len, type);
+ }
+
+ char **
+ qnx_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;
+ }
+
+ struct tidinfo *
+ qnx_thread_info (pid_t pid, short tid)
+ {
+ struct dspidlist *pidlist = (void *) recv.pkt.okdata.data;
+ struct tidinfo *tip;
+
+ tran.pkt.pidlist.tid = tid;
+ qnx_send_init (DStMsg_pidlist, DSMSG_PIDLIST_SPECIFIC_TID,
+ SET_CHANNEL_DEBUG);
+ tran.pkt.pidlist.pid = qnx_swap32 (pid);
+ qnx_send (sizeof (tran.pkt.pidlist), 0);
+
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ qnx_send_init (DStMsg_pidlist, DSMSG_PIDLIST_SPECIFIC,
+ SET_CHANNEL_DEBUG);
+ tran.pkt.pidlist.pid = qnx_swap32 (pid);
+ qnx_send (sizeof (tran.pkt.pidlist), 1);
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ errno = recv.pkt.err.err;
+ return NULL;
+ }
+ }
+
+ for (tip = (void *) &pidlist->name[(strlen (pidlist->name) + 1 + 3) & ~3];
+ tip->tid != 0; tip++)
+ {
+ if (tid == qnx_swap16 (tip->tid))
+ return tip;
+ }
+
+ return NULL;
+ }
+
+ char *
+ qnx_pid_to_str (ptid_t ptid)
+ {
+ static char buf[1024];
+ int pid, tid, n;
+ struct tidinfo *tip;
+
+ pid = ptid_get_pid (ptid); // returns pid if listed, else returns ptid
+ tid = ptid_get_tid (ptid); // returns tid if listed, else 0
+
+ n = sprintf (buf, "process %d", pid);
+
+ tip = qnx_thread_info (pid, tid);
+ if (tip != NULL)
+ sprintf (&buf[n], " (state = 0x%02x)", tip->state);
+
+ return buf;
+ }
+
+ void
+ qnx_supply_register (unsigned first, unsigned last, char *regp)
+ {
+ unsigned end, off, len;
+ unsigned char notused;
+
+ while (first <= last)
+ {
+ end = qnx_cpu_register_area (first, last, ¬used, &off, &len);
+ if (len > 0)
+ qnx_cpu_register_fetch ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG), first,
+ end, regp + off);
+ else
+ qnx_cpu_register_fetch ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG), first,
+ end, NULL);
+ first = end + 1;
+ }
+ }
+
+ CORE_ADDR
+ qnx_getbase (void)
+ {
+ unsigned long long base_address;
+ #if defined(__QNXNTO__) && defined(__QNXNTO_USE_PROCFS__)
+ extern int procfs_getbase (void);
+
+ if (qnx_desc == NULL)
+ {
+ return procfs_getbase ();
+ }
+ #endif
+
+ qnx_send_init (DStMsg_base_address, 0, SET_CHANNEL_DEBUG);
+ qnx_send (sizeof (tran.pkt.baseaddr), 0);
+
+ if (recv.pkt.hdr.cmd == DSrMsg_err)
+ {
+ errno = recv.pkt.err.err;
+ return -1;
+ }
+ memcpy (&base_address, &recv.pkt.okdata.data[0], sizeof (base_address));
+ if (base_address == 0)
+ return (CORE_ADDR) -1;
+ return (CORE_ADDR) qnx_swap64 (base_address);
+ }
+
+ #define IO_PORT_HACKS
+ #ifdef IO_PORT_HACKS
+ static int
+ qnx_read_ioport (long long addr, short len, void *dst)
+ {
+ qnx_send_init (DStMsg_memrd, DSMSG_MEM_IO, SET_CHANNEL_DEBUG);
+ tran.pkt.memrd.addr = qnx_swap64 (addr);
+ tran.pkt.memrd.size = qnx_swap16 (len);
+ len = qnx_send (sizeof (tran.pkt.memrd), 0) - sizeof (recv.pkt.hdr);
+
+ if (recv.pkt.hdr.cmd == DSrMsg_okdata)
+ {
+ memcpy (dst, recv.pkt.okdata.data, len);
+ return 0;
+ }
+ errno = recv.pkt.err.err;
+ printf ("error reading ioport %#llx: %s\n", addr, strerror (errno));
+ return -1;
+ }
+
+ void
+ qnx_read_ioport_8 (char *args, int from_tty)
+ {
+ unsigned char data;
+ long long addr;
+
+ addr = strtol (args, NULL, 0);
+ if (qnx_read_ioport (addr, 1, (void *) &data) == 0)
+ {
+ printf ("ioport @ %#llx: ", addr);
+ printf ("0x%02x\n", (int) data);
+ }
+ }
+
+ void
+ qnx_read_ioport_16 (char *args, int from_tty)
+ {
+ unsigned short data;
+ long long addr;
+
+ addr = strtol (args, NULL, 0);
+ if (qnx_read_ioport (addr, 2, (void *) &data) == 0)
+ {
+ printf ("ioport @ %#llx: ", addr);
+ printf ("0x%04x\n", (int) data);
+ }
+ }
+
+ void
+ qnx_read_ioport_32 (char *args, int from_tty)
+ {
+ unsigned int data;
+ long long addr;
+
+ addr = strtol (args, NULL, 0);
+ if (qnx_read_ioport (addr, 4, (void *) &data) == 0)
+ {
+ printf ("ioport @ %#llx: ", addr);
+ printf ("0x%08x\n", (int) data);
+ }
+ }
+
+ static int
+ qnx_write_ioport (long long addr, short len, void *src)
+ {
+ int i;
+
+ qnx_send_init (DStMsg_memwr, DSMSG_MEM_IO, SET_CHANNEL_DEBUG);
+ tran.pkt.memwr.addr = qnx_swap64 (addr);
+ printf ("iowrite to %#llx: ", addr);
+ memcpy (tran.pkt.memwr.data, src, len);
+
+ for (i = 0; i < len; i++)
+ printf ("%02x ", tran.pkt.memwr.data[i]);
+ printf ("\n");
+
+ qnx_send (offsetof (DStMsg_memwr_t, data) + len, 0);
+
+ if (recv.pkt.hdr.cmd != DSrMsg_err)
+ {
+ return 0;
+ }
+ errno = recv.pkt.err.err;
+ printf_filtered ("error writing to ioport %#llx: %s\n", addr,
+ strerror (errno));
+ return -1;
+ }
+
+ void
+ qnx_write_ioport_8 (char *args, int from_tty)
+ {
+ unsigned char data = 0;
+ long long addr = 0;
+ char *p;
+
+ p = strtok (args, " ,\t");
+ if (p != NULL)
+ addr = strtol (p, NULL, 0);
+ p = strtok (NULL, " ,\t");
+ if (p != NULL)
+ data = (unsigned char) strtol (p, NULL, 0);
+ qnx_write_ioport (addr, 1, (void *) &data);
+ }
+
+ void
+ qnx_write_ioport_16 (char *args, int from_tty)
+ {
+ unsigned char data = 0;
+ long long addr = 0;
+ char *p;
+
+ p = strtok (args, " ,\t");
+ if (p != NULL)
+ addr = strtol (p, NULL, 0);
+ p = strtok (NULL, " ,\t");
+ if (p != NULL)
+ data = (unsigned char) strtol (p, NULL, 0);
+ qnx_write_ioport (addr, 1, (void *) &data);
+ }
+
+ void
+ qnx_write_ioport_32 (char *args, int from_tty)
+ {
+ unsigned char data = 0;
+ long long addr = 0;
+ char *p;
+
+ p = strtok (args, " ,\t");
+ if (p != NULL)
+ addr = strtol (p, NULL, 0);
+ p = strtok (NULL, " ,\t");
+ if (p != NULL)
+ data = (unsigned char) strtol (p, NULL, 0);
+ qnx_write_ioport (addr, 1, (void *) &data);
+ }
+ #endif
+
+ #ifndef __QNXNTO__
+
+ #define QNXSIGHUP 1 /* hangup */
+ #define QNXSIGINT 2 /* interrupt */
+ #define QNXSIGQUIT 3 /* quit */
+ #define QNXSIGILL 4 /* illegal instruction (not reset when caught) */
+ #define QNXSIGTRAP 5 /* trace trap (not reset when caught) */
+ #define QNXSIGIOT 6 /* IOT instruction */
+ #define QNXSIGABRT 6 /* used by abort */
+ #define QNXSIGEMT 7 /* EMT instruction */
+ #define QNXSIGDEADLK 7 /* Mutex deadlock */
+ #define QNXSIGFPE 8 /* floating point exception */
+ #define QNXSIGKILL 9 /* kill (cannot be caught or ignored) */
+ #define QNXSIGBUS 10 /* bus error */
+ #define QNXSIGSEGV 11 /* segmentation violation */
+ #define QNXSIGSYS 12 /* bad argument to system call */
+ #define QNXSIGPIPE 13 /* write on pipe with no reader */
+ #define QNXSIGALRM 14 /* real-time alarm clock */
+ #define QNXSIGTERM 15 /* software termination signal from kill */
+ #define QNXSIGUSR1 16 /* user defined signal 1 */
+ #define QNXSIGUSR2 17 /* user defined signal 2 */
+ #define QNXSIGCHLD 18 /* death of child */
+ #define QNXSIGPWR 19 /* power-fail restart */
+ #define QNXSIGWINCH 20 /* window change */
+ #define QNXSIGURG 21 /* urgent condition on I/O channel */
+ #define QNXSIGPOLL 22 /* System V name for QNXSIGIO */
+ #define QNXSIGIO QNXSIGPOLL
+ #define QNXSIGSTOP 23 /* sendable stop signal not from tty */
+ #define QNXSIGTSTP 24 /* stop signal from tty */
+ #define QNXSIGCONT 25 /* continue a stopped process */
+ #define QNXSIGTTIN 26 /* attempted background tty read */
+ #define QNXSIGTTOU 27 /* attempted background tty write */
+ #define QNXSIGVTALRM 28 /* virtual timer expired */
+ #define QNXSIGPROF 29 /* profileing timer expired */
+ #define QNXSIGXCPU 30 /* exceded cpu limit */
+ #define QNXSIGXFSZ 31 /* exceded file size limit */
+
+ #endif
+
+ /* Convert qnx signal to gdb signal. */
+ enum target_signal
+ target_signal_from_qnx (sig)
+ int sig;
+ {
+ #ifndef __QNXNTO__
+ switch (sig)
+ {
+ case 0:
+ return 0;
+ break;
+ case QNXSIGHUP:
+ return TARGET_SIGNAL_HUP;
+ break;
+ case QNXSIGINT:
+ return TARGET_SIGNAL_INT;
+ break;
+ case QNXSIGQUIT:
+ return TARGET_SIGNAL_QUIT;
+ break;
+ case QNXSIGILL:
+ return TARGET_SIGNAL_ILL;
+ break;
+ case QNXSIGTRAP:
+ return TARGET_SIGNAL_TRAP;
+ break;
+ case QNXSIGABRT:
+ return TARGET_SIGNAL_ABRT;
+ break;
+ case QNXSIGEMT:
+ return TARGET_SIGNAL_EMT;
+ break;
+ case QNXSIGFPE:
+ return TARGET_SIGNAL_FPE;
+ break;
+ case QNXSIGKILL:
+ return TARGET_SIGNAL_KILL;
+ break;
+ case QNXSIGBUS:
+ return TARGET_SIGNAL_BUS;
+ break;
+ case QNXSIGSEGV:
+ return TARGET_SIGNAL_SEGV;
+ break;
+ case QNXSIGSYS:
+ return TARGET_SIGNAL_SYS;
+ break;
+ case QNXSIGPIPE:
+ return TARGET_SIGNAL_PIPE;
+ break;
+ case QNXSIGALRM:
+ return TARGET_SIGNAL_ALRM;
+ break;
+ case QNXSIGTERM:
+ return TARGET_SIGNAL_TERM;
+ break;
+ case QNXSIGUSR1:
+ return TARGET_SIGNAL_USR1;
+ break;
+ case QNXSIGUSR2:
+ return TARGET_SIGNAL_USR2;
+ break;
+ case QNXSIGCHLD:
+ return TARGET_SIGNAL_CHLD;
+ break;
+ case QNXSIGPWR:
+ return TARGET_SIGNAL_PWR;
+ break;
+ case QNXSIGWINCH:
+ return TARGET_SIGNAL_WINCH;
+ break;
+ case QNXSIGURG:
+ return TARGET_SIGNAL_URG;
+ break;
+ case QNXSIGPOLL:
+ return TARGET_SIGNAL_POLL;
+ break;
+ // case QNXSIGIO: return TARGET_SIGNAL_IO; break;
+ case QNXSIGSTOP:
+ return TARGET_SIGNAL_STOP;
+ break;
+ case QNXSIGTSTP:
+ return TARGET_SIGNAL_TSTP;
+ break;
+ case QNXSIGCONT:
+ return TARGET_SIGNAL_CONT;
+ break;
+ case QNXSIGTTIN:
+ return TARGET_SIGNAL_TTIN;
+ break;
+ case QNXSIGTTOU:
+ return TARGET_SIGNAL_TTOU;
+ break;
+ case QNXSIGVTALRM:
+ return TARGET_SIGNAL_VTALRM;
+ break;
+ case QNXSIGPROF:
+ return TARGET_SIGNAL_PROF;
+ break;
+ case QNXSIGXCPU:
+ return TARGET_SIGNAL_XCPU;
+ break;
+ case QNXSIGXFSZ:
+ return TARGET_SIGNAL_XFSZ;
+ break;
+ default:
+ break;
+ }
+ #endif /* __QNXNTO__ */
+ return target_signal_from_host (sig);
+ }
+
+
+ /* Convert gdb signal to qnx signal. */
+ enum target_signal
+ target_signal_to_qnx (sig)
+ int sig;
+ {
+ #ifndef __QNXNTO__
+ switch (sig)
+ {
+ case 0:
+ return 0;
+ break;
+ case TARGET_SIGNAL_HUP:
+ return QNXSIGHUP;
+ break;
+ case TARGET_SIGNAL_INT:
+ return QNXSIGINT;
+ break;
+ case TARGET_SIGNAL_QUIT:
+ return QNXSIGQUIT;
+ break;
+ case TARGET_SIGNAL_ILL:
+ return QNXSIGILL;
+ break;
+ case TARGET_SIGNAL_TRAP:
+ return QNXSIGTRAP;
+ break;
+ case TARGET_SIGNAL_ABRT:
+ return QNXSIGABRT;
+ break;
+ case TARGET_SIGNAL_EMT:
+ return QNXSIGEMT;
+ break;
+ case TARGET_SIGNAL_FPE:
+ return QNXSIGFPE;
+ break;
+ case TARGET_SIGNAL_KILL:
+ return QNXSIGKILL;
+ break;
+ case TARGET_SIGNAL_BUS:
+ return QNXSIGBUS;
+ break;
+ case TARGET_SIGNAL_SEGV:
+ return QNXSIGSEGV;
+ break;
+ case TARGET_SIGNAL_SYS:
+ return QNXSIGSYS;
+ break;
+ case TARGET_SIGNAL_PIPE:
+ return QNXSIGPIPE;
+ break;
+ case TARGET_SIGNAL_ALRM:
+ return QNXSIGALRM;
+ break;
+ case TARGET_SIGNAL_TERM:
+ return QNXSIGTERM;
+ break;
+ case TARGET_SIGNAL_USR1:
+ return QNXSIGUSR1;
+ break;
+ case TARGET_SIGNAL_USR2:
+ return QNXSIGUSR2;
+ break;
+ case TARGET_SIGNAL_CHLD:
+ return QNXSIGCHLD;
+ break;
+ case TARGET_SIGNAL_PWR:
+ return QNXSIGPWR;
+ break;
+ case TARGET_SIGNAL_WINCH:
+ return QNXSIGWINCH;
+ break;
+ case TARGET_SIGNAL_URG:
+ return QNXSIGURG;
+ break;
+ case TARGET_SIGNAL_IO:
+ return QNXSIGIO;
+ break;
+ case TARGET_SIGNAL_POLL:
+ return QNXSIGPOLL;
+ break;
+ case TARGET_SIGNAL_STOP:
+ return QNXSIGSTOP;
+ break;
+ case TARGET_SIGNAL_TSTP:
+ return QNXSIGTSTP;
+ break;
+ case TARGET_SIGNAL_CONT:
+ return QNXSIGCONT;
+ break;
+ case TARGET_SIGNAL_TTIN:
+ return QNXSIGTTIN;
+ break;
+ case TARGET_SIGNAL_TTOU:
+ return QNXSIGTTOU;
+ break;
+ case TARGET_SIGNAL_VTALRM:
+ return QNXSIGVTALRM;
+ break;
+ case TARGET_SIGNAL_PROF:
+ return QNXSIGPROF;
+ break;
+ case TARGET_SIGNAL_XCPU:
+ return QNXSIGXCPU;
+ break;
+ case TARGET_SIGNAL_XFSZ:
+ return QNXSIGXFSZ;
+ break;
+ default:
+ break;
+ }
+ #endif /* __QNXNTO__ */
+ return target_signal_to_host (sig);
+ }
+
+ #ifdef __CYGWIN__
+ char default_qnx_target[] = "C:\\QNXsdk\\target\\qnx6";
+ #elif defined(__QNX__) && !defined(__QNXNTO__)
+ char default_qnx_target[] = "/usr/nto";
+ #elif defined(__sun__) || defined(linux)
+ char default_qnx_target[] = "/opt/QNXsdk/target/qnx6";
+ #else
+ char default_qnx_target[] = "";
+ #endif
+
+ char *
+ qnx_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_qnx_target, buf);
+ return buf;
+ #else
+ return p ? p : default_qnx_target;
+ #endif
+ }
+
+ int
+ proc_iterate_over_mappings (int (*func) (int, CORE_ADDR))
+ {
+ struct dsmapinfo *lm;
+ char *tmp_pathname;
+ int fd;
+
+ lm = qnx_mapinfo (0, 1, 1);
+ while (lm != NULL)
+ {
+ if ((fd = solib_open (lm->name, &tmp_pathname)) != -1)
+ {
+ func (fd, lm->text.addr);
+ if (tmp_pathname)
+ xfree (tmp_pathname);
+ }
+ lm = qnx_mapinfo (0, 0, 1);
+ }
+ return 0;
+ }
+
+ void
+ qnx_init_solib_search_path (void)
+ {
+ char tmp[_POSIX_PATH_MAX * 2];
+ char *nto_root;
+ char *solib_search_path, *cmd_name = "solib-search-path";
+ struct cmd_list_element *c;
+
+ c = lookup_cmd (&cmd_name, setlist, "", 1, 1);
+
+ if (!c || !c->var)
+ return;
+
+ solib_search_path = *((char **) c->var);
+
+ if (solib_search_path != NULL)
+ return;
+ nto_root = qnx_target ();
+
+ #ifdef TARGET_BYTE_ORDER_SELECTABLE
+ #if defined(SOLIB_PROCESSOR_BE) && defined(SOLIB_PROCESSOR_LE)
+ sprintf (tmp, "set solib-absolute-prefix %s/%s",
+ nto_root,
+ (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) ?
+ SOLIB_PROCESSOR_BE : SOLIB_PROCESSOR_LE);
+ execute_command (tmp, 0);
+ sprintf (tmp,
+ "set solib-search-path %s/%s/lib:%s/%s/usr/lib:%s/%s/usr/photon/lib:%s/%s/usr/photon/dll:%s/%s/lib/dll",
+ nto_root,
+ (TARGET_BYTE_ORDER ==
+ BFD_ENDIAN_BIG) ? SOLIB_PROCESSOR_BE : SOLIB_PROCESSOR_LE,
+ nto_root,
+ (TARGET_BYTE_ORDER ==
+ BFD_ENDIAN_BIG) ? SOLIB_PROCESSOR_BE : SOLIB_PROCESSOR_LE,
+ nto_root,
+ (TARGET_BYTE_ORDER ==
+ BFD_ENDIAN_BIG) ? SOLIB_PROCESSOR_BE : SOLIB_PROCESSOR_LE,
+ nto_root,
+ (TARGET_BYTE_ORDER ==
+ BFD_ENDIAN_BIG) ? SOLIB_PROCESSOR_BE : SOLIB_PROCESSOR_LE,
+ nto_root,
+ (TARGET_BYTE_ORDER ==
+ BFD_ENDIAN_BIG) ? SOLIB_PROCESSOR_BE : SOLIB_PROCESSOR_LE);
+ execute_command (tmp, 0);
+ #endif
+ #else
+ #if defined(SOLIB_PROCESSOR)
+ sprintf (tmp, "set solib-absolute-prefix %s/%s", nto_root, SOLIB_PROCESSOR);
+ execute_command (tmp, 0);
+ sprintf (tmp,
+ "set solib-search-path %s/%s/lib:%s/%s/usr/lib:%s/%s/usr/photon/lib:%s/%s/usr/photon/dll:%s/%s/lib/dll",
+ nto_root, SOLIB_PROCESSOR, nto_root, SOLIB_PROCESSOR, nto_root,
+ SOLIB_PROCESSOR, nto_root, SOLIB_PROCESSOR, nto_root,
+ SOLIB_PROCESSOR);
+ execute_command (tmp, 0);
+ #endif
+ #endif
+ }
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -xMakefile.in -x configure src.orig/gdb/ser-ntopty.c src/gdb/ser-ntopty.c
*** src.orig/gdb/ser-ntopty.c Wed Dec 31 19:00:00 1969
--- src/gdb/ser-ntopty.c Mon Feb 3 13:43:00 2003
***************
*** 0 ****
--- 1,803 ----
+ #undef GKM_DEBUG
+
+ #include <string.h>
+ #include "defs.h"
+ #include "serial.h"
+ #include "command.h"
+ #include "gdbcmd.h"
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <signal.h>
+ #include "terminal.h"
+ #ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+ #endif
+ #ifdef __QNXTARGET__
+ #include "nto-share/dsmsgs.h" /* This is for TS_TEXT_MAX_SIZE */
+ #define re_comp ignore_re_comp // Use the one in defs.h...
+ #include <unix.h>
+ #undef re_comp
+ #endif
+
+ #ifndef PATH_MAX
+ #define PATH_MAX 255
+ #endif
+
+ #include <sys/time.h>
+
+ #ifdef HAVE_TERMIOS
+
+ struct ntopty_ttystate
+ {
+ struct termios termios;
+ };
+ #endif /* termios */
+
+ #ifdef HAVE_TERMIO
+
+ /* It is believed that all systems which have added job control to SVR3
+ (e.g. sco) have also added termios. Even if not, trying to figure out
+ all the variations (TIOCGPGRP vs. TCGETPGRP, etc.) would be pretty
+ bewildering. So we don't attempt it. */
+
+ struct ntopty_ttystate
+ {
+ struct termio termio;
+ };
+ #endif /* termio */
+
+ #ifdef HAVE_SGTTY
+ /* Needed for the code which uses select(). We would include <sys/select.h>
+ too if it existed on all systems. */
+ #include <sys/time.h>
+
+ struct ntopty_ttystate
+ {
+ struct sgttyb sgttyb;
+ struct tchars tc;
+ struct ltchars ltc;
+ /* Line discipline flags. */
+ int lmode;
+ };
+ #endif /* sgtty */
+
+ static int ntopty_open PARAMS ((struct serial * scb, const char *name));
+ static void ntopty_raw PARAMS ((struct serial * scb));
+ static int wait_for PARAMS ((struct serial * scb, int timeout));
+ static int ntopty_readchar PARAMS ((struct serial * scb, int timeout));
+ static int ntopty_setbaudrate PARAMS ((struct serial * scb, int rate));
+ static int ntopty_write
+ PARAMS ((struct serial * scb, const char *str, int len));
+ /* FIXME: static void ntopty_restore PARAMS ((struct serial *scb)); */
+ static void ntopty_close PARAMS ((struct serial * scb));
+ static int get_tty_state
+ PARAMS ((struct serial * scb, struct ntopty_ttystate * state));
+ static int set_tty_state
+ PARAMS ((struct serial * scb, struct ntopty_ttystate * state));
+ static serial_ttystate ntopty_get_tty_state PARAMS ((struct serial * scb));
+ static int ntopty_set_tty_state
+ PARAMS ((struct serial * scb, serial_ttystate state));
+ extern void qnx_outgoing_text (char *buf, int nbytes);
+
+ static char *ntoserver = NULL;
+ static char *ntoserverdev = NULL;
+ static pid_t ntopid = -1;
+ static int nto_ptydelay = 1;
+
+
+ /*
+ * Open up a pty/tty pair for IPC with the ntoserver (pdebug).
+ * We open both master and slave, fork, close the slave
+ * in the child and dup2 stdin/out/err to the master. We close
+ * the master in the parent, leaving the slave tty fd in the scb.
+ * This means pdebug has to use stdio, NOT the tty device, so we
+ * launch it now with "pdebug -", meaning "use stdio" as opposed
+ * to "pdebug /dev/ptyNM".
+ */
+
+ static int
+ ntopty_open (scb, name)
+ struct serial *scb;
+ const char *name;
+ {
+ char pty[PATH_MAX];
+ char *p;
+ int master;
+
+ if (openpty (&master, &scb->fd, &pty[0], 0, 0) == -1)
+ {
+ printf_unfiltered ("openpty() failed: %s\n", strerror (errno));
+ return -1;
+ }
+
+ p = strstr (pty, "tty");
+ *p = 'p';
+ printf_unfiltered ("Launching on pty %s\n", pty);
+
+ ntopid = fork ();
+
+ if (ntopid == -1)
+ {
+ printf_unfiltered ("fork() failed: %s\n", strerror (errno));
+ return -1;
+ }
+
+ else if (ntopid == 0)
+ { /* child */
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGUSR1);
+ sigprocmask (SIG_UNBLOCK, &set, NULL);
+
+ setsid ();
+
+ close (scb->fd); /* all done with slave in child */
+
+ /* master becomes stdin/stdout/stderr of child */
+ if (dup2 (master, STDIN_FILENO) != STDIN_FILENO)
+ {
+ printf_unfiltered ("dup2 of stdin failed.\n");
+ close (master);
+ exit (0);
+ }
+ if (dup2 (master, STDOUT_FILENO) != STDOUT_FILENO)
+ {
+ printf_unfiltered ("dup2 of stdout failed.\n");
+ close (master);
+ exit (0);
+ }
+ if (dup2 (master, STDERR_FILENO) != STDERR_FILENO)
+ {
+ printf_unfiltered ("dup2 of stderr failed.\n");
+ close (master);
+ exit (0);
+ }
+
+ /* Launch the ntoserver, which in this case has to be "pdebug -". */
+ execlp (ntoserver, ntoserver, ntoserverdev, 0);
+
+ printf_unfiltered ("execlp(%s) failed: %s\n", ntoserver,
+ strerror (errno));
+ close (master);
+ exit (1);
+ }
+ close (master);
+ printf_unfiltered ("Debug server launched.\n");
+ sleep (nto_ptydelay); // wait for a while for the server, pdebug.
+ return 0;
+ }
+
+ static int
+ get_tty_state (scb, state)
+ struct serial *scb;
+ struct ntopty_ttystate *state;
+ {
+ #ifdef HAVE_TERMIOS
+ extern int errno;
+
+ if (tcgetattr (scb->fd, &state->termios) < 0)
+ return -1;
+
+ return 0;
+ #endif
+
+ #ifdef HAVE_TERMIO
+ if (ioctl (scb->fd, TCGETA, &state->termio) < 0)
+ return -1;
+ return 0;
+ #endif
+
+ #ifdef HAVE_SGTTY
+ if (ioctl (scb->fd, TIOCGETP, &state->sgttyb) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCGETC, &state->tc) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCGLTC, &state->ltc) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCLGET, &state->lmode) < 0)
+ return -1;
+
+ return 0;
+ #endif
+ }
+
+ static int
+ set_tty_state (scb, state)
+ struct serial *scb;
+ struct ntopty_ttystate *state;
+ {
+ #ifdef HAVE_TERMIOS
+ if (tcsetattr (scb->fd, TCSANOW, &state->termios) < 0)
+ return -1;
+
+ return 0;
+ #endif
+
+ #ifdef HAVE_TERMIO
+ if (ioctl (scb->fd, TCSETA, &state->termio) < 0)
+ return -1;
+ return 0;
+ #endif
+
+ #ifdef HAVE_SGTTY
+ if (ioctl (scb->fd, TIOCSETN, &state->sgttyb) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCSETC, &state->tc) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCSLTC, &state->ltc) < 0)
+ return -1;
+ if (ioctl (scb->fd, TIOCLSET, &state->lmode) < 0)
+ return -1;
+
+ return 0;
+ #endif
+ }
+
+ static serial_ttystate
+ ntopty_get_tty_state (scb)
+ struct serial *scb;
+ {
+ struct ntopty_ttystate *state;
+
+ state = (struct ntopty_ttystate *) xmalloc (sizeof *state);
+
+ if (get_tty_state (scb, state))
+ return NULL;
+
+ return (serial_ttystate) state;
+ }
+
+ static int
+ ntopty_set_tty_state (scb, ttystate)
+ struct serial *scb;
+ serial_ttystate ttystate;
+ {
+ struct ntopty_ttystate *state;
+
+ state = (struct ntopty_ttystate *) ttystate;
+
+ return set_tty_state (scb, state);
+ }
+
+ static int
+ ntopty_noflush_set_tty_state (scb, new_ttystate, old_ttystate)
+ struct serial *scb;
+ serial_ttystate new_ttystate;
+ serial_ttystate old_ttystate;
+ {
+ struct ntopty_ttystate new_state;
+ #ifdef HAVE_SGTTY
+ struct ntopty_ttystate *state = (struct ntopty_ttystate *) old_ttystate;
+ #endif
+
+ new_state = *(struct ntopty_ttystate *) new_ttystate;
+
+ /* Don't change in or out of raw mode; we don't want to flush input.
+ termio and termios have no such restriction; for them flushing input
+ is separate from setting the attributes. */
+
+ #ifdef HAVE_SGTTY
+ if (state->sgttyb.sg_flags & RAW)
+ new_state.sgttyb.sg_flags |= RAW;
+ else
+ new_state.sgttyb.sg_flags &= ~RAW;
+
+ /* I'm not sure whether this is necessary; the manpage just mentions
+ RAW not CBREAK. */
+ if (state->sgttyb.sg_flags & CBREAK)
+ new_state.sgttyb.sg_flags |= CBREAK;
+ else
+ new_state.sgttyb.sg_flags &= ~CBREAK;
+ #endif
+
+ return set_tty_state (scb, &new_state);
+ }
+
+ static void
+ ntopty_print_tty_state (scb, ttystate)
+ struct serial *scb;
+ serial_ttystate ttystate;
+ {
+ struct ntopty_ttystate *state = (struct ntopty_ttystate *) ttystate;
+ int i;
+
+ #ifdef HAVE_TERMIOS
+ printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
+ (unsigned int) state->termios.c_iflag,
+ (unsigned int) state->termios.c_oflag);
+ printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x\n",
+ (unsigned int) state->termios.c_cflag,
+ (unsigned int) state->termios.c_lflag);
+ #if 0
+ /* This not in POSIX, and is not really documented by those systems
+ which have it (at least not Sun). */
+ printf_filtered ("c_line = 0x%x.\n", state->termios.c_line);
+ #endif
+ printf_filtered ("c_cc: ");
+ for (i = 0; i < NCCS; i += 1)
+ printf_filtered ("0x%x ", state->termios.c_cc[i]);
+ printf_filtered ("\n");
+ #endif
+
+ #ifdef HAVE_TERMIO
+ printf_filtered ("c_iflag = 0x%x, c_oflag = 0x%x,\n",
+ state->termio.c_iflag, state->termio.c_oflag);
+ printf_filtered ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
+ state->termio.c_cflag, state->termio.c_lflag,
+ state->termio.c_line);
+ printf_filtered ("c_cc: ");
+ for (i = 0; i < NCC; i += 1)
+ printf_filtered ("0x%x ", state->termio.c_cc[i]);
+ printf_filtered ("\n");
+ #endif
+
+ #ifdef HAVE_SGTTY
+ printf_filtered ("sgttyb.sg_flags = 0x%x.\n", state->sgttyb.sg_flags);
+
+ printf_filtered ("tchars: ");
+ for (i = 0; i < (int) sizeof (struct tchars); i++)
+ printf_filtered ("0x%x ", ((unsigned char *) &state->tc)[i]);
+ printf_filtered ("\n");
+
+ printf_filtered ("ltchars: ");
+ for (i = 0; i < (int) sizeof (struct ltchars); i++)
+ printf_filtered ("0x%x ", ((unsigned char *) &state->ltc)[i]);
+ printf_filtered ("\n");
+
+ printf_filtered ("lmode: 0x%x\n", state->lmode);
+ #endif
+ }
+
+ static int
+ ntopty_flush_output (scb)
+ struct serial *scb;
+ {
+ #ifdef HAVE_TERMIOS
+ return tcflush (scb->fd, TCOFLUSH);
+ #endif
+
+ #ifdef HAVE_TERMIO
+ return ioctl (scb->fd, TCFLSH, 1);
+ #endif
+
+ #ifdef HAVE_SGTTY
+ /* This flushes both input and output, but we can't do better. */
+ return ioctl (scb->fd, TIOCFLUSH, 0);
+ #endif
+ }
+
+ static int
+ ntopty_flush_input (scb)
+ struct serial *scb;
+ {
+ scb->bufcnt = 0;
+ scb->bufp = scb->buf;
+
+ #ifdef HAVE_TERMIOS
+ return tcflush (scb->fd, TCIFLUSH);
+ #endif
+
+ #ifdef HAVE_TERMIO
+ return ioctl (scb->fd, TCFLSH, 0);
+ #endif
+
+ #ifdef HAVE_SGTTY
+ /* This flushes both input and output, but we can't do better. */
+ return ioctl (scb->fd, TIOCFLUSH, 0);
+ #endif
+ }
+
+ static int
+ ntopty_send_break (scb)
+ struct serial *scb;
+ {
+ #ifdef HAVE_TERMIOS
+ return tcsendbreak (scb->fd, 0);
+ #endif
+
+ #ifdef HAVE_TERMIO
+ return ioctl (scb->fd, TCSBRK, 0);
+ #endif
+
+ #ifdef HAVE_SGTTY
+ {
+ int status;
+ struct timeval timeout;
+
+ status = ioctl (scb->fd, TIOCSBRK, 0);
+
+ /* Can't use usleep; it doesn't exist in BSD 4.2. */
+ /* Note that if this select() is interrupted by a signal it will not wait
+ the full length of time. I think that is OK. */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 250000;
+ select (0, 0, 0, 0, &timeout);
+ status = ioctl (scb->fd, TIOCCBRK, 0);
+ return status;
+ }
+ #endif
+ }
+
+ static void
+ ntopty_raw (scb)
+ struct serial *scb;
+ {
+ struct ntopty_ttystate state;
+
+ if (get_tty_state (scb, &state))
+ fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n",
+ safe_strerror (errno));
+
+ #ifdef HAVE_TERMIOS
+ state.termios.c_iflag = 0;
+ state.termios.c_oflag = 0;
+ state.termios.c_lflag = 0;
+ state.termios.c_cflag &= ~(CSIZE | PARENB);
+ state.termios.c_cflag |= CLOCAL | CS8;
+ state.termios.c_cc[VMIN] = 0;
+ state.termios.c_cc[VTIME] = 0;
+ #endif
+
+ #ifdef HAVE_TERMIO
+ state.termio.c_iflag = 0;
+ state.termio.c_oflag = 0;
+ state.termio.c_lflag = 0;
+ state.termio.c_cflag &= ~(CSIZE | PARENB);
+ state.termio.c_cflag |= CLOCAL | CS8;
+ state.termio.c_cc[VMIN] = 0;
+ state.termio.c_cc[VTIME] = 0;
+ #endif
+
+ #ifdef HAVE_SGTTY
+ state.sgttyb.sg_flags |= RAW | ANYP;
+ state.sgttyb.sg_flags &= ~(CBREAK | ECHO);
+ #endif
+
+ scb->current_timeout = 0;
+
+ if (set_tty_state (scb, &state))
+ fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n",
+ safe_strerror (errno));
+ }
+
+ /* Wait for input on scb, with timeout seconds. Returns 0 on success,
+ otherwise SERIAL_TIMEOUT or SERIAL_ERROR.
+
+ For termio{s}, we actually just setup VTIME if necessary, and let the
+ timeout occur in the read() in ntopty_read().
+ */
+
+ static int
+ wait_for (scb, timeout)
+ struct serial *scb;
+ int timeout;
+ {
+ scb->timeout_remaining = 0;
+
+ // We want to use the select so we can easily handle stdinput with the select
+ #if defined(HAVE_SGTTY) || defined(__QNXTARGET__)
+ {
+ struct timeval tv;
+ fd_set readfds;
+
+ tv.tv_sec = timeout;
+ tv.tv_usec = 0;
+
+
+ while (1)
+ {
+ int numfds;
+
+ FD_ZERO (&readfds);
+ FD_SET (scb->fd, &readfds);
+ if (timeout < 0)
+ FD_SET (STDIN_FILENO, &readfds);
+
+ if (timeout >= 0)
+ numfds = select (scb->fd + 1, &readfds, 0, 0, &tv);
+ else
+ numfds = select (scb->fd + 1, &readfds, 0, 0, 0);
+
+ if (numfds <= 0)
+ {
+ if (numfds == 0)
+ return SERIAL_TIMEOUT;
+ else if (errno == EINTR)
+ continue;
+ else
+ return SERIAL_ERROR; /* Got an error from select or poll */
+ }
+ if ((timeout < 0) && (FD_ISSET (STDIN_FILENO, &readfds)))
+ {
+ int i;
+ char buf[TS_TEXT_MAX_SIZE];
+ i = read (STDIN_FILENO, buf, TS_TEXT_MAX_SIZE);
+ qnx_outgoing_text (buf, i);
+ }
+ else
+ return 0;
+ }
+ }
+ #else /* end of HAVE_SGTTY || __QNXTARGET__ */
+
+ #if defined HAVE_TERMIO || defined HAVE_TERMIOS
+ if (timeout == scb->current_timeout)
+ return 0;
+
+ scb->current_timeout = timeout;
+
+ {
+ struct ntopty_ttystate state;
+
+ if (get_tty_state (scb, &state))
+ fprintf_unfiltered (gdb_stderr, "get_tty_state failed: %s\n",
+ safe_strerror (errno));
+
+ #ifdef HAVE_TERMIOS
+ if (timeout < 0)
+ {
+ /* No timeout. */
+ state.termios.c_cc[VTIME] = 0;
+ state.termios.c_cc[VMIN] = 1;
+ }
+ else
+ {
+ state.termios.c_cc[VMIN] = 0;
+ state.termios.c_cc[VTIME] = timeout * 10;
+ if (state.termios.c_cc[VTIME] != timeout * 10)
+ {
+
+ /* If c_cc is an 8-bit signed character, we can't go
+ bigger than this. If it is always unsigned, we could use
+ 25. */
+
+ scb->current_timeout = 12;
+ state.termios.c_cc[VTIME] = scb->current_timeout * 10;
+ scb->timeout_remaining = timeout - scb->current_timeout;
+ }
+ }
+ #endif
+
+ #ifdef HAVE_TERMIO
+ if (timeout < 0)
+ {
+ /* No timeout. */
+ state.termio.c_cc[VTIME] = 0;
+ state.termio.c_cc[VMIN] = 1;
+ }
+ else
+ {
+ state.termio.c_cc[VMIN] = 0;
+ state.termio.c_cc[VTIME] = timeout * 10;
+ if (state.termio.c_cc[VTIME] != timeout * 10)
+ {
+ /* If c_cc is an 8-bit signed character, we can't go
+ bigger than this. If it is always unsigned, we could use
+ 25. */
+
+ scb->current_timeout = 12;
+ state.termio.c_cc[VTIME] = scb->current_timeout * 10;
+ scb->timeout_remaining = timeout - scb->current_timeout;
+ }
+ }
+ #endif
+
+ if (set_tty_state (scb, &state))
+ fprintf_unfiltered (gdb_stderr, "set_tty_state failed: %s\n",
+ safe_strerror (errno));
+
+ return 0;
+ }
+ #endif /* HAVE_TERMIO || HAVE_TERMIOS */
+ #endif
+ }
+
+ /* Read a character with user-specified timeout. TIMEOUT is number of seconds
+ to wait, or -1 to wait forever. Use timeout of 0 to effect a poll. Returns
+ char if successful. Returns SERIAL_TIMEOUT if timeout expired, EOF if line
+ dropped dead, or SERIAL_ERROR for any other error (see errno in that case). */
+
+ static int
+ ntopty_readchar (scb, timeout)
+ struct serial *scb;
+ int timeout;
+ {
+ int status;
+
+ if (scb->bufcnt-- > 0)
+ return *scb->bufp++;
+
+ while (1)
+ {
+ status = wait_for (scb, timeout);
+
+ if (status < 0)
+ return status;
+
+ scb->bufcnt = read (scb->fd, scb->buf, BUFSIZ);
+
+ if (scb->bufcnt <= 0)
+ {
+ if (scb->bufcnt == 0)
+ {
+ /* Zero characters means timeout (it could also be EOF, but
+ we don't (yet at least) distinguish). */
+ if (scb->timeout_remaining > 0)
+ {
+ timeout = scb->timeout_remaining;
+ continue;
+ }
+ else
+ return SERIAL_TIMEOUT;
+ }
+ else if (errno == EINTR)
+ continue;
+ else
+ return SERIAL_ERROR; /* Got an error from read */
+ }
+
+ scb->bufcnt--;
+ scb->bufp = scb->buf;
+ return *scb->bufp++;
+ }
+ }
+
+ static int
+ ntopty_setbaudrate (scb, rate)
+ struct serial *scb;
+ int rate;
+ {
+ struct ntopty_ttystate state;
+
+ if (get_tty_state (scb, &state))
+ return -1;
+
+ #ifdef HAVE_TERMIOS
+ cfsetospeed (&state.termios, rate);
+ cfsetispeed (&state.termios, rate);
+ #endif
+
+ #ifdef HAVE_TERMIO
+ #ifndef CIBAUD
+ #define CIBAUD CBAUD
+ #endif
+
+ state.termio.c_cflag &= ~(CBAUD | CIBAUD);
+ state.termio.c_cflag |= rate;
+ #endif
+
+ #ifdef HAVE_SGTTY
+ state.sgttyb.sg_ispeed = rate;
+ state.sgttyb.sg_ospeed = rate;
+ #endif
+
+ return set_tty_state (scb, &state);
+ }
+
+ static int
+ ntopty_setstopbits (scb, num)
+ struct serial *scb;
+ int num;
+ {
+ struct ntopty_ttystate state;
+ int newbit;
+
+ if (get_tty_state (scb, &state))
+ return -1;
+
+ switch (num)
+ {
+ case SERIAL_1_STOPBITS:
+ newbit = 0;
+ break;
+ case SERIAL_1_AND_A_HALF_STOPBITS:
+ case SERIAL_2_STOPBITS:
+ newbit = 1;
+ break;
+ default:
+ return 1;
+ }
+
+ #ifdef HAVE_TERMIOS
+ if (!newbit)
+ state.termios.c_cflag &= ~CSTOPB;
+ else
+ state.termios.c_cflag |= CSTOPB; /* two bits */
+ #endif
+
+ #ifdef HAVE_TERMIO
+ if (!newbit)
+ state.termio.c_cflag &= ~CSTOPB;
+ else
+ state.termio.c_cflag |= CSTOPB; /* two bits */
+ #endif
+
+ #ifdef HAVE_SGTTY
+ return 0; /* sgtty doesn't support this */
+ #endif
+
+ return set_tty_state (scb, &state);
+ }
+
+ static int
+ ntopty_write (scb, str, len)
+ struct serial *scb;
+ const char *str;
+ int len;
+ {
+ int cc;
+
+ while (len > 0)
+ {
+ cc = write (scb->fd, str, len);
+
+ if (cc < 0)
+ return 1;
+ len -= cc;
+ str += cc;
+ }
+ return 0;
+ }
+
+ static void
+ ntopty_close (scb)
+ struct serial *scb;
+ {
+ if (scb->fd < 0)
+ return;
+
+ kill (ntopid, SIGTERM);
+ close (scb->fd);
+ scb->fd = -1;
+ }
+
+ static int
+ ntopty_nop_drain_output (struct serial *scb)
+ {
+ return 0;
+ }
+
+ static void
+ ntopty_nop_async (struct serial *scb, int async_p)
+ {
+ return;
+ }
+
+ void
+ _initialize_ser_ntopty ()
+ {
+ struct serial_ops *ops = xmalloc (sizeof (struct serial_ops));
+ memset (ops, sizeof (struct serial_ops), 0);
+ ops->name = "pty";
+ ops->next = 0;
+ ops->open = ntopty_open;
+ ops->close = ntopty_close;
+ ops->readchar = ntopty_readchar;
+ ops->write = ntopty_write;
+ ops->flush_output = ntopty_flush_output;
+ ops->flush_input = ntopty_flush_input;
+ ops->send_break = ntopty_send_break;
+ ops->go_raw = ntopty_raw;
+ ops->get_tty_state = ntopty_get_tty_state;
+ ops->set_tty_state = ntopty_set_tty_state;
+ ops->print_tty_state = ntopty_print_tty_state;
+ ops->noflush_set_tty_state = ntopty_noflush_set_tty_state;
+ ops->setbaudrate = ntopty_setbaudrate;
+ ops->setstopbits = ntopty_setstopbits;
+ ops->drain_output = ntopty_nop_drain_output;
+ ops->async = ntopty_nop_async;
+ serial_add_interface (ops);
+
+ ntoserver = strdup ("pdebug");
+ ntoserverdev = strdup ("-");
+ add_show_from_set (add_set_cmd ("ntoserver", no_class,
+ var_filename, (char *) &ntoserver,
+ "Set QNX debug protocol server.\n",
+ &setlist), &showlist);
+ add_show_from_set (add_set_cmd
+ ("ntoptydelay", no_class, var_integer,
+ (char *) &nto_ptydelay,
+ "Set delay before attempting to talk to pdebug.\n",
+ &setlist), &showlist);
+ }
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -x configure src.orig/readline/Makefile.in src/readline/Makefile.in
*** src.orig/readline/Makefile.in Sun Dec 8 17:31:37 2002
--- src/readline/Makefile.in Wed Jan 22 14:17:46 2003
*************** GCC_LINT_CFLAGS = $(XCCFLAGS) $(GCC_LINT
*** 86,91 ****
--- 86,98 ----
LIBRARY_NAME = libreadline.a
STATIC_LIBS = libreadline.a libhistory.a
+ HAVE_WCWIDTH = @HAVE_WCWIDTH@
+
+ ifeq ($(HAVE_WCWIDTH), no)
+ WCWIDTH_SRC = $(srcdir)/support/wcwidth.c
+ WCWIDTH_OBJ = wcwidth.o
+ endif
+
# The C code source files for this library.
CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \
$(srcdir)/vi_mode.c $(srcdir)/parens.c $(srcdir)/rltty.c \
*************** CSOURCES = $(srcdir)/readline.c $(srcdir
*** 98,104 ****
$(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \
$(srcdir)/shell.c $(srcdir)/savestring.c $(srcdir)/tilde.c \
$(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \
! $(srcdir)/mbutil.c
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
--- 105,111 ----
$(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \
$(srcdir)/shell.c $(srcdir)/savestring.c $(srcdir)/tilde.c \
$(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \
! $(srcdir)/mbutil.c $(WCWIDTH_SRC)
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
*************** TILDEOBJ = tilde.o
*** 111,117 ****
OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
rltty.o complete.o bind.o isearch.o display.o signals.o \
util.o kill.o undo.o macro.o input.o callback.o terminal.o \
! text.o nls.o misc.o compat.o xmalloc.o $(HISTOBJ) $(TILDEOBJ)
# The texinfo files which document this library.
DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo
--- 118,125 ----
OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
rltty.o complete.o bind.o isearch.o display.o signals.o \
util.o kill.o undo.o macro.o input.o callback.o terminal.o \
! text.o nls.o misc.o compat.o xmalloc.o $(HISTOBJ) $(TILDEOBJ) \
! $(WCWIDTH_OBJ)
# The texinfo files which document this library.
DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo
*************** libhistory.a: $(HISTOBJ) xmalloc.o
*** 147,152 ****
--- 155,166 ----
$(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o
-test -n "$(RANLIB)" && $(RANLIB) $@
+ ifeq ($(HAVE_WCWIDTH), no)
+ $(WCWIDTH_OBJ): $(WCWIDTH_SRC)
+ $(RM) $@
+ $(CC) $(CCFLAGS) -c $(WCWIDTH_SRC)
+ endif
+
# Since tilde.c is shared between readline and bash, make sure we compile
# it with the right flags when it's built as part of readline
tilde.o: tilde.c
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -x configure src.orig/readline/aclocal.m4 src/readline/aclocal.m4
*** src.orig/readline/aclocal.m4 Sun Dec 8 17:31:37 2002
--- src/readline/aclocal.m4 Wed Jan 22 14:14:26 2003
*************** AC_CHECK_HEADERS(wchar.h)
*** 1653,1659 ****
AC_CHECK_HEADERS(langinfo.h)
AC_CHECK_FUNC(mbsrtowcs, AC_DEFINE(HAVE_MBSRTOWCS))
! AC_CHECK_FUNC(wcwidth, AC_DEFINE(HAVE_WCWIDTH))
AC_CACHE_CHECK([for mbstate_t], bash_cv_have_mbstate_t,
[AC_TRY_RUN([
--- 1653,1659 ----
AC_CHECK_HEADERS(langinfo.h)
AC_CHECK_FUNC(mbsrtowcs, AC_DEFINE(HAVE_MBSRTOWCS))
! AC_CHECK_FUNC(wcwidth, AC_DEFINE(HAVE_WCWIDTH), AC_SUBST(HAVE_WCWIDTH,no))
AC_CACHE_CHECK([for mbstate_t], bash_cv_have_mbstate_t,
[AC_TRY_RUN([
diff -rc3p -N -x '.#*' -x CVS -x'*.cache' -x configure src.orig/readline/shlib/Makefile.in src/readline/shlib/Makefile.in
*** src.orig/readline/shlib/Makefile.in Sun Dec 8 17:31:38 2002
--- src/readline/shlib/Makefile.in Wed Jan 22 14:18:46 2003
*************** SHARED_READLINE = libreadline.$(SHLIB_LI
*** 103,108 ****
--- 103,115 ----
SHARED_HISTORY = libhistory.$(SHLIB_LIBVERSION)
SHARED_LIBS = $(SHARED_READLINE) $(SHARED_HISTORY)
+ HAVE_WCWIDTH = @HAVE_WCWIDTH@
+
+ ifeq ($(HAVE_WCWIDTH), no)
+ WCWIDTH_SRC = $(srcdir)/support/wcwidth.c
+ WCWIDTH_OBJ = wcwidth.so
+ endif
+
# The C code source files for this library.
CSOURCES = $(topdir)/readline.c $(topdir)/funmap.c $(topdir)/keymaps.c \
$(topdir)/vi_mode.c $(topdir)/parens.c $(topdir)/rltty.c \
*************** CSOURCES = $(topdir)/readline.c $(topdir
*** 115,121 ****
$(topdir)/histfile.c $(topdir)/nls.c $(topdir)/search.c \
$(topdir)/shell.c $(topdir)/savestring.c $(topdir)/tilde.c \
$(topdir)/text.c $(topdir)/misc.c $(topdir)/compat.c \
! $(topdir)/mbutil.c
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
--- 122,128 ----
$(topdir)/histfile.c $(topdir)/nls.c $(topdir)/search.c \
$(topdir)/shell.c $(topdir)/savestring.c $(topdir)/tilde.c \
$(topdir)/text.c $(topdir)/misc.c $(topdir)/compat.c \
! $(topdir)/mbutil.c $(WCWIDTH_SRC)
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
*************** SHARED_OBJ = readline.so vi_mode.so funm
*** 129,135 ****
rltty.so complete.so bind.so isearch.so display.so signals.so \
util.so kill.so undo.so macro.so input.so callback.so terminal.so \
text.so nls.so misc.so xmalloc.so $(SHARED_HISTOBJ) $(SHARED_TILDEOBJ) \
! compat.so
##########################################################################
--- 136,142 ----
rltty.so complete.so bind.so isearch.so display.so signals.so \
util.so kill.so undo.so macro.so input.so callback.so terminal.so \
text.so nls.so misc.so xmalloc.so $(SHARED_HISTOBJ) $(SHARED_TILDEOBJ) \
! compat.so $(WCWIDTH_OBJ)
##########################################################################
*************** $(SHARED_HISTORY): $(SHARED_HISTOBJ) xma
*** 153,158 ****
--- 160,172 ----
$(RM) $@
$(SHOBJ_LD) ${SHOBJ_LDFLAGS} ${SHLIB_XLDFLAGS} -o $@ $(SHARED_HISTOBJ) xmalloc.so $(SHLIB_LIBS)
+ ifeq ($(HAVE_WCWIDTH), no)
+ $(WCWIDTH_OBJ): $(WCWIDTH_SRC)
+ $(RM) $@
+ $(SHOBJ_CC) -c $(CCFLAGS) $(SHOBJ_FLAGS) -o wcwidth.o $(WCWIDTH_SRC)
+ $(MV) wcwidth.o $@
+ endif
+
# Since tilde.c is shared between readline and bash, make sure we compile
# it with the right flags when it's built as part of readline
tilde.so: tilde.c
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: patch to add QNX NTO i386 support
2003-02-03 20:19 patch to add QNX NTO i386 support Kris Warkentin
@ 2003-02-04 7:23 ` Eli Zaretskii
2003-02-04 13:33 ` Kris Warkentin
2003-02-04 22:02 ` Andrew Cagney
2003-02-05 20:48 ` Mark Kettenis
2 siblings, 1 reply; 64+ messages in thread
From: Eli Zaretskii @ 2003-02-04 7:23 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb-patches
On Mon, 3 Feb 2003, Kris Warkentin wrote:
> I am submitting, on behalf of my employer QNX Software Systems Ltd., a patch
> against the current HEAD branch of gdb (as of Feb.3/2003 - see attachment).
> We already have copywrite assignment paperwork on file with the FSF.
I don't know if these patches will be accepted by The Powers That Be, but
if they will, you need to update gdb/config/djgpp/fnchange.lst to take
care of file-name clashes on 8+3 filesystems.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-04 7:23 ` Eli Zaretskii
@ 2003-02-04 13:33 ` Kris Warkentin
2003-02-04 13:53 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-04 13:33 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
> > I am submitting, on behalf of my employer QNX Software Systems Ltd., a
patch
> > against the current HEAD branch of gdb (as of Feb.3/2003 - see
attachment).
> > We already have copywrite assignment paperwork on file with the FSF.
>
> I don't know if these patches will be accepted by The Powers That Be, but
> if they will, you need to update gdb/config/djgpp/fnchange.lst to take
> care of file-name clashes on 8+3 filesystems.
Doh! I remember reading that in the coding guidelines too. It must have
slipped my mind. I'll look into it right away.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-04 13:33 ` Kris Warkentin
@ 2003-02-04 13:53 ` Kris Warkentin
2003-02-04 19:59 ` Eli Zaretskii
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-04 13:53 UTC (permalink / raw)
To: Kris Warkentin, Eli Zaretskii; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 371 bytes --]
> > I don't know if these patches will be accepted by The Powers That Be,
but
> > if they will, you need to update gdb/config/djgpp/fnchange.lst to take
> > care of file-name clashes on 8+3 filesystems.
>
> Doh! I remember reading that in the coding guidelines too. It must have
> slipped my mind. I'll look into it right away.
Okay, here's the patch.
cheers,
Kris
[-- Attachment #2: fnchange.diff --]
[-- Type: application/octet-stream, Size: 2278 bytes --]
*** src.orig/gdb/config/djgpp/fnchange.lst Fri Jan 31 15:43:54 2003
--- src/gdb/config/djgpp/fnchange.lst Tue Feb 4 08:46:56 2003
***************
*** 79,84 ****
--- 79,85 ----
@V@/gdb/armnbsd-nat.c @V@/gdb/armnbd-nat.c
@V@/gdb/armnbsd-tdep.c @V@/gdb/armnbd-tdep.c
@V@/gdb/c-exp.tab.c @V@/gdb/c-exp_tab.c
+ @V@/gdb/config/tm-qnxnto.h @V@/gdb/config/tm-qnx.h
@V@/gdb/config/alpha/alpha-osf1.mh @V@/gdb/config/alpha/alphosf1.mh
@V@/gdb/config/alpha/alpha-osf2.mh @V@/gdb/config/alpha/alphosf2.mh
@V@/gdb/config/alpha/alpha-osf3.mh @V@/gdb/config/alpha/alphosf3.mh
***************
*** 90,95 ****
--- 91,97 ----
@V@/gdb/config/i386/nm-i386v4.h @V@/gdb/config/i386/nm-v4.h
@V@/gdb/config/i386/nm-i386v42mp.h @V@/gdb/config/i386/nm-v42mp.h
@V@/gdb/config/i386/tm-i386mk.h @V@/gdb/config/i386/tm-mk.h
+ @V@/gdb/config/i386/tm-i386nto.h @V@/gdb/config/i386/tm-nto.h
@V@/gdb/config/i386/tm-i386sol2.h @V@/gdb/config/i386/tm-sol2.h
@V@/gdb/config/i386/tm-i386v42mp.h @V@/gdb/config/i386/tm-v42mp.h
@V@/gdb/config/i386/xm-i386mach.h @V@/gdb/config/i386/xm-mach.h
***************
*** 159,164 ****
--- 161,167 ----
@V@/gdb/mipsnbsd-tdep.c @V@/gdb/mipsnbtdep.c
@V@/gdb/ns32knbsd-nat.c @V@/gdb/ns32nb-nat.c
@V@/gdb/ns32knbsd-tdep.c @V@/gdb/ns32nb-tdep.c
+ @V@/gdb/nto-procfs.c @V@/gdb/nto-proc.c
@V@/gdb/objc-exp.tab.c @V@/gdb/objc-exp_tab.c
@V@/gdb/osf-share/cma_stack_int.h @V@/gdb/osf-share/cma_stkint.h
@V@/gdb/p-exp.tab.c @V@/gdb/p-exp_tab.c
***************
*** 174,179 ****
--- 177,184 ----
@V@/gdb/remote-est.c @V@/gdb/rmt-est.c
@V@/gdb/remote-mips.c @V@/gdb/emt-mips.c
@V@/gdb/remote-mm.c @V@/gdb/emt-mm.c
+ @V@/gdb/remote-nto.c @V@/gdb/rmt-nto.c
+ @V@/gdb/remote-nto-i386.c @V@/gdb/rmt-n386.c
@V@/gdb/remote-nrom.c @V@/gdb/rmt-nrom.c
@V@/gdb/remote-rdi.c @V@/gdb/rmt-rdi.c
@V@/gdb/remote-rdp.c @V@/gdb/rmt-rdp.c
***************
*** 187,192 ****
--- 192,198 ----
@V@/gdb/remote-vx960.c @V@/gdb/rmt-vx960.c
@V@/gdb/remote-vxmips.c @V@/gdb/rmt-vxmips.c
@V@/gdb/remote-vxsparc.c @V@/gdb/rmt-vxsparc.c
+ @V@/gdb/ser-ntopty.c @V@/gdb/sr-ntopty.c
@V@/gdb/sparclet-rom.c @V@/gdb/splet-rom.c
@V@/gdb/sparclet-stub.c @V@/gdb/splet-stub.c
@V@/gdb/sparcnbsd-nat.c @V@/gdb/spnb-nat.c
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-04 13:53 ` Kris Warkentin
@ 2003-02-04 19:59 ` Eli Zaretskii
2003-02-04 20:12 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Eli Zaretskii @ 2003-02-04 19:59 UTC (permalink / raw)
To: kewarken; +Cc: gdb-patches
> From: "Kris Warkentin" <kewarken@qnx.com>
> Date: Tue, 4 Feb 2003 08:55:08 -0500
>
> Okay, here's the patch.
Thanks.
However, I don't understand why did you include some of the files in
fnchange.lst: AFAICS they don't create any conflicts. For example:
> + @V@/gdb/config/tm-qnxnto.h @V@/gdb/config/tm-qnx.h
There's no other file in the gdb/config/ directory whose name will
clash with tm-qnxnto.h after truncation to 8+3 limits.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-04 19:59 ` Eli Zaretskii
@ 2003-02-04 20:12 ` Kris Warkentin
2003-02-05 5:50 ` Eli Zaretskii
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-04 20:12 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 713 bytes --]
> > Okay, here's the patch.
>
> Thanks.
>
> However, I don't understand why did you include some of the files in
> fnchange.lst: AFAICS they don't create any conflicts. For example:
>
> > + @V@/gdb/config/tm-qnxnto.h @V@/gdb/config/tm-qnx.h
>
> There's no other file in the gdb/config/ directory whose name will
> clash with tm-qnxnto.h after truncation to 8+3 limits.
That would be a lack of understanding on my part. I assumed we needed to
give aliases for any filename longer than 8+3. You're saying we just need
to be conscious of the autoconversion dos stuff. In that case, probably the
only ones I'd need to look at would be the remote-qnx* and the tm-i386nto.h.
Revised patch attached.
cheers,
Kris
[-- Attachment #2: fnchange.diff --]
[-- Type: application/octet-stream, Size: 1042 bytes --]
*** src.orig/gdb/config/djgpp/fnchange.lst Fri Jan 31 15:43:54 2003
--- src/gdb/config/djgpp/fnchange.lst Tue Feb 4 08:46:56 2003
***************
*** 90,95 ****
--- 91,97 ----
@V@/gdb/config/i386/nm-i386v4.h @V@/gdb/config/i386/nm-v4.h
@V@/gdb/config/i386/nm-i386v42mp.h @V@/gdb/config/i386/nm-v42mp.h
@V@/gdb/config/i386/tm-i386mk.h @V@/gdb/config/i386/tm-mk.h
+ @V@/gdb/config/i386/tm-i386nto.h @V@/gdb/config/i386/tm-nto.h
@V@/gdb/config/i386/tm-i386sol2.h @V@/gdb/config/i386/tm-sol2.h
@V@/gdb/config/i386/tm-i386v42mp.h @V@/gdb/config/i386/tm-v42mp.h
@V@/gdb/config/i386/xm-i386mach.h @V@/gdb/config/i386/xm-mach.h
***************
*** 174,179 ****
--- 177,184 ----
@V@/gdb/remote-est.c @V@/gdb/rmt-est.c
@V@/gdb/remote-mips.c @V@/gdb/emt-mips.c
@V@/gdb/remote-mm.c @V@/gdb/emt-mm.c
+ @V@/gdb/remote-nto.c @V@/gdb/rmt-nto.c
+ @V@/gdb/remote-nto-i386.c @V@/gdb/rmt-n386.c
@V@/gdb/remote-nrom.c @V@/gdb/rmt-nrom.c
@V@/gdb/remote-rdi.c @V@/gdb/rmt-rdi.c
@V@/gdb/remote-rdp.c @V@/gdb/rmt-rdp.c
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-04 20:12 ` Kris Warkentin
@ 2003-02-05 5:50 ` Eli Zaretskii
0 siblings, 0 replies; 64+ messages in thread
From: Eli Zaretskii @ 2003-02-05 5:50 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb-patches
On Tue, 4 Feb 2003, Kris Warkentin wrote:
> That would be a lack of understanding on my part. I assumed we needed to
> give aliases for any filename longer than 8+3. You're saying we just need
> to be conscious of the autoconversion dos stuff.
Yes, the file names are automatically truncated to 8+3 when the tarball
is unpacked on 8+3 filesystems. So only files that map to the same name
after this truncation should be considered. Also, file whose name
includes characters that DOS does not allow (like `+' in `gdb.c++')
should be mapped to something different.
> In that case, probably the
> only ones I'd need to look at would be the remote-qnx* and the tm-i386nto.h.
Yes.
> Revised patch attached.
Thanks.
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-03 20:19 patch to add QNX NTO i386 support Kris Warkentin
2003-02-04 7:23 ` Eli Zaretskii
@ 2003-02-04 22:02 ` Andrew Cagney
2003-02-05 1:29 ` Kris Warkentin
` (2 more replies)
2003-02-05 20:48 ` Mark Kettenis
2 siblings, 3 replies; 64+ messages in thread
From: Andrew Cagney @ 2003-02-04 22:02 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb-patches
Suggest separating the GDB stuff out (native, target, remote) and using
separate e-mail threads to discuss each.
> gdb/ChangeLog entry:
>
> 2003-03-02 Kris Warkentin kewarken@qnx.com
>
> * config/i386/i386nto.mt: New file
The MH_CFLAGS and XM_FILE flags should not be needed. Instead
gdb/configure should be able to handle this.
> * config/i386/nm-nto.h: New file
The file nm-nto.h should not be needed. Instead define it's only macro
local to remote-nto.c. (Disclaimer, you're breaking new ground with
this one. Some existing targets don't have xm-*.h files, but I think
you're first with the no-*.h file).
> * config/i386/nto.mh: New file
Yes, you need this, you've a native support.
> * config/i386/tm-i386nto.h: New file
The file tm-i386nto.h should not be needed. Instead, gdbarch handles
architecture specific issues. The only exception is with shared
libraries (as there is a bit of this that isn't yet multi-arched). If
nto has architecture specific features then create an i386-nto-tdep.c or
nto-tdep.c file (typically it ends up containing the sigtramp code).
> * config/i386/xm-nto.h: New file
The file xm-nto.h should not be needed. gdb/configure should be able to
handle all host specific problems.
> * config/tm-qnxnto.h: New file
> * configure.host: add gdb_host=nto
> * configure.tgt: add gdb_target=i386nto
> * nto-procfs.c: New file
Once the target stuff is sorted, please re-submit nto-procfs.c as a
separate patch.
> * nto-share/debug.h: New file
> * nto-share/dsmsgs.h: New file
> * remote-nto-i386.c: New file
> * remote-nto.c: New file
Can you expand on how these relate to each other?
> * ser-ntopty.c: New file
Hmm, is this specific to nto? Also, glancing through the code, how
different is this to the existing serial code. I'm wondering if the
file exists due to local fixes and not because it is needed.
--
Regarding coding standards.
Look through http://sources.redhat.com/gdb/current/ari/.
Anything listed under `Critical', `Code', or `Fixed' should be
addressed, also glance through `info'. I immediatly noticed `PARAMS()'
(GDB uses ISO C) `//' (C, not C++) and `extern' in C files (always bad).
All files need a proper (C) notice at the top. The year should include
`2003' since this is the year that the FSF will first include it.
Run all the new files through ./gdb_indent.sh.
Audit all `#ifdef ...' many of those macro's have been deleted (I
noticed TARGET_BYTE_ORDER_SELECTABLE'.
Many of the functions have `^qnx_' prefixes. Should they be given
`^nto_' prefixes?
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: patch to add QNX NTO i386 support
2003-02-04 22:02 ` Andrew Cagney
@ 2003-02-05 1:29 ` Kris Warkentin
2003-02-05 2:40 ` Andrew Cagney
2003-02-05 2:55 ` Andrew Cagney
2003-02-05 17:15 ` Kris Warkentin
2003-02-07 1:48 ` Kris Warkentin
2 siblings, 2 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-05 1:29 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
> Suggest separating the GDB stuff out (native, target, remote) and using
> separate e-mail threads to discuss each.
I was going to but it's easier this way. The native nto-procfs.c makes use
of some of the code in remote-qnx.c and remote-qnx-<target>.c (we still have
four more targets.) If you really feel it's necessary I could do the work
but I had started on it and concluded it would either lead to a lot of
duplicated code or an explosion of files.
> > gdb/ChangeLog entry:
> >
> > 2003-03-02 Kris Warkentin kewarken@qnx.com
> >
> > * config/i386/i386nto.mt: New file
>
> The MH_CFLAGS and XM_FILE flags should not be needed. Instead
> gdb/configure should be able to handle this.
Noted.
> > * config/i386/nm-nto.h: New file
>
> The file nm-nto.h should not be needed. Instead define it's only macro
> local to remote-nto.c. (Disclaimer, you're breaking new ground with
> this one. Some existing targets don't have xm-*.h files, but I think
> you're first with the no-*.h file).
Not sure what you mean by no-*.h but I see what you mean about some of the
short files.
> > * config/i386/nto.mh: New file
>
> Yes, you need this, you've a native support.
Cool. I got ONE thing right. ;-)
> > * config/i386/tm-i386nto.h: New file
>
> The file tm-i386nto.h should not be needed. Instead, gdbarch handles
> architecture specific issues. The only exception is with shared
> libraries (as there is a bit of this that isn't yet multi-arched). If
> nto has architecture specific features then create an i386-nto-tdep.c or
> nto-tdep.c file (typically it ends up containing the sigtramp code).
Okay. I'll look into this.
> > * config/i386/xm-nto.h: New file
>
> The file xm-nto.h should not be needed. gdb/configure should be able to
> handle all host specific problems.
Okay.
> > * config/tm-qnxnto.h: New file
> > * configure.host: add gdb_host=nto
> > * configure.tgt: add gdb_target=i386nto
> > * nto-procfs.c: New file
>
> Once the target stuff is sorted, please re-submit nto-procfs.c as a
> separate patch.
>
> > * nto-share/debug.h: New file
> > * nto-share/dsmsgs.h: New file
>
> > * remote-nto-i386.c: New file
> > * remote-nto.c: New file
>
> Can you expand on how these relate to each other?
Do you want details in the ChangeLog entry other than 'new file'? I wasn't
sure.
FYI:
debug.h has all the procfs stuff needed for all our targets.
dsmsgs.h has our remote pdebug debugging protocol definition.
remote-nto.c has all generic code for remote debugging plus code shared by
local and remote.
remote-nto-<cpu>.c is any specific code for a particular cpu. This can also
be shared by local and remote.
> > * ser-ntopty.c: New file
>
> Hmm, is this specific to nto? Also, glancing through the code, how
> different is this to the existing serial code. I'm wondering if the
> file exists due to local fixes and not because it is needed.
Not 100 percent sure. That's one of the files that I inherited. It's
possible that it's not needed anymore so I'll have to look a little deeper
and get back to you.
> Regarding coding standards.
>
> Look through http://sources.redhat.com/gdb/current/ari/.
> Anything listed under `Critical', `Code', or `Fixed' should be
> addressed, also glance through `info'. I immediatly noticed `PARAMS()'
> (GDB uses ISO C) `//' (C, not C++) and `extern' in C files (always bad).
Ah...lint. ;-)
> All files need a proper (C) notice at the top. The year should include
> `2003' since this is the year that the FSF will first include it.
Okay.
> Run all the new files through ./gdb_indent.sh.
Did that.
> Audit all `#ifdef ...' many of those macro's have been deleted (I
> noticed TARGET_BYTE_ORDER_SELECTABLE'.
Okay.
> Many of the functions have `^qnx_' prefixes. Should they be given
> `^nto_' prefixes?
Yeah. All the original code and filenames used 'qnx' and I partially
refactored to 'nto' since it seemed more appropriate to use the OS rather
than the company. I suppose it wouldn't hurt to do the rest of it.
Thanks for all the feedback. You've certainly given me some more work to
keep me occupied. You're probably right about some of the code being
redundant. Much of this stuff was brought forward from gdb 4.17 so there
may be many more redundancies. (you should have seen how much we had ripped
out already ;-)
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 1:29 ` Kris Warkentin
@ 2003-02-05 2:40 ` Andrew Cagney
2003-02-05 2:59 ` Andrew Cagney
2003-02-05 2:55 ` Andrew Cagney
1 sibling, 1 reply; 64+ messages in thread
From: Andrew Cagney @ 2003-02-05 2:40 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb-patches
> Suggest separating the GDB stuff out (native, target, remote) and using
>> separate e-mail threads to discuss each.
>
>
> I was going to but it's easier this way.
It isn't for the person doing the review -> the easier the reviewer's
life is, the quicker (well, ok, in theory :-/) the reviewer should be.
I'd strongly focus on getting the cross debugger
(--target=i386-unknown-nto) integrated into GDB, and then worry above
the native.
> The native nto-procfs.c makes use
> of some of the code in remote-qnx.c and remote-qnx-<target>.c (we
still have
> four more targets.) If you really feel it's necessary I could do the
work
> but I had started on it and concluded it would either lead to a lot of
> duplicated code or an explosion of files.
That looks like a design problem. The common code should likely be
moved to something like nto-tdep.c. What exactly is common?
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 2:40 ` Andrew Cagney
@ 2003-02-05 2:59 ` Andrew Cagney
2003-02-05 12:31 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Andrew Cagney @ 2003-02-05 2:59 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Kris Warkentin, gdb-patches
> Suggest separating the GDB stuff out (native, target, remote) and using
> separate e-mail threads to discuss each.
>
>
> I was going to but it's easier this way.
>
> It isn't for the person doing the review -> the easier the reviewer's life is, the quicker (well, ok, in theory :-/) the reviewer should be. I'd strongly focus on getting the cross debugger (--target=i386-unknown-nto) integrated into GDB, and then worry above the native.
>
>> The native nto-procfs.c makes use
>> of some of the code in remote-qnx.c and remote-qnx-<target>.c (we still have
>> four more targets.) If you really feel it's necessary I could do the work
>> but I had started on it and concluded it would either lead to a lot of
>> duplicated code or an explosion of files.
>
> That looks like a design problem. The common code should likely be moved to something like nto-tdep.c. What exactly is common?
Er, s/design/structural/
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 2:59 ` Andrew Cagney
@ 2003-02-05 12:31 ` Kris Warkentin
0 siblings, 0 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-05 12:31 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
> > Suggest separating the GDB stuff out (native, target, remote) and using
> > separate e-mail threads to discuss each.
> >
> >
> > I was going to but it's easier this way.
> >
> > It isn't for the person doing the review -> the easier the reviewer's
life is, the quicker (well, ok, in theory :-/) the reviewer should be. I'd
strongly focus on getting the cross debugger (--target=i386-unknown-nto)
integrated into GDB, and then worry above the native.
> >
> >> The native nto-procfs.c makes use
> >> of some of the code in remote-qnx.c and remote-qnx-<target>.c (we still
have
> >> four more targets.) If you really feel it's necessary I could do the
work
> >> but I had started on it and concluded it would either lead to a lot of
> >> duplicated code or an explosion of files.
> >
> > That looks like a design problem. The common code should likely be
moved to something like nto-tdep.c. What exactly is common?
>
> Er, s/design/structural/
Yeah... That would have implied some design in the first place. ;-) This
port is a totally organic thing, grown in the fertilizer of many developers
over the years. That's what makes it so much fun to clean up. I'm trying
to make a snarled, weedy garden into a bonzai.
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 1:29 ` Kris Warkentin
2003-02-05 2:40 ` Andrew Cagney
@ 2003-02-05 2:55 ` Andrew Cagney
1 sibling, 0 replies; 64+ messages in thread
From: Andrew Cagney @ 2003-02-05 2:55 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb-patches
>> The file nm-nto.h should not be needed. Instead define it's only macro
>> local to remote-nto.c. (Disclaimer, you're breaking new ground with
>> this one. Some existing targets don't have xm-*.h files, but I think
>> you're first with the no-*.h file).
>
>
> Not sure what you mean by no-*.h but I see what you mean about some of the
> short files.
tipo. s/no/nm/.
>> > * config/i386/nto.mh: New file
>
>>
>> Yes, you need this, you've a native support.
>
>
> Cool. I got ONE thing right. ;-)
GDB's things to do today includes break the .mh files into .mh, .mn.
At present what you see doesn't make much sense :-)
>> Can you expand on how these relate to each other?
>
>
> Do you want details in the ChangeLog entry other than 'new file'? I wasn't
> sure.
Not really. A full of contributors doesn't hurt. However, from the
FSF's point of view, the file only comes into existance when it is
approved - it has no prior history.
> Yeah. All the original code and filenames used 'qnx' and I partially
> refactored to 'nto' since it seemed more appropriate to use the OS rather
> than the company. I suppose it wouldn't hurt to do the rest of it.
I think your decision to use nto was a good one - definitly more
logical. Yes, now before things get committed, is the time to finish it
off with s/qnx/nto/.
> Thanks for all the feedback. You've certainly given me some more work to
> keep me occupied. You're probably right about some of the code being
> redundant. Much of this stuff was brought forward from gdb 4.17 so there
> may be many more redundancies. (you should have seen how much we had ripped
> out already ;-)
SNAFU.
Every branched GDB I've seen has breed superfulous[sp] changes - you
should see the original version of the interp patch before Elena and
then I attacked it with avengence ...
Much thanks for going through that code and stripping the unnecessary
stuff out. It is much easier for all concerned, saving frustration on
both ends - the reviewer having to reject junk code out of hand, and the
contributor wondering why their mega jumbo patch (hey it works right?
:-) isn't simply accepted.
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-04 22:02 ` Andrew Cagney
2003-02-05 1:29 ` Kris Warkentin
@ 2003-02-05 17:15 ` Kris Warkentin
2003-02-05 18:46 ` Andrew Cagney
2003-02-07 1:48 ` Kris Warkentin
2 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-05 17:15 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
> > * ser-ntopty.c: New file
>
> Hmm, is this specific to nto? Also, glancing through the code, how
> different is this to the existing serial code. I'm wondering if the
> file exists due to local fixes and not because it is needed.
It took me a few minutes to remember what this was. When we originally
ported gdb, the only way it worked was using the remote pdebug protocol,
even on the local machine (we had no native procfs port). So, you would
issue a command 'target qnx pty' (instead of 'target qnx <serial port>' or
'target qnx '<host>:<port>') and it would automatically spawn the pdebug
server on a pty and connect to it. Since we've got a native procfs port
working, this is by and large redundant so I'll take it out. It was only
there for legacy support and because it was sometimes useful to compare the
procfs vs. the pdebug to make sure things are working. Since the equivalent
can be accomplished with 'target qnx localhost:<port>', I think it's time
for ser-ntopty.c to die.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 17:15 ` Kris Warkentin
@ 2003-02-05 18:46 ` Andrew Cagney
0 siblings, 0 replies; 64+ messages in thread
From: Andrew Cagney @ 2003-02-05 18:46 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb-patches
>> > * ser-ntopty.c: New file
>
>>
>> Hmm, is this specific to nto? Also, glancing through the code, how
>> different is this to the existing serial code. I'm wondering if the
>> file exists due to local fixes and not because it is needed.
>
>
> It took me a few minutes to remember what this was. When we originally
> ported gdb, the only way it worked was using the remote pdebug protocol,
> even on the local machine (we had no native procfs port). So, you would
> issue a command 'target qnx pty' (instead of 'target qnx <serial port>' or
> 'target qnx '<host>:<port>') and it would automatically spawn the pdebug
> server on a pty and connect to it. Since we've got a native procfs port
> working, this is by and large redundant so I'll take it out. It was only
> there for legacy support and because it was sometimes useful to compare the
> procfs vs. the pdebug to make sure things are working. Since the equivalent
> can be accomplished with 'target qnx localhost:<port>', I think it's time
> for ser-ntopty.c to die.
Ah. There is also now ser-pipe.c vis:
(gdb) target remote |program
A `ser-pty' might also be useful but that isn't specific to nto. I've
no idea on the syntax (... pty:...).
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-04 22:02 ` Andrew Cagney
2003-02-05 1:29 ` Kris Warkentin
2003-02-05 17:15 ` Kris Warkentin
@ 2003-02-07 1:48 ` Kris Warkentin
2003-02-07 19:22 ` Mark Kettenis
2 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-07 1:48 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
> > * config/i386/nm-nto.h: New file
>
> The file nm-nto.h should not be needed. Instead define it's only macro
> local to remote-nto.c. (Disclaimer, you're breaking new ground with
> this one. Some existing targets don't have xm-*.h files, but I think
> you're first with the no-*.h file).
>
> > * config/i386/nto.mh: New file
>
> Yes, you need this, you've a native support.
When I got rid of nm-nto.h and took out 'NAT_FILE=nm-nto.h' from nto.mh, all
of a sudden I wasn't building a native compiler anymore. Looks like
configure uses the presence of a native file to determine whether to build a
self hosted debugger or not. If I just 'touch nm-nto.h' and reconfigure, I
build a native gdb. Any suggestions? I was thinking that I could perhaps
point to one of my other headers and then share some remote and native
definitions.
As long as I'm asking questions, below is what I've reduced our tm-i386nto.h
file to. Is it absolutely verboten to have this file? There are a few
handy definitions there like EXTRA_GDBINIT and so on that we like to define
per target. Also, I couldn't see how to get rid of the solib stuff. Is
there some place else I can put these definitions?
cheers,
Kris
#ifndef TM_I386QNX_H
#define TM_I386QNX_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"
#define __QNXTARGET__
#define QNX_TARGET_CPUTYPE CPUTYPE_X86
/* After a watchpoint trap, the PC points to the instruction after
the one that caused the trap. Therefore we don't need to step over it.
But we do need to reset the status register to avoid another trap. */
#define HAVE_CONTINUABLE_WATCHPOINT
/* default processor for search path for libs */
#define SOLIB_PROCESSOR "x86"
/* Use .ntox86-gdbinit */
#define EXTRA_GDBINIT_FILENAME ".ntox86-gdbinit"
#define HANDLE_SVR4_EXEC_EMULATORS 1
#include "solib.h" /* shared lib support */
#endif /* ifndef TM_I386QNX_H */
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-07 1:48 ` Kris Warkentin
@ 2003-02-07 19:22 ` Mark Kettenis
2003-02-07 20:08 ` Kris Warkentin
` (2 more replies)
0 siblings, 3 replies; 64+ messages in thread
From: Mark Kettenis @ 2003-02-07 19:22 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Andrew Cagney, gdb-patches
"Kris Warkentin" <kewarken@qnx.com> writes:
> As long as I'm asking questions, below is what I've reduced our tm-i386nto.h
> file to. Is it absolutely verboten to have this file?
The goal is to get rid of the tm.h files. Adding new stuff to tm.h
files that will be difficult to get rid of would be rather
counterproductive. As Andrew already mentioned, having the shared
library stuff in your tm-i386nto.h file would be acceptable; it
represents a problem we'll have to solve anyway so it doesn't burden
us with an additional problem. The real-time signal stuff in
tm-qnxnto.h is fine too for similar reasons.
> There are a few handy definitions there like EXTRA_GDBINIT and so on
> that we like to define per target. Also, I couldn't see how to get
> rid of the solib stuff. Is there some place else I can put these
> definitions?
See my comments below.
> cheers,
>
> Kris
> #ifndef TM_I386QNX_H
> #define TM_I386QNX_H 1
Please use TM_I386NTO_H if your file is called tm-i386nto.h.
>
> /* Pick up most of what we need from the generic i386 target include file.
> */
>
> #include "i386/tm-i386.h"
> #include "tm-qnxnto.h"
The tm-qnxnto.h will need to be considered too. See even further below.
> #define __QNXTARGET__
> #define QNX_TARGET_CPUTYPE CPUTYPE_X86
These should really be avoided here. Since they're only used in files listed in NATDEPFILES, these definitions could be moved to your nm.h file.
> /* After a watchpoint trap, the PC points to the instruction after
> the one that caused the trap. Therefore we don't need to step over it.
> But we do need to reset the status register to avoid another trap. */
> #define HAVE_CONTINUABLE_WATCHPOINT
Hmm, this poses an interesting problem. The other i386 targets have
this in their nm.h file, since they consider hardware watchpoints as a
native-only feature. However, this isn't necessarily right since we
might support hardware breakpoints via the remote protocol. If you
can live with the native-only approach, please move this to your nm.h
file. Otherwise we might need to multi-arch this definition.
> /* default processor for search path for libs */
> #define SOLIB_PROCESSOR "x86"
I think the feature that you need this define for is interesting, but
this file is the wrong place to set it. It'd be better to implement
this feature in a less QNX-specific way, and let configure handle the
necessary configuration details.
> /* Use .ntox86-gdbinit */
> #define EXTRA_GDBINIT_FILENAME ".ntox86-gdbinit"
Likewise.
> #define HANDLE_SVR4_EXEC_EMULATORS 1
> #include "solib.h" /* shared lib support */
Including solib.h is fine. However I wonder why you need
HANDLE_SVR4_EXEC_EMULATORS. AFAIK this deals with Solaris BCP
(running SunOS 4 a.out files on Solaris 2 a.k.a. SunOS 5). What is
its relevance on QNX? Could this be the reason that you need to set
SOLIB_BKPT_NAME?
> #endif /* ifndef TM_I386QNX_H */
Here is the meat from tm-qnxnto.h that needs some discussion.
Please add protection against multiple inclusion to this file.
+ #define __QNXTARGET__
Same story as above.
+ #include "tm-sysv4.h"
Shared library stoof so OK.
+ #define FIND_NEW_THREADS qnx_find_new_threads
+ void qnx_find_new_threads PARAMS ((void));
FIND_NEW_THREADS has been obsoleted quite some time ago.
+ #define target_pid_to_str(PTID) \
+ qnx_pid_to_str(PTID)
+ extern char *qnx_pid_to_str PARAMS ((ptid_t ptid));
This is not quite right. I'm afraid that getting your target to debug
multi-threaded programs will incolve some serious work.
+ /* 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"}
This signal stuff is OK for now.
+ /* See solib-svr4.c
+ * This works around a problem with static binaries. An internal breakpoint
+ * is set on _start but for whatever reason, gdb doesn't handle it properly
+ * and claims a SIGTRAP has been raised on the inferior. If we move the
+ * shlib_event breakpoint ahead to main (this already happened by default
+ * on sh for some reason), then it works. FIXME: we need to discover why
+ * gdb isn't handling breakpoints properly at the early stages of execution. */
+ #define SOLIB_BKPT_NAME "main"
Hmm, we shouldn't need any shlib_event breakpoint for static
binaries... This workaround should be OK for now. The style of the
comment is violating our coding standards though; please remove the *
at the beginning of the lines.
Mark
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: patch to add QNX NTO i386 support
2003-02-07 19:22 ` Mark Kettenis
@ 2003-02-07 20:08 ` Kris Warkentin
2003-02-07 21:59 ` Andrew Cagney
2003-02-12 22:18 ` patch to add QNX NTO i386 support Kris Warkentin
2003-02-13 21:56 ` Kris Warkentin
2 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-07 20:08 UTC (permalink / raw)
To: Mark Kettenis; +Cc: Andrew Cagney, gdb-patches
> "Kris Warkentin" <kewarken@qnx.com> writes:
>
> > As long as I'm asking questions, below is what I've reduced our
tm-i386nto.h
> > file to. Is it absolutely verboten to have this file?
>
> The goal is to get rid of the tm.h files. Adding new stuff to tm.h
> files that will be difficult to get rid of would be rather
> counterproductive. As Andrew already mentioned, having the shared
> library stuff in your tm-i386nto.h file would be acceptable; it
> represents a problem we'll have to solve anyway so it doesn't burden
> us with an additional problem. The real-time signal stuff in
> tm-qnxnto.h is fine too for similar reasons.
Okay.
<snip>
> > #define __QNXTARGET__
> > #define QNX_TARGET_CPUTYPE CPUTYPE_X86
>
> These should really be avoided here. Since they're only used in files
listed in NATDEPFILES, these definitions could be moved to your nm.h file.
Yes, you're right. Since I've separated the native and remote stuff
properly, this will work.
>
> > /* After a watchpoint trap, the PC points to the instruction after
> > the one that caused the trap. Therefore we don't need to step over
it.
> > But we do need to reset the status register to avoid another trap.
*/
> > #define HAVE_CONTINUABLE_WATCHPOINT
>
> Hmm, this poses an interesting problem. The other i386 targets have
> this in their nm.h file, since they consider hardware watchpoints as a
> native-only feature. However, this isn't necessarily right since we
> might support hardware breakpoints via the remote protocol. If you
> can live with the native-only approach, please move this to your nm.h
> file. Otherwise we might need to multi-arch this definition.
Okay, file that under TODO along with the solib stuff. We have hardware
breakpoints on all our remote targets that support them.
> > /* default processor for search path for libs */
> > #define SOLIB_PROCESSOR "x86"
>
> I think the feature that you need this define for is interesting, but
> this file is the wrong place to set it. It'd be better to implement
> this feature in a less QNX-specific way, and let configure handle the
> necessary configuration details.
>
> > /* Use .ntox86-gdbinit */
> > #define EXTRA_GDBINIT_FILENAME ".ntox86-gdbinit"
>
> Likewise.
So something like adding an extra -D at configure time?
> > #define HANDLE_SVR4_EXEC_EMULATORS 1
> > #include "solib.h" /* shared lib support */
>
> Including solib.h is fine. However I wonder why you need
> HANDLE_SVR4_EXEC_EMULATORS. AFAIK this deals with Solaris BCP
> (running SunOS 4 a.out files on Solaris 2 a.k.a. SunOS 5). What is
> its relevance on QNX? Could this be the reason that you need to set
> SOLIB_BKPT_NAME?
I'm not sure the legacy behind this. All I know is that if it isn't
defined, we don't find the linker entry point in our libc. I can look
further into it. The SOLIB_BKPT_NAME worked around an issue with statically
linked binaries. I never chased it further than coming up with the
workaround. You have some ideas?
> Here is the meat from tm-qnxnto.h that needs some discussion.
I cleaned this file yesterday. There's basically nothing left but the
signal stuff.
> Please add protection against multiple inclusion to this file.
Yes. Doh.
> + #define __QNXTARGET__
>
> Same story as above.
gone
> FIND_NEW_THREADS has been obsoleted quite some time ago.
I had already removed it. This refactoring stuff is great. Our port is
getting really clean.
> + #define target_pid_to_str(PTID) \
> + qnx_pid_to_str(PTID)
> + extern char *qnx_pid_to_str PARAMS ((ptid_t ptid));
>
> This is not quite right. I'm afraid that getting your target to debug
> multi-threaded programs will incolve some serious work.
Gone. Also would have been changed to nto_pid_to_str.
> + /* See solib-svr4.c
> + * This works around a problem with static binaries. An internal
breakpoint
> + * is set on _start but for whatever reason, gdb doesn't handle it
properly
> + * and claims a SIGTRAP has been raised on the inferior. If we move the
> + * shlib_event breakpoint ahead to main (this already happened by
default
> + * on sh for some reason), then it works. FIXME: we need to discover
why
> + * gdb isn't handling breakpoints properly at the early stages of
execution. */
> + #define SOLIB_BKPT_NAME "main"
>
> Hmm, we shouldn't need any shlib_event breakpoint for static
> binaries... This workaround should be OK for now. The style of the
> comment is violating our coding standards though; please remove the *
> at the beginning of the lines.
I thought I had run indent on all the files. I might have missed
tm-qnxnto.h. I've got a FIXME in there for future reference. There's
definitely something up with our solib stuff as you can see but I don't
completely understand all the issues yet.
Thank you very much. I've been more productive the last couple days than I
have in quite a while thanks to your and Andrew's help.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-07 20:08 ` Kris Warkentin
@ 2003-02-07 21:59 ` Andrew Cagney
2003-02-11 18:11 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Andrew Cagney @ 2003-02-07 21:59 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Mark Kettenis, gdb-patches
> /* After a watchpoint trap, the PC points to the instruction after
>> > the one that caused the trap. Therefore we don't need to step over
>
> it.
>
>> > But we do need to reset the status register to avoid another trap.
>
> */
>
>> > #define HAVE_CONTINUABLE_WATCHPOINT
>
>>
>> Hmm, this poses an interesting problem. The other i386 targets have
>> this in their nm.h file, since they consider hardware watchpoints as a
>> native-only feature. However, this isn't necessarily right since we
>> might support hardware breakpoints via the remote protocol. If you
>> can live with the native-only approach, please move this to your nm.h
>> file. Otherwise we might need to multi-arch this definition.
>
>
> Okay, file that under TODO along with the solib stuff. We have hardware
> breakpoints on all our remote targets that support them.
Just FYI, this needs to be added to the target vector (target.h) and not
the architecture vector.
For examples, see STOPPED_BY_WATCHPOINT et.al. A bit of manipulation of
the existing nm-*.h files will be needed - have them define the value as 1.
Can you please submit a separate patch that does just this.
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-07 21:59 ` Andrew Cagney
@ 2003-02-11 18:11 ` Kris Warkentin
2003-02-11 18:41 ` patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-11 18:11 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Mark Kettenis, gdb-patches
Hi Andrew,
Sorry it took so long to reply - I took a couple days to do a port of a
vxworks lib for a BSP we're working on.
Question: can I make any assumption about the initialization of the
target_ops vector? It looks like infrun.c wants HAVE_CONTINUABLE_BREAKPOINT
to default to zero but I didn't see anywhere int target.[ch] that ops were
being initialized.
cheers,
Kris
> > /* After a watchpoint trap, the PC points to the instruction after
> >> > the one that caused the trap. Therefore we don't need to step
over
> >
> > it.
> >
> >> > But we do need to reset the status register to avoid another trap.
> >
> > */
> >
> >> > #define HAVE_CONTINUABLE_WATCHPOINT
> >
> >>
> >> Hmm, this poses an interesting problem. The other i386 targets have
> >> this in their nm.h file, since they consider hardware watchpoints as a
> >> native-only feature. However, this isn't necessarily right since we
> >> might support hardware breakpoints via the remote protocol. If you
> >> can live with the native-only approach, please move this to your nm.h
> >> file. Otherwise we might need to multi-arch this definition.
> >
> >
> > Okay, file that under TODO along with the solib stuff. We have hardware
> > breakpoints on all our remote targets that support them.
>
> Just FYI, this needs to be added to the target vector (target.h) and not
> the architecture vector.
>
> For examples, see STOPPED_BY_WATCHPOINT et.al. A bit of manipulation of
> the existing nm-*.h files will be needed - have them define the value as
1.
>
> Can you please submit a separate patch that does just this.
>
> Andrew
>
>
>
^ permalink raw reply [flat|nested] 64+ messages in thread
* patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops
2003-02-11 18:11 ` Kris Warkentin
@ 2003-02-11 18:41 ` Kris Warkentin
0 siblings, 0 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-11 18:41 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Mark Kettenis, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 2651 bytes --]
Probably easier if I just give a diff for you to comment on.
Changelog Entry:
2003-02-11 Kris Warkentin kewarken@qnx.com
* target.h: Add to_have_continuable_watchpoint to struct target_ops.
Initialize HAVE_CONTINUABLE_WATCHPOINT.
* target.c: update_current_target(): Add to_have_continuable_watchpoint.
* infrun.c: remove initialization of HAVE_CONTINUABLE_WATCHPOINT.
* config/i386/nm-i386.h: Change HAVE_CONTINUABLE_WATCHPOINT defines to
1.
* config/i386/nm-i386sco5.h: ditto
* config/i386/nm-i386sol2.h: ditto
* config/s390/nm-linux.h: ditto
* config/sparc/nm-sun4sol2.h: ditto
cheers,
Kris
----- Original Message -----
From: "Kris Warkentin" <kewarken@qnx.com>
To: "Andrew Cagney" <ac131313@redhat.com>
Cc: "Mark Kettenis" <kettenis@chello.nl>; <gdb-patches@sources.redhat.com>
Sent: Tuesday, February 11, 2003 1:11 PM
Subject: Re: patch to add QNX NTO i386 support
> Hi Andrew,
>
> Sorry it took so long to reply - I took a couple days to do a port of a
> vxworks lib for a BSP we're working on.
>
> Question: can I make any assumption about the initialization of the
> target_ops vector? It looks like infrun.c wants
HAVE_CONTINUABLE_BREAKPOINT
> to default to zero but I didn't see anywhere int target.[ch] that ops were
> being initialized.
>
> cheers,
>
> Kris
>
> > > /* After a watchpoint trap, the PC points to the instruction after
> > >> > the one that caused the trap. Therefore we don't need to step
> over
> > >
> > > it.
> > >
> > >> > But we do need to reset the status register to avoid another
trap.
> > >
> > > */
> > >
> > >> > #define HAVE_CONTINUABLE_WATCHPOINT
> > >
> > >>
> > >> Hmm, this poses an interesting problem. The other i386 targets have
> > >> this in their nm.h file, since they consider hardware watchpoints as
a
> > >> native-only feature. However, this isn't necessarily right since we
> > >> might support hardware breakpoints via the remote protocol. If you
> > >> can live with the native-only approach, please move this to your nm.h
> > >> file. Otherwise we might need to multi-arch this definition.
> > >
> > >
> > > Okay, file that under TODO along with the solib stuff. We have
hardware
> > > breakpoints on all our remote targets that support them.
> >
> > Just FYI, this needs to be added to the target vector (target.h) and not
> > the architecture vector.
> >
> > For examples, see STOPPED_BY_WATCHPOINT et.al. A bit of manipulation of
> > the existing nm-*.h files will be needed - have them define the value as
> 1.
> >
> > Can you please submit a separate patch that does just this.
> >
> > Andrew
> >
> >
> >
>
>
[-- Attachment #2: contin.diff --]
[-- Type: application/octet-stream, Size: 5709 bytes --]
Index: config/i386/nm-i386.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nm-i386.h,v
retrieving revision 1.3
diff -u -r1.3 nm-i386.h
--- config/i386/nm-i386.h 4 Jul 2002 12:32:29 -0000 1.3
+++ config/i386/nm-i386.h 11 Feb 2003 18:31:35 -0000
@@ -93,7 +93,7 @@
one that caused the trap. Therefore we don't need to step over it.
But we do need to reset the status register to avoid another trap. */
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
#define STOPPED_BY_WATCHPOINT(W) (i386_stopped_data_address () != 0)
Index: config/i386/nm-i386sco5.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nm-i386sco5.h,v
retrieving revision 1.3
diff -u -r1.3 nm-i386sco5.h
--- config/i386/nm-i386sco5.h 18 Aug 2002 22:23:32 -0000 1.3
+++ config/i386/nm-i386sco5.h 11 Feb 2003 18:31:35 -0000
@@ -63,7 +63,7 @@
/* After a watchpoint trap, the PC points to the instruction which
caused the trap. But we can continue over it without disabling the
trap. */
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
#define HAVE_STEPPABLE_WATCHPOINT
#define STOPPED_BY_WATCHPOINT(W) \
Index: config/i386/nm-i386sol2.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nm-i386sol2.h,v
retrieving revision 1.7
diff -u -r1.7 nm-i386sol2.h
--- config/i386/nm-i386sol2.h 5 Jun 2002 19:18:19 -0000 1.7
+++ config/i386/nm-i386sol2.h 11 Feb 2003 18:31:35 -0000
@@ -32,7 +32,7 @@
/* When a hardware watchpoint fires off the PC will be left at the
instruction following the one which caused the watchpoint.
It will *NOT* be necessary for GDB to step over the watchpoint. */
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
/* Solaris x86 2.6 and 2.7 targets have a kernel bug when stepping
over an instruction that causes a page fault without triggering
Index: config/s390/nm-linux.h
===================================================================
RCS file: /cvs/src/src/gdb/config/s390/nm-linux.h,v
retrieving revision 1.5
diff -u -r1.5 nm-linux.h
--- config/s390/nm-linux.h 24 Feb 2002 22:56:06 -0000 1.5
+++ config/s390/nm-linux.h 11 Feb 2003 18:31:35 -0000
@@ -51,7 +51,7 @@
/* WATCHPOINT SPECIFIC STUFF */
#define TARGET_HAS_HARDWARE_WATCHPOINTS
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
#define target_insert_watchpoint(addr, len, type) \
s390_insert_watchpoint (PIDGET (inferior_ptid), addr, len, type)
Index: config/sparc/nm-sun4sol2.h
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/nm-sun4sol2.h,v
retrieving revision 1.9
diff -u -r1.9 nm-sun4sol2.h
--- config/sparc/nm-sun4sol2.h 14 Nov 2002 00:25:05 -0000 1.9
+++ config/sparc/nm-sun4sol2.h 11 Feb 2003 18:31:35 -0000
@@ -51,7 +51,7 @@
/* When a hardware watchpoint fires off the PC will be left at the
instruction following the one which caused the watchpoint.
It will *NOT* be necessary for GDB to step over the watchpoint. */
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
extern int procfs_stopped_by_watchpoint (ptid_t);
#define STOPPED_BY_WATCHPOINT(W) \
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.96
diff -u -r1.96 infrun.c
--- infrun.c 31 Jan 2003 15:22:57 -0000 1.96
+++ infrun.c 11 Feb 2003 18:31:36 -0000
@@ -226,13 +226,6 @@
#define HAVE_STEPPABLE_WATCHPOINT 1
#endif
-#ifndef HAVE_CONTINUABLE_WATCHPOINT
-#define HAVE_CONTINUABLE_WATCHPOINT 0
-#else
-#undef HAVE_CONTINUABLE_WATCHPOINT
-#define HAVE_CONTINUABLE_WATCHPOINT 1
-#endif
-
#ifndef CANNOT_STEP_HW_WATCHPOINTS
#define CANNOT_STEP_HW_WATCHPOINTS 0
#else
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.49
diff -u -r1.49 target.c
--- target.c 19 Jan 2003 04:06:46 -0000 1.49
+++ target.c 11 Feb 2003 18:31:37 -0000
@@ -573,6 +573,7 @@
INHERIT (to_remove_watchpoint, t);
INHERIT (to_stopped_data_address, t);
INHERIT (to_stopped_by_watchpoint, t);
+ INHERIT (to_have_continuable_watchpoint, t);
INHERIT (to_region_size_ok_for_hw_watchpoint, t);
INHERIT (to_terminal_init, t);
INHERIT (to_terminal_inferior, t);
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.35
diff -u -r1.35 target.h
--- target.h 19 Jan 2003 04:06:46 -0000 1.35
+++ target.h 11 Feb 2003 18:31:37 -0000
@@ -256,6 +256,7 @@
int (*to_remove_watchpoint) (CORE_ADDR, int, int);
int (*to_insert_watchpoint) (CORE_ADDR, int, int);
int (*to_stopped_by_watchpoint) (void);
+ int to_have_continuable_watchpoint;
CORE_ADDR (*to_stopped_data_address) (void);
int (*to_region_size_ok_for_hw_watchpoint) (int);
void (*to_terminal_init) (void);
@@ -961,6 +962,13 @@
#ifndef STOPPED_BY_WATCHPOINT
#define STOPPED_BY_WATCHPOINT(w) \
(*current_target.to_stopped_by_watchpoint) ()
+#endif
+
+/* Non-zero if we have continuable watchpoints */
+
+#ifndef HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT \
+ (*current_target.to_have_continuable_watchpoint)
#endif
/* HP-UX supplies these operations, which respectively disable and enable
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-07 19:22 ` Mark Kettenis
2003-02-07 20:08 ` Kris Warkentin
@ 2003-02-12 22:18 ` Kris Warkentin
2003-02-12 22:44 ` Daniel Jacobowitz
2003-02-13 22:21 ` Mark Kettenis
2003-02-13 21:56 ` Kris Warkentin
2 siblings, 2 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-12 22:18 UTC (permalink / raw)
To: Mark Kettenis; +Cc: Andrew Cagney, gdb-patches
Okay. I've got all our config files down to what's below. Not much left to
them. Andrew had wanted me to submit separate native and remote patches but
I can't figure out how to do that. We would never build a native only gdb -
we always support the remote protocol as well - so I'm at a loss for how to
get it to NOT compile the remote-nto.c file.
As you can see, I've got the common stuff separated into nto-tdep.c and
i386-nto-tdep.c which will be used by both remote-nto.c and nto-procfs.c.
The problem seems to be that when I build a native debugger, it includes the
stuff from i386nto.mt as well. I'm thinking that I want NATDEPFILES and
TDEPFILES to both have the *nto-tdep in them but then where does the
remote-nto.c go? Any help?
cheers,
Kris
>>>>>>i386nto.mt<<<<<<<<<
# 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
>>>>>>nm-nto.h<<<<<<<<<
#ifndef _NM_NTO_H
#define _NM_NTO_H
/* I'll be getting rid of this... */
#define QNX_TARGET_CPUTYPE CPUTYPE_X86
#endif /* _NM_NTO_H */
>>>>>>nto.mh<<<<<<<<<
# Host: Intel 386 running QNX
NAT_FILE= nm-nto.h
NATDEPFILES= nto-procfs.o nto-tdep.o
>>>>>>tm-i386nto.h<<<<<<<<<
#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"
#define HANDLE_SVR4_EXEC_EMULATORS 1
#include "solib.h" /* shared lib support */
#endif /* ifndef TM_I386QNX_H */
>>>>>>tm-nto.h<<<<<<<<<
#include "tm-i386.h"
#include "config/tm-qnxnto.h"
/* This is the amount to subtract from u.u_ar0
to get the offset in the core file of the register values. */
#define KERNEL_U_ADDR 0xe0000000
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-12 22:18 ` patch to add QNX NTO i386 support Kris Warkentin
@ 2003-02-12 22:44 ` Daniel Jacobowitz
2003-02-13 0:52 ` Kris Warkentin
2003-02-13 22:21 ` Mark Kettenis
1 sibling, 1 reply; 64+ messages in thread
From: Daniel Jacobowitz @ 2003-02-12 22:44 UTC (permalink / raw)
To: gdb-patches
On Wed, Feb 12, 2003 at 05:18:35PM -0500, Kris Warkentin wrote:
> Okay. I've got all our config files down to what's below. Not much left to
> them. Andrew had wanted me to submit separate native and remote patches but
> I can't figure out how to do that. We would never build a native only gdb -
> we always support the remote protocol as well - so I'm at a loss for how to
> get it to NOT compile the remote-nto.c file.
You don't; basically, it means you submit the remote part first and
then the native part.
> As you can see, I've got the common stuff separated into nto-tdep.c and
> i386-nto-tdep.c which will be used by both remote-nto.c and nto-procfs.c.
> The problem seems to be that when I build a native debugger, it includes the
> stuff from i386nto.mt as well. I'm thinking that I want NATDEPFILES and
> TDEPFILES to both have the *nto-tdep in them but then where does the
> remote-nto.c go? Any help?
A native build should include both NATDEPFILES and TDEPFILES; is it not
doing that?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-12 22:44 ` Daniel Jacobowitz
@ 2003-02-13 0:52 ` Kris Warkentin
0 siblings, 0 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-13 0:52 UTC (permalink / raw)
To: Daniel Jacobowitz, gdb-patches
> On Wed, Feb 12, 2003 at 05:18:35PM -0500, Kris Warkentin wrote:
> > Okay. I've got all our config files down to what's below. Not much
left to
> > them. Andrew had wanted me to submit separate native and remote patches
but
> > I can't figure out how to do that. We would never build a native only
gdb -
> > we always support the remote protocol as well - so I'm at a loss for how
to
> > get it to NOT compile the remote-nto.c file.
>
> You don't; basically, it means you submit the remote part first and
> then the native part.
Okay. Maybe I got the order mixed up.
> > As you can see, I've got the common stuff separated into nto-tdep.c and
> > i386-nto-tdep.c which will be used by both remote-nto.c and
nto-procfs.c.
> > The problem seems to be that when I build a native debugger, it includes
the
> > stuff from i386nto.mt as well. I'm thinking that I want NATDEPFILES and
> > TDEPFILES to both have the *nto-tdep in them but then where does the
> > remote-nto.c go? Any help?
>
> A native build should include both NATDEPFILES and TDEPFILES; is it not
> doing that?
Yes it does. That was what was confusing me. If I'm submitting the remote
part first, then I'm no longer confused. The difference between remote and
native is only one file either way. Either compile nto-procfs.c or
remote-nto.c.
Thanks Daniel.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-12 22:18 ` patch to add QNX NTO i386 support Kris Warkentin
2003-02-12 22:44 ` Daniel Jacobowitz
@ 2003-02-13 22:21 ` Mark Kettenis
2003-02-13 22:29 ` Kris Warkentin
1 sibling, 1 reply; 64+ messages in thread
From: Mark Kettenis @ 2003-02-13 22:21 UTC (permalink / raw)
To: kewarken; +Cc: ac131313, gdb-patches
From: "Kris Warkentin" <kewarken@qnx.com>
Date: Wed, 12 Feb 2003 17:18:35 -0500
Okay. I've got all our config files down to what's below. Not
much left to them. Andrew had wanted me to submit separate native
and remote patches but I can't figure out how to do that. We would
never build a native only gdb - we always support the remote
protocol as well - so I'm at a loss for how to get it to NOT
compile the remote-nto.c file.
I think we'd want the remote stuff to be optional. One way to make it
such is having a configure option, say --enable-remote-nto, to enable
it (which would be the default on QNX NTO systems, where you'd be able
to use --disable-remote-nto to disable it). GDB should compile either
way (but the remote-nto stuff probably wouldn't be of any use except
for connecting to QNX NTO systems).
As you can see, I've got the common stuff separated into nto-tdep.c and
i386-nto-tdep.c which will be used by both remote-nto.c and nto-procfs.c.
The problem seems to be that when I build a native debugger, it includes the
stuff from i386nto.mt as well. I'm thinking that I want NATDEPFILES and
TDEPFILES to both have the *nto-tdep in them but then where does the
remote-nto.c go? Any help?
Sorry I'm not following you here. There's no point in listing files
both in NATDEPFILES and TDEPFILES, since a native GDB by definition
also includes the target stuff for the host its being built for.
I'm missing config/tm-qnxnto.h from the files you listed. And what
purpose fulfills the tm-nto.h file you listed? Anyway, show me the
complete target-stuff and let's get that integrated first!
Mark
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-13 22:21 ` Mark Kettenis
@ 2003-02-13 22:29 ` Kris Warkentin
2003-02-13 22:53 ` Mark Kettenis
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-13 22:29 UTC (permalink / raw)
To: Mark Kettenis; +Cc: ac131313, gdb-patches
> From: "Kris Warkentin" <kewarken@qnx.com>
> Date: Wed, 12 Feb 2003 17:18:35 -0500
>
> Okay. I've got all our config files down to what's below. Not
> much left to them. Andrew had wanted me to submit separate native
> and remote patches but I can't figure out how to do that. We would
> never build a native only gdb - we always support the remote
> protocol as well - so I'm at a loss for how to get it to NOT
> compile the remote-nto.c file.
>
> I think we'd want the remote stuff to be optional. One way to make it
> such is having a configure option, say --enable-remote-nto, to enable
> it (which would be the default on QNX NTO systems, where you'd be able
> to use --disable-remote-nto to disable it). GDB should compile either
> way (but the remote-nto stuff probably wouldn't be of any use except
> for connecting to QNX NTO systems).
How would this work? If the option were supplied would I append
remote-qnx.o to TDEPFILES?
> As you can see, I've got the common stuff separated into nto-tdep.c and
> i386-nto-tdep.c which will be used by both remote-nto.c and
nto-procfs.c.
> The problem seems to be that when I build a native debugger, it
includes the
> stuff from i386nto.mt as well. I'm thinking that I want NATDEPFILES
and
> TDEPFILES to both have the *nto-tdep in them but then where does the
> remote-nto.c go? Any help?
>
> Sorry I'm not following you here. There's no point in listing files
> both in NATDEPFILES and TDEPFILES, since a native GDB by definition
> also includes the target stuff for the host its being built for.
Yes. Daniel J. explained this to me.
> I'm missing config/tm-qnxnto.h from the files you listed. And what
> purpose fulfills the tm-nto.h file you listed? Anyway, show me the
> complete target-stuff and let's get that integrated first!
The missing tm-qnxnto.h was an oversight - not necessary for the question I
was asking. The tm-nto.h file is necessary because configure will not build
a native debugger without it, even if it's empty. I'm trying to solve a few
annoying bugs (SOLIB_BKPT_NAME and SVR$_EXEC_EMU) first before I submit.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-13 22:29 ` Kris Warkentin
@ 2003-02-13 22:53 ` Mark Kettenis
2003-02-13 23:55 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Mark Kettenis @ 2003-02-13 22:53 UTC (permalink / raw)
To: kewarken; +Cc: ac131313, gdb-patches
From: "Kris Warkentin" <kewarken@qnx.com>
Cc: <ac131313@redhat.com>, <gdb-patches@sources.redhat.com>
Date: Thu, 13 Feb 2003 17:29:13 -0500
Content-Type: text/plain;
charset="iso-8859-1"
X-Priority: 3
X-MSMail-Priority: Normal
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1106
> From: "Kris Warkentin" <kewarken@qnx.com>
> Date: Wed, 12 Feb 2003 17:18:35 -0500
>
> Okay. I've got all our config files down to what's below. Not
> much left to them. Andrew had wanted me to submit separate native
> and remote patches but I can't figure out how to do that. We would
> never build a native only gdb - we always support the remote
> protocol as well - so I'm at a loss for how to get it to NOT
> compile the remote-nto.c file.
>
> I think we'd want the remote stuff to be optional. One way to make it
> such is having a configure option, say --enable-remote-nto, to enable
> it (which would be the default on QNX NTO systems, where you'd be able
> to use --disable-remote-nto to disable it). GDB should compile either
> way (but the remote-nto stuff probably wouldn't be of any use except
> for connecting to QNX NTO systems).
How would this work? If the option were supplied would I append
remote-qnx.o to TDEPFILES?
You can add to the various CONFIG_ variables, e.g. you would add
remote-nto.o to CONFIG_OBS. See how the CLI, MI, TUI etc. are handled
in configure.in.
Anyway, I don't consider the fact that remote-nto.o is listed in
TDEPFILES a problem, as long as the *nto-tdep.c files don't depend on
it.
> I'm missing config/tm-qnxnto.h from the files you listed. And what
> purpose fulfills the tm-nto.h file you listed? Anyway, show me the
> complete target-stuff and let's get that integrated first!
The missing tm-qnxnto.h was an oversight - not necessary for the question I
was asking. The tm-nto.h file is necessary because configure will not build
a native debugger without it, even if it's empty.
Huh? Are you saying that, even though you don't mention tm-nto.h in
any of the Makefile-fragments you're adding, you need the file to
build GDB?
I'm trying to solve a few annoying bugs (SOLIB_BKPT_NAME and
SVR$_EXEC_EMU) first before I submit.
Fair enough. I'm just looking forward to the end-result.
Mark
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-13 22:53 ` Mark Kettenis
@ 2003-02-13 23:55 ` Kris Warkentin
2003-02-14 0:01 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-13 23:55 UTC (permalink / raw)
To: Mark Kettenis; +Cc: ac131313, gdb-patches
> How would this work? If the option were supplied would I append
> remote-qnx.o to TDEPFILES?
>
> You can add to the various CONFIG_ variables, e.g. you would add
> remote-nto.o to CONFIG_OBS. See how the CLI, MI, TUI etc. are handled
> in configure.in.
>
> Anyway, I don't consider the fact that remote-nto.o is listed in
> TDEPFILES a problem, as long as the *nto-tdep.c files don't depend on
> it.
Okay. That seems straight forward enough.
> The missing tm-qnxnto.h was an oversight - not necessary for the
question I
> was asking. The tm-nto.h file is necessary because configure will not
build
> a native debugger without it, even if it's empty.
>
> Huh? Are you saying that, even though you don't mention tm-nto.h in
> any of the Makefile-fragments you're adding, you need the file to
> build GDB?
Actually, NAT_FILE is nm-nto.h. I was quite confused when I eliminated
NAT_FILE from nto.mh and all of a sudden couldn't build a native gdb
anymore. If you look at the configure script, you'll see that if NAT_FILE
isn't defined, you never build a native gdb. So I went 'touch nto.mh' and
added it to nto.mh. I expect it will eventually be an empty file (once I
get rid of the single define in it).
> I'm trying to solve a few annoying bugs (SOLIB_BKPT_NAME and
> SVR$_EXEC_EMU) first before I submit.
>
> Fair enough. I'm just looking forward to the end-result.
And I'd like to thank you and everyone else once again for all the help and
patience. I really want to do this right.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-13 23:55 ` Kris Warkentin
@ 2003-02-14 0:01 ` Kris Warkentin
0 siblings, 0 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-14 0:01 UTC (permalink / raw)
To: Kris Warkentin, Mark Kettenis; +Cc: ac131313, gdb-patches
> >
> > Huh? Are you saying that, even though you don't mention tm-nto.h in
> > any of the Makefile-fragments you're adding, you need the file to
> > build GDB?
>
> Actually, NAT_FILE is nm-nto.h. I was quite confused when I eliminated
> NAT_FILE from nto.mh and all of a sudden couldn't build a native gdb
> anymore. If you look at the configure script, you'll see that if NAT_FILE
> isn't defined, you never build a native gdb. So I went 'touch nto.mh' and
> added it to nto.mh. I expect it will eventually be an empty file (once I
> get rid of the single define in it).
Oh...I didn't read that correctly. You're right. There is a tm-nto.h
there. How the heck did that happen? I must have copied something
incorrectly. Tomorrow when I'm back to work I'll have to figure out what I
was doing. I've been moving so much stuff around that I must have slipped
somewhere.
Good eyes.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-07 19:22 ` Mark Kettenis
2003-02-07 20:08 ` Kris Warkentin
2003-02-12 22:18 ` patch to add QNX NTO i386 support Kris Warkentin
@ 2003-02-13 21:56 ` Kris Warkentin
2003-02-13 22:08 ` Daniel Jacobowitz
2 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-13 21:56 UTC (permalink / raw)
To: Mark Kettenis; +Cc: Andrew Cagney, gdb-patches
> > #define HANDLE_SVR4_EXEC_EMULATORS 1
> > #include "solib.h" /* shared lib support */
>
> Including solib.h is fine. However I wonder why you need
> HANDLE_SVR4_EXEC_EMULATORS. AFAIK this deals with Solaris BCP
> (running SunOS 4 a.out files on Solaris 2 a.k.a. SunOS 5). What is
> its relevance on QNX? Could this be the reason that you need to set
> SOLIB_BKPT_NAME?
I've discovered why HANDLE_SVR4_EXEC_EMULATORS is needed but I'm not sure of
the correct way to fix it. The relevant code is from solib-svr4.c below. A
typical remote qnx debugging session would be something like this:
kewarken@CATDOG ~/test
$ ntox86-gdb
GNU gdb 5.2.1qnx-326 QNX Neutrino 6.2.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=i686-pc-cygwin --target=ntox86".
(gdb) target qnx ren:10000
Remote debugging using ren:10000
(gdb) sym blah
Reading symbols from blah...done.
(gdb) upload blah /tmp/blah
(gdb) r /tmp/blah
Starting program: /tmp/blah
(gdb) b main
Breakpoint 1 at 0x8048402: file blah.c, line 10.
(gdb) c
Continuing.
Breakpoint 1, main () at blah.c:10
10 func();
The problem that we're running into is that exec_bfd is NULL in the code
below so we fall back on the 'hard way' which is not really necessary (if
exec_bfd is set). On the native qnx gdb, this isn't a problem because
exec_bfd is set when main() calls attach_command() which calls
exec_file_attach(). What I'd like to know is at what point should I stuff
exec_bfd? In the case of remote debugging, the file with the symbols is
'/home/kewarken/test/blah' and the file being run (on the remote) is
/tmp/blah. We need to set exec_bfd to point to the same file as the one
we've read symbols from but the question is, when and where?
cheers,
Kris
static CORE_ADDR
locate_base (void)
{
if (debug_base == 0)
{
if (exec_bfd != NULL
&& bfd_get_flavour (exec_bfd) == bfd_target_elf_flavour)
debug_base = elf_locate_base ();
#ifdef HANDLE_SVR4_EXEC_EMULATORS
/* Try it the hard way for emulated executables. */
else if (!ptid_equal (inferior_ptid, null_ptid) &&
target_has_execution)
proc_iterate_over_mappings (look_for_base);
#endif
}
return (debug_base);
}
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: patch to add QNX NTO i386 support
2003-02-13 21:56 ` Kris Warkentin
@ 2003-02-13 22:08 ` Daniel Jacobowitz
2003-02-13 22:25 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Daniel Jacobowitz @ 2003-02-13 22:08 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Mark Kettenis, Andrew Cagney, gdb-patches
On Thu, Feb 13, 2003 at 04:56:58PM -0500, Kris Warkentin wrote:
> > > #define HANDLE_SVR4_EXEC_EMULATORS 1
> > > #include "solib.h" /* shared lib support */
> >
> > Including solib.h is fine. However I wonder why you need
> > HANDLE_SVR4_EXEC_EMULATORS. AFAIK this deals with Solaris BCP
> > (running SunOS 4 a.out files on Solaris 2 a.k.a. SunOS 5). What is
> > its relevance on QNX? Could this be the reason that you need to set
> > SOLIB_BKPT_NAME?
>
> I've discovered why HANDLE_SVR4_EXEC_EMULATORS is needed but I'm not sure of
> the correct way to fix it. The relevant code is from solib-svr4.c below. A
> typical remote qnx debugging session would be something like this:
>
> kewarken@CATDOG ~/test
> $ ntox86-gdb
> GNU gdb 5.2.1qnx-326 QNX Neutrino 6.2.1
> Copyright 2002 Free Software Foundation, Inc.
> GDB is free software, covered by the GNU General Public License, and you are
> welcome to change it and/or distribute copies of it under certain
> conditions.
> Type "show copying" to see the conditions.
> There is absolutely no warranty for GDB. Type "show warranty" for details.
> This GDB was configured as "--host=i686-pc-cygwin --target=ntox86".
> (gdb) target qnx ren:10000
> Remote debugging using ren:10000
> (gdb) sym blah
> Reading symbols from blah...done.
Silly question - why not say "file blah" here? That'll set exec_bfd,
and you'll be just fine.
If I'm right, and you want to support the above sequence, you could
probably locally make sym set the exec file, if none was set.
> (gdb) upload blah /tmp/blah
> (gdb) r /tmp/blah
> Starting program: /tmp/blah
> (gdb) b main
> Breakpoint 1 at 0x8048402: file blah.c, line 10.
> (gdb) c
> Continuing.
>
> Breakpoint 1, main () at blah.c:10
> 10 func();
>
> The problem that we're running into is that exec_bfd is NULL in the code
> below so we fall back on the 'hard way' which is not really necessary (if
> exec_bfd is set). On the native qnx gdb, this isn't a problem because
> exec_bfd is set when main() calls attach_command() which calls
> exec_file_attach(). What I'd like to know is at what point should I stuff
> exec_bfd? In the case of remote debugging, the file with the symbols is
> '/home/kewarken/test/blah' and the file being run (on the remote) is
> /tmp/blah. We need to set exec_bfd to point to the same file as the one
> we've read symbols from but the question is, when and where?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-13 22:08 ` Daniel Jacobowitz
@ 2003-02-13 22:25 ` Kris Warkentin
2003-02-13 22:29 ` Daniel Jacobowitz
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-13 22:25 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Mark Kettenis, Andrew Cagney, gdb-patches
> > This GDB was configured as "--host=i686-pc-cygwin --target=ntox86".
> > (gdb) target qnx ren:10000
> > Remote debugging using ren:10000
> > (gdb) sym blah
> > Reading symbols from blah...done.
>
> Silly question - why not say "file blah" here? That'll set exec_bfd,
> and you'll be just fine.
Not silly. If you say 'file' you have tied yourself to the host and target
file being the same. I need to be able to get syms from /home/kewarken/foo
and run /tmp/foo.
> If I'm right, and you want to support the above sequence, you could
> probably locally make sym set the exec file, if none was set.
I'm trying to find the right place to call exec_file_attach or some such. I
think I'm close....;-)
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-13 22:25 ` Kris Warkentin
@ 2003-02-13 22:29 ` Daniel Jacobowitz
2003-02-13 23:48 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Daniel Jacobowitz @ 2003-02-13 22:29 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Mark Kettenis, Andrew Cagney, gdb-patches
On Thu, Feb 13, 2003 at 05:25:14PM -0500, Kris Warkentin wrote:
> > > This GDB was configured as "--host=i686-pc-cygwin --target=ntox86".
> > > (gdb) target qnx ren:10000
> > > Remote debugging using ren:10000
> > > (gdb) sym blah
> > > Reading symbols from blah...done.
> >
> > Silly question - why not say "file blah" here? That'll set exec_bfd,
> > and you'll be just fine.
>
>
> Not silly. If you say 'file' you have tied yourself to the host and target
> file being the same. I need to be able to get syms from /home/kewarken/foo
> and run /tmp/foo.
Wait, but from your earlier sequence, isn't /home/kewarken/foo on the
host and uploaded to /tmp/foo on the target?
I don't follow why GDB needs to know anything about the target
filename. I can see that this remote protocol is very different from
the normal one, if you're ssending full paths.
> > If I'm right, and you want to support the above sequence, you could
> > probably locally make sym set the exec file, if none was set.
>
> I'm trying to find the right place to call exec_file_attach or some such. I
> think I'm close....;-)
>
> cheers,
>
> Kris
>
>
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-13 22:29 ` Daniel Jacobowitz
@ 2003-02-13 23:48 ` Kris Warkentin
2003-02-14 0:03 ` Daniel Jacobowitz
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-13 23:48 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Mark Kettenis, Andrew Cagney, gdb-patches
> > > Silly question - why not say "file blah" here? That'll set exec_bfd,
> > > and you'll be just fine.
> >
> >
> > Not silly. If you say 'file' you have tied yourself to the host and
target
> > file being the same. I need to be able to get syms from
/home/kewarken/foo
> > and run /tmp/foo.
>
> Wait, but from your earlier sequence, isn't /home/kewarken/foo on the
> host and uploaded to /tmp/foo on the target?
>
> I don't follow why GDB needs to know anything about the target
> filename. I can see that this remote protocol is very different from
> the normal one, if you're ssending full paths.
Yeah. The remote system is an Unix OS with filesystem, etc. just like the
host. I suppose an interesting thing to do might be to have the remote
server remember what was uploaded but that would actually limit you. We can
upload shared objects, set remote LD_LIBRARY_PATH, etc. or not upload at all
but just run an arbitrary binary on the remote (which could be nfs or samba
mounted) or even attach to a running pid on the remote. Flexible.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-13 23:48 ` Kris Warkentin
@ 2003-02-14 0:03 ` Daniel Jacobowitz
2003-02-14 0:09 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Daniel Jacobowitz @ 2003-02-14 0:03 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Mark Kettenis, Andrew Cagney, gdb-patches
On Thu, Feb 13, 2003 at 06:51:13PM -0500, Kris Warkentin wrote:
> > > > Silly question - why not say "file blah" here? That'll set exec_bfd,
> > > > and you'll be just fine.
> > >
> > >
> > > Not silly. If you say 'file' you have tied yourself to the host and
> target
> > > file being the same. I need to be able to get syms from
> /home/kewarken/foo
> > > and run /tmp/foo.
> >
> > Wait, but from your earlier sequence, isn't /home/kewarken/foo on the
> > host and uploaded to /tmp/foo on the target?
> >
> > I don't follow why GDB needs to know anything about the target
> > filename. I can see that this remote protocol is very different from
> > the normal one, if you're ssending full paths.
>
> Yeah. The remote system is an Unix OS with filesystem, etc. just like the
> host. I suppose an interesting thing to do might be to have the remote
> server remember what was uploaded but that would actually limit you. We can
> upload shared objects, set remote LD_LIBRARY_PATH, etc. or not upload at all
> but just run an arbitrary binary on the remote (which could be nfs or samba
> mounted) or even attach to a running pid on the remote. Flexible.
These are all things I'd want gdbserver to do, at some point. Need to
do it with extensions to the existing remote protocol (or kick the
bucket and create a new one).
That said, I still think you should be using "file" above. File
specifies the main program, and that's what it is. Then you can give
whatever path you want to the stub.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-14 0:03 ` Daniel Jacobowitz
@ 2003-02-14 0:09 ` Kris Warkentin
2003-02-14 0:13 ` Daniel Jacobowitz
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-14 0:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
> That said, I still think you should be using "file" above. File
> specifies the main program, and that's what it is. Then you can give
> whatever path you want to the stub.
Once you say 'file /home/kewarken/foo', I don't believe there is any way to
tell it to run /tmp/foo. After I've said 'file', if I go 'run /tmp/foo' it
tries to run /home/kewarken/foo with /tmp/foo as an argument. Perhaps I'm
just missing something?
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-14 0:09 ` Kris Warkentin
@ 2003-02-14 0:13 ` Daniel Jacobowitz
2003-02-14 0:35 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Daniel Jacobowitz @ 2003-02-14 0:13 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb-patches
On Thu, Feb 13, 2003 at 07:11:58PM -0500, Kris Warkentin wrote:
> > That said, I still think you should be using "file" above. File
> > specifies the main program, and that's what it is. Then you can give
> > whatever path you want to the stub.
>
> Once you say 'file /home/kewarken/foo', I don't believe there is any way to
> tell it to run /tmp/foo. After I've said 'file', if I go 'run /tmp/foo' it
> tries to run /home/kewarken/foo with /tmp/foo as an argument. Perhaps I'm
> just missing something?
Oh! I was misunderstanding - I've never seen that particular syntax
for run before, and if you ask me, it should be killed ASAP. It's
terribly confusing to ambiguously use the first argument as a program.
Let me guess, it's the documented way to use GDB with target qnx?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-14 0:13 ` Daniel Jacobowitz
@ 2003-02-14 0:35 ` Kris Warkentin
2003-02-17 14:58 ` Andrew Cagney
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-14 0:35 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
> > Once you say 'file /home/kewarken/foo', I don't believe there is any way
to
> > tell it to run /tmp/foo. After I've said 'file', if I go 'run /tmp/foo'
it
> > tries to run /home/kewarken/foo with /tmp/foo as an argument. Perhaps
I'm
> > just missing something?
>
> Oh! I was misunderstanding - I've never seen that particular syntax
> for run before, and if you ask me, it should be killed ASAP. It's
> terribly confusing to ambiguously use the first argument as a program.
>
> Let me guess, it's the documented way to use GDB with target qnx?
Bingo. And it's also the way our ide talks to gdb. If the exec filename is
not set, gdb treats the first argument to run as the path to the file and
subsequent arguments as regular args.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-14 0:35 ` Kris Warkentin
@ 2003-02-17 14:58 ` Andrew Cagney
2003-02-17 15:44 ` Daniel Jacobowitz
0 siblings, 1 reply; 64+ messages in thread
From: Andrew Cagney @ 2003-02-17 14:58 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Daniel Jacobowitz, gdb-patches
>> Oh! I was misunderstanding - I've never seen that particular syntax
>> for run before, and if you ask me, it should be killed ASAP. It's
>> terribly confusing to ambiguously use the first argument as a program.
>>
>> Let me guess, it's the documented way to use GDB with target qnx?
>
>
> Bingo. And it's also the way our ide talks to gdb. If the exec filename is
> not set, gdb treats the first argument to run as the path to the file and
> subsequent arguments as regular args.
I don't think that change would be accepted into GDB. It makes `run'
just too modal :-/
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-17 14:58 ` Andrew Cagney
@ 2003-02-17 15:44 ` Daniel Jacobowitz
2003-02-17 16:45 ` Andrew Cagney
2003-02-27 19:02 ` Kris Warkentin
0 siblings, 2 replies; 64+ messages in thread
From: Daniel Jacobowitz @ 2003-02-17 15:44 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Kris Warkentin, gdb-patches
On Sat, Feb 15, 2003 at 11:19:28PM +0100, Andrew Cagney wrote:
>
> >>Oh! I was misunderstanding - I've never seen that particular syntax
> >>for run before, and if you ask me, it should be killed ASAP. It's
> >>terribly confusing to ambiguously use the first argument as a program.
> >>
> >>Let me guess, it's the documented way to use GDB with target qnx?
> >
> >
> >Bingo. And it's also the way our ide talks to gdb. If the exec filename
> >is
> >not set, gdb treats the first argument to run as the path to the file and
> >subsequent arguments as regular args.
>
> I don't think that change would be accepted into GDB. It makes `run'
> just too modal :-/
That was my first reaction too. But he's not describing a local change
to GDB - we already do this! Argh!
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-17 15:44 ` Daniel Jacobowitz
@ 2003-02-17 16:45 ` Andrew Cagney
2003-02-17 18:54 ` Kris Warkentin
2003-02-27 19:02 ` Kris Warkentin
1 sibling, 1 reply; 64+ messages in thread
From: Andrew Cagney @ 2003-02-17 16:45 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Kris Warkentin, gdb-patches
> On Sat, Feb 15, 2003 at 11:19:28PM +0100, Andrew Cagney wrote:
>
>>
>
>> >>Oh! I was misunderstanding - I've never seen that particular syntax
>> >>for run before, and if you ask me, it should be killed ASAP. It's
>> >>terribly confusing to ambiguously use the first argument as a program.
>> >>
>> >>Let me guess, it's the documented way to use GDB with target qnx?
>
>> >
>> >
>> >Bingo. And it's also the way our ide talks to gdb. If the exec filename
>> >is
>> >not set, gdb treats the first argument to run as the path to the file and
>> >subsequent arguments as regular args.
>
>>
>> I don't think that change would be accepted into GDB. It makes `run'
>> just too modal :-/
>
>
> That was my first reaction too. But he's not describing a local change
> to GDB - we already do this! Argh!
Yes, arrrg! Bug!
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-17 16:45 ` Andrew Cagney
@ 2003-02-17 18:54 ` Kris Warkentin
2003-02-18 21:26 ` Andrew Cagney
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-17 18:54 UTC (permalink / raw)
To: Andrew Cagney, Daniel Jacobowitz; +Cc: gdb-patches
> >> >Bingo. And it's also the way our ide talks to gdb. If the exec
filename
> >> >is
> >> >not set, gdb treats the first argument to run as the path to the file
and
> >> >subsequent arguments as regular args.
> >
> >>
> >> I don't think that change would be accepted into GDB. It makes `run'
> >> just too modal :-/
> >
> >
> > That was my first reaction too. But he's not describing a local change
> > to GDB - we already do this! Argh!
>
> Yes, arrrg! Bug!
Why arrrgh? I know it makes run a little context sensitive but I don't
think anyone trips on it. The normal usage pattern of gdb precludes people
having problems with it and it's very useful for us. I still haven't heard
any suggestions of how we might accomplish what we do.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-17 18:54 ` Kris Warkentin
@ 2003-02-18 21:26 ` Andrew Cagney
2003-02-18 22:30 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Andrew Cagney @ 2003-02-18 21:26 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Daniel Jacobowitz, gdb-patches
> Bingo. And it's also the way our ide talks to gdb. If the exec
>
> filename
>
>> >> >is
>> >> >not set, gdb treats the first argument to run as the path to the file
>
> and
>
>> >> >subsequent arguments as regular args.
>
>> >
>
>> >>
>> >> I don't think that change would be accepted into GDB. It makes `run'
>> >> just too modal :-/
>
>> >
>> >
>> > That was my first reaction too. But he's not describing a local change
>> > to GDB - we already do this! Argh!
>
>>
>> Yes, arrrg! Bug!
>
>
> Why arrrgh? I know it makes run a little context sensitive but I don't
> think anyone trips on it. The normal usage pattern of gdb precludes people
> having problems with it and it's very useful for us. I still haven't heard
> any suggestions of how we might accomplish what we do.
In a single sentence, what does this command do?
run /a/program
Your answer cannot contain the word `if' :-)
There are separate commands for specifying the program to be run.
Perhaphs additional commands are needed.
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-18 21:26 ` Andrew Cagney
@ 2003-02-18 22:30 ` Kris Warkentin
2003-02-20 0:42 ` Andrew Cagney
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-18 22:30 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Daniel Jacobowitz, gdb-patches
> > Why arrrgh? I know it makes run a little context sensitive but I don't
> > think anyone trips on it. The normal usage pattern of gdb precludes
people
> > having problems with it and it's very useful for us. I still haven't
heard
> > any suggestions of how we might accomplish what we do.
>
> In a single sentence, what does this command do?
>
> run /a/program
>
> Your answer cannot contain the word `if' :-)
>
> There are separate commands for specifying the program to be run.
> Perhaphs additional commands are needed.
Alright. Perhaps the 'exec-file' command? It seems to me that
'symbol-file' and 'exec-file' should combine into the 'file' command. The
problem is that 'exec-file /tmp/some_file' fails if there is no
/tmp/some_file. Maybe we could make the exec-file command unconditional?
That way the target_ops run command can deal with it.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-18 22:30 ` Kris Warkentin
@ 2003-02-20 0:42 ` Andrew Cagney
0 siblings, 0 replies; 64+ messages in thread
From: Andrew Cagney @ 2003-02-20 0:42 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Daniel Jacobowitz, gdb-patches
> Alright. Perhaps the 'exec-file' command? It seems to me that
> 'symbol-file' and 'exec-file' should combine into the 'file' command. The
> problem is that 'exec-file /tmp/some_file' fails if there is no
> /tmp/some_file. Maybe we could make the exec-file command unconditional?
> That way the target_ops run command can deal with it.
If this is strictly a remote target setting that only applies to the
remote side, why not `set remote ....'.
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-17 15:44 ` Daniel Jacobowitz
2003-02-17 16:45 ` Andrew Cagney
@ 2003-02-27 19:02 ` Kris Warkentin
2003-02-27 19:56 ` Andrew Cagney
2003-02-27 20:02 ` Daniel Jacobowitz
1 sibling, 2 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-27 19:02 UTC (permalink / raw)
To: Daniel Jacobowitz, Andrew Cagney; +Cc: gdb-patches
> > >Bingo. And it's also the way our ide talks to gdb. If the exec
filename
> > >is
> > >not set, gdb treats the first argument to run as the path to the file
and
> > >subsequent arguments as regular args.
> >
> > I don't think that change would be accepted into GDB. It makes `run'
> > just too modal :-/
>
> That was my first reaction too. But he's not describing a local change
> to GDB - we already do this! Argh!
Yup. Serves you right for implementing something that comes in handy and
that people use. ;-)
Seriously though, I'd love to hear proposals for alternative methods of
accomplishing this. We need to get symbols from a file on the host and then
exec this file at an arbitrary path on the target. If you think about it,
the current solution encapsulates that perfectly. Like I said though, I'd
love to hear other ideas.
BTW, Andrew, that HAVE_CONTINUABLE_WATCHPOINT patch....my current QNX patch
which I'm about ready to submit, relies on it. I know you're busy but can
you tell me if it's at least mostly okay so that I can tell whether or not I
need to change my backend before I submit.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-27 19:02 ` Kris Warkentin
@ 2003-02-27 19:56 ` Andrew Cagney
2003-02-27 20:02 ` Daniel Jacobowitz
1 sibling, 0 replies; 64+ messages in thread
From: Andrew Cagney @ 2003-02-27 19:56 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Daniel Jacobowitz, gdb-patches
[-- Attachment #1: Type: text/plain, Size: 295 bytes --]
> BTW, Andrew, that HAVE_CONTINUABLE_WATCHPOINT patch....my current QNX patch
> which I'm about ready to submit, relies on it. I know you're busy but can
> you tell me if it's at least mostly okay so that I can tell whether or not I
> need to change my backend before I submit.
See attached.
[-- Attachment #2: mailbox-message://ac131313@movemail/Trash#186564366 --]
[-- Type: message/rfc822, Size: 3401 bytes --]
From: Andrew Cagney <ac131313@redhat.com>
To: Kris Warkentin <kewarken@qnx.com>
Cc: gdb-patches@sources.redhat.com
Subject: Re: [Patch] add HAVE_CONTINUABLE_WATCHPOINT to target ops
Date: Mon, 24 Feb 2003 16:53:38 -0500
Message-ID: <3E5A9462.10405@redhat.com>
> 2003-02-24 Kris Warkentin <kewarken@qnx.com>
>
> * target.h: (HAVE_CONTINUABLE_WATCHPOINT): define.
> (target_ops): add to_have_continuable_watchpoint.
> * target.c (update_current_target): add INHERIT line for
> to_have_continuable_watchpoint.
> * infrun.c: remove HAVE_CONTINUABLE_WATCHPOINT defines
> * config/i386/nm-i386.h, config/i386/nm-i386sco5.h,
> config/i386/nm-i386sol2.h, config/s390/nm-linux.h,
> config/sparc/nm-sun4sol2.h: HAVE_CONTINUABLE_WATCHPOINT defined as 1.
You need to get the hang of change logs. Sentences that start with a
capital and end with a fullstop.
Otherwize the patch is approved.
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-27 19:02 ` Kris Warkentin
2003-02-27 19:56 ` Andrew Cagney
@ 2003-02-27 20:02 ` Daniel Jacobowitz
2003-02-27 20:10 ` Andrew Cagney
2003-02-27 20:11 ` Kris Warkentin
1 sibling, 2 replies; 64+ messages in thread
From: Daniel Jacobowitz @ 2003-02-27 20:02 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Andrew Cagney, gdb-patches
On Mon, Feb 17, 2003 at 11:02:58AM -0500, Kris Warkentin wrote:
> > > >Bingo. And it's also the way our ide talks to gdb. If the exec
> filename
> > > >is
> > > >not set, gdb treats the first argument to run as the path to the file
> and
> > > >subsequent arguments as regular args.
> > >
> > > I don't think that change would be accepted into GDB. It makes `run'
> > > just too modal :-/
> >
> > That was my first reaction too. But he's not describing a local change
> > to GDB - we already do this! Argh!
>
> Yup. Serves you right for implementing something that comes in handy and
> that people use. ;-)
>
> Seriously though, I'd love to hear proposals for alternative methods of
> accomplishing this. We need to get symbols from a file on the host and then
> exec this file at an arbitrary path on the target. If you think about it,
> the current solution encapsulates that perfectly. Like I said though, I'd
> love to hear other ideas.
"set remote exec-path"? Except that's not quite accurate, because the
normal remote protocol doesn't support it. Maybe "set nto exec-path",
since it'd only be used by remote-nto.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-27 20:02 ` Daniel Jacobowitz
@ 2003-02-27 20:10 ` Andrew Cagney
2003-02-27 20:11 ` Kris Warkentin
1 sibling, 0 replies; 64+ messages in thread
From: Andrew Cagney @ 2003-02-27 20:10 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Kris Warkentin, gdb-patches
> "set remote exec-path"? Except that's not quite accurate, because the
> normal remote protocol doesn't support it. Maybe "set nto exec-path",
> since it'd only be used by remote-nto.
It should though.
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-27 20:02 ` Daniel Jacobowitz
2003-02-27 20:10 ` Andrew Cagney
@ 2003-02-27 20:11 ` Kris Warkentin
2003-02-27 20:23 ` Andrew Cagney
1 sibling, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-27 20:11 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Andrew Cagney, gdb-patches
> > Seriously though, I'd love to hear proposals for alternative methods of
> > accomplishing this. We need to get symbols from a file on the host and
then
> > exec this file at an arbitrary path on the target. If you think about
it,
> > the current solution encapsulates that perfectly. Like I said though,
I'd
> > love to hear other ideas.
>
> "set remote exec-path"? Except that's not quite accurate, because the
> normal remote protocol doesn't support it. Maybe "set nto exec-path",
> since it'd only be used by remote-nto.
Or you could just leave it the way it is....if it ain't broke, don't fix it
right?
(note: I don't know when this was sent - our email server held onto a bunch
of my mail for a few days for some reason so my apologies if this reply is
really late.)
That being said, I'm of the opinion that exec-file should be unconditional.
If symbol-file is set to one thing and exec-file to another, should gdb even
need to check to see if exec-file exists? I haven't looked to see what info
exec-file seems to feel it needs from the binary but I figure the run
command will discover that the exec file isn't there and report an error
itself. Then, in our case, the run command spawns on the remote and
everyone is happy and we don't need a special command.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-27 20:11 ` Kris Warkentin
@ 2003-02-27 20:23 ` Andrew Cagney
2003-02-27 20:28 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Andrew Cagney @ 2003-02-27 20:23 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Daniel Jacobowitz, gdb-patches
> That being said, I'm of the opinion that exec-file should be unconditional.
> If symbol-file is set to one thing and exec-file to another, should gdb even
> need to check to see if exec-file exists? I haven't looked to see what info
> exec-file seems to feel it needs from the binary but I figure the run
> command will discover that the exec file isn't there and report an error
> itself. Then, in our case, the run command spawns on the remote and
> everyone is happy and we don't need a special command.
Good point. Would a doco / code comparison be better to see if what
currently goes on makes sense?
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-27 20:23 ` Andrew Cagney
@ 2003-02-27 20:28 ` Kris Warkentin
0 siblings, 0 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-27 20:28 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Daniel Jacobowitz, gdb-patches
> > That being said, I'm of the opinion that exec-file should be
unconditional.
> > If symbol-file is set to one thing and exec-file to another, should gdb
even
> > need to check to see if exec-file exists? I haven't looked to see what
info
> > exec-file seems to feel it needs from the binary but I figure the run
> > command will discover that the exec file isn't there and report an error
> > itself. Then, in our case, the run command spawns on the remote and
> > everyone is happy and we don't need a special command.
>
> Good point. Would a doco / code comparison be better to see if what
> currently goes on makes sense?
The docs only say the following:
<doc>
exec-file [ filename ]
Specify that the program to be run (but not the symbol table) is found in
filename. GDB searches the environment variable PATH if necessary to locate
your program. Omitting filename means to discard information on the
executable file.
</doc>
Right now it errors out if it doesn't find the file. Inquiry: does
searching the path seem like a sensible thing to do? It seems to me that
there could be unforseen consequences.
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-03 20:19 patch to add QNX NTO i386 support Kris Warkentin
2003-02-04 7:23 ` Eli Zaretskii
2003-02-04 22:02 ` Andrew Cagney
@ 2003-02-05 20:48 ` Mark Kettenis
2003-02-05 21:23 ` Kris Warkentin
2 siblings, 1 reply; 64+ messages in thread
From: Mark Kettenis @ 2003-02-05 20:48 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb-patches
"Kris Warkentin" <kewarken@qnx.com> writes:
> Please let me know if the patch and these ChangeLog entries are
> satisfactory.
Thanks for the contribution. Andrew already posted some comments, but
here are a few more comments that are more specific for those parts of
your patch that are i386-specefic.
The i386-target was "multi-arched" a while ago, which unfortunately
means that your patch will need extensive modification before we can
add it. Don't worry, I'll help you where needed.
Basically, most of what's in your tm-i386nto.h file will have to go.
Instead you should create a i386nto-tdep.c file where you put and
register an OS/ABI handler for you OS. Based on the contents of yoyr
tm.h file, you should probably base your OS/ABI handler on
i386-tdep.c:i386_svr4_init_abi(). AFAICT, you'll need
set_gdbarch_decr_pc_after_break() and
set_solib_svr4_fetch_link_map_offsets() there. Move
i386_qnx_xvr4_link_map_offsets to that file.
You'll also need to find a way to distinguish QNX binaries from other
OS'es. The hardware breakpoint stuff will have to be moved to the
nm.h. Most of the other stuff shouldn't be necessary or should be
moved there too.
You should probably use xm-i386.h as your xm.h file. The other stuff
should either be discarded or moved to your nm.h file too.
I don't think you should try to match x86-*-nto* in configure.host;
the configure.tgt doesn't either.
As Andrew already said, it is probably a good idea to add the QNX i386
target stuff first, such that we can build cross-debuggers for it.
Then we can look more closely at the native stuff.
Mark
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 20:48 ` Mark Kettenis
@ 2003-02-05 21:23 ` Kris Warkentin
2003-02-05 21:43 ` Kris Warkentin
2003-02-05 22:48 ` Mark Kettenis
0 siblings, 2 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-05 21:23 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> The i386-target was "multi-arched" a while ago, which unfortunately
> means that your patch will need extensive modification before we can
> add it. Don't worry, I'll help you where needed.
Funny you should write. This is just what I've been working on for the past
few hours.
> Basically, most of what's in your tm-i386nto.h file will have to go.
> Instead you should create a i386nto-tdep.c file where you put and
> register an OS/ABI handler for you OS. Based on the contents of yoyr
Already made the tdep file. I was just about to email the list to ask about
how to register the handler (I had been looking at the i386-interix-tdep.c
file) when I got your email.
> tm.h file, you should probably base your OS/ABI handler on
> i386-tdep.c:i386_svr4_init_abi(). AFAICT, you'll need
> set_gdbarch_decr_pc_after_break() and
> set_solib_svr4_fetch_link_map_offsets() there. Move
> i386_qnx_xvr4_link_map_offsets to that file.
Yeah. I had started with an _init function in i386-nto-tdep that just set
some gdbarch stuff but I quickly realized that it wasn't the right way to do
it.
> You'll also need to find a way to distinguish QNX binaries from other
> OS'es. The hardware breakpoint stuff will have to be moved to the
> nm.h. Most of the other stuff shouldn't be necessary or should be
> moved there too.
Okay. Not sure how but I'll look into it. Once I've done that, do I
register an osabi_sniffer to determine the binary?
> You should probably use xm-i386.h as your xm.h file. The other stuff
> should either be discarded or moved to your nm.h file too.
Okay.
> I don't think you should try to match x86-*-nto* in configure.host;
> the configure.tgt doesn't either.
Probably right. We have a chief architect here that insists that i386 is
not correct as a generic specifier and, since our uname doesn't tell you 5
or 686, it returns x86. We take care of that mapping in config.guess though
so I believe that the x86 part is redundant now. We still build
with --target=ntox86 though.
> As Andrew already said, it is probably a good idea to add the QNX i386
> target stuff first, such that we can build cross-debuggers for it.
> Then we can look more closely at the native stuff.
Sure. The separation went quite well actually. I've got all the remote and
native stuff separated and cpu specific tdep files and headers made. The
only major work left is cleaning up our stupid config/i386 stuff and getting
the gdbarch setup properly.
Thanks
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 21:23 ` Kris Warkentin
@ 2003-02-05 21:43 ` Kris Warkentin
2003-02-05 22:24 ` Mark Kettenis
2003-02-05 22:48 ` Mark Kettenis
1 sibling, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-05 21:43 UTC (permalink / raw)
To: Kris Warkentin, Mark Kettenis; +Cc: gdb-patches
> > You'll also need to find a way to distinguish QNX binaries from other
> > OS'es. The hardware breakpoint stuff will have to be moved to the
> > nm.h. Most of the other stuff shouldn't be necessary or should be
> > moved there too.
>
> Okay. Not sure how but I'll look into it. Once I've done that, do I
> register an osabi_sniffer to determine the binary?
I don't think this is going to work. Our binaries are very generic elf with
no special sections or anything to distinguish them. The only way to tell
that we're targetting a qnx binary will be when someone types 'target qnx
...'. Is it acceptable to have the gdbarch stuff come into play when
someone does that targetting?
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 21:43 ` Kris Warkentin
@ 2003-02-05 22:24 ` Mark Kettenis
2003-02-06 15:13 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Mark Kettenis @ 2003-02-05 22:24 UTC (permalink / raw)
To: kewarken; +Cc: kewarken, gdb-patches
From: "Kris Warkentin" <kewarken@qnx.com>
Date: Wed, 5 Feb 2003 16:42:32 -0500
> > You'll also need to find a way to distinguish QNX binaries from other
> > OS'es. The hardware breakpoint stuff will have to be moved to the
> > nm.h. Most of the other stuff shouldn't be necessary or should be
> > moved there too.
>
> Okay. Not sure how but I'll look into it. Once I've done that, do I
> register an osabi_sniffer to determine the binary?
I don't think this is going to work. Our binaries are very generic elf with
no special sections or anything to distinguish them.
In that case you'll have to provide a default OS/ABI for your target.
Add something like:
*-*-nto*) gdb_osabi=GDB_OSABI_QNX ;;
to the appropriate case-statement at the end of configure.tgt.
The only way to tell that we're targetting a qnx binary will be when
someone types 'target qnx ...'. Is it acceptable to have the
gdbarch stuff come into play when someone does that targetting?
I'm not sure. If the "qnx" protocol implies that the OS/ABI is QNX,
this would make sense to me, but there are other people on this list
that could judge better.
Mark
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 22:24 ` Mark Kettenis
@ 2003-02-06 15:13 ` Kris Warkentin
2003-02-06 18:19 ` Andrew Cagney
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-06 15:13 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> > > You'll also need to find a way to distinguish QNX binaries from
other
> > > OS'es. The hardware breakpoint stuff will have to be moved to the
> > > nm.h. Most of the other stuff shouldn't be necessary or should be
> > > moved there too.
> >
> > Okay. Not sure how but I'll look into it. Once I've done that, do I
> > register an osabi_sniffer to determine the binary?
>
> I don't think this is going to work. Our binaries are very generic elf
with
> no special sections or anything to distinguish them.
>
> In that case you'll have to provide a default OS/ABI for your target.
> Add something like:
>
> *-*-nto*) gdb_osabi=GDB_OSABI_QNX ;;
>
> to the appropriate case-statement at the end of configure.tgt.
This seems like a good way to do it. I added GDB_OSABI_QNXNTO to defs.h.
I'm in general using 'nto' since that describes the kernel but people don't
always know that so I made sure to leave the 'qnx' in a few places like here
and config/tm-qnxnto.h.
> The only way to tell that we're targetting a qnx binary will be when
> someone types 'target qnx ...'. Is it acceptable to have the
> gdbarch stuff come into play when someone does that targetting?
>
> I'm not sure. If the "qnx" protocol implies that the OS/ABI is QNX,
> this would make sense to me, but there are other people on this list
> that could judge better.
You're right about this. It's unlikely that anyone else would use our qnx
pdebug protocol for remote debugging but one of my future projects is to
port the gdbserver to Neutrino. People wouldn't necessarily need to use
pdebug but in this case, there would really be no way of knowing the ABI
other than having a default set.
cheers,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-06 15:13 ` Kris Warkentin
@ 2003-02-06 18:19 ` Andrew Cagney
0 siblings, 0 replies; 64+ messages in thread
From: Andrew Cagney @ 2003-02-06 18:19 UTC (permalink / raw)
To: Kris Warkentin; +Cc: Mark Kettenis, gdb-patches
>> The only way to tell that we're targetting a qnx binary will be when
>> someone types 'target qnx ...'. Is it acceptable to have the
>> gdbarch stuff come into play when someone does that targetting?
>>
>> I'm not sure. If the "qnx" protocol implies that the OS/ABI is QNX,
>> this would make sense to me, but there are other people on this list
>> that could judge better.
>
>
> You're right about this. It's unlikely that anyone else would use our qnx
> pdebug protocol for remote debugging but one of my future projects is to
> port the gdbserver to Neutrino. People wouldn't necessarily need to use
> pdebug but in this case, there would really be no way of knowing the ABI
> other than having a default set.
FYI,
A long term objective of GDB is to get the sequence:
$ gdb
(gdb) target remote who-knows-what-we-debugging:47
Connected to target who-knows-what-we-debugging.
Architecture set to now-we-know.
(gdb) info registers
... display of now-we-know architecture's registers ...
(gdb)
This involves the target supplying the thread's architecture via the
target stack ....
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 21:23 ` Kris Warkentin
2003-02-05 21:43 ` Kris Warkentin
@ 2003-02-05 22:48 ` Mark Kettenis
2003-02-06 15:08 ` Kris Warkentin
1 sibling, 1 reply; 64+ messages in thread
From: Mark Kettenis @ 2003-02-05 22:48 UTC (permalink / raw)
To: kewarken; +Cc: gdb-patches
From: "Kris Warkentin" <kewarken@qnx.com>
Date: Wed, 5 Feb 2003 16:22:33 -0500
> The i386-target was "multi-arched" a while ago, which unfortunately
> means that your patch will need extensive modification before we can
> add it. Don't worry, I'll help you where needed.
Funny you should write. This is just what I've been working on for the past
few hours.
Great!
> You should probably use xm-i386.h as your xm.h file. The other stuff
> should either be discarded or moved to your nm.h file too.
Okay.
> I don't think you should try to match x86-*-nto* in configure.host;
> the configure.tgt doesn't either.
Probably right. We have a chief architect here that insists that i386 is
not correct as a generic specifier and, since our uname doesn't tell you 5
or 686, it returns x86. We take care of that mapping in config.guess though
so I believe that the x86 part is redundant now. We still build
with --target=ntox86 though.
Hmm, looking at config.sub it seems that x86 is recognized especially
for QNX. Since config.sub doesn't map x86, it's OK to add x86-*-nto*
if you want to allow people to build with something like
--target=x86-nto. Just make sure you add it to configure.tgt too.
Speaking about the ntox86 alias; patches for config.sub should be sent
to config-patches@gnu.org. Once they're added to the official CONFIG
source we'll import a new version.
Mark
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add QNX NTO i386 support
2003-02-05 22:48 ` Mark Kettenis
@ 2003-02-06 15:08 ` Kris Warkentin
0 siblings, 0 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-06 15:08 UTC (permalink / raw)
To: Mark Kettenis; +Cc: gdb-patches
> Hmm, looking at config.sub it seems that x86 is recognized especially
> for QNX. Since config.sub doesn't map x86, it's OK to add x86-*-nto*
> if you want to allow people to build with something like
> --target=x86-nto. Just make sure you add it to configure.tgt too.
Okay. It's easier that way since people in the QNX world always say 'x86'
rather than anything else. Aren't we a strange bunch? ;-)
> Speaking about the ntox86 alias; patches for config.sub should be sent
> to config-patches@gnu.org. Once they're added to the official CONFIG
> source we'll import a new version.
We've gotten the automake/autoconf patches accepted quite a while ago. They
seem to be satisfactory for all our uses.
Thanks,
Kris
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops
@ 2003-02-12 19:42 Kris Warkentin
2003-02-14 18:49 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-12 19:42 UTC (permalink / raw)
To: Kris Warkentin, Andrew Cagney; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 3413 bytes --]
Here's take 2 on the patch. I had a slight error in the definition of
HAVE_CONTINUABLE_WATCHPOINT in the first one. I was worried about
initialization (since infrun.c wanted the default to be zero) but since
target_ops structures are always declared as global data, it will be fine.
cheers,
Kris
----- Original Message -----
From: "Kris Warkentin" <kewarken@qnx.com>
To: "Andrew Cagney" <ac131313@redhat.com>
Cc: "Mark Kettenis" <kettenis@chello.nl>; <gdb-patches@sources.redhat.com>
Sent: Tuesday, February 11, 2003 1:41 PM
Subject: patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops
> Probably easier if I just give a diff for you to comment on.
>
> Changelog Entry:
>
> 2003-02-11 Kris Warkentin kewarken@qnx.com
>
> * target.h: Add to_have_continuable_watchpoint to struct target_ops.
> Initialize HAVE_CONTINUABLE_WATCHPOINT.
> * target.c: update_current_target(): Add
to_have_continuable_watchpoint.
> * infrun.c: remove initialization of HAVE_CONTINUABLE_WATCHPOINT.
> * config/i386/nm-i386.h: Change HAVE_CONTINUABLE_WATCHPOINT defines to
> 1.
> * config/i386/nm-i386sco5.h: ditto
> * config/i386/nm-i386sol2.h: ditto
> * config/s390/nm-linux.h: ditto
> * config/sparc/nm-sun4sol2.h: ditto
>
> cheers,
>
> Kris
>
> ----- Original Message -----
> From: "Kris Warkentin" <kewarken@qnx.com>
> To: "Andrew Cagney" <ac131313@redhat.com>
> Cc: "Mark Kettenis" <kettenis@chello.nl>; <gdb-patches@sources.redhat.com>
> Sent: Tuesday, February 11, 2003 1:11 PM
> Subject: Re: patch to add QNX NTO i386 support
>
>
> > Hi Andrew,
> >
> > Sorry it took so long to reply - I took a couple days to do a port of a
> > vxworks lib for a BSP we're working on.
> >
> > Question: can I make any assumption about the initialization of the
> > target_ops vector? It looks like infrun.c wants
> HAVE_CONTINUABLE_BREAKPOINT
> > to default to zero but I didn't see anywhere int target.[ch] that ops
were
> > being initialized.
> >
> > cheers,
> >
> > Kris
> >
> > > > /* After a watchpoint trap, the PC points to the instruction after
> > > >> > the one that caused the trap. Therefore we don't need to step
> > over
> > > >
> > > > it.
> > > >
> > > >> > But we do need to reset the status register to avoid another
> trap.
> > > >
> > > > */
> > > >
> > > >> > #define HAVE_CONTINUABLE_WATCHPOINT
> > > >
> > > >>
> > > >> Hmm, this poses an interesting problem. The other i386 targets
have
> > > >> this in their nm.h file, since they consider hardware watchpoints
as
> a
> > > >> native-only feature. However, this isn't necessarily right since
we
> > > >> might support hardware breakpoints via the remote protocol. If you
> > > >> can live with the native-only approach, please move this to your
nm.h
> > > >> file. Otherwise we might need to multi-arch this definition.
> > > >
> > > >
> > > > Okay, file that under TODO along with the solib stuff. We have
> hardware
> > > > breakpoints on all our remote targets that support them.
> > >
> > > Just FYI, this needs to be added to the target vector (target.h) and
not
> > > the architecture vector.
> > >
> > > For examples, see STOPPED_BY_WATCHPOINT et.al. A bit of manipulation
of
> > > the existing nm-*.h files will be needed - have them define the value
as
> > 1.
> > >
> > > Can you please submit a separate patch that does just this.
> > >
> > > Andrew
> > >
> > >
> > >
> >
> >
>
[-- Attachment #2: contin2.diff --]
[-- Type: application/octet-stream, Size: 5708 bytes --]
Index: config/i386/nm-i386.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nm-i386.h,v
retrieving revision 1.3
diff -u -r1.3 nm-i386.h
--- config/i386/nm-i386.h 4 Jul 2002 12:32:29 -0000 1.3
+++ config/i386/nm-i386.h 12 Feb 2003 19:38:15 -0000
@@ -93,7 +93,7 @@
one that caused the trap. Therefore we don't need to step over it.
But we do need to reset the status register to avoid another trap. */
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
#define STOPPED_BY_WATCHPOINT(W) (i386_stopped_data_address () != 0)
Index: config/i386/nm-i386sco5.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nm-i386sco5.h,v
retrieving revision 1.3
diff -u -r1.3 nm-i386sco5.h
--- config/i386/nm-i386sco5.h 18 Aug 2002 22:23:32 -0000 1.3
+++ config/i386/nm-i386sco5.h 12 Feb 2003 19:38:15 -0000
@@ -63,7 +63,7 @@
/* After a watchpoint trap, the PC points to the instruction which
caused the trap. But we can continue over it without disabling the
trap. */
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
#define HAVE_STEPPABLE_WATCHPOINT
#define STOPPED_BY_WATCHPOINT(W) \
Index: config/i386/nm-i386sol2.h
===================================================================
RCS file: /cvs/src/src/gdb/config/i386/nm-i386sol2.h,v
retrieving revision 1.7
diff -u -r1.7 nm-i386sol2.h
--- config/i386/nm-i386sol2.h 5 Jun 2002 19:18:19 -0000 1.7
+++ config/i386/nm-i386sol2.h 12 Feb 2003 19:38:15 -0000
@@ -32,7 +32,7 @@
/* When a hardware watchpoint fires off the PC will be left at the
instruction following the one which caused the watchpoint.
It will *NOT* be necessary for GDB to step over the watchpoint. */
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
/* Solaris x86 2.6 and 2.7 targets have a kernel bug when stepping
over an instruction that causes a page fault without triggering
Index: config/s390/nm-linux.h
===================================================================
RCS file: /cvs/src/src/gdb/config/s390/nm-linux.h,v
retrieving revision 1.5
diff -u -r1.5 nm-linux.h
--- config/s390/nm-linux.h 24 Feb 2002 22:56:06 -0000 1.5
+++ config/s390/nm-linux.h 12 Feb 2003 19:38:15 -0000
@@ -51,7 +51,7 @@
/* WATCHPOINT SPECIFIC STUFF */
#define TARGET_HAS_HARDWARE_WATCHPOINTS
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
#define target_insert_watchpoint(addr, len, type) \
s390_insert_watchpoint (PIDGET (inferior_ptid), addr, len, type)
Index: config/sparc/nm-sun4sol2.h
===================================================================
RCS file: /cvs/src/src/gdb/config/sparc/nm-sun4sol2.h,v
retrieving revision 1.9
diff -u -r1.9 nm-sun4sol2.h
--- config/sparc/nm-sun4sol2.h 14 Nov 2002 00:25:05 -0000 1.9
+++ config/sparc/nm-sun4sol2.h 12 Feb 2003 19:38:15 -0000
@@ -51,7 +51,7 @@
/* When a hardware watchpoint fires off the PC will be left at the
instruction following the one which caused the watchpoint.
It will *NOT* be necessary for GDB to step over the watchpoint. */
-#define HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT 1
extern int procfs_stopped_by_watchpoint (ptid_t);
#define STOPPED_BY_WATCHPOINT(W) \
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.96
diff -u -r1.96 infrun.c
--- infrun.c 31 Jan 2003 15:22:57 -0000 1.96
+++ infrun.c 12 Feb 2003 19:38:16 -0000
@@ -226,13 +226,6 @@
#define HAVE_STEPPABLE_WATCHPOINT 1
#endif
-#ifndef HAVE_CONTINUABLE_WATCHPOINT
-#define HAVE_CONTINUABLE_WATCHPOINT 0
-#else
-#undef HAVE_CONTINUABLE_WATCHPOINT
-#define HAVE_CONTINUABLE_WATCHPOINT 1
-#endif
-
#ifndef CANNOT_STEP_HW_WATCHPOINTS
#define CANNOT_STEP_HW_WATCHPOINTS 0
#else
Index: target.c
===================================================================
RCS file: /cvs/src/src/gdb/target.c,v
retrieving revision 1.49
diff -u -r1.49 target.c
--- target.c 19 Jan 2003 04:06:46 -0000 1.49
+++ target.c 12 Feb 2003 19:38:17 -0000
@@ -573,6 +573,7 @@
INHERIT (to_remove_watchpoint, t);
INHERIT (to_stopped_data_address, t);
INHERIT (to_stopped_by_watchpoint, t);
+ INHERIT (to_have_continuable_watchpoint, t);
INHERIT (to_region_size_ok_for_hw_watchpoint, t);
INHERIT (to_terminal_init, t);
INHERIT (to_terminal_inferior, t);
Index: target.h
===================================================================
RCS file: /cvs/src/src/gdb/target.h,v
retrieving revision 1.35
diff -u -r1.35 target.h
--- target.h 19 Jan 2003 04:06:46 -0000 1.35
+++ target.h 12 Feb 2003 19:38:17 -0000
@@ -256,6 +256,7 @@
int (*to_remove_watchpoint) (CORE_ADDR, int, int);
int (*to_insert_watchpoint) (CORE_ADDR, int, int);
int (*to_stopped_by_watchpoint) (void);
+ int to_have_continuable_watchpoint;
CORE_ADDR (*to_stopped_data_address) (void);
int (*to_region_size_ok_for_hw_watchpoint) (int);
void (*to_terminal_init) (void);
@@ -961,6 +962,13 @@
#ifndef STOPPED_BY_WATCHPOINT
#define STOPPED_BY_WATCHPOINT(w) \
(*current_target.to_stopped_by_watchpoint) ()
+#endif
+
+/* Non-zero if we have continuable watchpoints */
+
+#ifndef HAVE_CONTINUABLE_WATCHPOINT
+#define HAVE_CONTINUABLE_WATCHPOINT \
+ (current_target.to_have_continuable_watchpoint)
#endif
/* HP-UX supplies these operations, which respectively disable and enable
^ permalink raw reply [flat|nested] 64+ messages in thread* Re: patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops
2003-02-12 19:42 patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops Kris Warkentin
@ 2003-02-14 18:49 ` Kris Warkentin
2003-02-20 0:41 ` Andrew Cagney
0 siblings, 1 reply; 64+ messages in thread
From: Kris Warkentin @ 2003-02-14 18:49 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
Ping.
----- Original Message -----
From: "Kris Warkentin" <kewarken@qnx.com>
To: "Kris Warkentin" <kewarken@qnx.com>; "Andrew Cagney"
<ac131313@redhat.com>
Cc: <gdb-patches@sources.redhat.com>
Sent: Wednesday, February 12, 2003 2:42 PM
Subject: Re: patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops
> Here's take 2 on the patch. I had a slight error in the definition of
> HAVE_CONTINUABLE_WATCHPOINT in the first one. I was worried about
> initialization (since infrun.c wanted the default to be zero) but since
> target_ops structures are always declared as global data, it will be fine.
>
> cheers,
>
> Kris
>
> ----- Original Message -----
> From: "Kris Warkentin" <kewarken@qnx.com>
> To: "Andrew Cagney" <ac131313@redhat.com>
> Cc: "Mark Kettenis" <kettenis@chello.nl>; <gdb-patches@sources.redhat.com>
> Sent: Tuesday, February 11, 2003 1:41 PM
> Subject: patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops
>
>
> > Probably easier if I just give a diff for you to comment on.
> >
> > Changelog Entry:
> >
> > 2003-02-11 Kris Warkentin kewarken@qnx.com
> >
> > * target.h: Add to_have_continuable_watchpoint to struct target_ops.
> > Initialize HAVE_CONTINUABLE_WATCHPOINT.
> > * target.c: update_current_target(): Add
> to_have_continuable_watchpoint.
> > * infrun.c: remove initialization of HAVE_CONTINUABLE_WATCHPOINT.
> > * config/i386/nm-i386.h: Change HAVE_CONTINUABLE_WATCHPOINT defines
to
> > 1.
> > * config/i386/nm-i386sco5.h: ditto
> > * config/i386/nm-i386sol2.h: ditto
> > * config/s390/nm-linux.h: ditto
> > * config/sparc/nm-sun4sol2.h: ditto
> >
> > cheers,
> >
> > Kris
> >
> > ----- Original Message -----
> > From: "Kris Warkentin" <kewarken@qnx.com>
> > To: "Andrew Cagney" <ac131313@redhat.com>
> > Cc: "Mark Kettenis" <kettenis@chello.nl>;
<gdb-patches@sources.redhat.com>
> > Sent: Tuesday, February 11, 2003 1:11 PM
> > Subject: Re: patch to add QNX NTO i386 support
> >
> >
> > > Hi Andrew,
> > >
> > > Sorry it took so long to reply - I took a couple days to do a port of
a
> > > vxworks lib for a BSP we're working on.
> > >
> > > Question: can I make any assumption about the initialization of the
> > > target_ops vector? It looks like infrun.c wants
> > HAVE_CONTINUABLE_BREAKPOINT
> > > to default to zero but I didn't see anywhere int target.[ch] that ops
> were
> > > being initialized.
> > >
> > > cheers,
> > >
> > > Kris
> > >
> > > > > /* After a watchpoint trap, the PC points to the instruction after
> > > > >> > the one that caused the trap. Therefore we don't need to
step
> > > over
> > > > >
> > > > > it.
> > > > >
> > > > >> > But we do need to reset the status register to avoid another
> > trap.
> > > > >
> > > > > */
> > > > >
> > > > >> > #define HAVE_CONTINUABLE_WATCHPOINT
> > > > >
> > > > >>
> > > > >> Hmm, this poses an interesting problem. The other i386 targets
> have
> > > > >> this in their nm.h file, since they consider hardware watchpoints
> as
> > a
> > > > >> native-only feature. However, this isn't necessarily right since
> we
> > > > >> might support hardware breakpoints via the remote protocol. If
you
> > > > >> can live with the native-only approach, please move this to your
> nm.h
> > > > >> file. Otherwise we might need to multi-arch this definition.
> > > > >
> > > > >
> > > > > Okay, file that under TODO along with the solib stuff. We have
> > hardware
> > > > > breakpoints on all our remote targets that support them.
> > > >
> > > > Just FYI, this needs to be added to the target vector (target.h) and
> not
> > > > the architecture vector.
> > > >
> > > > For examples, see STOPPED_BY_WATCHPOINT et.al. A bit of
manipulation
> of
> > > > the existing nm-*.h files will be needed - have them define the
value
> as
> > > 1.
> > > >
> > > > Can you please submit a separate patch that does just this.
> > > >
> > > > Andrew
> > > >
> > > >
> > > >
> > >
> > >
> >
>
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops
2003-02-14 18:49 ` Kris Warkentin
@ 2003-02-20 0:41 ` Andrew Cagney
2003-02-20 1:09 ` Kris Warkentin
0 siblings, 1 reply; 64+ messages in thread
From: Andrew Cagney @ 2003-02-20 0:41 UTC (permalink / raw)
To: Kris Warkentin; +Cc: gdb-patches
Kris,
I remember asking a question about debug info (so that set debug target
1) did something useful (or did I misremember?).
Andrew
^ permalink raw reply [flat|nested] 64+ messages in thread
* Re: patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops
2003-02-20 0:41 ` Andrew Cagney
@ 2003-02-20 1:09 ` Kris Warkentin
0 siblings, 0 replies; 64+ messages in thread
From: Kris Warkentin @ 2003-02-20 1:09 UTC (permalink / raw)
To: Andrew Cagney; +Cc: gdb-patches
The original message pasted below. You had asked me to submit a separate
patch.
cheers,
Kris
>> > #define HAVE_CONTINUABLE_WATCHPOINT
>
>>
>> Hmm, this poses an interesting problem. The other i386 targets have
>> this in their nm.h file, since they consider hardware watchpoints as a
>> native-only feature. However, this isn't necessarily right since we
>> might support hardware breakpoints via the remote protocol. If you
>> can live with the native-only approach, please move this to your nm.h
>> file. Otherwise we might need to multi-arch this definition.
>
>
> Okay, file that under TODO along with the solib stuff. We have hardware
> breakpoints on all our remote targets that support them.
Just FYI, this needs to be added to the target vector (target.h) and not
the architecture vector.
For examples, see STOPPED_BY_WATCHPOINT et.al. A bit of manipulation of
the existing nm-*.h files will be needed - have them define the value as 1.
Can you please submit a separate patch that does just this.
Andrew
----- Original Message -----
From: "Andrew Cagney" <ac131313@redhat.com>
To: "Kris Warkentin" <kewarken@qnx.com>
Cc: <gdb-patches@sources.redhat.com>
Sent: Wednesday, February 19, 2003 7:46 PM
Subject: Re: patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops
> Kris,
>
> I remember asking a question about debug info (so that set debug target
> 1) did something useful (or did I misremember?).
>
> Andrew
>
>
^ permalink raw reply [flat|nested] 64+ messages in thread
end of thread, other threads:[~2003-02-27 20:28 UTC | newest]
Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-03 20:19 patch to add QNX NTO i386 support Kris Warkentin
2003-02-04 7:23 ` Eli Zaretskii
2003-02-04 13:33 ` Kris Warkentin
2003-02-04 13:53 ` Kris Warkentin
2003-02-04 19:59 ` Eli Zaretskii
2003-02-04 20:12 ` Kris Warkentin
2003-02-05 5:50 ` Eli Zaretskii
2003-02-04 22:02 ` Andrew Cagney
2003-02-05 1:29 ` Kris Warkentin
2003-02-05 2:40 ` Andrew Cagney
2003-02-05 2:59 ` Andrew Cagney
2003-02-05 12:31 ` Kris Warkentin
2003-02-05 2:55 ` Andrew Cagney
2003-02-05 17:15 ` Kris Warkentin
2003-02-05 18:46 ` Andrew Cagney
2003-02-07 1:48 ` Kris Warkentin
2003-02-07 19:22 ` Mark Kettenis
2003-02-07 20:08 ` Kris Warkentin
2003-02-07 21:59 ` Andrew Cagney
2003-02-11 18:11 ` Kris Warkentin
2003-02-11 18:41 ` patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops Kris Warkentin
2003-02-12 22:18 ` patch to add QNX NTO i386 support Kris Warkentin
2003-02-12 22:44 ` Daniel Jacobowitz
2003-02-13 0:52 ` Kris Warkentin
2003-02-13 22:21 ` Mark Kettenis
2003-02-13 22:29 ` Kris Warkentin
2003-02-13 22:53 ` Mark Kettenis
2003-02-13 23:55 ` Kris Warkentin
2003-02-14 0:01 ` Kris Warkentin
2003-02-13 21:56 ` Kris Warkentin
2003-02-13 22:08 ` Daniel Jacobowitz
2003-02-13 22:25 ` Kris Warkentin
2003-02-13 22:29 ` Daniel Jacobowitz
2003-02-13 23:48 ` Kris Warkentin
2003-02-14 0:03 ` Daniel Jacobowitz
2003-02-14 0:09 ` Kris Warkentin
2003-02-14 0:13 ` Daniel Jacobowitz
2003-02-14 0:35 ` Kris Warkentin
2003-02-17 14:58 ` Andrew Cagney
2003-02-17 15:44 ` Daniel Jacobowitz
2003-02-17 16:45 ` Andrew Cagney
2003-02-17 18:54 ` Kris Warkentin
2003-02-18 21:26 ` Andrew Cagney
2003-02-18 22:30 ` Kris Warkentin
2003-02-20 0:42 ` Andrew Cagney
2003-02-27 19:02 ` Kris Warkentin
2003-02-27 19:56 ` Andrew Cagney
2003-02-27 20:02 ` Daniel Jacobowitz
2003-02-27 20:10 ` Andrew Cagney
2003-02-27 20:11 ` Kris Warkentin
2003-02-27 20:23 ` Andrew Cagney
2003-02-27 20:28 ` Kris Warkentin
2003-02-05 20:48 ` Mark Kettenis
2003-02-05 21:23 ` Kris Warkentin
2003-02-05 21:43 ` Kris Warkentin
2003-02-05 22:24 ` Mark Kettenis
2003-02-06 15:13 ` Kris Warkentin
2003-02-06 18:19 ` Andrew Cagney
2003-02-05 22:48 ` Mark Kettenis
2003-02-06 15:08 ` Kris Warkentin
2003-02-12 19:42 patch to add HAVE_CONTINUABLE_BREAKPOINT to target_ops Kris Warkentin
2003-02-14 18:49 ` Kris Warkentin
2003-02-20 0:41 ` Andrew Cagney
2003-02-20 1:09 ` Kris Warkentin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox