diff options
author | Michael Snyder <msnyder@redhat.com> | 2008-06-12 00:56:00 +0000 |
---|---|---|
committer | Michael Snyder <msnyder@redhat.com> | 2008-06-12 00:56:00 +0000 |
commit | 280e2d671ade34d52f35be6bee65968d1cd642fe (patch) | |
tree | 12566a2b671f7d3014267c4557f728942bd15deb | |
parent | 2c7811d77ae27fea5e7cd49f2c32f51f14d6916a (diff) | |
download | gdb-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/ChangeLog | 1241 | ||||
-rw-r--r-- | rda/lib/gdbserv-state.c | 1327 |
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, ®); + else + memset (®, 0, sizeof (reg)); + gdbserv->target->output_reg (gdbserv, ®, 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, ®) >= 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, + ®, 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, + ®, size) >= 0) + /* only supply registers that are useful. */ + gdbserv->target->set_thread_reg (gdbserv, + gdbserv->general_thread, + reg_nr, ®); + } + 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, ®nr) < 0) + { + result = "E01"; + break; + } + if (gdbserv_input_string_match (gdbserv, "=") >= 0) + { + if (gdbserv->target->input_reg (gdbserv, ®, 0) < 0) + { + result = "E02"; + break; + } + } + else + { + result = "E04"; + break; + } + if (gdbserv->target->set_thread_reg (gdbserv, + gdbserv->general_thread, + regnr, ®) < 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, ®nr) < 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, ®); + if (status < 0) + memset (®, 0, sizeof (reg)); + } + else + memset (®, 0, sizeof (reg)); + gdbserv->target->output_reg (gdbserv, ®, 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, ®, len); + if (sizeof_reg > 0) + /* only supply registers that are useful. */ + gdbserv->target->set_reg (gdbserv, reg_nr, ®); + } + 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, ®nr) < 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, ®nr) < 0) + { + gdbserv_output_string (gdbserv, "E01"); + } + else if (gdbserv_input_char (gdbserv) != '=') + { + gdbserv_output_string (gdbserv, "E02"); + } + else if (gdbserv->target->input_reg (gdbserv, ®, 0) < 0) + { + gdbserv_output_string (gdbserv, "E03"); + } + else + { + gdbserv->target->set_reg (gdbserv, regnr, ®); + gdbserv_output_string (gdbserv, "OK"); + } + } + else if (gdbserv->target->process_set_reg != NULL) + { + unsigned long regnr; + if (gdbserv_input_hex_ulong (gdbserv, ®nr) < 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; +} |