summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Snyder <msnyder@redhat.com>2008-06-12 00:56:00 +0000
committerMichael Snyder <msnyder@redhat.com>2008-06-12 00:56:00 +0000
commit280e2d671ade34d52f35be6bee65968d1cd642fe (patch)
tree12566a2b671f7d3014267c4557f728942bd15deb
parent2c7811d77ae27fea5e7cd49f2c32f51f14d6916a (diff)
downloadgdb-280e2d671ade34d52f35be6bee65968d1cd642fe.tar.gz
2008-06-11 Michael Snyder <msnyder@specifix.com>
* gdbserv-state.c (gdbserv_data_packet): Parse reverse step and reverse continue packets. For now, uses an ugly global variable to export the reverse flag.
-rw-r--r--rda/ChangeLog1241
-rw-r--r--rda/lib/gdbserv-state.c1327
2 files changed, 2568 insertions, 0 deletions
diff --git a/rda/ChangeLog b/rda/ChangeLog
new file mode 100644
index 00000000000..e2d386a80dd
--- /dev/null
+++ b/rda/ChangeLog
@@ -0,0 +1,1241 @@
+2008-06-11 Michael Snyder <msnyder@specifix.com>
+
+ * gdbserv-state.c (gdbserv_data_packet): Parse reverse step
+ and reverse continue packets. For now, uses an ugly global
+ variable to export the reverse flag.
+
+2005-03-03 Kevin Buettner <kevinb@redhat.com>
+
+ * lib/crc32.h, lib/crc32.c: New files.
+ * lib/Makefile.am (librda_la_SOURCES): Add crc32.c to list.
+ * lib/Makefile.in: Regenerate.
+ * lib/gdbserv-state.c (crc32.h): Include.
+ (read_memory, do_qCRC_packet): New functions.
+ (gdbserv_data_packet): Add support for qCRC packet.
+
+2005-02-07 Jim Blandy <jimb@redhat.com>
+
+ Regenerate Makefile.in files generated by top-level configure
+ script using Automake 1.9.3.
+ * lib/Makefile.am: Don't write out rules for both '.a' and '.la'
+ versions of the library. Libtool generates a '.a' library
+ automatically.
+ * Makefile.in, lib/Makefile.in, qe/Makefile.in,
+ samples/Makefile.in: Regenerated.
+
+2004-12-09 Jim Blandy <jimb@redhat.com>
+
+ * configure.in: Clean up junk whitespace. Don't call
+ AC_CONFIG_SUBDIRS on variables' values; invoke it on a constant
+ value, at each place we add a directory to targ_subdirs, as
+ recommended by the autoconf manual.
+ * aclocal.m4, configure: Regenerated.
+
+2004-10-07 Jim Blandy <jimb@redhat.com>
+
+ * lib/gdbserv-state.c (do_get_registers_p_packet): Don't produce a
+ ';' trailing the register value unless there are more register
+ values to come. This makes the multi-register packet
+ upward-compatible with the single-register request / reply
+ expected by GDB.
+
+ * samples/async.c: #define _GNU_SOURCE before #including any
+ files, to get prototypes for GNU-specific functions like
+ strsignal.
+
+2004-09-24 Jim Blandy <jimb@redhat.com>
+
+ * lib/gdbserv-output.c, samples/demo-target.c, samples/main.c,
+ samples/poll.c: #include <string.h>.
+
+2004-09-14 Jim Blandy <jimb@theseus.home>
+
+ * HOWTO: Fix typos.
+
+2004-07-23 Michael Snyder <msnyder@redhat.com>
+
+ * MAINTAINERS: Remove Andrew Cagney, at his request.
+
+2004-07-09 Michael Snyder <msnyder@redhat.com>
+
+ * samples/demo-target.c (demo_set_thread_mem): Allocate new
+ simulated memory in hunks, rather than one byte at a time.
+ If target_mem.base moves down, copy contents up.
+
+ * samples/demo-target.c (demo_target): Call malloc only once,
+ so that gdb can detach and re-attach repeatedly.
+
+ * lib/gdbserv-target.c (gdbserv_fromtarget_terminate): Rename
+ parameter from exitval to sigval (it's a signal number).
+ * lib/gdbserv-target.c (gdbserv_totarget): Comment spelling fix.
+ * lib/gdbserv-state.c (gdbserv_fromclient_break): Add break
+ statement to default.
+
+2003-05-20 Kevin Buettner <kevinb@redhat.com>
+
+ * lib/gdbserv-utils.c (gdbserv_le_bytes_from_reg): Fix typo that
+ caused incorrect number of bytes to be copied.
+
+2003-01-16 Kevin Buettner <kevinb@redhat.com>
+
+ * lib/gdbserv-state.c (do_status_packet, gdbserv_data_packet): Fix
+ memset() calls - the arguments were in the wrong order.
+ (gdbserv_data_packet): Check return value from get_reg() call.
+
+2002-12-02 Kevin Buettner <kevinb@redhat.com>
+
+ * include/gdbserv-utils.h, lib/gdbserv-utils.c
+ (gdbserv_be_bytes_to_reg, gdbserv_le_bytes_to_reg)
+ (gdbserv_be_bytes_from_reg, gdbserv_le_bytes_from_reg)
+ (gdbserv_host_bytes_to_reg, gdbserv_host_bytes_from_reg):
+ Revise interfaces.
+
+2002-11-04 Kevin Buettner <kevinb@redhat.com>
+
+ * Makefile.in, aclocal.m4, configure, lib/Makefile.in, qe/Makefile.in,
+ samples/Makefile.in, unix/configure: Regenerate configury using
+ aclocal 1.6.3, automake 1.6.3, and autoconf 2.53.
+
+2002-08-22 Kevin Buettner <kevinb@redhat.com>
+
+ * lib/Makefile.am (INCLUDES): Remove references to bfd.
+ (THESOURCES): Remove bfd-loader.c from list.
+ * lib/Makefile.in: Regenerate.
+ * samples/Makefile.am (sample_DEPLIBS): Remove references to
+ bfd and libiberty.
+ * samples/Makefile.in: Regenerate.
+
+2002-08-21 Kevin Buettner <kevinb@redhat.com>
+
+ * HOWTO, MAINTAINERS, NEWS, README, REMOTE-HACK-RULES,
+ configure.in, lib/Makefile.am, lib/gdbserv-target.c,
+ samples/Makefile.am, samples/async.c, samples/demo-target.c,
+ samples/main.c, samples/poll.c: Change ``libremote'' references
+ into ``RDA'' references.
+ * configure, lib/Makefile.in, samples/Makefile.in: Regenerate.
+
+2002-08-15 Kevin Buettner <kevinb@redhat.com>
+
+ * include/gdblog.h, include/gdbloop.h, include/gdbsched.h,
+ include/gdbserv-client.h, include/gdbserv-input.h,
+ include/gdbserv-log.h, include/gdbserv-output.h,
+ include/gdbserv-target.h, include/gdbserv-utils.h,
+ include/gdbserv.h, include/gdbsocket.h, include/stdio-log.h,
+ lib/gdblog.c, lib/gdbloop.c, lib/gdbsched.c,
+ lib/gdbserv-input.c, lib/gdbserv-log.c, lib/gdbserv-output.c,
+ lib/gdbserv-state.c, lib/gdbserv-state.h,
+ lib/gdbserv-target.c, lib/gdbserv-utils.c, lib/gdbsocket.c,
+ lib/stdio-log.c, qe/README, qe/inc-backwards.c,
+ qe/inc-forward.c, qe/inc-gdblog.c, qe/inc-gdbloop.c,
+ qe/inc-gdbsched.c, qe/inc-gdbserv-client.c,
+ qe/inc-gdbserv-input.c, qe/inc-gdbserv-log.c,
+ qe/inc-gdbserv-output.c, qe/inc-gdbserv-target.c,
+ qe/inc-gdbserv-utils.c, qe/inc-gdbserv.c, qe/inc-gdbsocket.c,
+ qe/inc-stdio-log.c, samples/async.c, samples/demo-target.c,
+ samples/demo-target.h, samples/main.c, samples/poll.c,
+ samples/thread.c: Update copyright notices.
+
+2002-08-14 Kevin Buettner <kevinb@redhat.com>
+
+ * include/bfd-loader.h: Delete.
+ * lib/bfd-loader.c: Delete.
+ * samples/main.c (main): Eliminate code for loading files.
+ (usage): Adjust usage message to account for the fact that we can
+ no longer load files.
+
+2002-01-02 Ben Elliston <bje@redhat.com>
+
+ * MAINTAINERS: Update mail addresses.
+
+2001-10-13 Kevin Buettner <kevinb@redhat.com>
+
+ * include/gdbserv-utils.h (gdbserv_be_bytes_to_reg)
+ (gdbserv_le_bytes_to_reg, gdbserv_be_bytes_from_reg)
+ (gdbserv_le_bytes_from_reg, gdbserv_native_bytes_to_reg)
+ (gdbserv_native_bytes_from_reg): New functions.
+ * lib/gdbserv-utils.c (config.h): Include.
+ (string.h): Include.
+ (reverse_copy_bytes, gdbserv_be_bytes_to_reg)
+ (gdbserv_le_bytes_to_reg, gdbserv_be_bytes_from_reg)
+ (gdbserv_le_bytes_from_reg, gdbserv_host_bytes_to_reg)
+ (gdbserv_host_bytes_from_reg): New functions.
+
+2001-09-28 Andrew Haley <aph@cambridge.redhat.com>
+
+ * samples/main.c (main): Work around SIGCHLD problem.
+
+2001-09-27 David Woodhouse <dwmw2@redhat.com>
+
+ * lib/gdbserver-target.c (gdbserv-totarget): Zero sigval to indicate
+ success if target->process_signal succeeds, instead of doing so
+ only if it failed.
+
+2001-08-20 Jonathan Larmour <jlarmour@redhat.com>
+
+ * lib/gdbsocket.c (process_read): Treat a read reporting shutdown
+ or connection reset as EOF.
+
+2001-08-02 Michael Keezer <mkeezer@redhat.com>
+
+ * unix/configure.in: Add am33_2.0 & mn10300.
+ * unix/config.in: Add AM33_LINUX_TARGET & AM33_2_0_LINUX_TARGET.
+ * unix/linux-target.c: am33_2.0 & mn10300 support.
+
+2001-07-26 Michael Snyder <msnyder@redhat.com>
+
+ * lib/gdbserv-utils.c (gdbserv_raw_to_hex): Increment pointer.
+
+2001-06-25 Michael Snyder <msnyder@redhat.com>
+
+ * include/gdbserv-target.h: Fill in the remaining GDB signal numbers.
+
+2001-06-12 Corinna Vinschen <vinschen@redhat.com>
+
+ * configure.in: Add linux as possible host for xscale subdir.
+ * configure: Regenerated.
+
+2001-04-26 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbsocket.c: Include <ctype.h>.
+ (dump_buf): New function. Handle unprintable characters.
+ (process_read): Use.
+ (raw_write): Use.
+
+ * lib/bfd-loader.c (struct lng): Add exit_addr and loaded_p.
+ (fromtarget): Check for unexpected stops.
+ (bfd_loader_exit): Report the exit status and stop address.
+
+2001-04-23 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbserv-target.c: Include <assert.h>.
+ (gdbserv_totarget): Abort when the target fails to handle either
+ START_ADDR or SIGVAL.
+
+2001-04-23 Andrew Cagney <ac131313@redhat.com>
+
+ * include/gdblog.h (gdblog_xlong, gdblog_xlong_ftype): Declare.
+ (gdblog_new): Add log_xlong parameter.
+ * lib/gdblog.c (struct gdblog): Add log_xlong.
+ (gdblog_xlong): New function.
+ (gdblog_new): Initialize log_xlong.
+ * lib/stdio-log.c (do_stdio_log_xlong): New function.
+ (stdio_log): Add do_stdio_log_xlong.
+
+ * lib/bfd-loader.c (load_n_go): Use gdblog_xlong to print
+ addresses.
+
+2001-04-19 Andrew Cagney <ac131313@redhat.com>
+
+ * samples/async.c: Include <string.h> for strsignal.
+
+2001-04-17 Alexandre Oliva <aoliva@redhat.com>
+
+ * acinclude.m4: Get macros from ../libtool.m4 and ../gettext.m4.
+ * configure.in: Call CY_WITH_NLS.
+ * samples/Makefile.am (sample_DEPLIBS): New. Copied from
+ sample_LDADD, except for libintl.a.
+ (sample_LDADD): Set as sample_DEPLIBS plus INTLLIBS.
+ (sample_DEPENDENCIES): New. Same as sample_DEPLIBS plus INTLDEPS.
+ * aclocal.m4, configure, samples/Makefile.in: Rebuilt.
+
+2001-04-16 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbsocket.c (process_accept): Only SIGIO when
+ gdbsocket_async_p.
+
+2001-04-15 Andrew Cagney <ac131313@redhat.com>
+
+ * include/bfd-loader.h (bfd_loader_exit): Replace bfd_shutdown.
+ * lib/bfd-loader.c (lng): Add ``exit_val''.
+ (fromtarget): Save the exit value.
+ (bfd_loader_exit): Call exit with ``exit_val''.
+ * samples/main.c (main): Replace bfd_shutdown with
+ bfd_loader_exit.
+
+2001-04-15 Andrew Cagney <ac131313@redhat.com>
+
+ * include/gdbserv-target.h (struct gdbserv_target): Add ``to''.
+ (gdbserv_totarget): Declare.
+ (struct gdbserv_target): Make process_set_pc's ``val'' parameter
+ constant.
+ * lib/gdbserv-target.c: Include "gdbserv-utils.h" and "gdbserv.h".
+ (gdbserv_totarget): New function.
+
+ * lib/gdbserv-state.c (gdbserv_data_packet): Rewrite ``c'', ``C'',
+ ``s'', ``S'' and ``i'' packet code. Use gdbserv_totarget. Never
+ transition into state GDBSERV_STATE_STEPPING.
+ * lib/gdbserv-state.h (enum gdbserv_state): Delete
+ GDBSERV_STATE_STEPPING.
+ * lib/gdbserv-state.c (state2str, fromtarget): Update.
+ (gdbserv_fromclient_break): Ditto..
+
+ * lib/bfd-loader.c (load_n_go): Compute the start address. Pass
+ it to gdbserv_totarget.
+ * samples/demo-target.c (demo_process_set_pc): New function.
+ (demo_target): Initialize process_set_pc.
+
+2001-04-15 Andrew Cagney <ac131313@redhat.com>
+
+ * include/gdbserv-target.h: Add ``stop_addr'' parameter. Document.
+ (struct gdbserv_target): Update member ``from''.
+ * lib/gdbserv-target.c (gdbserv_fromtarget_reset)
+ (gdbserv_fromtarget_restarted, gdbserv_fromtarget_terminate)
+ (gdbserv_fromtarget_exit, gdbserv_fromtarget_thread_break)
+ (gdbserv_fromtarget_break, gdbserv_fromtarget): Update.
+ * lib/gdbserv-state.c (fromtarget): Update.
+ * lib/bfd-loader.c (fromtarget_stopped): Delete.
+ (fromtarget): Update.
+ * samples/demo-target.c (do_fromtarget_ready): Update.
+
+2001-04-13 Andrew Cagney <ac131313@redhat.com>
+
+ * samples/demo-target.c: Replace demo_set_memo with
+ demo_set_thread_mem. Replace demo_continue_program with
+ demo_continue_thread.
+
+ * lib/Makefile.am (THESOURCES): Add bfd-loader.c
+ (INCLUDES): Add top level include and bfd directories.
+ * lib/Makefile.in: Regenerate.
+ * include/bfd-loader.h: New file.
+ * lib/bfd-loader.c: New file.
+
+ * samples/main.c: Include "bfd-loader.h", "gdbsched.h" and
+ "gdbserv-target.h".
+ (main): Add ``-v'' verbose option.
+ (main): If the parameter isn't numeric or ``-'' assume that it is
+ a file to load using bfd_load. Schedule a program quit event.
+ (usage): Update.
+ (fake_exit): New function.
+ * samples/Makefile.am (sample_LDADD): Add libbfd.la, libintl.a and
+ libiberty.a.
+ * samples/Makefile.in: Regenerate.
+
+2001-04-13 Andrew Cagney <ac131313@redhat.com>
+
+ * samples/main.c: Include <unistd.h>, <signal.h>, <ctype.h>,
+ "gdbsched.h", "gdbserv-target.h" and <time.h>.
+ (main): Add -d option. Interpret ``-'' parameter as stdio.
+ Validate port number. Add usage/help message. Use variable
+ shutdown to determine if the startup worked.
+ (usage): New function.
+ (do_close): New function.
+ * samples/stdio.c: Delete.
+ * samples/Makefile.am (noinst_PROGRAMS): Delete stdio.
+ (stdio_SOURCES, stdio_LDADD): Delete.
+ * samples/Makefile.in: Regenerate.
+
+2001-04-13 Andrew Cagney <ac131313@redhat.com>
+
+ * samples/demo-target.c (demo_target): New function.
+ (do_fromtarget_reset): New function.
+ (demo_attach): Use demo_target and do_fromtarget_reset. Take
+ server out of reset state.
+ * samples/thread.c (thread_attach): Call demo_target.
+
+2001-04-12 Andrew Cagney <ac131313@redhat.com>
+
+ * include/gdbserv.h (gdbserv_state): Delete declaration
+ (GDBSERV_STATE_STUMBLING): Delete.
+ (enum gdbserv_state): Move from here.
+ * lib/gdbserv-state.h (enum gdbserv_state): Back to here.
+ * lib/gdbserv-state.c (state2str): Update.
+ * lib/gdbserv-target.c: Don't include "gdbserv.h".
+
+2001-04-12 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbserv-state.c (gdbserv_fromclient_attach): Create a cycle
+ of GDBSERVs. Initialize ``from'' method in target vector.
+ (gdbserv_fromclient_detach): Clear ``from'' method.
+ (do_exit_packet): New function. Output an exit/terminate packet.
+ (fromtarget): New function.
+ (gdbserv_fromtarget_reset): Delete.
+ (gdbserv_fromtarget_break): Delete.
+ (gdbserv_fromtarget_thread_break): Delete.
+ (gdbserv_fromtarget_exit): Delete.
+ (gdbserv_fromtarget_terminate): Delete.
+
+ * include/gdbserv-target.h (gdbserv_fromtarget): Declare.
+ (enum gdbserv_fromtarget_event): Define.
+ (struct gdbserv_target): Add ``from''.
+ (GDBSERV_SIG): Move definitions to start of file.
+
+ * lib/gdbserv-state.h (struct gdbserv): Add ``from'' and ``to'' as
+ links up and down the target stack.
+ * lib/gdbserv-target.c: New file.
+ * lib/Makefile.am (THESOURCES): Add gdbserv-target.c
+ * lib/Makefile.in: Regenerate.
+
+2001-04-12 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbsocket.c (gdbsocket_had_sigio_p): Delete.
+ (sigio_socket): Delete.
+ (gdbsocket_sigio_enable, gdbsocket_sigio_disable): Delete.
+ (gdbsocket_async, gdbsocket_async_p): New function and variable.
+ (async_fd): Only enable O_ASYNC when async selected.
+ (gdbsocket_startup): Don't call gdbsocket_sigio_disable.
+
+ * include/gdbsocket.h (gdbsocket_had_sigio_p): Delete.
+ (gdbsocket_sigio_enable, gdbsocket_sigio_enable): Delete.
+ (gdbsocket_async): New function.
+
+ * samples/async.c (set_poll_p): Replace handle_sigalrm.
+ (poll_p): Volatile global.
+ (main): Register signal handlers for both SIGIO and SIGALRM. Check
+ poll_p. Call gdbsocket_sigio to enable O_ASYNC on all file
+ descriptors.
+
+ * include/gdbloop.h (gdbloop_p): Delete.
+ (gdbloop_sigio_enable, gdbloop_sigio_disable): Delete.
+ * lib/gdbloop.c: Update.
+
+2001-04-12 Andrew Cagney <ac131313@redhat.com>
+
+ * include/gdbsocket.h (gdbsocket_poll): Delete declaration.
+ * lib/gdbsocket.c (struct fds): Delete.
+ (gdbsocket_poll, fds_isset, fds_set): Delete functions.
+ * lib/gdbloop.c (poll_gdbsocket): Rename gdbloop_poll.
+ (gdbloop_poll): New function.
+ (gdbloop): Call poll_gdbsocket.
+ * HOWTO: Update
+ * samples/main.c (main): Call gdbloop_poll. Don't include <time.h>
+ * samples/demo-target.h, samples/demo-target.c: Update comments.
+ * samples/thread.c: Update comments.
+
+2001-04-12 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbloop.c (gdbloop): Reverse file / queue processing order -
+ do the task queue second.
+
+2001-04-11 Andrew Cagney <ac131313@redhat.com>
+
+ * samples/async.c: Include <signal.h>, "gdblog.h", "gdbsched.h"
+ and <unistd.h>.
+
+ * lib/gdbloop.c (gdbloop): Delete alarm code. Moved to
+ samples/async.c
+ (handle_sigalarm): Delete. Moved to samples/async.c.
+ (gdbloop_sigio_enabled_p): Delete.
+ (gdbloop_sigio_enable, gdbloop_sigio_disable): Update.
+
+ * samples/async.c (handle_sigalarm): New function.
+ (main): Use alarm to handle timer events.
+
+2001-04-11 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbserv-state.c (reset_state): New function. Fully
+ re-initialize gdbserv.
+ (gdbserv_fromclient_attach): Call reset_state.
+ (gdbserv_data_packet): Ditto for "r" and "R" packets.
+
+ * lib/gdbserv-state.h (struct gdbserv): Add ``event_thread'' and
+ ``event_sigval''.
+
+ * lib/gdbserv-state.c (gdbserv_fromtarget_thread_break): Update
+ ``event_thread'' and ``event_sigval''. Clear "continue_thread".
+ (do_status_packet): New function. Move "T" packet code to here.
+ (gdbserv_fromtarget_thread_break): Call do_status_packet.
+ (gdbserv_data_packet): Use do_status_packet to respond to "?".
+ (do_current_thread_query): Always return the general thread.
+
+2001-04-11 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbloop.c (gdbloop_sigio_enabled_p): New global.
+ (handle_sigalarm): New function.
+ (gdbloop_sigio_enable): Register handle_sigalarm for SIGALRM.
+ (gdbloop_sigio_disable): Deregister SIGALRM.
+ (gdbloop): When gdbloop_sigio_enabled_p, schedule an alarm to
+ triger the next round of event processing.
+
+2001-04-11 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbsched.c: Include "gdblog.h" and "gdbsocket.h".
+ (gdbsched_schedule, gdbsched_deschedule)
+ (gdbsched_dispatch): Add tracing.
+
+ * lib/gdbsched.c (gdbsched_schedule): Pre- rather than post-
+ increment sched_db. Stop the first sched tag being NULL.
+
+2001-04-10 Andrew Cagney <ac131313@redhat.com>
+
+ * samples/demo-target.h (demo_break): Delete declaration.
+ (struct gdbserv_target): Delete declaration.
+ (demo_ticks_before_break_p): Delete declaration.
+ * samples/demo-target.c: Include <time.h>, <sys/time.h> and
+ "gdbsched.h".
+ (demo_ticks_before_break_p): Delete global variable.
+ (dispatch_break, sched_break): New functions.
+ (demo_break_program): Call sched_break.
+ (demo_restart_program): Ditto.
+ (demo_singlestep_program): Ditto.
+ (demo_cyclestep_program): Ditto.
+ (demo_continue_program): Ditto.
+ (demo_break): Delete function.
+
+ * samples/poll.c: Include <time.h>, <sys/time.h> and
+ "gdbsched.h". Delete redundant include of <sys/types.h>.
+ (main): Replace demo_ticks_before_break_p with call to
+ gdbsched_dispatch.
+ * samples/fdset.c (main): Ditto.
+
+ * samples/main.c: Include <time.h>, <sys/time.h> and "gdbloop.h".
+ (main): Replace gdbsocket_poll and demo_ticks_before_break_p with
+ call to gdbloop.
+ * samples/stdio.c: Ditto.
+
+ * samples/thread.c: New file.
+ * samples/thread-target.c: Delete.
+ * samples/Makefile.am (thread_SOURCES): Update.
+ * samples/Makefile.in: Regnerate.
+
+2001-04-11 Andrew Cagney <ac131313@redhat.com>
+
+ * samples/fdset.c: Delete. See lib/gdbloop.c.
+ * samples/Makefile.am (noinst_PROGRAMS): Delete fdset.
+ (fdset_SOURCES): Delete.
+ (fdset_LDADD): Ditto.
+ * samples/Makefile.in: Regenerate.
+
+2001-04-11 Andrew Cagney <ac131313@redhat.com>
+
+ * include/gdbloop.h (gdbloop_p): Declare.
+ (gdbloop_sigio_enable, gdbloop_sigio_disable): Declare.
+ (gdbloop): Add TIMEOUT parameter.
+ * lib/gdbloop.c: Don't include <sys/types.h>. Include <assert.h>,
+ <signal.h> and <fcntl.h>.
+ (sigio_fd): New function.
+ (gdbloop_sigio_enable, gdbloop_sigio_disable): New functions.
+ (gdbloop_poll): Cleanup. Check gdbloop_p. Make static.
+ (gdbloop): Update to handle timeout as a parameter.
+
+ * include/gdbsocket.h (gdbsocket_poll): Deprecate.
+ (gdbsocket_sigio_disable): Deprecate.
+ (gdbsocket_sigio_enable): Deprecate.
+ (gdbsocket_had_sigio_p): Deprecate.
+
+ * samples/async.c: New file.
+ * samples/Makefile.am (noinst_PROGRAMS): Add async demo.
+ (async_LDADD, sample_SOURCES): Define.
+ * samples/Makefile.in: Regenerate.
+ * samples/demo-target.c (demo_break_program): Print a trace
+ message.
+
+2001-04-10 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbsocket.c (async_fd): Ensure that the SIGIO is delivered
+ to this PID.
+ (process_accept): Use kill SIGIO, instead of setting
+ gdbsocket_had_sigio_p, to force the re-read.
+
+2001-04-10 Andrew Cagney <ac131313@redhat.com>
+
+ * qe/inc-gdbloop.c, qe/inc-gdbsched.c: New files.
+ * qe/Makefile.am (qe_SOURCES): Add inc-gdbloop.c and
+ inc-gdbsched.c.
+ * qe/Makefile.in: Regenerate.
+
+2001-04-10 Andrew Cagney <ac131313@redhat.com>
+
+ * include/gdbsched.h, lib/gdbsched.c: New files. Simple
+ scheduler.
+ * lib/gdbloop.c, include/gdbloop.h: New files. Simple
+ event-loop.
+ * lib/Makefile.am (THESOURCES): Add gdbloop.c and gdbsched.c.
+ * lib/Makefile.in: Regenerate.
+
+2001-04-10 Andrew Cagney <ac131313@redhat.com>
+
+ * include/gdbserv-utils.h: Add fake close of extern "C" to pacify
+ emacs indentation.
+ * include/gdbserv-target.h: Ditto.
+ * include/gdbserv-output.h: Ditto.
+ * include/gdbserv-input.h: Ditto.
+ * include/gdbserv-client.h: Ditto.
+ * include/gdbserv.h: Ditto.
+
+2001-04-09 Michael Snyder <msnyder@redhat.com>
+
+ * lib/gdbserv-state.c (gdbserv_data_packet): Give preference to
+ threaded cyclestep method. Likewise threaded get_mem / set_mem.
+
+2001-04-05 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbserv-state.c (gdbserv_fromtarget_thread_break): Revert
+ change ``2001-04-05 Andrew Cagney <ac131313@redhat.com>'' that
+ cleared the general_thread.
+
+ * lib/gdbserv-state.c (gdbserv_data_packet)
+ (do_select_thread_packet): Revert ``2001-04-05 Michael Snyder
+ <msnyder@redhat.com>'' that cleared the general_thread.
+
+2001-04-05 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbserv-state.c (gdbserv_data_packet): Move code clearing
+ the general thread to gdbserv_fromtarget_thread_break.
+
+2001-04-05 Michael Snyder <msnyder@redhat.com>
+
+ * gdbserv-state.c (gdbserv_data_packet): Discard any saved general
+ thread on step or continue. GDB doesn't always cancel it, but the
+ general thread should not persist between stop events.
+ (do_select_thread_packet): Both the continue
+ thread and the general thread may be set to null.
+ NOTE: All methods that may receive the general thread must be
+ prepared to receive NULL (defaulting to the current thread).
+
+2001-04-03 David Smith <dsmith@redhat.com>
+
+ * lib/gdbserv-state.c (do_current_thread_query): Try to figure out
+ the correct thread to use when returning the thread id.
+
+2001-04-02 Michael Snyder <msnyder@redhat.com>
+
+ * lib/gdbserv-state.c (do_get_registers_p_packet): Check for
+ get_thread_reg rather than get_reg, since that is what will
+ be used. While we're at it, check for reg_format and output_reg.
+ (gdbserv_data_packet): Give first preference to thread-aware
+ register methods (if defined) for g/G/P packets. That way, to
+ add thread awareness, a backend need only define the new methods
+ (without nullifying the old ones). This makes it possible to
+ fall back on the old ones if necessary. FIXME should it be an
+ error if there is no target register method? Also give first
+ preference to thread-aware step and continue methods.
+
+2001-03-23 David Smith <dsmith@redhat.com>
+
+ * lib/gdbserv-state.c (gdbserv_fromtarget_thread_break): If a NULL
+ thread is passed in, try to figure out the correct thread to use.
+ In addition, don't change the value of the "continue_thread".
+
+ * samples/thread-target.c (demo_break): Calls
+ gdbserv_fromtarget_thread_break() with a NULL thread.
+
+2001-03-22 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbsocket.c (struct session): Rename ``struct gdbsocket''.
+ (session_db): Rename gdb_sockets.
+ (gdbsocket_shutdown): Update.
+ (gdbsocket_reopen): Update.
+ (gdbsocket_fd_set): Update.
+ (gdbsocket_fd_isset): Update.
+
+ * include/gdbsocket.h (gdbsocket_fd_isset, gdbsocket_poll): Delete
+ paramters to_target_attach and target_attach_data.
+ (gdbsocket_startup): Add parameters to_target_attach and
+ target_attach_data.
+
+ * lib/gdbsockets.c (gdbscket_fd): Delete static variable.
+ (struct server): Declare.
+ (server_db): Declare static variable.
+ (gdbsocket_startup): Add to_target_attach and target_attach_data
+ parameters. Enter the server in the server_db.
+ (gdbsocket_shutdown): Handle servers in server_db instead of
+ single gdbsocket_fd.
+ (gdbsocket_fd_set): Ditto.
+ (gdbsocket_fd_isset): Ditto.
+ (process_accept): Replace to_target_attach and target_attach_data
+ with single ``struct server'' parameter.
+ (gdbsocket_fd_isset): Update call.
+
+ * samples/fdset.c (main): Update calls to gdbsocket_startup and
+ gdbsocket_fd_isset.
+ * samples/poll.c (main): Ditto.
+ * samples/main.c (main): Ditto for gdbsocket_startup and
+ gdbsocket_poll.
+ * samples/stdio.c (main): Ditto for gdbsocket_poll.
+
+Thu Mar 22 16:53:09 2001 David Taylor <taylor@redhat.com>
+
+ * lib/gdbserv-state.c (gdbserv_fromtarget_thread_break): When
+ output'ing a register, output the full length, not zero bytes.
+
+2001-03-16 Elena Zannoni <ezannoni@redhat.com>
+
+ * include/gdbserv-target.h (struct gdbserv_target): Add
+ parameter to detach function pointer.
+ * lib/gdbserv-state.c (gdbserv_fromclient_detach): Pass
+ gdbserv->target to detach target call.
+ * samples/demo-target.c (demo_detach): Add parameter.
+ * samples/thread-target.c (demo_detach): Add parameter.
+ * win32/win32-target.c (win32-detach): Add new parameter.
+
+2001-03-15 Andrew Cagney <ac131313@redhat.com>
+
+ * Makefile.am, configure.in: Add qe directory.
+ * Makefile.in, configure: Regenerate.
+ * qe: New directory.
+ * qe/README: New file.
+ * qe/Makefile.am: New file.
+ * qe/Makefile.in: Regenerate.
+ * qe/inc-backwards.c: New file.
+ * qe/inc-forward.c: New file.
+ * qe/inc-gdblog.c: New file.
+ * qe/inc-gdbserv-client.c: New file.
+ * qe/inc-gdbserv-input.c: New file.
+ * qe/inc-gdbserv-log.c: New file.
+ * qe/inc-gdbserv-output.c: New file.
+ * qe/inc-gdbserv-target.c: New file.
+ * qe/inc-gdbserv-utils.c: New file.
+ * qe/inc-gdbserv.c: New file.
+ * qe/inc-gdbsocket.c: New file.
+ * qe/inc-stdio-log.c: New file.
+ * qe/qe.c: New file.
+
+2001-03-15 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdbserv-input.c (gdbserv_input_trace): Delete variable.
+ * lib/gdbsocket.c (gdbsocket_trace): Ditto.
+ * lib/gdbserv-state.c (gdbserv_state_trace): Ditto.
+ * lib/gdbserv-output.c (gdbserv_output_trace): Ditto.
+ * include/gdbsocket.h (gdbsocket_trace): Delete declaration.
+ * include/gdbserv.h (gdbserv_state_trace, gdbserv_input_trace)
+ (gdbserv_output_trace): Ditto.
+
+2001-03-14 Andrew Cagney <ac131313@redhat.com>
+
+ * Move native/ directory to unix/.
+ * configure.in (*linux*): Update.
+ * configure: Regenerate.
+ * aclocal.m4: Regenerate.
+
+2001-03-14 Elena Zannoni <ezannoni@redhat.com>
+
+ * lib/gdbserv-state.h, include/gdbserv-state.h:
+ Revert the previous change. gdbserv-state.h should
+ NOT be exported!!
+
+2001-03-14 Elena Zannoni <ezannoni@redhat.com>
+
+ * lib/gdbserv-state.h: Move from here.
+ * include/gdbserv-state.h: To here.
+
+2001-03-14 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/gdblog.h: Move from here.
+ * include/gdblog.h: To here.
+ * lib/gdbserv-client.h, include/gdbserv-client.h: Ditto.
+ * lib/gdbserv-input.h, include/gdbserv-input.h: Ditto.
+ * lib/gdbserv-log.h, include/gdbserv-log.h: Ditto.
+ * lib/gdbserv-output.h, include/gdbserv-output.h: Ditto.
+ * lib/gdbserv-target.h, include/gdbserv-target.h: Ditto.
+ * lib/gdbserv-utils.h, include/gdbserv-utils.h: Ditto.
+ * lib/gdbserv.h, include/gdbserv.h: Ditto.
+ * lib/gdbsocket.h, include/gdbsocket.h: Ditto.
+ * lib/stdio-log.h, include/stdio-log.h: Ditto.
+
+ * lib/Makefile.am (INCLUDES): Update. Headers moved to ../include.
+ * lib/Makefile.in: Regenerate.
+ * samples/Makefile.am (INCLUDES): Ditto.
+ * samples/Makefile.in: Regenerate.
+
+2001-03-02 Andrew Cagney <ac131313@redhat.com>
+
+ * lib/Makefile.am (THESOURCES): Add gdblog.c, stdio-log.c and
+ gdbserv-log.c.
+ * lib/Makefile.in: Regenerate.
+ * lib/gdblog.h, lib/gdblog.c: New files.
+ * lib/stdio-log.h, lib/stdio-log.c: New files.
+ * lib/gdbserv-log.h, lib/gdbserv-log.c: New files.
+
+ * lib/gdbsocket.h (gdbsocket_trace): Document as deprecated.
+ (gdbsocket_log): Declare variable.
+ * lib/gdbsocket.c: Include "gdblog.h". Update to use gdblog
+ interface for tracing.
+ (gdbsocket_log): Define variable.
+
+ * lib/gdbserv.h (gdbserv_state_trace, gdbserv_input_trace)
+ (gdbserv_output_trace): Document as deprecated.
+ * lib/gdbserv-input.c: Include "gdblog.h" and "gdbserv-log.h".
+ Update to use gdblog interface for tracing.
+ * lib/gdbsocket.c: Ditto.
+ * lib/gdbserv-output.c: Ditto.
+ * lib/gdbserv-state.c: Ditto.
+ (log_state): New function.
+
+ * samples/fdset.c: Include "gdblog.h", "stdio-log.h" and
+ "gdbserv-log.h".
+ (main): Update to use gdbsocket_log, gdbserv_warning_log and
+ gdblog interface.
+ * samples/main.c: Ditto.
+ * samples/poll.c: Ditto.
+ * samples/stdio.c: Ditto.
+ * samples/demo-target.c (demo_attach): Delete code initializing
+ tracing.
+ * samples/thread-target.c (demo_attach): Ditto.
+
+2001-03-02 Andrew Cagney <ac131313@redhat.com>
+
+ * samples/thread-target.c (thread_lookup_by_id): Fix printf fmt
+ argument.
+ (thread_info): Print thread ID, not an internal thread address.
+
+2001-03-02 Andrew Cagney <ac131313@redhat.com>
+
+ * configure.in: Add support for --enable-build-warnings and
+ (--enable-libremote-build-warnings.
+ * configure: Regenerate.
+
+ * Makefile.am (WARN_CFLAGS, WERROR_CFLAGS): Define. Initialized
+ by configure.
+ (AM_CFLAGS): Define.
+ * Makefile.in: Regenerate.
+ * samples/Makefile.am, samples/Makefile.in: Ditto.
+ * lib/Makefile.am, lib/Makefile.in: Ditto.
+
+Thu Dec 21 02:54:39 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * samples/thread-target.c: Include <string.h>.
+ (thread_info): Use sprintf and strdup instead of asprintf.
+
+Thu Dec 21 02:11:49 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-utils.h: Declare ``struct gdbserv'' and ``struct
+ gdbserv_reg''.
+ * lib/gdbserv-output.h: Ditto.
+ * lib/gdbserv-input.h: Declare ``struct gdbserv''.
+
+Wed Dec 20 17:19:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * samples/thread-target.c: New file.
+ * samples/Makefile.am (noinst_PROGRAMS): Add the program thread.
+ (thread_SOURCES, thread_LDADD): Define.
+
+Wed Dec 20 15:51:04 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-output.h, lib/gdbserv-input.h, lib/gdbserv-client.h,
+ lib/gdbserv-state.h, lib/gdbserv.h, lib/gdbsocket.h: Remove
+ #ifndef wrappers. Not needed.
+
+Wed Dec 20 16:29:12 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-state.c (gdbserv_data_packet): Separate check for
+ qRcmd from check that the target supports it.
+ (gdbserv_data_packet): Remove #if 1 from around ``P'' packet code.
+ (gdbserv_data_packet): Check for process_get_reg when handling
+ ``p'' packet.
+ (gdbserv_data_packet): Check for target support before processing
+ ``?'' packet.
+
+Wed Dec 20 16:12:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-target.h (struct gdbserv_target): Add thread aware
+ memory access methods - get_thread_mem, set_thread_mem.
+ * lib/gdbserv-state.c (gdbserv_data_packet): Rewrite memory
+ read/write code to use thread aware methods when available.
+
+Wed Dec 20 15:36:24 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-target.h: Add thread aware resume methods -
+ continue_thread, cyclestep_thread, singlestep_thread.
+ * lib/gdbserv-state.c (gdbserv_data_packet): Rewrite continue code
+ to use thread mechanism when available.
+
+Wed Dec 20 12:09:42 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-target.h (struct gdbserv_target): Add thread aware
+ register methods - next_gg_reg, next_expedited_reg, reg_format,
+ set_thread_reg, get_thread_reg.
+
+ * lib/gdbserv-state.c (output_thread_reg): New function. Use
+ thread aware methods to output a register.
+ (do_get_registers_g_packet): Ditto.
+ (do_set_registers_g_packet): Ditto.
+ (do_get_registers_p_packet): Ditto.
+ (do_set_registers_p_packet): Ditto.
+ (gdbserv_data_packet): Use new functions to process ``G'', ``g'',
+ ``p'' and ``P'' packets.
+ (gdbserv_fromtarget_thread_break): Update using thread aware
+ methods when available.
+
+Wed Dec 20 11:46:32 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-target.h (gdbserv_fromtarget_thread_break): Declare.
+ * lib/gdbserv-state.c (gdbserv_fromtarget_break): Call
+ gdbserv_fromtarget_thread_break.
+ (gdbserv_fromtarget_thread_break): New function. Replace
+ gdbserv_fromtarget_break. Return thread ID when known. Fix
+ formatting of expedited registers.
+
+Wed Dec 20 10:26:36 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-state.c: Include <assert.h>.
+ (gdbserv_data_packet): Add support for ``H'', ``T'' packets. Add
+ support for ``ThreadInfo'', ``ThreadExtraInfo'' and ``C'' queries.
+ (do_select_thread_packet): New function, handle ``H'' packet.
+ (do_current_thread_query): New function, handle ``C'' query.
+ (do_thread_info_query): New function.
+ (do_thread_extra_info_query): New function.
+ (do_thread_alive_packet): New function, handle ``T'' packet.
+
+2000-12-19 <brolley@redhat.com>
+
+ * configure.in: Rename gidl to cidl. More detailed messages for
+ subdirs not supported on various hosts/targets.
+ * configure: regenerated.
+
+Tue Dec 19 17:51:58 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-output.c: Include <assert.h>.
+ (gdbserv_output_reg_beb, gdbserv_output_reg_leb): Use assert to
+ check negative_p.
+ (gdbserv_output_reg_beb, gdbserv_output_reg_leb): Handle zero reg.
+
+ * lib/gdbserv-input.c (gdbserv_input_hex_long): New function.
+ * lib/gdbserv.h (int gdbserv_input_hex_long): Declare.
+
+ * lib/gdbserv-utils.c (gdbserv_reg_to_ulong,
+ gdbserv_reg_to_ulonglong, gdbserv_ulong_to_reg,
+ gdbserv_ulonglong_to_reg): Change return type to void.
+ (gdbserv_reg_to_ulong, gdbserv_reg_to_ulonglong): Make ``reg''
+ parameter constant.
+ (unpack_ulonglong): New function.
+ (gdbserv_ulong_to_reg, gdbserv_long_to_reg,
+ gdbserv_ulonglong_to_reg, gdbserv_longlong_to_reg): Use.
+ * lib/gdbserv-utils.h (gdbserv_reg_to_ulong,
+ gdbserv_reg_to_ulonglong, gdbserv_ulong_to_reg,
+ gdbserv_ulonglong_to_reg): Update function declarations.
+
+2000-12-18 David Smith <dsmith@redhat.com>
+
+ * lib/gdbserv-client.h, lib/gdbserv-input.h, lib/gdbserv-output.h:
+ Added macros to guard against mutiple inclusion and added C++
+ support (by adding 'extern "C"').
+ * lib/gdbserv-state.h, lib/gdbserv-target.h, lib/gdbserv-utils.h:
+ Ditto.
+ * lib/gdbserv.h, lib/gdbsocket.h: Ditto.
+
+2000-11-28 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * lib/gdbserv-state.c (gdbserv_data_packet): Return error if
+ get_mem method does not return the requested number of bytes.
+
+2000-11-21 Corinna Vinschen <vinschen@cygnus.com>
+
+ * configure.in: Add subdir dependency for win32 target.
+
+2000-11-14 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * samples/demo-target.c (demo_get_mem, demo_set_mem):
+ Add a memory cache that can be modified by GDB.
+ (demo_process_get_regs, demo_process_set_regs):
+ Add a register cache that can be modified by GDB.
+ (demo_attach): Hook in demo_process_set_regs.
+ (demo_set_mem): Check for malloc failure in pseudo-memory cache.
+
+2000-11-08 Rudy Folden <rfolden@redhat.com>
+
+ * configure.in (case "$target" in sh-*): Removed erroneous CC case.
+ * native/configure.in (case "$target" in sh-*): Removed erroneous CC case.
+
+2000-11-07 Rudy Folden <rfolden@redhat.com>
+
+ * README: Doc update.
+
+2000-11-07 Rudy Folden <rfolden@redhat.com>
+
+ * configure.in (case "$target" in sh-*): Added case for CC.
+ * native/configure.in (case "$target" in sh-*): Added case for CC.
+ * native/Makefile.am (CC=, CFLAGS=): removed erroneous CC ad CFLAGS entiries.
+ * native/Makefile.in (CC=, CFLAGS=): removed erroneous CC ad CFLAGS entiries.
+
+2000-09-15 Fernando Nasser <fnasser@totem.to.cygnus.com>
+
+ With Andrew Cagney <cagney@b1.cygnus.com>
+ * lib/gdbserv-input.c (add_char_to_packet): Improve handling of
+ missing ACK packets, NACKs and other exceptional conditions.
+ This fixies a bug where libremote would lock up and ignore everything
+ if GDB died on it.
+ (gdbserv_input_wait_for_ack): Do not print switch to ACK warning
+ when retrying. Rephrase the warning message.
+
+2000-09-13 Michael Snyder <msnyder@michael.wirespeed.com>
+
+ * lib/gdbserv-state.c (gdbserv_fromtarget_terminate): New function.
+ (gdbserv_fromtarget_exit): Rename arg from signum to exitcode.
+ * lib/gdbserv-target.h (gdbserv_fromtarget_terminate): Export.
+
+Thu Sep 7 16:53:22 2000 David Taylor <taylor@texas.cygnus.com>
+
+ * lib/gdbserv-utils.c (gdbserv_ulong_to_reg,
+ gdbserv_ulonglong_to_reg): New functions.
+ * lib/gdbserv-utils.h (gdbserv_ulong_to_reg,
+ gdbserv_ulonglong_to_reg): Declare them.
+
+2000-09-06 Michael Snyder <msnyder@cleaver.cygnus.com>
+
+ * configure.in: Add "native" subdirectory to targ_subdirs.
+ * configure: Regenerate.
+ * configure.in: Remove native/Makefile from output.
+ Native subdirectory now has its own configure and automake.
+ * configure: Regenerate.
+
+Thu Jun 8 14:32:21 2000 David Taylor <taylor@texas.cygnus.com>
+
+ * lib/gdbsocket.c (process_read): change "else if" to "if",
+ otherwise, when gdbsocket_trace is set, packets never get
+ processed.
+
+Tue May 23 17:33:02 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * samples/poll.c (main): Pass POLLFDS and not POLL to
+ gdbsocket_fd_set.
+
+ * samples/demo-target.c (sole_target): Delete global.
+ * samples/demo-target.c (demo_attach): Create and initialize
+ target vector at runtime.
+
+Tue May 23 16:44:26 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbsocket.c, lib/gdbserv-client.h, lib/gdbserv-target.h:
+ More comments.
+
+Mon May 22 20:29:05 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * samples/demo-target.c (sole_target): Fix initialization.
+
+Thu May 18 10:55:33 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbsocket.c: Do not include "gdbserv.h". "gdbserv-client.h"
+ provides all required server declarations.
+
+2000-05-17 Fernando Nasser <fnasser@cygnus.com>
+
+ * lib/gdbserv-output.c (gdbserv_output_string_as_bytes): New function.
+ Send a null terminated string as hex encoded bytes (useful for
+ "O" packets and "qRcmd" answers).
+ * lib/gdbserv.h: Add prototype of the above.
+ * lib/gdbserv-state.c (gdbserv_data_packet): Fix and reactivate code
+ that handles "p" packets.
+ * lib/gdbserv-target.h: Add prototype for process_get_reg callback
+ (activated by a "p" packet).
+
+Wed May 3 18:46:02 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbsocket.h (enum gdbsocket_fd_event,
+ gdbsocket_fd_set_ftype, gdbsocket_fd_isset_ftype): Declare.
+ (gdbsocket_fd_set, gdbsocket_fd_isset): Pass fd_set/fd_isset and
+ context instead of readfs.
+ * lib/gdbsocket.c (gdbsocket_fd_set): Replace ``fd_set'' with with
+ function parameter for accumulating file descriptors.
+ (gdbsocket_fd_isset): Ditto with a function parameter that
+ indicates that a file descriptor is ready.
+ (struct fds): Define.
+ (fds_set, fds_isset): New functions.
+ (gdbsocket_poll): Update. Add support for both read and write
+ fd_sets.
+
+ * samples/fdset.c (struct fdset, set, isset): Declare.
+ (main): Update to use new gdbsocket_fd_set / gdbsocket_fd_isset
+ interface.
+
+ * samples/Makefile.am: Add program poll.
+ * samples/Makefile.in: Re-generate.
+ * samples/poll.c: New file. Demonstrate gdbsocket's poll interface.
+
+Mon Apr 24 19:33:35 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * samples/demo-target.c (demo_attach, demo_continue_program,
+ demo_detach): Write traces to STDERR instead of STDOUT.
+
+ * samples/stdio.c: New file.
+ * samples/Makefile.am (noinst_PROGRAMS): Add stdio.
+ * samples/Makefile.in: Re-generate.
+
+ * lib/gdbsocket.h (gdbsocket_reopen): Add declaration.
+ * lib/gdbsocket.c (process_accept): Use gdbsocket_reopen.
+ (gdbsockt_reopen): New function.
+
+Mon Apr 24 19:09:29 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbsocket.c (gdbsocket_fd): Initialize to -1.
+ (gdbsocket_shutdown, gdbsocket_fd_set, gdbsocket_fd_isset): Do not
+ assume that there is an open port.
+ (gdbsocket_startup): Mark gdbsocket_fd as closed.
+
+Mon Apr 24 18:43:29 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbsocket.h, lib/gdbsocket.c: Update comments.
+ (gdbsocket_attach_ftype): Replace typedef gdbsocket_attach.
+ * lib/gdbsocket.c (process_accept, gdbsocket_fd_isset,
+ gdbsocket_poll): Update.
+ (process_read): Document interface flaw.
+
+Mon Apr 24 18:12:14 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbsocket.c (struct gdbsocket): Replace ``fd'' with
+ ``readfd'' and WRITEFD. Add ``close'' method.
+ (gdbsocket_shutdown): Update. Use ``close'' method.
+ (process_read): Ditto. Replace ``fd'' with ``readfd''.
+ (raw_write): Ditto. Replace ``fd'' with ``writefd''.
+ (session_close): New function. Close ``readfd''.
+ (process_accept): Update. Initialize ``close'' method with
+ session_close.
+ (gdbsocket_fd_isset, gdbsocket_fd_set): Replace ``fd'' with
+ ``readfd''.
+
+Mon Apr 24 17:14:21 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * samples/demo-target.c (sole_target): Fix initialization of
+ flush_icache.
+
+2000-04-17 Fernando Nasser <fnasser@cygnus.com>
+
+ * HOWTO: New version. More complete, includes architecture.
+ Callback function prototypes are removed and related comments
+ moved to lib/gdbserv-target.h.
+
+Mon Apr 17 17:11:30 2000 Fernando Nasser <fnasser@cygnus.com>
+
+ * lib/gdbserv-state.c (gdbserv_data_packet): Add processing of a
+ "D" packet.
+
+Mon Apr 17 17:11:30 2000 Fernando Nasser <fnasser@cygnus.com>
+
+ * lib/gdbserv-target.h (struct gdbserv-target): Add comments
+ relating the callback routines to the corresponding remote
+ protocol packet(s).
+
+2000-04-12 Frank Ch. Eigler <fche@redhat.com>
+
+ * HOWTO: Remove mention of gdbserv_fromclient calls. Fix some
+ typos. Minor rewording.
+
+2000-04-11 Fernando Nasser <fnasser@cygnus.com>
+
+ * HOWTO: New file. A brief guide to write code that use libremote.
+
+Wed Apr 12 22:35:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv.h (gdbserv_target_attach, gdbserv_fromclient_attach,
+ gdbserv_fromclient_detach, gdbserv_fromclient_data,
+ gdbserv_fromclient_break): Move from here.
+ * lib/gdbserv-client.h: To here.
+
+ * lib/gdbserv.h (gdbserv_fromtarget_break,
+ gdbserv_fromtarget_reset, gdbserv_fromtarget_exit): Move from
+ here.
+ * lib/gdbserv-target.h: To here.
+
+Wed Apr 12 23:39:33 2000 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * configure.in: Configure in ASVP when ASVPLAB is defined.
+ * configure: Re-generate.
+
+Wed Apr 12 22:06:57 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * samples/fdset.c: Include <stdlib.h> for atoi.
+ Include <string.h>, work around FreeBSD header problem.
+ * samples/demo-target.c: Include <stdlib.h> for rand.
+ (demo_get_mem): Add paren around ``+'' and ``%'' per GCCs
+ suggestion.
+ * samples/main.c: Include <stdlib.h> for atoi.
+ * lib/gdbserv-state.c: Include <string.h> for memset.
+
+Wed Apr 12 20:22:36 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-utils.h, lib/gdbserv-utils.c (gdbserv_reg_to_hex):
+ Delete. Replaced by gdbserv_output_reg_beb and
+ gdbserv_output_reg_leb.
+
+Wed Apr 12 19:13:58 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbserv-state.c (gdbserv_state): New function.
+ * lib/gdbserv-state.h (enum gdbserv_state): Move from here.
+ * lib/gdbserv.h (enum gdbserv_state): To here.
+ (gdbserv_state): Add declaration.
+
+Tue Apr 11 20:20:43 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * samples/demo-target.c, samples/demo-target.h: New files. Copy
+ demo target in main.c.
+ * samples/main.c: Delete demo target code. Include
+ "demo-target.h".
+ * samples/Makefile.am: Update.
+
+ * samples/fdset.c: New file. Demo gdbsocket.h's FD_SET interface.
+ * samples/Makefile.am: Add program `fdset'.
+ * samples/Makefile.in, stamp-h.in: Re-generate.
+
+2000-04-11 Fernando Nasser <fnasser@cygnus.com>
+
+ * configure.in: Add check for target-dependent subdirectories.
+ * configure: Regenerate.
+ * Makefile.am: Use targ_subdirs generated above.
+ * Makefile.in: Regenerate
+
+2000-04-11 Fernando Nasser <fnasser@cygnus.com>
+
+ * configure.in: Test for host byte order.
+ * config.in: Regenerate.
+ * configure: Regenerate.
+
+Tue Apr 11 20:06:34 2000 Andrew Cagney <cagney@b1.cygnus.com>
+
+ * lib/gdbsocket.h: Break dependency on "gdbserv.h".
+ (gdbsocket_attach): New type.
+ (struct gdbserv, struct gdbserv_target): Add declarations.
+ * lib/gdbsocket.c (process_accept, gdbsocket_fd_isset,
+ gdbsocket_poll): Update.
+
+Tue Apr 11 18:36:06 2000 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * lib/gdbsocket.c (gdbsocket_shutdown): Only trace when
+ gdbsocket_trace. Avoid core dump.
+ (gdbsocket_fd_set): New function.
+ (gdbsocket_fd_isset): New function - better name?
+ (gdbsocket_poll): Use gdbsocket_fd_set and gdbsocket_fd_isset to
+ set/process FDs.
+ * lib/gdbsocket.h (gdbsocket_fd_set, gdbsocket_fd_isset): Add
+ declarations conditional on having FD_SET.
+
+ * samples/main.c: Do not include "gdbserv-client.h". "gdbsocket.h"
+ implements the client side code.
+
+Tue Apr 11 17:49:29 2000 Andrew Cagney <cagney@amy.cygnus.com>
+
+ * lib/gdbserv-state.h: Document that the file is gdbserv internal.
+ * samples/main.c: Include system headers before stub headers.
+ * lib/gdbserv.h: Don't include <stdio.h>.
+
+2000-04-06 Frank Ch. Eigler <fche@redhat.com>
+
+ MAINTAINERS: New file.
+ Makefile.am: New file.
+ NEWS: New file.
+ README: New file.
+ REMOTE-HACK-RULES: New file.
+ configure.in: New file.
+ Makefile.in: New generated file.
+ aclocal.m4: New generated file.
+ config.in: New generated file.
+ configure: New generated file.
+ stamp-h.in: New generated file.
+
+ By Andrew Cagney <cagney@cygnus.com>:
+ lib/ARCH: Imported file.
+ lib/Makefile.am: New file.
+ lib/Makefile.in: New generated file.
+ lib/gdbserv-client.h: Imported file.
+ lib/gdbserv-input.c: Imported file.
+ lib/gdbserv-input.h: Imported file.
+ lib/gdbserv-output.c: Imported file.
+ lib/gdbserv-output.h: Imported file.
+ lib/gdbserv-state.c: Imported file.
+ lib/gdbserv-state.h: Imported file.
+ lib/gdbserv-target.h: Imported file.
+ lib/gdbserv-utils.c: Imported file.
+ lib/gdbserv-utils.h: Imported file.
+ lib/gdbserv.h: Imported file.
+ lib/gdbsocket.c: Imported file.
+ lib/gdbsocket.h: Imported file.
+
+ samples/Makefile.am: New file.
+ samples/Makefile.in: New generated file.
+ samples/main.c: New file.
+
+
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/rda/lib/gdbserv-state.c b/rda/lib/gdbserv-state.c
new file mode 100644
index 00000000000..f84046af686
--- /dev/null
+++ b/rda/lib/gdbserv-state.c
@@ -0,0 +1,1327 @@
+/* gdbserv-state.c
+
+ Copyright 2000, 2001, 2002 Red Hat, Inc.
+
+ This file is part of RDA, the Red Hat Debug Agent (and library).
+
+ 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.
+
+ Alternative licenses for RDA may be arranged by contacting Red Hat,
+ Inc. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "gdbserv.h"
+#include "gdbserv-state.h"
+#include "gdbserv-utils.h"
+#include "gdblog.h"
+#include "gdbserv-log.h"
+#include "crc32.h"
+
+static int output_thread_reg (struct gdbserv *gdbserv,
+ struct gdbserv_thread *thread,
+ int reg_nr,
+ int reg_nr_p);
+
+static void fromtarget (struct gdbserv *gdbserv,
+ struct gdbserv_thread *ignore1,
+ enum gdbserv_fromtarget_event event,
+ const struct gdbserv_reg *stop_addr,
+ int exitcode);
+
+static const char *
+state2str (struct gdbserv *gdbserv)
+{
+ switch (gdbserv->state)
+ {
+ case GDBSERV_STATE_UNINITIALIZED: return "UNINITIALIZED";
+ case GDBSERV_STATE_RESETTING: return "RESETTING";
+ case GDBSERV_STATE_RUNNING: return "RUNNING";
+ case GDBSERV_STATE_BROKEN: return "BROKEN";
+ case GDBSERV_STATE_EXITING: return "EXITING";
+ case GDBSERV_STATE_EXITED: return "EXITED";
+ }
+ return "?";
+}
+
+enum gdbserv_state
+gdbserv_state (struct gdbserv *gdbserv)
+{
+ return gdbserv->state;
+}
+
+void *
+gdbserv_client_data (struct gdbserv *gdbserv)
+{
+ return gdbserv->client->data;
+}
+
+void *
+gdbserv_target_data (struct gdbserv *gdbserv)
+{
+ return gdbserv->target->data;
+}
+
+void
+log_state (struct gdbserv *gdbserv, const char *function)
+{
+ if (gdbserv_state_log)
+ {
+ gdblog_string (gdbserv_state_log, "<");
+ gdblog_string (gdbserv_state_log, function);
+ gdblog_string (gdbserv_state_log, " ");
+ gdblog_string (gdbserv_state_log, state2str (gdbserv));
+ gdblog_string (gdbserv_state_log, ">\n");
+ }
+}
+
+static void
+reset_state (struct gdbserv *gdbserv)
+{
+ gdbserv->state = GDBSERV_STATE_RESETTING;
+ gdbserv->continue_thread = NULL;
+ gdbserv->general_thread = NULL;
+ gdbserv->event_thread = NULL;
+ gdbserv->event_sigval = GDBSERV_SIGNONE;
+}
+
+struct gdbserv *
+gdbserv_fromclient_attach (struct gdbserv_client *gdbclient,
+ gdbserv_target_attach *to_target_attach,
+ void *target_attach_data)
+{
+ struct gdbserv *gdbserv = malloc (sizeof (struct gdbserv));
+ log_state (gdbserv, "gdbserv_fromclient_attach");
+ gdbserv->client = gdbclient;
+ /* HACK: Create a cycle of gdbservers. This allows the new stack
+ based fromtarget code to climb the stack while, at the same time,
+ keeping the old flat totarget code working. Once the totarget
+ code is converted to a stack this hack can be removed. */
+ gdbserv->from = gdbserv;
+ gdbserv->to = gdbserv;
+ /* Wire up the servers input and output handlers. */
+ gdbserv_input_attach (gdbserv);
+ gdbserv_output_attach (gdbserv);
+ /* Try to connect the client, if it fails bail out. */
+ gdbserv->target = to_target_attach (gdbserv, target_attach_data);
+ if (gdbserv->target == NULL)
+ {
+ gdbserv_output_detach (gdbserv);
+ gdbserv_input_detach (gdbserv);
+ free (gdbserv);
+ return NULL;
+ }
+ /* Check that the target has supplied all the manditory methods. It
+ had better, at least be able to handle a detach. */
+ assert (gdbserv->target->detach != NULL);
+ /* HACK: Plug gdbserv-state's local fromtarget() method into the
+ target vector returned by the attatch. Since that target is at
+ the bottom of the stack, the fromtarget method is NULL. Once
+ there is a true stack, this hack can be eliminated necessary. */
+ assert (gdbserv->target->from == NULL);
+ gdbserv->target->from = fromtarget;
+ reset_state (gdbserv);
+ return gdbserv;
+}
+
+void
+gdbserv_fromclient_detach (struct gdbserv *gdbserv)
+{
+ log_state (gdbserv, "gdbserv_fromclient_detach");
+ gdbserv->target->from = NULL;
+ gdbserv->target->detach (gdbserv, gdbserv->target);
+ /* Avoid a dangling reference. */
+ gdbserv->target = NULL;
+ gdbserv_input_detach (gdbserv);
+ gdbserv_output_detach (gdbserv);
+ free (gdbserv);
+}
+
+
+void
+gdbserv_fromclient_break (struct gdbserv *gdbserv)
+{
+ log_state (gdbserv, "gdbserv_fromclient_break");
+ switch (gdbserv->state)
+ {
+ case GDBSERV_STATE_RUNNING:
+ gdbserv->target->break_program (gdbserv);
+ /* NOTE: no state change - we might break the program at the
+ same time as it stops itself */
+ break;
+ default:
+ break;
+ }
+}
+
+
+void
+gdbserv_fromclient_data (struct gdbserv *gdbserv,
+ const char *buf,
+ int len)
+{
+ log_state (gdbserv, "gdbserv_fromclient_data");
+ gdbserv_input_data_packet (gdbserv, buf, len);
+}
+
+static void
+do_status_packet (struct gdbserv *gdbserv)
+{
+ gdbserv_output_char (gdbserv, 'T');
+ gdbserv_output_byte (gdbserv, gdbserv->event_sigval);
+ /* If the thread is known, pass that back to GDB. */
+ if (gdbserv->event_thread != NULL
+ && gdbserv->target->thread_id != NULL)
+ {
+ struct gdbserv_reg thread_id;
+ gdbserv_output_string (gdbserv, "thread");
+ gdbserv_output_char (gdbserv, ':');
+ gdbserv->target->thread_id (gdbserv, gdbserv->event_thread, &thread_id);
+ gdbserv_output_reg_beb (gdbserv, &thread_id, 0);
+ gdbserv_output_string (gdbserv, ";");
+ }
+ /* When the target knows how, expedite the supply of register
+ values back to GDB. Do this by appending them to the end of
+ the T packet response. */
+ if (gdbserv->target->next_expedited_reg != NULL
+ && gdbserv->target->get_thread_reg != NULL
+ && gdbserv->target->output_reg != NULL)
+ {
+ int reg_nr;
+ for (reg_nr = gdbserv->target->next_expedited_reg (gdbserv,
+ gdbserv->event_thread,
+ -1);
+ reg_nr >= 0;
+ reg_nr = gdbserv->target->next_expedited_reg (gdbserv,
+ gdbserv->event_thread,
+ reg_nr))
+ {
+ if (output_thread_reg (gdbserv, gdbserv->event_thread, reg_nr, 1)
+ < 0)
+ continue;
+ gdbserv_output_string (gdbserv, ";");
+ }
+ return;
+ }
+ if (gdbserv->target->expedited_reg_nr != NULL
+ && gdbserv->target->get_reg != NULL
+ && gdbserv->target->sizeof_reg != NULL
+ && gdbserv->target->output_reg != NULL)
+ {
+ int i;
+ int reg_nr;
+ for (i = 0, reg_nr = gdbserv->target->expedited_reg_nr (gdbserv, i);
+ reg_nr >= 0;
+ i++, reg_nr = gdbserv->target->expedited_reg_nr (gdbserv, i))
+ {
+ struct gdbserv_reg reg;
+ long sizeof_reg = gdbserv->target->sizeof_reg (gdbserv, reg_nr);
+ long len = (sizeof_reg < 0 ? -sizeof_reg : sizeof_reg);
+
+ gdbserv_output_byte (gdbserv, reg_nr);
+ gdbserv_output_char (gdbserv, ':');
+ if (sizeof_reg > 0)
+ gdbserv->target->get_reg (gdbserv, reg_nr, &reg);
+ else
+ memset (&reg, 0, sizeof (reg));
+ gdbserv->target->output_reg (gdbserv, &reg, len);
+ gdbserv_output_char (gdbserv, ';');
+ }
+ return;
+ }
+}
+
+static void
+do_exit_packet (struct gdbserv *gdbserv,
+ enum gdbserv_fromtarget_event event,
+ int sigval)
+{
+ switch (event)
+ {
+ case GDBSERV_FROMTARGET_TERMINATED:
+ gdbserv_output_char (gdbserv, 'X');
+ break;
+ case GDBSERV_FROMTARGET_EXITED:
+ gdbserv_output_char (gdbserv, 'W');
+ break;
+ }
+ gdbserv_output_byte (gdbserv, sigval);
+}
+
+static void
+do_select_thread_packet (struct gdbserv *gdbserv)
+{
+ if (gdbserv->target->thread_lookup_by_id != NULL)
+ {
+ struct gdbserv_reg thread_id;
+ struct gdbserv_thread *thread;
+ int id;
+ int gen;
+
+ gen = gdbserv_input_char (gdbserv);
+ if (gen != 'g' && gen != 'c')
+ {
+ gdbserv_output_string (gdbserv, "E01");
+ return;
+ }
+ if (gdbserv_input_reg_beb (gdbserv, &thread_id, 0) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E02");
+ return;
+ }
+
+ id = gdbserv->target->thread_lookup_by_id (gdbserv, &thread_id,
+ &thread);
+ if (id > 0)
+ assert (thread != NULL);
+
+ if (gen == 'c' && id <= 0)
+ {
+ /* A thread ID of ``0'' or ``-1'' (well anything) indicates
+ that GDB wants all threads to continue. Pass that
+ information on by selecting a NULL continuation thread.
+ NB: This won't scale to where GDB wants to select a
+ number of continuation threads. A new protocol extension
+ will be needed. */
+ gdbserv->continue_thread = NULL;
+ }
+ else if (gen == 'c')
+ {
+ gdbserv->continue_thread = thread;
+ }
+ else if (gen == 'g')
+ {
+ gdbserv->general_thread = thread;
+ }
+ else
+ assert (0);
+ gdbserv_output_string (gdbserv, "OK");
+ }
+}
+
+static void
+do_thread_alive_packet (struct gdbserv *gdbserv)
+{
+ /* thread-alive [ thread ] */
+ if (gdbserv->target->thread_lookup_by_id != NULL)
+ {
+ struct gdbserv_reg thread_id;
+ struct gdbserv_thread *thread;
+ int id;
+ if (gdbserv_input_reg_beb (gdbserv, &thread_id, 0) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E01");
+ return;
+ }
+ id = gdbserv->target->thread_lookup_by_id (gdbserv, &thread_id,
+ &thread);
+ if (id > 0)
+ gdbserv_output_string (gdbserv, "OK");
+ }
+}
+
+static void
+do_current_thread_query (struct gdbserv *gdbserv)
+{
+ struct gdbserv_thread *thread = gdbserv->general_thread;
+ if (gdbserv->target->thread_id != NULL && thread != NULL)
+ {
+ struct gdbserv_reg thread_id;
+ gdbserv->target->thread_id (gdbserv, thread, &thread_id);
+ gdbserv_output_string (gdbserv, "QC");
+ gdbserv_output_reg_beb (gdbserv, &thread_id, 0);
+ }
+}
+
+static void
+do_thread_info_query (struct gdbserv *gdbserv,
+ struct gdbserv_thread *last_thread)
+{
+ if (gdbserv->target->thread_id != NULL
+ && gdbserv->target->thread_next != NULL)
+ {
+ struct gdbserv_thread *next_thread;
+ struct gdbserv_reg thread_id;
+ next_thread = gdbserv->target->thread_next (gdbserv, last_thread);
+ if (next_thread == NULL)
+ {
+ gdbserv_output_string (gdbserv, "l");
+ return;
+ }
+ gdbserv->query_thread = next_thread; /* for next time */
+ gdbserv->target->thread_id (gdbserv, next_thread, &thread_id);
+ gdbserv_output_string (gdbserv, "m");
+ gdbserv_output_reg_beb (gdbserv, &thread_id, 0);
+ }
+}
+
+static void
+do_thread_extra_info_query (struct gdbserv *gdbserv)
+{
+ if (gdbserv->target->thread_lookup_by_id != NULL
+ && gdbserv->target->thread_info != NULL)
+ {
+ struct gdbserv_reg thread_id;
+ struct gdbserv_thread *thread;
+ int id;
+ char *info;
+
+ if (gdbserv_input_reg_beb (gdbserv, &thread_id, 0) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E01");
+ return;
+ }
+ id = gdbserv->target->thread_lookup_by_id (gdbserv, &thread_id,
+ &thread);
+ assert (thread != NULL);
+ if (id <= 0)
+ {
+ gdbserv_output_string (gdbserv, "E02");
+ return;
+ }
+
+ info = gdbserv->target->thread_info (gdbserv, thread);
+ if (info == NULL)
+ {
+ gdbserv_output_string (gdbserv, "E03");
+ return;
+ }
+ gdbserv_output_string_as_bytes (gdbserv, info);
+ free (info);
+ }
+}
+
+
+static int
+output_thread_reg (struct gdbserv *gdbserv,
+ struct gdbserv_thread *thread,
+ int reg_nr,
+ int reg_nr_p)
+{
+ int size;
+ int padding;
+ struct gdbserv_reg reg;
+ assert (gdbserv->target->reg_format != NULL);
+ assert (gdbserv->target->get_thread_reg != NULL);
+ assert (gdbserv->target->output_reg != NULL);
+ if (gdbserv->target->reg_format (gdbserv, thread,
+ reg_nr, &size, &padding) < 0)
+ return -1;
+ if (gdbserv->target->get_thread_reg (gdbserv, thread,
+ reg_nr, &reg) >= 0)
+ {
+ if (reg_nr_p)
+ {
+ gdbserv_output_byte (gdbserv, reg_nr);
+ gdbserv_output_char (gdbserv, ':');
+ }
+ for (; padding < 0; padding++)
+ gdbserv_output_string (gdbserv, "00");
+ if (size > 0)
+ gdbserv->target->output_reg (gdbserv,
+ &reg, size);
+ for (; padding > 0; padding--)
+ gdbserv_output_string (gdbserv, "00");
+ }
+ else
+ {
+ if (reg_nr_p)
+ {
+ gdbserv_output_byte (gdbserv, reg_nr);
+ gdbserv_output_char (gdbserv, ':');
+ }
+ for (; padding < 0; padding++)
+ gdbserv_output_string (gdbserv, "xx");
+ for (; size > 0; size--)
+ gdbserv_output_string (gdbserv, "xx");
+ for (; padding > 0; padding--)
+ gdbserv_output_string (gdbserv, "xx");
+ }
+ return 0;
+}
+
+static void
+do_get_registers_g_packet (struct gdbserv *gdbserv)
+{
+ if (gdbserv->target->next_gg_reg != NULL
+ && gdbserv->target->get_thread_reg != NULL
+ && gdbserv->target->reg_format != NULL
+ && gdbserv->target->output_reg != NULL)
+ {
+ int reg_nr;
+ for (reg_nr = gdbserv->target->next_gg_reg (gdbserv,
+ gdbserv->general_thread,
+ -1);
+ reg_nr >= 0;
+ reg_nr = gdbserv->target->next_gg_reg (gdbserv,
+ gdbserv->general_thread,
+ reg_nr))
+ {
+ if (output_thread_reg (gdbserv, gdbserv->general_thread,
+ reg_nr, 0) < 0)
+ {
+ gdbserv_output_discard (gdbserv);
+ gdbserv_output_string (gdbserv, "E99");
+ return;
+ }
+ }
+ }
+}
+
+static void
+do_set_registers_g_packet (struct gdbserv *gdbserv)
+{
+ if (gdbserv->target->next_gg_reg != NULL
+ && gdbserv->target->set_thread_reg != NULL
+ && gdbserv->target->reg_format != NULL
+ && gdbserv->target->input_reg != NULL)
+ {
+ int reg_nr;
+ for (reg_nr = gdbserv->target->next_gg_reg (gdbserv,
+ gdbserv->general_thread,
+ -1);
+ reg_nr >= 0;
+ reg_nr = gdbserv->target->next_gg_reg (gdbserv,
+ gdbserv->general_thread,
+ reg_nr))
+ {
+ int size;
+ int padding;
+ gdbserv->target->reg_format (gdbserv, gdbserv->general_thread,
+ reg_nr, &size, &padding);
+ for (; padding < 0; padding++)
+ gdbserv_input_byte (gdbserv);
+ if (size > 0)
+ {
+ struct gdbserv_reg reg;
+ if (gdbserv->target->input_reg (gdbserv,
+ &reg, size) >= 0)
+ /* only supply registers that are useful. */
+ gdbserv->target->set_thread_reg (gdbserv,
+ gdbserv->general_thread,
+ reg_nr, &reg);
+ }
+ for (; padding > 0; padding--)
+ gdbserv_input_byte (gdbserv);
+ }
+ gdbserv_output_string (gdbserv, "OK");
+ }
+}
+
+static void
+do_set_registers_p_packet (struct gdbserv *gdbserv)
+{
+ /* FIXME: This accepts a list of registers which isn't in the
+ protocol. */
+ if (gdbserv->target->set_thread_reg != NULL
+ && gdbserv->target->input_reg != NULL)
+ {
+ const char *result = "OK";
+ while (gdbserv_input_size (gdbserv) > 0)
+ {
+ unsigned long regnr;
+ struct gdbserv_reg reg;
+ if (gdbserv_input_hex_ulong (gdbserv, &regnr) < 0)
+ {
+ result = "E01";
+ break;
+ }
+ if (gdbserv_input_string_match (gdbserv, "=") >= 0)
+ {
+ if (gdbserv->target->input_reg (gdbserv, &reg, 0) < 0)
+ {
+ result = "E02";
+ break;
+ }
+ }
+ else
+ {
+ result = "E04";
+ break;
+ }
+ if (gdbserv->target->set_thread_reg (gdbserv,
+ gdbserv->general_thread,
+ regnr, &reg) < 0)
+ {
+ result = "E05";
+ break;
+ }
+ if (gdbserv_input_string_match (gdbserv, ";") < 0)
+ {
+ if (gdbserv_input_size (gdbserv) > 0)
+ result = "E06";
+ break;
+ }
+ }
+ if (result == NULL)
+ gdbserv_output_string (gdbserv, "OK");
+ else
+ {
+ gdbserv_output_discard (gdbserv);
+ gdbserv_output_string (gdbserv, result);
+ }
+ }
+}
+
+static void
+do_get_registers_p_packet (struct gdbserv *gdbserv)
+{
+ /* FIXME: This returns a list of registers which isn't in the
+ protocol. */
+ /* FIXME: This would really like to return ;REGNR!VALUE ... */
+
+ if (gdbserv->target->get_thread_reg != NULL
+ && gdbserv->target->reg_format != NULL
+ && gdbserv->target->output_reg != NULL)
+ {
+ const char *result = NULL;
+ while (gdbserv_input_size (gdbserv) > 0)
+ {
+ unsigned long regnr;
+ struct gdbserv_reg reg;
+ if (gdbserv_input_hex_ulong (gdbserv, &regnr) < 0)
+ {
+ result = "E01";
+ break;
+ }
+ if (output_thread_reg (gdbserv, gdbserv->general_thread,
+ regnr, 0) < 0)
+ {
+ result = "E02";
+ break;
+ }
+ if (gdbserv_input_string_match (gdbserv, ";") < 0)
+ {
+ if (gdbserv_input_size (gdbserv) > 0)
+ result = "E03";
+ break;
+ }
+ gdbserv_output_string (gdbserv, ";");
+ }
+ if (result != NULL)
+ {
+ gdbserv_output_discard (gdbserv);
+ gdbserv_output_string (gdbserv, result);
+ }
+ }
+}
+
+static long
+read_memory (struct gdbserv *gdbserv, struct gdbserv_reg *addr_p, void *block,
+ long len)
+{
+ long nr_read;
+ if (gdbserv->target->get_thread_mem != NULL)
+ nr_read =
+ gdbserv->target->get_thread_mem (gdbserv,
+ gdbserv->general_thread,
+ addr_p, block, len);
+ else if (gdbserv->target->get_mem != NULL)
+ nr_read = gdbserv->target->get_mem (gdbserv, addr_p, block, len);
+ else
+ assert (0);
+ return nr_read;
+}
+
+static void
+do_qCRC_packet (struct gdbserv *gdbserv)
+{
+ struct gdbserv_reg addr;
+ long len;
+ unsigned long crc = 0xffffffff; /* See crc32.h. */
+ struct gdbserv_reg crc_reg;
+
+ /* Fetch addr,length. */
+ if (gdbserv_input_reg_beb (gdbserv, &addr, 0) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E01");
+ }
+ else if (gdbserv_input_char (gdbserv) != ',')
+ {
+ gdbserv_output_string (gdbserv, "E02");
+ }
+ else if (gdbserv_input_hex_ulong (gdbserv, &len) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E03");
+ }
+
+ while (len > 0)
+ {
+ char buf[1024];
+ unsigned long long addr_ull;
+ int size = sizeof (buf) < len ? sizeof (buf) : len;
+
+ /* Read a block. Quit early if the read doesn't succeed. */
+ size = read_memory (gdbserv, &addr, buf, size);
+ if (size <= 0)
+ {
+ gdbserv_output_string (gdbserv, "E07");
+ return;
+ }
+
+ /* Compute the accumlated CRC. */
+ crc = crc32 (buf, size, crc);
+
+ /* Advance ``addr'' by ``size''. */
+ gdbserv_reg_to_ulonglong (gdbserv, &addr, &addr_ull);
+ addr_ull += size;
+ gdbserv_ulonglong_to_reg (gdbserv, addr_ull, &addr);
+
+ /* Adjust the length based on amount actually read. */
+ len -= size;
+ }
+
+ /* Output the CRC in the format expected by GDB. */
+ gdbserv_output_char (gdbserv, 'C');
+ gdbserv_ulong_to_reg (gdbserv, crc, &crc_reg);
+ gdbserv_output_reg_beb (gdbserv, &crc_reg, 0);
+}
+
+int demo_reverse_flag;
+
+void
+gdbserv_data_packet (struct gdbserv *gdbserv)
+{
+ char packet_type = gdbserv_input_char (gdbserv);
+
+ demo_reverse_flag = 0;
+
+ if (gdbserv_state_log)
+ {
+ gdblog_string (gdbserv_state_log, "<gdbserv_data_packet:");
+ gdblog_char (gdbserv_state_log, packet_type);
+ gdblog_string (gdbserv_state_log, ">\n");
+ }
+
+ /* NB: default is for this to send an empty packet */
+
+ backward:
+ switch (packet_type)
+ {
+
+ case '?':
+ do_status_packet (gdbserv);
+ break;
+
+ case 'H': /* select general/continue thread */
+ do_select_thread_packet (gdbserv);
+ break;
+
+ case 'd': /* toggle debug flag */
+ gdbserv_output_string (gdbserv, "");
+ break;
+
+ case 'D': /* detach from target */
+ gdbserv_output_string (gdbserv, "");
+ /* NOP. We detach when an EOF is sensed on the socket. */
+ break;
+
+ case 'q': /* general query packet */
+ if (gdbserv_input_string_match (gdbserv, "Rcmd,") >= 0)
+ {
+ if (gdbserv->target->process_rcmd)
+ {
+ /* Format: qRcmd,<hex-encoded-command> */
+ char *cmd;
+ int sizeof_cmd;
+ /* create a buffer sufficent to hold the decoded
+ command. There are two hex digits per encoded byte. */
+ sizeof_cmd = gdbserv_input_size (gdbserv) / 2;
+ if (sizeof_cmd < 0)
+ {
+ gdbserv_output_string (gdbserv, "E11");
+ break;
+ }
+ cmd = alloca (sizeof_cmd + 1);
+ /* Decode/read the command into the buffer, check that
+ the command exactly fits - not to many, not to few
+ bytes of input. */
+ if (gdbserv_input_bytes (gdbserv, cmd, sizeof_cmd) < sizeof_cmd
+ || gdbserv_input_size (gdbserv) != 0)
+ {
+ gdbserv_output_string (gdbserv, "E12");
+ break;
+ }
+ /* Process the command. Guarentee that that it is NUL
+ terminated. */
+ cmd[sizeof_cmd] = '\0';
+ gdbserv->target->process_rcmd (gdbserv, cmd, sizeof_cmd);
+ }
+ }
+ else if (gdbserv_input_string_match (gdbserv, "CRC:") >= 0)
+ {
+ do_qCRC_packet (gdbserv);
+ }
+ else if (gdbserv_input_string_match (gdbserv, "C") >= 0)
+ {
+ do_current_thread_query (gdbserv);
+ }
+ else if (gdbserv_input_string_match (gdbserv, "fThreadInfo") >= 0)
+ {
+ do_thread_info_query (gdbserv, NULL);
+ }
+ else if (gdbserv_input_string_match (gdbserv, "sThreadInfo") >= 0)
+ {
+ do_thread_info_query (gdbserv, gdbserv->query_thread);
+ }
+ else if (gdbserv_input_string_match (gdbserv, "ThreadExtraInfo,") >= 0)
+ {
+ do_thread_extra_info_query (gdbserv);
+ }
+ else if (gdbserv->target->process_get_gen)
+ {
+ gdbserv->target->process_get_gen (gdbserv);
+ }
+ else
+ {
+ if (gdbserv_state_log != NULL)
+ gdblog_string (gdbserv_state_log, "<general_query>\n");
+ }
+ break;
+
+ case 'Q': /* general set packet */
+ if (gdbserv->target->process_set_gen)
+ gdbserv->target->process_set_gen (gdbserv);
+ else
+ {
+ if (gdbserv_state_log)
+ gdblog_string (gdbserv_state_log, "<general_set>\n");
+ }
+ break;
+
+ case 'g': /* return the value of the CPU registers. */
+ /* Give first preference to the thread-aware method. */
+ if (gdbserv->target->get_thread_reg != NULL
+ && gdbserv->target->next_gg_reg != NULL
+ && gdbserv->target->reg_format != NULL
+ && gdbserv->target->output_reg != NULL)
+ {
+ do_get_registers_g_packet (gdbserv);
+ }
+ /* Give second preference to the get_reg method. */
+ else if (gdbserv->target->get_reg != NULL
+ && gdbserv->target->gg_reg_nr != NULL
+ && gdbserv->target->sizeof_reg != NULL
+ && gdbserv->target->output_reg != NULL)
+ {
+ int i;
+ int reg_nr;
+ for (i = 0, reg_nr = gdbserv->target->gg_reg_nr (gdbserv, i);
+ reg_nr >= 0;
+ i++, reg_nr = gdbserv->target->gg_reg_nr (gdbserv, i))
+ {
+ struct gdbserv_reg reg;
+ long sizeof_reg = gdbserv->target->sizeof_reg (gdbserv, reg_nr);
+ long len = (sizeof_reg < 0 ? -sizeof_reg : sizeof_reg);
+ if (sizeof_reg > 0)
+ {
+ int status;
+ status = gdbserv->target->get_reg (gdbserv, reg_nr, &reg);
+ if (status < 0)
+ memset (&reg, 0, sizeof (reg));
+ }
+ else
+ memset (&reg, 0, sizeof (reg));
+ gdbserv->target->output_reg (gdbserv, &reg, len);
+ }
+ }
+ else if (gdbserv->target->process_get_regs != NULL)
+ {
+ gdbserv->target->process_get_regs (gdbserv);
+ }
+ /* else error? */
+ break;
+
+ case 'G': /* set the value of the CPU registers - return OK */
+ /* Give first preference to the thread-aware method. */
+ if (gdbserv->target->set_thread_reg != NULL
+ && gdbserv->target->next_gg_reg != NULL
+ && gdbserv->target->reg_format != NULL
+ && gdbserv->target->input_reg != NULL)
+ {
+ do_set_registers_g_packet (gdbserv);
+ }
+ /* Give second preference to the set_reg method. */
+ else if (gdbserv->target->gg_reg_nr != NULL
+ && gdbserv->target->set_reg != NULL
+ && gdbserv->target->sizeof_reg != NULL
+ && gdbserv->target->input_reg != NULL)
+ {
+ int i;
+ int reg_nr;
+ for (i = 0, reg_nr = gdbserv->target->gg_reg_nr (gdbserv, i);
+ reg_nr >= 0;
+ i++, reg_nr = gdbserv->target->gg_reg_nr (gdbserv, i))
+ {
+ struct gdbserv_reg reg;
+ long sizeof_reg = gdbserv->target->sizeof_reg (gdbserv, reg_nr);
+ long len = (sizeof_reg < 0 ? -sizeof_reg : sizeof_reg);
+ gdbserv->target->input_reg (gdbserv, &reg, len);
+ if (sizeof_reg > 0)
+ /* only supply registers that are useful. */
+ gdbserv->target->set_reg (gdbserv, reg_nr, &reg);
+ }
+ gdbserv_output_string (gdbserv, "OK");
+ }
+ else if (gdbserv->target->process_set_regs != NULL)
+ {
+ gdbserv->target->process_set_regs (gdbserv);
+ }
+ /* else error? */
+ break;
+
+ case 'A': /* UNOFFICIAL: set program arguments */
+ gdbserv->target->process_set_args (gdbserv);
+ break;
+
+ case 'p': /* UNOFFICIAL: read single reg */
+ /* Give first preference to the thread-aware method. */
+ if (gdbserv->target->get_thread_reg != NULL
+ && gdbserv->target->output_reg != NULL
+ && gdbserv->target->reg_format != NULL)
+ {
+ do_get_registers_p_packet (gdbserv);
+ }
+ /* FIXME: Give second preference to the get_reg method? */
+ else if (gdbserv->target->process_get_reg != NULL)
+ {
+ unsigned long regnr;
+ if (gdbserv_input_hex_ulong (gdbserv, &regnr) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E01");
+ }
+ else if (gdbserv->target->process_get_reg (gdbserv, regnr) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E03");
+ }
+ }
+ /* else error? */
+ break;
+
+ case 'P': /* write single reg */
+ /* Give first preference to the thread-aware method. */
+ if (gdbserv->target->set_thread_reg != NULL
+ && gdbserv->target->input_reg != NULL)
+ {
+ do_set_registers_p_packet (gdbserv);
+ }
+ /* Give second preference to the set_reg method. */
+ else if (gdbserv->target->set_reg != NULL
+ && gdbserv->target->input_reg != NULL)
+ {
+ unsigned long regnr;
+ struct gdbserv_reg reg;
+ if (gdbserv_input_hex_ulong (gdbserv, &regnr) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E01");
+ }
+ else if (gdbserv_input_char (gdbserv) != '=')
+ {
+ gdbserv_output_string (gdbserv, "E02");
+ }
+ else if (gdbserv->target->input_reg (gdbserv, &reg, 0) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E03");
+ }
+ else
+ {
+ gdbserv->target->set_reg (gdbserv, regnr, &reg);
+ gdbserv_output_string (gdbserv, "OK");
+ }
+ }
+ else if (gdbserv->target->process_set_reg != NULL)
+ {
+ unsigned long regnr;
+ if (gdbserv_input_hex_ulong (gdbserv, &regnr) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E01");
+ }
+ else if (gdbserv_input_char (gdbserv) != '=')
+ {
+ gdbserv_output_string (gdbserv, "E02");
+ }
+ else if (gdbserv->target->process_set_reg (gdbserv, regnr) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E03");
+ }
+ else
+ {
+ gdbserv_output_string (gdbserv, "OK");
+ }
+ }
+ /* else error? */
+ break;
+
+ case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
+ case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
+ case 'X': /* XAA..AA,LLLL: Write LLLL binary bytes at AA.AA return OK */
+ if ((packet_type == 'm'
+ && (gdbserv->target->get_mem != NULL
+ || gdbserv->target->get_thread_mem != NULL))
+ || ((packet_type == 'M' || packet_type == 'X')
+ && (gdbserv->target->set_mem != NULL
+ || gdbserv->target->set_thread_mem != NULL)))
+ {
+ struct gdbserv_reg addr;
+ long len;
+ if (gdbserv_input_reg_beb (gdbserv, &addr, 0) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E01");
+ }
+ else if (gdbserv_input_char (gdbserv) != ',')
+ {
+ gdbserv_output_string (gdbserv, "E02");
+ }
+ else if (gdbserv_input_hex_ulong (gdbserv, &len) < 0)
+ {
+ gdbserv_output_string (gdbserv, "E03");
+ }
+ else if (packet_type == 'm')
+ {
+ void *data = alloca (len);
+ long nr_read;
+ if (gdbserv->target->get_thread_mem != NULL)
+ nr_read =
+ gdbserv->target->get_thread_mem (gdbserv,
+ gdbserv->general_thread,
+ &addr, data, len);
+ else if (gdbserv->target->get_mem != NULL)
+ nr_read = gdbserv->target->get_mem (gdbserv, &addr, data, len);
+ else
+ assert (0);
+ if (nr_read < 0)
+ gdbserv_output_string (gdbserv, "E07");
+ else
+ gdbserv_output_bytes (gdbserv, data, nr_read);
+ }
+ else if (gdbserv_input_char (gdbserv) == ':')
+ {
+ void *data = alloca (len);
+ int nr_written;
+ if (packet_type == 'X')
+ {
+ if (gdbserv_input_escaped_binary (gdbserv, data, len) != len)
+ {
+ gdbserv_output_string (gdbserv, "E08");
+ break;
+ }
+ }
+ else
+ {
+ if (gdbserv_input_bytes (gdbserv, data, len) != len)
+ {
+ gdbserv_output_string (gdbserv, "E09");
+ break;
+ }
+ }
+ if (gdbserv->target->set_thread_mem != NULL)
+ nr_written =
+ gdbserv->target->set_thread_mem (gdbserv,
+ gdbserv->general_thread,
+ &addr, data, len);
+ else if (gdbserv->target->set_mem != NULL)
+ nr_written = gdbserv->target->set_mem (gdbserv,
+ &addr, data, len);
+ else
+ assert (0);
+ if (nr_written < 0)
+ gdbserv_output_string (gdbserv, "E10");
+ else if (nr_written != len)
+ gdbserv_output_string (gdbserv, "E10");
+ else
+ gdbserv_output_string (gdbserv, "OK");
+ }
+ else
+ {
+ gdbserv_output_string (gdbserv, "E04");
+ }
+ }
+ break;
+
+ case 'b':
+ /* The 'b' prefix before 's' or 'c' means "backward".
+ This is for reverse debugging.
+
+ Fetch the next char, and if it is 's' or 'c', then
+ just set reverse_flag and go back to the switch statement
+ (from there to return to step or continue as appropriate).
+
+ Else, error. */
+
+ packet_type = gdbserv_input_char (gdbserv);
+ switch (packet_type) {
+ case 'S': case 's':
+ case 'C': case 'c':
+ demo_reverse_flag = 1;
+ goto backward;
+ break;
+
+ default:
+ if (gdbserv_state_log)
+ gdblog_string (gdbserv_state_log, "<target_packet>\n");
+ gdbserv_output_string (gdbserv, "");
+ break;
+ }
+ break;
+
+ case 's': case 'c': case 'i':
+ /* [isc]AA..AA
+ Resume program execution (at optional address ``AA..AA''). */
+ case 'S': case 'C': /* case 'I': */
+ /* [ISC]ss;AA..AA
+ Deliver signal ``ss'' (after setting program up to resume
+ execution at optional address ``AA..AA''). */
+ {
+ int sigval;
+ enum gdbserv_totarget_event event;
+ struct gdbserv_reg tmppc;
+ struct gdbserv_reg *pc;
+
+ switch (packet_type)
+ {
+ case 'c': case 'C': event = GDBSERV_TOTARGET_CONTINUE; break;
+ case 'i': case 'I': event = GDBSERV_TOTARGET_CYCLESTEP; break;
+ case 's': case 'S': event = GDBSERV_TOTARGET_SINGLESTEP; break;
+ default: assert (0);
+ }
+
+ /* Get the signal. The signal is a small GDB defined integer.
+ It is not a target dependant value. */
+ switch (packet_type)
+ {
+ case 'C': case 'S': case 'I':
+ sigval = gdbserv_input_byte (gdbserv);
+ if (sigval < 0)
+ {
+ gdbserv_output_string (gdbserv, "E01");
+ break;
+ }
+ if (gdbserv_input_peek (gdbserv) == ';')
+ gdbserv_input_char (gdbserv);
+ break;
+ case 'c': case 's': case 'i':
+ sigval = 0;
+ break;
+ }
+
+ /* NOTE: While GDB never passes an address down as part of a
+ continue packet, target stack entries might. For instance,
+ a ``load 'n' go'' target might need to set the continue
+ address as part of starting a target. */
+
+ if (gdbserv_input_reg_beb (gdbserv, &tmppc, 0) >= 0)
+ pc = &tmppc;
+ else
+ pc = NULL;
+
+ switch (gdbserv_totarget (gdbserv, gdbserv->continue_thread,
+ event, pc, sigval))
+ {
+ case GDBSERV_TARGET_RC_OK:
+ gdbserv->state = GDBSERV_STATE_RUNNING;
+ return;
+ default:
+ gdbserv_output_string (gdbserv, "E99");
+ break;
+ }
+ }
+
+ /* kill the program */
+ case 'k' :
+ {
+ gdbserv->target->exit_program (gdbserv);
+ gdbserv->state = GDBSERV_STATE_EXITING;
+ return;
+ }
+
+ case 'Z':
+ case 'z':
+ /* breakpoint [Zz]<type>,<address>,<length> */
+ if (gdbserv->target->remove_breakpoint != NULL
+ && gdbserv->target->set_breakpoint != NULL)
+ {
+ enum gdbserv_target_bp bp;
+ enum gdbserv_target_rc rc;
+ unsigned long type;
+ struct gdbserv_reg addr;
+ struct gdbserv_reg len;
+ if (gdbserv_input_hex_ulong (gdbserv, &type) < 0
+ || gdbserv_input_char (gdbserv) != ','
+ || gdbserv_input_reg_beb (gdbserv, &addr, 0) < 0
+ || gdbserv_input_char (gdbserv) != ','
+ || gdbserv_input_reg_beb (gdbserv, &len, 0) < 0)
+ {
+ /* Signal parse error */
+ gdbserv_output_string (gdbserv, "E01");
+ break;
+ }
+ switch (type)
+ {
+ case 0: bp = GDBSERV_TARGET_BP_SOFTWARE; break;
+ case 1: bp = GDBSERV_TARGET_BP_HARDWARE; break;
+ case 2: bp = GDBSERV_TARGET_BP_WRITE; break;
+ case 3: bp = GDBSERV_TARGET_BP_READ; break;
+ case 4: bp = GDBSERV_TARGET_BP_ACCESS; break;
+ default: bp = GDBSERV_TARGET_BP_UNKNOWN; break;
+ }
+ if (bp == GDBSERV_TARGET_BP_UNKNOWN)
+ {
+ /* only recognize software breakpoints */
+ gdbserv_output_string (gdbserv, "E02");
+ break;
+ }
+ if (packet_type == 'z')
+ rc = gdbserv->target->remove_breakpoint (gdbserv, bp, &addr, &len);
+ else
+ rc = gdbserv->target->set_breakpoint (gdbserv, bp, &addr, &len);
+ switch (rc)
+ {
+ case GDBSERV_TARGET_RC_OK:
+ gdbserv_output_string (gdbserv, "OK");
+ break;
+ case GDBSERV_TARGET_RC_ERROR:
+ gdbserv_output_string (gdbserv, "E03");
+ break;
+ case GDBSERV_TARGET_RC_UNKNOWN:
+ /* Behave as if operation isn't supported. */
+ break;
+ }
+ }
+ break;
+
+
+ case 'r': /* Reset */
+ if (gdbserv->target->reset_program)
+ {
+ gdbserv->target->reset_program (gdbserv);
+ reset_state (gdbserv);
+ }
+ break;
+
+
+ case 'R': /* Rnn restart server */
+ if (gdbserv->target->restart_program)
+ {
+ gdbserv->target->restart_program (gdbserv);
+ reset_state (gdbserv);
+ return;
+ }
+ break;
+
+
+ case 'T':
+ do_thread_alive_packet (gdbserv);
+ break;
+
+ default:
+ if (gdbserv->target->process_target_packet)
+ gdbserv->target->process_target_packet (gdbserv);
+ else
+ {
+ if (gdbserv_state_log)
+ gdblog_string (gdbserv_state_log, "<target_packet>\n");
+ gdbserv_output_string (gdbserv, "");
+ }
+ break;
+
+ }
+ gdbserv_output_packet (gdbserv);
+}
+
+static void
+fromtarget (struct gdbserv *gdbserv,
+ struct gdbserv_thread *thread,
+ enum gdbserv_fromtarget_event event,
+ const struct gdbserv_reg *stop_addr,
+ int sigval)
+{
+ enum gdbserv_state nextstate;
+ log_state (gdbserv, "fromtarget");
+
+ /* A multi-threaded target may not necessarily have a thread to bind
+ the event to. This happens when the event, such as ``cntrl-c''
+ isn't directed at a specific thread. Since GDB assumes that
+ every event is bound to a specific thread the below fudges things
+ by selecting an earlier thread. If at the end, there is still no
+ thread then that is OK as the target wasn't multi-threaded to
+ start with. If GDB is ever modified so that it doesn't assume
+ that all events belong to threads then this heuristic can be
+ eliminated. */
+ if (thread == NULL)
+ thread = gdbserv->continue_thread;
+ if (thread == NULL)
+ thread = gdbserv->event_thread;
+ if (thread == NULL)
+ thread = gdbserv->general_thread;
+ gdbserv->event_thread = thread;
+ gdbserv->event_sigval = sigval;
+
+ /* GDB assumes that, unless the target is told otherwize, a "g"
+ query will return the regiters for the event that triggered the
+ event. */
+ gdbserv->general_thread = gdbserv->event_thread;
+
+ /* GDB assumes that, unless told otherwize, the target will resume
+ the entire system. A NULL "continue" thread implies this. */
+ gdbserv->continue_thread = NULL;
+
+ switch (event)
+ {
+ case GDBSERV_FROMTARGET_STOPPED:
+ switch (gdbserv->state)
+ {
+ case GDBSERV_STATE_RESETTING:
+ nextstate = GDBSERV_STATE_BROKEN;
+ /* After a reset / power-on GDB expects the remote target to
+ silently stop at the first instruction ready for further
+ commands. Hence NO NOTIFY. */
+ break;
+ case GDBSERV_STATE_RUNNING:
+ nextstate = GDBSERV_STATE_BROKEN;
+ do_status_packet (gdbserv);
+ gdbserv_output_packet (gdbserv);
+ break;
+ default:
+ nextstate = gdbserv->state;
+ gdblog_string (gdbserv_warning_log, "STOPPED -> unknown event\n");
+ break;
+ }
+ break;
+ case GDBSERV_FROMTARGET_EXITED:
+ case GDBSERV_FROMTARGET_TERMINATED:
+ switch (gdbserv->state)
+ {
+ case GDBSERV_STATE_RUNNING:
+ nextstate = GDBSERV_STATE_EXITED;
+ do_exit_packet (gdbserv, event, sigval);
+ gdbserv_output_packet (gdbserv);
+ break;
+ default:
+ nextstate = gdbserv->state;
+ gdblog_string (gdbserv_warning_log, "EXITED/TERMINATED -> unknown event\n");
+ break;
+ }
+ break;
+ default:
+ nextstate = gdbserv->state;
+ gdblog_string (gdbserv_warning_log, "UNKNOWN STATE -> unknown event\n");
+ break;
+ }
+ gdbserv->state = nextstate;
+}