OSDN Git Service

Added files comprising RDA.
authorkevinb <kevinb>
Wed, 28 Aug 2002 01:22:27 +0000 (01:22 +0000)
committerkevinb <kevinb>
Wed, 28 Aug 2002 01:22:27 +0000 (01:22 +0000)
98 files changed:
rda/ChangeLog [new file with mode: 0644]
rda/HOWTO [new file with mode: 0644]
rda/MAINTAINERS [new file with mode: 0644]
rda/Makefile.am [new file with mode: 0644]
rda/Makefile.in [new file with mode: 0644]
rda/NEWS [new file with mode: 0644]
rda/README [new file with mode: 0644]
rda/REMOTE-HACK-RULES [new file with mode: 0644]
rda/acinclude.m4 [new file with mode: 0644]
rda/aclocal.m4 [new file with mode: 0644]
rda/config.in [new file with mode: 0644]
rda/configure [new file with mode: 0755]
rda/configure.in [new file with mode: 0644]
rda/include/gdblog.h [new file with mode: 0644]
rda/include/gdbloop.h [new file with mode: 0644]
rda/include/gdbsched.h [new file with mode: 0644]
rda/include/gdbserv-client.h [new file with mode: 0644]
rda/include/gdbserv-input.h [new file with mode: 0644]
rda/include/gdbserv-log.h [new file with mode: 0644]
rda/include/gdbserv-output.h [new file with mode: 0644]
rda/include/gdbserv-target.h [new file with mode: 0644]
rda/include/gdbserv-utils.h [new file with mode: 0644]
rda/include/gdbserv.h [new file with mode: 0644]
rda/include/gdbsocket.h [new file with mode: 0644]
rda/include/stdio-log.h [new file with mode: 0644]
rda/lib/ARCH [new file with mode: 0644]
rda/lib/Makefile.am [new file with mode: 0644]
rda/lib/Makefile.in [new file with mode: 0644]
rda/lib/gdblog.c [new file with mode: 0644]
rda/lib/gdbloop.c [new file with mode: 0644]
rda/lib/gdbsched.c [new file with mode: 0644]
rda/lib/gdbserv-input.c [new file with mode: 0644]
rda/lib/gdbserv-log.c [new file with mode: 0644]
rda/lib/gdbserv-output.c [new file with mode: 0644]
rda/lib/gdbserv-state.c [new file with mode: 0644]
rda/lib/gdbserv-state.h [new file with mode: 0644]
rda/lib/gdbserv-target.c [new file with mode: 0644]
rda/lib/gdbserv-utils.c [new file with mode: 0644]
rda/lib/gdbsocket.c [new file with mode: 0644]
rda/lib/stdio-log.c [new file with mode: 0644]
rda/qe/Makefile.am [new file with mode: 0644]
rda/qe/Makefile.in [new file with mode: 0644]
rda/qe/README [new file with mode: 0644]
rda/qe/inc-backwards.c [new file with mode: 0644]
rda/qe/inc-forward.c [new file with mode: 0644]
rda/qe/inc-gdblog.c [new file with mode: 0644]
rda/qe/inc-gdbloop.c [new file with mode: 0644]
rda/qe/inc-gdbsched.c [new file with mode: 0644]
rda/qe/inc-gdbserv-client.c [new file with mode: 0644]
rda/qe/inc-gdbserv-input.c [new file with mode: 0644]
rda/qe/inc-gdbserv-log.c [new file with mode: 0644]
rda/qe/inc-gdbserv-output.c [new file with mode: 0644]
rda/qe/inc-gdbserv-target.c [new file with mode: 0644]
rda/qe/inc-gdbserv-utils.c [new file with mode: 0644]
rda/qe/inc-gdbserv.c [new file with mode: 0644]
rda/qe/inc-gdbsocket.c [new file with mode: 0644]
rda/qe/inc-stdio-log.c [new file with mode: 0644]
rda/qe/qe.c [new file with mode: 0644]
rda/samples/Makefile.am [new file with mode: 0644]
rda/samples/Makefile.in [new file with mode: 0644]
rda/samples/async.c [new file with mode: 0644]
rda/samples/demo-target.c [new file with mode: 0644]
rda/samples/demo-target.h [new file with mode: 0644]
rda/samples/main.c [new file with mode: 0644]
rda/samples/poll.c [new file with mode: 0644]
rda/samples/thread.c [new file with mode: 0644]
rda/stamp-h.in [new file with mode: 0644]
rda/unix/ChangeLog [new file with mode: 0644]
rda/unix/Makefile.am [new file with mode: 0644]
rda/unix/Makefile.in [new file with mode: 0644]
rda/unix/aclocal.m4 [new file with mode: 0644]
rda/unix/config.in [new file with mode: 0644]
rda/unix/configure [new file with mode: 0755]
rda/unix/configure.in [new file with mode: 0644]
rda/unix/dummy-target.c [new file with mode: 0644]
rda/unix/gdb_proc_service.h [new file with mode: 0644]
rda/unix/gdbserv-thread-db.h [new file with mode: 0644]
rda/unix/linux-target.c [new file with mode: 0644]
rda/unix/no-threads.c [new file with mode: 0644]
rda/unix/ptrace-target.c [new file with mode: 0644]
rda/unix/ptrace-target.h [new file with mode: 0644]
rda/unix/server.c [new file with mode: 0644]
rda/unix/server.h [new file with mode: 0644]
rda/unix/solaris-target.c [new file with mode: 0644]
rda/unix/thread-db.c [new file with mode: 0644]
rda/win32/ChangeLog [new file with mode: 0644]
rda/win32/Makefile.am [new file with mode: 0644]
rda/win32/Makefile.in [new file with mode: 0644]
rda/win32/aclocal.m4 [new file with mode: 0644]
rda/win32/child_process.cc [new file with mode: 0644]
rda/win32/config.in [new file with mode: 0644]
rda/win32/configure [new file with mode: 0755]
rda/win32/configure.in [new file with mode: 0644]
rda/win32/server.cc [new file with mode: 0644]
rda/win32/server.h [new file with mode: 0644]
rda/win32/stamp-h.in [new file with mode: 0644]
rda/win32/win32-strace.cc [new file with mode: 0644]
rda/win32/win32-target.cc [new file with mode: 0644]

diff --git a/rda/ChangeLog b/rda/ChangeLog
new file mode 100644 (file)
index 0000000..e7ef1f7
--- /dev/null
@@ -0,0 +1,1143 @@
+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.
+
+\f
+Local Variables:
+mode: change-log
+left-margin: 8
+fill-column: 74
+version-control: never
+End:
diff --git a/rda/HOWTO b/rda/HOWTO
new file mode 100644 (file)
index 0000000..d79ba46
--- /dev/null
+++ b/rda/HOWTO
@@ -0,0 +1,330 @@
+How to implement a stub or server using RDA (Red Hat Debug Agent and library).
+==================================================
+Andrew Cagney <cagney@cygnus.com>
+Fernando Nasser <fnasser@cygnus.com>
+Frank Eigler <fche@cygnus.com>
+
+Introduction
+------------
+
+This is the implementation of a server for the gdb remote protocol.
+It is available as a host library that provides most of the common code
+required.  By adding a relatively small amount of target dependent code,
+one can build a server that allows gdb to connect to that target using
+the gdb "target remote" command.
+
+Gdb connects to this server through a TCP/IP connection.  The server
+waits for a connection from GDB by listening to a non-restricted TCP port.
+Anyone with GDB (or even telnet) network connectivity to the machine
+running the server can initiate a connection to it.
+
+Note: The user of this software is advised to ensure
+that access to the TCP port being used is restricted to
+secure siblings.  For instance, the user may need to take
+action that ensures that `The Internet' is not able to access
+the TCP port being used.
+
+Architecture
+------------
+
+The following diagram shows the components of RDA.
+
+       (GDB) <---"remote"---> CLIENT <--> SERVER <--> TARGET
+       -------                 ------------------------------
+     The client.                         The server.
+
+Where:
+
+       CLIENT  Provides the raw interface between
+               GDB and the internal SERVER
+               mechanism.
+
+               The client passes on any data relevant
+               to the server.  The SERVER presents
+               CLIENT with raw output to be returned
+               to GDB.
+
+       SERVER  Implements the state-machine that
+               is capable of decoding / processing
+               various GDB remote protocol requests.
+
+       TARGET  The embedded system proper.  SERVER
+               passes decoded requests onto the TARGET
+               while TARGET notifies the SERVER of any
+               target state changes.
+
+
+Looking at SERVER in more detail, that component consists of three sub
+components INPUT, OUTPUT and STATE.  Visually:
+
+                                    .------------ fromtarget_*
+                                   \|/
+       fromclient_*   -> INPUT -> STATE (M/C) -> target->*
+                          /|\         |
+                            |
+                          \|/         |
+       client->write  <- OUTPUT <----'
+
+Where:
+
+       INPUT   Filters the raw input stream from the client
+               breaking it up into complete packets and
+               passing them onto STATE.
+
+               This component co-operates with OUTPUT for
+               the ACK/NAK of input packets.
+
+       OUTPUT  Wraps up and then passes onto the client
+               raw output packets ready for transmission
+               on the output stream.
+
+               This component  co-operates with INPUT for
+               the ACK/NAK of output packets.
+
+       STATE   The state machine proper.
+
+
+The Appendix provides various scenarios showing in some detail how typical
+operations are handled by these components.  It may be convenient to read the
+next section first before turning to the Appendix.
+
+
+Adding the target dependent code
+--------------------------------
+
+In the following discussion, assume your debugger (gdb) is using 
+the remote protocol to communicate with the code you are building here.
+The "target" is a simulator, hardware device, board, program or whatever you
+are interfacing to with your stub/server.
+
+The library provides gdbsocket_*() and gdbserv_fromtarget_*() routines that
+must be called and requires you to set a series of callback routines.
+You make these callbacks known/available to the library by filling the entries
+of a "gdbserv_target" object.  You must also provide an extra function that
+will be invoked when a new connection is detected on the input port (a socket).
+
+
+Handling the connection:
+
+The server is capable of handling several connections (named, sessions)
+simultaneously.  This is possible because each session data is kept on
+an instance of a GDBSERV object.  A routine called gdbserv_fromclient_attach()
+is called when a connection request is received by the socket.
+If the connection is accepted, a new instance of a GDBSERV object is returned,
+otherwise NULL is returned indicating that it has been rejected (a EOF will be
+sensed on the other end).
+
+The server will, in turn, pass the request onto the target.  The target can
+either reject the connection (returning NULL) or accept the connection
+(returning a target object).  That is where you come in.
+
+You must provide a routine like (please see the precise API in the header file
+lib/gdbserv-client.h):
+
+typedef struct gdbserv_target *(gdbserv_target_attach) (struct gdbserv *gdbserv,                                                        void *attatch_data);
+
+This will be called by the server to notify that the client has initiated a
+connection.  You must return a GDBSERV_TARGET struct for the session or null
+if your target has rejected the connection.
+
+The recommended way to create your gdbsert_target object is:
+
+struct gdbserv_target *gdbtarget = malloc (sizeof (struct gdbserv_target));
+memset (gdbtarget, 0, sizeof (*gdbtarget));
+gdbtarget->process_get_gen = process_get_gen;
+(...)
+
+If you initialize it like this, you will not have to change your code even if
+new entries are added to this struct.
+
+
+Handling target events:
+
+The fromtarget_* routines may be called by your target.  Before you despair, let
+me tell you that they are only three: reset, break and exit.  They indicate that
+some interesting condition happened in your target that requires debugger
+attention.  Reset and exit are quite obvious and break is for everything else.
+These routines must *not* be called from within a gdbserv_target callback
+function, so it may be necessary for your target to set some flags to signal
+state change calls later.
+
+If your target is a simulator, call those when the corresponding
+condition arises in your simulated target.  If it is a board, it will probably
+be called from your ISRs.  A special case occurs if your target is a device that
+has to be polled in order to detect state changes.  If this is the case, you
+will call these routines from the polling code.
+
+
+The main loop:
+
+At some point you must get things going by:
+
+1) looking for connection requests from gdb and 
+2) causing remote protocol commands to be read from the input port (socket).
+
+You must (repeatedly) call a function called gdbloop_poll().  This
+will be in your main loop.  If it is a server it will be in you main()
+function.  If it is a simulator that also accepts input from other
+sources, it will have to be added to the existing main loop. If it is
+a board, it will probably be called from the timer ISR.
+
+Before doing that you must initialize your socket interface.  Look in
+the main() routine of the sample program to see what to call.  When
+calling gdbsocket_startup() you must give the address of the callback
+that handles connection requests for your target.
+
+If your target has to be polled for state changes, you will have to alternate 
+calls to poll() and to check your target status.  As I mentioned before,
+your status checking routine must call the appropriate fromtarget_* function.
+
+
+The callbacks:
+
+All that is left now is to implement your callbacks, which are, directly or
+indirectly, called as a result of a remote protocol packet being received and
+processed by some fromclient_* routine.  I will assume that the remote
+protocol packets are known.  If not, please refer to the "Remote Protocol"
+section of the gdb manual.  There you will find how your target should be
+affected by each packet and what the response should be.  It is always
+useful to look at what some other remote targets do as well.
+
+The list of all callbacks with the situation in which they are invoked can be
+found in the header file lib/gdbserv-target.h.
+
+Have fun!
+
+
+
+Appendix
+--------
+
+SCENARIOS
+
+
+ATTACH: Creating a connection into the server/target.
+
+Client receives a connect request from the remote GDB.  A socket
+interface would see this as an attach.  For Cygmon this is the
+``transfer'' command.
+
+The client creates an output object (struct gdbserv_client) and passes
+that and the target side attach function onto GDBSERV.  SERVER will
+then initialize itself and call ``to_target_attach'' for final
+approval of the request.
+
+       struct gdbserv_client *client;
+       ...
+       client->write = client_write_to_output_port;
+       client->data = ... local state ...
+       server = gdbserv_fromclient_attach (client, to_target_attach,
+                                           target_data);
+
+The target_attach() function is expected to either create and return a
+gdbserv_target object or return NULL.  The latter indicates that the
+connection request is rejected.
+
+Finally gdbserv_fromclient_attach() returns a SERVER state object that
+should be passed to all client->server calls.
+
+
+DATA-IN: Data being sent to the client from the remote GDB
+
+The client passes the data vis:
+
+       len = read (fd, buf, sizeof (buf));
+       gdbserv_fromclient_data (server, buf, len);
+
+
+BREAK-IN: Request to stop sent to the client from the remote GDB
+
+The client passes the request to SERVER:
+
+       server.c:
+
+       volatile
+       break_handler ()
+       {
+         gdbserv_fromclient_break (server);
+       }
+
+If the target is currently running, the server will in turn pass the
+request onto the TARGET:
+
+       ->target->break_program (server);
+
+and the target will record the break request and then return control
+back to the SERVER.  The server returning control to the client.
+
+Later, once the target has halted, the SERVER is notified of the state
+change vis:
+
+       target.c:
+
+         gdbserv_fromtarget_break (server);
+
+
+NB: Often ``break'' is sent across the stream interface as a special
+character sequence.
+
+FIXME: gdbserv-input.c should be able to parse such character
+sequences.
+
+
+DATA-OUT: Data for the remote GDB from SERVER
+
+The ``write'' function specified in the ``struct gdbserv_client''
+object is called.
+
+
+DETACH: Remote GDB disconnects from the SERVER
+
+The CLIENT notifies SERVER via the gdbserv_fromclient_detach() call.
+
+
+HARD-RESET:  A hard reset is performed on a serial board.
+
+Assuming a standalone system, the client/target side sequences would
+be performed:
+
+       /* create the server */
+       server = gdbserv_fromclient_attach (...);
+       /* notify the server that the target was just reset */
+       gdbserv_fromtarget_reset (server);
+
+
+WRITE-MEMORY: GDB sends the server a write-memory packet.
+
+Eventually SERVER passes the request onto the TARGET with the call:
+
+       ->target->process_set_mem (server, addr, len);
+
+where ADDR and LEN contain the uninterpreted address/length of the
+data to follow.  target_process_set_mem() might be implemented as:
+
+       long long addr;
+       long int;
+       gdbserv_reg_to_ulonglong (server, reg_addr, &addr);
+       gdbserv_reg_to_ulong (server, reg_len, &len);
+       /* just blat local memory */
+       len = gdbserv_input_bytes (server, addr, len);
+       
+
+READ-MEMORY: GDB requests memory from the target.
+
+Eventually target_process_get_mem() function is called.  An
+implementation may look like:
+
+       gdbserv_reg_to_ulonglong (gdbserv, reg_addr, &addr);
+       gdbserv_reg_to_ulong (gdbserv, reg_len, &len);
+       /* assume we're reading raw memory from the local mc */
+       gdbserv_output_bytes (gdbserv, addr, len);
+
+
+TARGET-RESUME: GDB requests that the target resume execution.
+
+Eventually ->target->continue_program() is called.  That function
+should record the request and then wait for SERVER to exit before
+actually continuing the target.
+
+--
+
diff --git a/rda/MAINTAINERS b/rda/MAINTAINERS
new file mode 100644 (file)
index 0000000..76c9e8f
--- /dev/null
@@ -0,0 +1,11 @@
+RDA (Red Hat Debug Agent and library) maintainers:
+
+       lib/
+       samples/
+
+Andrew Cagney          ac131313@redhat.com
+Frank Ch. Eigler       fche@redhat.com
+
+       unix/
+
+Michael Snyder         msnyder@redhat.com
diff --git a/rda/Makefile.am b/rda/Makefile.am
new file mode 100644 (file)
index 0000000..bb2a537
--- /dev/null
@@ -0,0 +1,11 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+WARN_CFLAGS = @WARN_CFLAGS@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+
+APPL_DIRS = @targ_subdirs@
+SUBDIRS = lib samples qe $(APPL_DIRS)
+
diff --git a/rda/Makefile.in b/rda/Makefile.in
new file mode 100644 (file)
index 0000000..166ccba
--- /dev/null
@@ -0,0 +1,399 @@
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+GCJ = @GCJ@
+GCJFLAGS = @GCJFLAGS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+l = @l@
+targ_subdirs = @targ_subdirs@
+
+AUTOMAKE_OPTIONS = foreign
+
+WARN_CFLAGS = @WARN_CFLAGS@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+
+APPL_DIRS = @targ_subdirs@
+SUBDIRS = lib samples qe $(APPL_DIRS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = 
+DIST_COMMON =  README ./stamp-h.in ChangeLog Makefile.am Makefile.in \
+NEWS acinclude.m4 aclocal.m4 config.in configure configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in  acinclude.m4
+       cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+       @if test ! -f $@; then \
+               rm -f stamp-h; \
+               $(MAKE) stamp-h; \
+       else :; fi
+stamp-h: $(srcdir)/config.in $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \
+            $(SHELL) ./config.status
+       @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+       @if test ! -f $@; then \
+               rm -f $(srcdir)/stamp-h.in; \
+               $(MAKE) $(srcdir)/stamp-h.in; \
+       else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+       @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+       -rm -f config.h
+
+maintainer-clean-hdr:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive  \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+       @set fnord $(MAKEFLAGS); amf=$$2; \
+       dot_seen=no; \
+       target=`echo $@ | sed s/-recursive//`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           dot_seen=yes; \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done; \
+       if test "$$dot_seen" = "no"; then \
+         $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+       fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+       @set fnord $(MAKEFLAGS); amf=$$2; \
+       dot_seen=no; \
+       rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+         rev="$$subdir $$rev"; \
+         test "$$subdir" != "." || dot_seen=yes; \
+       done; \
+       test "$$dot_seen" = "no" && rev=". $$rev"; \
+       target=`echo $@ | sed s/-recursive//`; \
+       for subdir in $$rev; do \
+         echo "Making $$target in $$subdir"; \
+         if test "$$subdir" = "."; then \
+           local_target="$$target-am"; \
+         else \
+           local_target="$$target"; \
+         fi; \
+         (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+          || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+       done && test -z "$$fail"
+tags-recursive:
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+         test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+       done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SUBDIRS)'; for subdir in $$list; do \
+   if test "$$subdir" = .; then :; else \
+           test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+   fi; \
+       done; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       -rm -rf $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+       mkdir $(distdir)/=build
+       mkdir $(distdir)/=inst
+       dc_install_base=`cd $(distdir)/=inst && pwd`; \
+       cd $(distdir)/=build \
+         && ../configure --srcdir=.. --prefix=$$dc_install_base \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) dist
+       -rm -rf $(distdir)
+       @banner="$(distdir).tar.gz is ready for distribution"; \
+       dashes=`echo "$$banner" | sed s/./=/g`; \
+       echo "$$dashes"; \
+       echo "$$banner"; \
+       echo "$$dashes"
+dist: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+dist-all: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+distdir: $(DISTFILES)
+       -rm -rf $(distdir)
+       mkdir $(distdir)
+       -chmod 777 $(distdir)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+       for subdir in $(SUBDIRS); do \
+         if test "$$subdir" = .; then :; else \
+           test -d $(distdir)/$$subdir \
+           || mkdir $(distdir)/$$subdir \
+           || exit 1; \
+           chmod 777 $(distdir)/$$subdir; \
+           (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+             || exit 1; \
+         fi; \
+       done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+all-recursive-am: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile config.h
+all-redirect: all-recursive-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-hdr mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am:  clean-hdr clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am:  distclean-hdr distclean-tags distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-recursive
+       -rm -f config.status
+
+maintainer-clean-am:  maintainer-clean-hdr maintainer-clean-tags \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+       -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+install-data-recursive uninstall-data-recursive install-exec-recursive \
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
+all-recursive check-recursive installcheck-recursive info-recursive \
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
+install-exec-am install-exec install-data-am install-data install-am \
+install uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/rda/NEWS b/rda/NEWS
new file mode 100644 (file)
index 0000000..f956d25
--- /dev/null
+++ b/rda/NEWS
@@ -0,0 +1,6 @@
+
+2000-04-06
+
+       The RDA package is created by factoring out
+       a gdb remote-stub implementation by Andrew Cagney.
+
diff --git a/rda/README b/rda/README
new file mode 100644 (file)
index 0000000..a3e7bb1
--- /dev/null
@@ -0,0 +1,16 @@
+This directory contains an implementation of a server for the gdb remote
+protocol, built as a host library.  It is suitable for applications that
+are to be remote targets of a debugger, such as simulators, interfaces to ICE
+hardware, etc.
+
+Roadmap:
+
+       lib/            contains the remote protocol stub implementation
+                       is not meant to be installed
+                       builds into librda.a and librda.la
+                       includes headers
+
+       samples/        contains a sample application of the library
+
+Note: remember to use autoconf and automake to configure, unlike some of the other
+tools.
diff --git a/rda/REMOTE-HACK-RULES b/rda/REMOTE-HACK-RULES
new file mode 100644 (file)
index 0000000..52ba52b
--- /dev/null
@@ -0,0 +1,37 @@
+RDA hack rules:
+
+The RDA package is used by several programs, so it is important to
+keep the external interface of the lib part as stable as possible.  
+
+Since some programs that depend on RDA are kept in separate source
+trees, it is not easy to test whether changes to the lib/ directory will
+regress them.  Each proposed change to devo/remote/lib should be tested
+by building:
+       remote/samples
+       sid/component/gdb
+and running gdb against the code.  Submit patches to the MAINTAINERS.  
+
+You are welcome to create new subdirectories for applications that use
+this library.
+
+Discussion of this package is held at
+       gdb@sourceware.cygnus.com
+
+
+TODO:
+
+New sample server programs for remote/samples.
+
+Convert RDA into an optionally installable library,
+with tidied-up headers.
+
+MAN pages.
+
+Test suite.
+
+Ports to more hosts.
+
+
+
+add --enable-build-warnings.
+See bfd for how to have it work with automake.
diff --git a/rda/acinclude.m4 b/rda/acinclude.m4
new file mode 100644 (file)
index 0000000..c5879e6
--- /dev/null
@@ -0,0 +1,16 @@
+sinclude(../libtool.m4)
+dnl The lines below arrange for aclocal not to bring libtool.m4
+dnl AM_PROG_LIBTOOL into aclocal.m4, while still arranging for automake
+dnl to add a definition of LIBTOOL to Makefile.in.
+ifelse(yes,no,[
+AC_DEFUN([AM_PROG_LIBTOOL],)
+AC_SUBST(LIBTOOL)
+])
+
+sinclude(../gettext.m4)
+dnl The lines below arrange for aclocal not to bring gettext.m4's
+dnl CY_WITH_NLS into aclocal.m4.
+ifelse(yes,no,[
+AC_DEFUN([CY_WITH_NLS],)
+AC_SUBST(INTLLIBS)
+])
diff --git a/rda/aclocal.m4 b/rda/aclocal.m4
new file mode 100644 (file)
index 0000000..7fd654f
--- /dev/null
@@ -0,0 +1,177 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+sinclude(../libtool.m4)
+dnl The lines below arrange for aclocal not to bring libtool.m4
+dnl AM_PROG_LIBTOOL into aclocal.m4, while still arranging for automake
+dnl to add a definition of LIBTOOL to Makefile.in.
+ifelse(yes,no,[
+AC_DEFUN([AM_PROG_LIBTOOL],)
+AC_SUBST(LIBTOOL)
+])
+
+sinclude(../gettext.m4)
+dnl The lines below arrange for aclocal not to bring gettext.m4's
+dnl CY_WITH_NLS into aclocal.m4.
+ifelse(yes,no,[
+AC_DEFUN([CY_WITH_NLS],)
+AC_SUBST(INTLLIBS)
+])
+
+# Do all the work for Automake.  This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "[$]*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   if test "[$]*" != "X $srcdir/configure conftestfile" \
+      && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "[$]2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+   $1=$2
+   AC_MSG_RESULT(found)
+else
+   $1="$3/missing $2"
+   AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated.  We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+  case " <<$>>CONFIG_HEADERS " in
+  *" <<$>>am_file "*<<)>>
+    echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+    ;;
+  esac
+  am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode is disabled by default
+  AC_ARG_ENABLE(maintainer-mode,
+[  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer],
+      USE_MAINTAINER_MODE=$enableval,
+      USE_MAINTAINER_MODE=no)
+  AC_MSG_RESULT($USE_MAINTAINER_MODE)
+  AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi])
+
diff --git a/rda/config.in b/rda/config.in
new file mode 100644 (file)
index 0000000..097afed
--- /dev/null
@@ -0,0 +1,39 @@
+/* config.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define if you can safely include both <sys/time.h> and <time.h>.  */
+#undef TIME_WITH_SYS_TIME
+
+/* Define if your processor stores words with the most significant
+   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
+#undef WORDS_BIGENDIAN
+
+/* Define if you have the <arpa/inet.h> header file.  */
+#undef HAVE_ARPA_INET_H
+
+/* Define if you have the <netinet/in.h> header file.  */
+#undef HAVE_NETINET_IN_H
+
+/* Define if you have the <netinet/tcp.h> header file.  */
+#undef HAVE_NETINET_TCP_H
+
+/* Define if you have the <sys/socket.h> header file.  */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define if you have the <sys/time.h> header file.  */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the nsl library (-lnsl).  */
+#undef HAVE_LIBNSL
+
+/* Define if you have the resolv library (-lresolv).  */
+#undef HAVE_LIBRESOLV
+
+/* Define if you have the socket library (-lsocket).  */
+#undef HAVE_LIBSOCKET
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
diff --git a/rda/configure b/rda/configure
new file mode 100755 (executable)
index 0000000..9fa74ed
--- /dev/null
@@ -0,0 +1,3707 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+  --enable-shared[=PKGS]  build shared libraries [default=yes]"
+ac_help="$ac_help
+  --enable-static[=PKGS]  build static libraries [default=yes]"
+ac_help="$ac_help
+  --enable-fast-install[=PKGS]  optimize for fast installation [default=yes]"
+ac_help="$ac_help
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+  --disable-libtool-lock  avoid locking (might break parallel builds)"
+ac_help="$ac_help
+  --with-pic              try to use only PIC/non-PIC objects [default=use both]"
+ac_help="$ac_help
+  --enable-build-warnings Enable build-time compiler warnings if gcc is used"
+ac_help="$ac_help
+  --enable-rda-build-warnings Enable RDA specific build-time compiler warnings if gcc is used"
+ac_help="$ac_help
+  --with-ilu=DIR          ilu is in DIR/include and DIR/lib"
+ac_help="$ac_help
+  --disable-nls           do not use Native Language Support"
+ac_help="$ac_help
+  --with-included-gettext use the GNU gettext library included here"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=README
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:550: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 555 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:566: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_cygwin=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:583: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 588 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:595: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_mingw32=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+#    configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+#    same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+#    as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:659: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:680: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+  case $nonopt in
+  NONE) target_alias=$host_alias ;;
+  *) target_alias=$nonopt ;;
+  esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:698: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+  case $nonopt in
+  NONE) build_alias=$host_alias ;;
+  *) build_alias=$nonopt ;;
+  esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:732: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:785: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   if test "$*" != "X $srcdir/configure conftestfile" \
+      && test "$*" != "X conftestfile $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { echo "configure: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+   fi
+
+   test "$2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+  program_transform_name=
+else
+  # Double any \ or $.  echo might interpret backslashes.
+  cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+  rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:842: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+       @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=rda
+
+VERSION=0.1
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:888: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+   ACLOCAL=aclocal
+   echo "$ac_t""found" 1>&6
+else
+   ACLOCAL="$missing_dir/missing aclocal"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:901: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+   AUTOCONF=autoconf
+   echo "$ac_t""found" 1>&6
+else
+   AUTOCONF="$missing_dir/missing autoconf"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:914: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+   AUTOMAKE=automake
+   echo "$ac_t""found" 1>&6
+else
+   AUTOMAKE="$missing_dir/missing automake"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:927: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+   AUTOHEADER=autoheader
+   echo "$ac_t""found" 1>&6
+else
+   AUTOHEADER="$missing_dir/missing autoheader"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:940: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+   MAKEINFO=makeinfo
+   echo "$ac_t""found" 1>&6
+else
+   MAKEINFO="$missing_dir/missing makeinfo"
+   echo "$ac_t""missing" 1>&6
+fi
+
+
+
+
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:958: checking whether to enable maintainer-specific portions of Makefiles" >&5
+    # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+  enableval="$enable_maintainer_mode"
+  USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+  
+
+if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+  MAINT=$MAINTAINER_MODE_TRUE
+  
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_fast_install=yes
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1052: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1082: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1133: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1165: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1176 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1181: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1207: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1212: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1221: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1240: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1283: checking for ld used by GCC" >&5
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1313: checking for GNU ld" >&5
+else
+  echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1316: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1351: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  lt_cv_prog_gnu_ld=yes
+else
+  lt_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6
+echo "configure:1368: checking for $LD option to reload object files" >&5
+if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+
+echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1380: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    tmp_nm=$ac_dir/${ac_tool_prefix}nm
+    if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      # Tru64's nm complains that /dev/null is an invalid object file
+      if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+       lt_cv_path_NM="$tmp_nm -B"
+       break
+      elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       lt_cv_path_NM="$tmp_nm -p"
+       break
+      else
+       lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+
+NM="$lt_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1418: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6
+echo "configure:1439: checking how to recognise dependant libraries" >&5
+if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [regex]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi4*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin* | mingw* |pw32*)
+  lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  case "$host_os" in
+  rhapsody* | darwin1.012)
+    lt_cv_file_magic_test_file='/System/Library/Frameworks/System.framework/System'
+    ;;
+  *) # Darwin 1.3 on
+    lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+    ;;
+  esac
+  ;;
+
+freebsd* )
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20*|hpux11*)
+  lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libc.sl
+  ;;
+
+irix5* | irix6*)
+  case $host_os in
+  irix5*)
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+    ;;
+  *)
+    case $LD in
+    *-32|*"-32 ") libmagic=32-bit;;
+    *-n32|*"-n32 ") libmagic=N32;;
+    *-64|*"-64 ") libmagic=64-bit;;
+    *) libmagic=never-match;;
+    esac
+    # this will be overridden with pass_all, but let us keep it just in case
+    lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+    ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+  case $host_cpu in
+  alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* )
+    lt_cv_deplibs_check_method=pass_all ;;
+  *)
+    # glibc up to 2.1.1 does not perform some relocations on ARM
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
+  esac
+  lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
+  fi
+  ;;
+
+newsos6)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+osf3* | osf4* | osf5*)
+  # this will be overridden with pass_all, but let us keep it just in case
+  lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sco3.2v5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  lt_cv_file_magic_test_file=/lib/libc.so
+  ;;
+
+sysv5uw[78]* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+  case $host_vendor in
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  esac
+  ;;
+esac
+
+fi
+
+echo "$ac_t""$lt_cv_deplibs_check_method" 1>&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+
+echo $ac_n "checking for object suffix""... $ac_c" 1>&6
+echo "configure:1603: checking for object suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftest*
+echo 'int i = 1;' > conftest.$ac_ext
+if { (eval echo configure:1609: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  for ac_file in conftest.*; do
+    case $ac_file in
+    *.c) ;;
+    *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
+    esac
+  done
+else
+  { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_objext" 1>&6
+OBJEXT=$ac_cv_objext
+ac_objext=$ac_cv_objext
+
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:1629: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+  ac_cv_exeext=.exe
+else
+  rm -f conftest*
+  echo 'int main () { return 0; }' > conftest.$ac_ext
+  ac_cv_exeext=
+  if { (eval echo configure:1639: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+    for file in conftest.*; do
+      case $file in
+      *.c | *.o | *.obj) ;;
+      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+      esac
+    done
+  else
+    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+  fi
+  rm -f conftest*
+  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+if test $host != $build; then
+  ac_tool_prefix=${host_alias}-
+else
+  ac_tool_prefix=
+fi
+
+# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers!
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6
+echo "configure:1672: checking for ${ac_tool_prefix}file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case $MAGIC_CMD in
+  /*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+  ?:/*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  ac_save_MAGIC_CMD="$MAGIC_CMD"
+  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="/usr/bin:$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           egrep "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  MAGIC_CMD="$ac_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    echo $ac_n "checking for file""... $ac_c" 1>&6
+echo "configure:1734: checking for file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case $MAGIC_CMD in
+  /*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+  ?:/*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  ac_save_MAGIC_CMD="$MAGIC_CMD"
+  IFS="${IFS=   }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="/usr/bin:$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+       case $deplibs_check_method in
+       "file_magic "*)
+         file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+         MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+         if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+           egrep "$file_magic_regex" > /dev/null; then
+           :
+         else
+           cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+         fi ;;
+       esac
+      fi
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  MAGIC_CMD="$ac_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1805: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1837: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  RANLIB=":"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1872: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+  echo "$ac_t""$STRIP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_STRIP"; then
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1904: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_STRIP="strip"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+  echo "$ac_t""$STRIP" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+else
+  STRIP=":"
+fi
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$GCC" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$lt_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+  :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+  withval="$with_pic"
+  pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+test x"$pic_mode" = xyes && libtool_flags="$libtool_flags --prefer-pic"
+test x"$pic_mode" = xno && libtool_flags="$libtool_flags --prefer-non-pic"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 1971 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:1972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1993: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+     ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+     cat > conftest.$ac_ext <<EOF
+#line 2006 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2013: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+     ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+AR="$AR" LTCC="$CC" CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+MAGIC_CMD="$MAGIC_CMD" LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" STRIP="$STRIP" \
+AS="$AS" DLLTOOL="$DLLTOOL" OBJDUMP="$OBJDUMP" \
+objext="$OBJEXT" exeext="$EXEEXT" reload_flag="$reload_flag" \
+deplibs_check_method="$deplibs_check_method" file_magic_cmd="$file_magic_cmd" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify --build="$build" $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh $ac_aux_dir/ltcf-c.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+  
+
+  
+        
+        
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:2131: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+  ac_cv_exeext=.exe
+else
+  rm -f conftest*
+  echo 'int main () { return 0; }' > conftest.$ac_ext
+  ac_cv_exeext=
+  if { (eval echo configure:2141: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+    for file in conftest.*; do
+      case $file in
+      *.c | *.o | *.obj) ;;
+      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+      esac
+    done
+  else
+    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+  fi
+  rm -f conftest*
+  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:2170: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 2185 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2191: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 2202 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2208: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 2219 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2225: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+for ac_hdr in sys/time.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2253: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2258 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2263: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:2290: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2295 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:2304: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_header_time=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+  cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:2326: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 2333 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:2344: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 2348 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:2359: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_bigendian=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2379 "configure"
+#include "confdefs.h"
+main () {
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:2392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_bigendian=no
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+  cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
+echo "configure:2417: checking for connect in -lsocket" >&5
+ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lsocket  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2425 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char connect();
+
+int main() {
+connect()
+; return 0; }
+EOF
+if { (eval echo configure:2436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo socket | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lsocket $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
+echo "configure:2464: checking for gethostbyname in -lnsl" >&5
+ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lnsl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2472 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:2483: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo nsl | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lnsl $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for gethostbyname in -lresolv""... $ac_c" 1>&6
+echo "configure:2511: checking for gethostbyname in -lresolv" >&5
+ac_lib_var=`echo resolv'_'gethostbyname | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lresolv  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2519 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gethostbyname();
+
+int main() {
+gethostbyname()
+; return 0; }
+EOF
+if { (eval echo configure:2530: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_lib=HAVE_LIB`echo resolv | sed -e 's/[^a-zA-Z0-9_]/_/g' \
+    -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+  LIBS="-lresolv $LIBS"
+
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+for ac_hdr in sys/socket.h netinet/in.h netinet/tcp.h arpa/inet.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2561: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2566 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2571: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# NOTE: Don't add -Wall or -Wunused, they both include
+# -Wunused-parameter which reports bogus warnings.
+build_warnings="-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs \
+-Wformat -Wparentheses -Wpointer-arith"
+# Up for debate: -Wswitch -Wcomment -trigraphs -Wtrigraphs
+# -Wunused-function -Wunused-label -Wunused-variable -Wunused-value
+# -Wchar-subscripts -Wuninitialized -Wtraditional -Wshadow -Wcast-qual
+# -Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes
+# -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls
+# -Woverloaded-virtual -Winline -Werror"
+# Check whether --enable-build-warnings or --disable-build-warnings was given.
+if test "${enable_build_warnings+set}" = set; then
+  enableval="$enable_build_warnings"
+  case "${enableval}" in
+  yes) ;;
+  no)  build_warnings="-w";;
+  ,*)   t=`echo "${enableval}" | sed -e "s/,/ /g"`
+        build_warnings="${build_warnings} ${t}";;
+  *,)   t=`echo "${enableval}" | sed -e "s/,/ /g"`
+        build_warnings="${t} ${build_warnings}";;
+  *)    build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+  echo "Setting compiler warning flags = $build_warnings" 6>&1
+fi
+fi
+# Check whether --enable-rda-build-warnings or --disable-rda-build-warnings was given.
+if test "${enable_rda_build_warnings+set}" = set; then
+  enableval="$enable_rda_build_warnings"
+  case "${enableval}" in
+  yes) ;;
+  no)  build_warnings="-w";;
+  ,*)   t=`echo "${enableval}" | sed -e "s/,/ /g"`
+        build_warnings="${build_warnings} ${t}";;
+  *,)   t=`echo "${enableval}" | sed -e "s/,/ /g"`
+        build_warnings="${t} ${build_warnings}";;
+  *)    build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+  echo "Setting LIBREMOTE specific compiler warning flags = $build_warnings" 6>&1
+fi
+fi
+WARN_CFLAGS=""
+WERROR_CFLAGS=""
+if test "x${build_warnings}" != x -a "x$GCC" = xyes
+then
+    echo $ac_n "checking compiler warning flags""... $ac_c" 1>&6
+echo "configure:2645: checking compiler warning flags" >&5
+    # Separate out the -Werror flag as some files just cannot be
+    # compiled with it enabled.
+    for w in ${build_warnings}; do
+       case $w in
+       -Werr*) WERROR_CFLAGS=-Werror ;;
+       *) # Check that GCC accepts it
+           if $CC $w 2>&1 | grep 'unrecognized option' > /dev/null; then
+               :
+           else
+               WARN_CFLAGS="${WARN_CFLAGS} $w"
+           fi
+       esac
+    done
+    echo "$ac_t""${WARN_CFLAGS}${WERROR_CFLAGS}" 1>&6
+fi
+
+
+
+# Add target dependent subdirectories here
+targ_subdirs=
+
+
+case "$target" in
+   *linux*) targ_subdirs="$targ_subdirs unix" ;;
+esac
+
+
+
+
+
+subdirs="$targ_subdirs"
+
+
+
+echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:2768: checking whether NLS is requested" >&5
+        # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+  enableval="$enable_nls"
+  USE_NLS=$enableval
+else
+  USE_NLS=yes
+fi
+
+    echo "$ac_t""$USE_NLS" 1>&6
+    
+
+    USE_INCLUDED_LIBINTL=no
+
+        if test "$USE_NLS" = "yes"; then
+      cat >> confdefs.h <<\EOF
+#define ENABLE_NLS 1
+EOF
+
+      echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
+echo "configure:2788: checking whether included gettext is requested" >&5
+      # Check whether --with-included-gettext or --without-included-gettext was given.
+if test "${with_included_gettext+set}" = set; then
+  withval="$with_included_gettext"
+  nls_cv_force_use_gnu_gettext=$withval
+else
+  nls_cv_force_use_gnu_gettext=no
+fi
+
+      echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6
+
+      nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+      if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+                                       nls_cv_header_intl=
+       nls_cv_header_libgt=
+       CATOBJEXT=NONE
+
+       ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
+echo "configure:2807: checking for libintl.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2812 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2817: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
+echo "configure:2834: checking for gettext in libc" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2839 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:2846: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  gt_cv_func_gettext_libc=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  gt_cv_func_gettext_libc=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
+
+          if test "$gt_cv_func_gettext_libc" != "yes"; then
+            echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
+echo "configure:2862: checking for bindtextdomain in -lintl" >&5
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lintl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2870 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char bindtextdomain();
+
+int main() {
+bindtextdomain()
+; return 0; }
+EOF
+if { (eval echo configure:2881: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
+echo "configure:2897: checking for gettext in libintl" >&5
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2902 "configure"
+#include "confdefs.h"
+
+int main() {
+return (int) gettext ("")
+; return 0; }
+EOF
+if { (eval echo configure:2909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  gt_cv_func_gettext_libintl=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  gt_cv_func_gettext_libintl=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+          fi
+
+          if test "$gt_cv_func_gettext_libc" = "yes" \
+             || test "$gt_cv_func_gettext_libintl" = "yes"; then
+             cat >> confdefs.h <<\EOF
+#define HAVE_GETTEXT 1
+EOF
+
+             # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2937: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$MSGFMT" in
+  /*)
+  ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+       ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+       break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+  ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+  echo "$ac_t""$MSGFMT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+             if test "$MSGFMT" != "no"; then
+               for ac_func in dcgettext
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2971: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2976 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+               # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3026: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$GMSGFMT" in
+  /*)
+  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+  ;;
+  ?:/*)                         
+  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+  ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+  echo "$ac_t""$GMSGFMT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+               # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3062: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$XGETTEXT" in
+  /*)
+  ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+       ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+       break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+  ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+  echo "$ac_t""$XGETTEXT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+               cat > conftest.$ac_ext <<EOF
+#line 3094 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr;
+                              return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:3102: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  CATOBJEXT=.gmo
+                  DATADIRNAME=share
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CATOBJEXT=.mo
+                  DATADIRNAME=lib
+fi
+rm -f conftest*
+               INSTOBJEXT=.mo
+             fi
+           fi
+       
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+               
+        if test "$CATOBJEXT" = "NONE"; then
+                         nls_cv_use_gnu_gettext=yes
+        fi
+      fi
+
+      if test "$nls_cv_use_gnu_gettext" = "yes"; then
+                INTLOBJS="\$(GETTOBJS)"
+        # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3134: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$MSGFMT" in
+  /*)
+  ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+       ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+       break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt"
+  ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+  echo "$ac_t""$MSGFMT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+        # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3168: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$GMSGFMT" in
+  /*)
+  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+  ;;
+  ?:/*)                         
+  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+  ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+  echo "$ac_t""$GMSGFMT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+        # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3204: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$XGETTEXT" in
+  /*)
+  ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+       ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+       break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+  ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+  echo "$ac_t""$XGETTEXT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+        
+       USE_INCLUDED_LIBINTL=yes
+        CATOBJEXT=.gmo
+        INSTOBJEXT=.mo
+        DATADIRNAME=share
+       INTLDEPS='$(top_builddir)/../intl/libintl.a'
+       INTLLIBS=$INTLDEPS
+       LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+        nls_cv_header_intl=libintl.h
+        nls_cv_header_libgt=libgettext.h
+      fi
+
+            if test "$XGETTEXT" != ":"; then
+                       if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+         : ;
+       else
+         echo "$ac_t""found xgettext programs is not GNU xgettext; ignore it" 1>&6
+         XGETTEXT=":"
+       fi
+      fi
+
+      # We need to process the po/ directory.
+      POSUB=po
+    else
+      DATADIRNAME=share
+      nls_cv_header_intl=libintl.h
+      nls_cv_header_libgt=libgettext.h
+    fi
+
+    # If this is used in GNU gettext we have to set USE_NLS to `yes'
+    # because some of the sources are only built for this goal.
+    if test "$PACKAGE" = gettext; then
+      USE_NLS=yes
+      USE_INCLUDED_LIBINTL=yes
+    fi
+
+                for lang in $ALL_LINGUAS; do
+      GMOFILES="$GMOFILES $lang.gmo"
+      POFILES="$POFILES $lang.po"
+    done
+
+        
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile lib/Makefile samples/Makefile qe/Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@CC@%$CC%g
+s%@LN_S@%$LN_S%g
+s%@OBJEXT@%$OBJEXT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@RANLIB@%$RANLIB%g
+s%@STRIP@%$STRIP%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@CPP@%$CPP%g
+s%@WARN_CFLAGS@%$WARN_CFLAGS%g
+s%@WERROR_CFLAGS@%$WERROR_CFLAGS%g
+s%@subdirs@%$subdirs%g
+s%@targ_subdirs@%$targ_subdirs%g
+s%@USE_NLS@%$USE_NLS%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g
+s%@CATALOGS@%$CATALOGS%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@DATADIRNAME@%$DATADIRNAME%g
+s%@GMOFILES@%$GMOFILES%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@INTLDEPS@%$INTLDEPS%g
+s%@INTLLIBS@%$INTLLIBS%g
+s%@INTLOBJS@%$INTLOBJS%g
+s%@POFILES@%$POFILES%g
+s%@POSUB@%$POSUB%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile samples/Makefile qe/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='\([     ][      ]*\)[^  ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='\([     ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file and --srcdir arguments so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  for ac_arg in $ac_configure_args; do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case "$ac_arg" in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    *) ac_sub_configure_args="$ac_sub_configure_args $ac_arg" ;;
+    esac
+  done
+
+  for ac_config_dir in $targ_subdirs; do
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    if test ! -d $srcdir/$ac_config_dir; then
+      continue
+    fi
+
+    echo configuring in $ac_config_dir
+
+    case "$srcdir" in
+    .) ;;
+    *)
+      if test -d ./$ac_config_dir || mkdir ./$ac_config_dir; then :;
+      else
+        { echo "configure: error: can not create `pwd`/$ac_config_dir" 1>&2; exit 1; }
+      fi
+      ;;
+    esac
+
+    ac_popdir=`pwd`
+    cd $ac_config_dir
+
+      # A "../" for each directory in /$ac_config_dir.
+      ac_dots=`echo $ac_config_dir|sed -e 's%^\./%%' -e 's%[^/]$%&/%' -e 's%[^/]*/%../%g'`
+
+    case "$srcdir" in
+    .) # No --srcdir option.  We are building in place.
+      ac_sub_srcdir=$srcdir ;;
+    /*) # Absolute path.
+      ac_sub_srcdir=$srcdir/$ac_config_dir ;;
+    *) # Relative path.
+      ac_sub_srcdir=$ac_dots$srcdir/$ac_config_dir ;;
+    esac
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_sub_srcdir/configure; then
+      ac_sub_configure=$ac_sub_srcdir/configure
+    elif test -f $ac_sub_srcdir/configure.in; then
+      ac_sub_configure=$ac_configure
+    else
+      echo "configure: warning: no configuration information is in $ac_config_dir" 1>&2
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+
+      # Make the cache file name correct relative to the subdirectory.
+      case "$cache_file" in
+      /*) ac_sub_cache_file=$cache_file ;;
+      *) # Relative path.
+        ac_sub_cache_file="$ac_dots$cache_file" ;;
+      esac
+  case "$ac_given_INSTALL" in
+        [/$]*) INSTALL="$ac_given_INSTALL" ;;
+        *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+        esac
+
+      echo "running ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir"
+      # The eval makes quoting arguments work.
+      if eval ${CONFIG_SHELL-/bin/sh} $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_sub_srcdir
+      then :
+      else
+        { echo "configure: error: $ac_sub_configure failed for $ac_config_dir" 1>&2; exit 1; }
+      fi
+    fi
+
+    cd $ac_popdir
+  done
+fi
+
diff --git a/rda/configure.in b/rda/configure.in
new file mode 100644 (file)
index 0000000..c0a4600
--- /dev/null
@@ -0,0 +1,107 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(README)
+AC_CANONICAL_SYSTEM
+AM_INIT_AUTOMAKE(rda, 0.1)
+AM_CONFIG_HEADER(config.h:config.in)
+
+dnl automake support
+AM_MAINTAINER_MODE
+dnl AC_LIBTOOL_WIN32_DLL
+AM_PROG_LIBTOOL
+AC_EXEEXT
+AC_LANG_C
+
+dnl Check for types
+AC_CHECK_HEADERS(sys/time.h)
+AC_HEADER_TIME
+
+dnl Check for host characteristics
+AC_C_BIGENDIAN
+
+dnl Check for socket libs
+AC_CHECK_LIB(socket, connect)
+AC_CHECK_LIB(nsl, gethostbyname)
+AC_CHECK_LIB(resolv, gethostbyname)
+AC_CHECK_HEADERS(sys/socket.h netinet/in.h netinet/tcp.h arpa/inet.h)
+
+# NOTE: Don't add -Wall or -Wunused, they both include
+# -Wunused-parameter which reports bogus warnings.
+build_warnings="-Wimplicit -Wreturn-type -Wcomment -Wtrigraphs \
+-Wformat -Wparentheses -Wpointer-arith"
+# Up for debate: -Wswitch -Wcomment -trigraphs -Wtrigraphs
+# -Wunused-function -Wunused-label -Wunused-variable -Wunused-value
+# -Wchar-subscripts -Wuninitialized -Wtraditional -Wshadow -Wcast-qual
+# -Wcast-align -Wwrite-strings -Wconversion -Wstrict-prototypes
+# -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls
+# -Woverloaded-virtual -Winline -Werror"
+AC_ARG_ENABLE(build-warnings,
+[  --enable-build-warnings Enable build-time compiler warnings if gcc is used],
+[case "${enableval}" in
+  yes) ;;
+  no)  build_warnings="-w";;
+  ,*)   t=`echo "${enableval}" | sed -e "s/,/ /g"`
+        build_warnings="${build_warnings} ${t}";;
+  *,)   t=`echo "${enableval}" | sed -e "s/,/ /g"`
+        build_warnings="${t} ${build_warnings}";;
+  *)    build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+  echo "Setting compiler warning flags = $build_warnings" 6>&1
+fi])dnl
+AC_ARG_ENABLE(rda-build-warnings,
+[  --enable-rda-build-warnings Enable RDA specific build-time compiler warnings if gcc is used],
+[case "${enableval}" in
+  yes) ;;
+  no)  build_warnings="-w";;
+  ,*)   t=`echo "${enableval}" | sed -e "s/,/ /g"`
+        build_warnings="${build_warnings} ${t}";;
+  *,)   t=`echo "${enableval}" | sed -e "s/,/ /g"`
+        build_warnings="${t} ${build_warnings}";;
+  *)    build_warnings=`echo "${enableval}" | sed -e "s/,/ /g"`;;
+esac
+if test x"$silent" != x"yes" && test x"$build_warnings" != x""; then
+  echo "Setting LIBREMOTE specific compiler warning flags = $build_warnings" 6>&1
+fi])dnl
+WARN_CFLAGS=""
+WERROR_CFLAGS=""
+if test "x${build_warnings}" != x -a "x$GCC" = xyes
+then
+    AC_MSG_CHECKING(compiler warning flags)
+    # Separate out the -Werror flag as some files just cannot be
+    # compiled with it enabled.
+    for w in ${build_warnings}; do
+       case $w in
+       -Werr*) WERROR_CFLAGS=-Werror ;;
+       *) # Check that GCC accepts it
+           if $CC $w 2>&1 | grep 'unrecognized option' > /dev/null; then
+               :
+           else
+               WARN_CFLAGS="${WARN_CFLAGS} $w"
+           fi
+       esac
+    done
+    AC_MSG_RESULT(${WARN_CFLAGS}${WERROR_CFLAGS})
+fi
+AC_SUBST(WARN_CFLAGS)
+AC_SUBST(WERROR_CFLAGS)
+
+# Add target dependent subdirectories here
+targ_subdirs=
+
+
+case "$target" in
+   *linux*) targ_subdirs="$targ_subdirs unix" ;;
+esac
+
+
+
+
+
+dnl $targ_subdirs is expanded at configure run time
+AC_CONFIG_SUBDIRS($targ_subdirs)
+AC_SUBST(targ_subdirs)
+
+CY_WITH_NLS
+
+dnl Outputs
+AC_OUTPUT(Makefile lib/Makefile samples/Makefile qe/Makefile)
diff --git a/rda/include/gdblog.h b/rda/include/gdblog.h
new file mode 100644 (file)
index 0000000..4477020
--- /dev/null
@@ -0,0 +1,54 @@
+/* gdblog.h -- declarations for logging facilities
+   Copyright 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.  */
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdblog;
+
+/* Write to the log device.  No new line is appended.  */
+
+extern void gdblog_string (struct gdblog *, const char *val);
+extern void gdblog_long (struct gdblog *, long val);
+extern void gdblog_xlong (struct gdblog *, long val);
+extern void gdblog_char (struct gdblog *, char val);
+
+
+typedef void gdblog_string_ftype (void *context, const char *val);
+typedef void gdblog_long_ftype (void *context, long val);
+typedef void gdblog_xlong_ftype (void *context, long val);
+typedef void gdblog_char_ftype (void *context, char val);
+
+extern struct gdblog *gdblog_new (void *context,
+                                 gdblog_string_ftype *log_string,
+                                 gdblog_long_ftype *log_long,
+                                 gdblog_xlong_ftype *log_xlong,
+                                 gdblog_char_ftype *log_char);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbloop.h b/rda/include/gdbloop.h
new file mode 100644 (file)
index 0000000..70a5559
--- /dev/null
@@ -0,0 +1,49 @@
+/* gdbloop.h -- event loop facilities
+   Copyright 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.  */
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+/* Something goes here to register additional FDs. */
+
+/* Something goes here to register additional signals. */
+
+/* Really simple minded event-loop.  Assumes that the target is using
+   both gdbsocket* and gdbsched* to implement things. If TIMEOUT is
+   negative, block infinitely.  If TIMEOUT is zero, don't block.  */
+
+void gdbloop (long current_time, int timeout);
+
+/* Even more simple minded event-loop.  Assumes that everything is in
+   units of one second.  Calls gdbloop() above, using time() for
+   CURRENT_TIME.  */
+
+void gdbloop_poll (int timeout);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbsched.h b/rda/include/gdbsched.h
new file mode 100644 (file)
index 0000000..a0bdfa7
--- /dev/null
@@ -0,0 +1,84 @@
+/* gdbsched.h -- event scheduling facitilies
+   Copyright 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.  */
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdbserv;
+struct gdbserv_target;
+struct gdblog;
+struct gdbserv_thread;
+
+/* Simple minded event scheduler. */
+
+/* Handle for a scheduled event.  Use this when removing scheduled
+   events. */
+
+struct gdbsched;
+
+/* Ftype for handling events.  To make life easier (?) the handler
+   takes a GDBSERV and a THREAD as well as a context. */
+
+typedef void gdbsched_handler_ftype (struct gdbserv *gdbserv,
+                                    struct gdbserv_thread *thread,
+                                    void *context);
+
+/* Schedule an event at absolute TIME.  The TIME ``0'' is special and
+   implies that the event should be scheduled immediatly.  The unit of
+   TIME is target implementation dependant.  Typically it will be
+   seconds. */
+
+struct gdbsched *gdbsched_schedule (long time,
+                                   gdbsched_handler_ftype *sched,
+                                   struct gdbserv *gdbserv,
+                                   struct gdbserv_thread *thread,
+                                   void *context);
+
+/* Unschedule an event.  Pass in NULL to just unschedule the first
+   event on the queue.  Any of TIME, HANDLER, GDBSERV, THREAD and
+   CONTEXT will be assigned if non-NULL.  If there is no event, *TIME
+   is set to ``-1'' and everything else is set to NULL. */
+
+void gdbsched_deschedule (struct gdbsched *sched,
+                         long *time,
+                         gdbsched_handler_ftype **handler,
+                         struct gdbserv **gdbserv,
+                         struct gdbserv_thread **thread,
+                         void **context);
+
+/* Process any events scheduled on or before TIME.  Call with ``0'' to
+   process any events scheduled for immediate delivery.  Call with
+   ``-1'' to determine the time of the next event. Return the absolute
+   time of the next unprocessed event or ``-1'' if no events are
+   outstanding. */
+
+long gdbsched_dispatch (long time);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbserv-client.h b/rda/include/gdbserv-client.h
new file mode 100644 (file)
index 0000000..ba39899
--- /dev/null
@@ -0,0 +1,85 @@
+/* gdbserv-client.h -- Facilities for communicating with remote client
+   using GDB remote protocol.
+
+   Copyright 1998, 2000, 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.  */
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdbserv;
+
+struct gdbserv_client {
+  void *data;
+  /* Write LEN characters to the remote client. */
+  void (*write) (struct gdbserv *gdbserv, const unsigned char *ch,
+                unsigned len);
+};
+
+void *gdbserv_client_data (struct gdbserv *gdbserv);
+
+
+/* This is a call into the target so that it to is notified of the
+   connecting client.  The target can reject the connection by
+   returning NULL */
+
+/* Notify the server that the client has initiated a connection.
+   Returns a GDBSERV struct for the session (or null if the target
+   rejected the connect).  The server will, in turn, pass the request
+   onto the target.  The target can either reject the connection
+   (returning NULL) or accept the connection (returning a target
+   object). */
+
+typedef struct gdbserv_target *(gdbserv_target_attach) (struct gdbserv *gdbserv,
+                                                       void *attatch_data);
+
+struct gdbserv *gdbserv_fromclient_attach (struct gdbserv_client *gdbclient,
+                                          gdbserv_target_attach *to_target_attach,
+                                          void *target_attach_data);
+
+
+/* Notify the server that the client has disconnected. */
+
+void gdbserv_fromclient_detach (struct gdbserv *gdbserv);
+
+
+
+/* The low level client code pumps packets/data into GDBSERV using the
+   following. */
+
+/* Raw characters from the client<->server. */
+
+void gdbserv_fromclient_data (struct gdbserv *gdbserv, const char *data,
+                             int sizeof_data);
+
+/* The remote client has requested that the target ``break'' (halt).
+   Notify gdbserv of the request so that it can pass it through to the
+   target (using gdbserv_target->break_program()). */
+
+void gdbserv_fromclient_break (struct gdbserv *gdbserv);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbserv-input.h b/rda/include/gdbserv-input.h
new file mode 100644 (file)
index 0000000..b4836f2
--- /dev/null
@@ -0,0 +1,73 @@
+/* gdbserv-input.h
+
+   Copyright 1998, 2000, 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.  */
+
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdbserv;
+
+enum gdbinput_state {
+  /*  0 = looking for start of packet */
+  GDBINPUT_STATE_IDLE,
+  /*  1 = got start of packet, looking for # terminator */
+  GDBINPUT_STATE_TERM,
+  /*  2 = looking for first byte of checksum */
+  GDBINPUT_STATE_CRC1,
+  /*  3 = looking for second byte of checksum (indicating end of packet) */
+  GDBINPUT_STATE_CRC2,
+  /*  4 = ignoring everything while looking for an ack packet */
+  GDBINPUT_STATE_ACK,
+};
+
+
+struct gdbserv_input {
+  
+  /* The checksum calculated so far (sizeof >= 32 bits). */
+  unsigned long checksum;
+  /* The checksum we've received from the remote side (sizeof >= 32 bits). */
+  unsigned long xmitcsum;
+  /* Contents of the accumulated packet. */
+  unsigned char *buf;
+  unsigned long sizeof_buf;
+  /* Number of characters received. */
+  unsigned len;
+  /* Number of characters retrieved */
+  unsigned out;
+  /* what we are doing */
+  enum gdbinput_state state;
+
+};
+
+void gdbserv_input_attach (struct gdbserv *gdbserv);
+void gdbserv_input_detach (struct gdbserv *gdbserv);
+void gdbserv_input_data_packet (struct gdbserv *gdbserv, const char *buf, int len);
+void gdbserv_input_wait_for_ack (struct gdbserv *gdbserv);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbserv-log.h b/rda/include/gdbserv-log.h
new file mode 100644 (file)
index 0000000..ad3de97
--- /dev/null
@@ -0,0 +1,47 @@
+/* gdbserv-log.h
+
+   Copyright 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.  */
+
+#if defined __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdbserv;
+struct gdblog;
+
+/* If non-NULL, used to write tracing from the corresponding
+   comonent. */
+
+extern struct gdblog *gdbserv_state_log;
+extern struct gdblog *gdbserv_input_log;
+extern struct gdblog *gdbserv_output_log;
+
+/* Stream for the output of warnings. */
+
+extern struct gdblog *gdbserv_warning_log;
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbserv-output.h b/rda/include/gdbserv-output.h
new file mode 100644 (file)
index 0000000..df3cf9f
--- /dev/null
@@ -0,0 +1,50 @@
+/* gdbserv-output.h
+
+   Copyright 1998, 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.  */
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdbserv;
+
+struct gdbserv_output {
+  
+  /* serial data */
+  int len;
+  char buf[2048];
+  /* additional space incase the checksum overflows the buf */
+  char padding_for_checksum[3];
+};
+
+void gdbserv_output_attach (struct gdbserv *gdbserv);
+void gdbserv_output_detach (struct gdbserv *gdbserv);
+
+void gdbserv_output_packet (struct gdbserv *gdbserv);
+void gdbserv_output_discard (struct gdbserv *gdbserv);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbserv-target.h b/rda/include/gdbserv-target.h
new file mode 100644 (file)
index 0000000..faa4cb1
--- /dev/null
@@ -0,0 +1,539 @@
+/* gdbserv-target.h
+
+   Copyright 1998, 2000, 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.  */
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdbserv;
+struct gdbserv_reg;
+
+/* The target manages threads using a 100% private target thread
+   object.  A trivial thread implementation could simply map the
+   thread object onto an internal thread ID using the hack: ``int
+   thread_id = thread - (struct gdbserv_thread *) NULL''. */
+struct gdbserv_thread;
+
+enum gdbserv_target_rc {
+  GDBSERV_TARGET_RC_ERROR = -1, /* Failed, ack with ``Enn''. */
+  GDBSERV_TARGET_RC_OK = 0, /* Ok, ack with ``OK'' where applicable. */
+  GDBSERV_TARGET_RC_UNKNOWN = 1 /* Not supported, or silent. */
+};
+
+enum gdbserv_target_bp {
+  GDBSERV_TARGET_BP_UNKNOWN = -1,
+  GDBSERV_TARGET_BP_SOFTWARE,
+  GDBSERV_TARGET_BP_HARDWARE,
+  GDBSERV_TARGET_BP_WRITE,
+  GDBSERV_TARGET_BP_READ,
+  GDBSERV_TARGET_BP_ACCESS
+};
+
+
+/* GDBSERV's signal encoding.  This is lifted direct from
+   gdb/defs.h.  The remote protocol passes back and forth ``gdb''
+   signal numbers.  It is up to the target to convert to/from a target
+   signal number. */
+
+enum {
+  GDBSERV_SIGNONE = 0,
+  GDBSERV_SIGHUP = 1,
+  GDBSERV_SIGINT = 2, /* program execution interrupted */
+  GDBSERV_SIGQUIT = 3,
+  GDBSERV_SIGILL  = 4,
+  GDBSERV_SIGTRAP = 5, /* program hit breakpoint */
+  GDBSERV_SIGABRT = 6,
+  GDBSERV_SIGEMT = 7,
+  GDBSERV_SIGFPE = 8,
+  GDBSERV_SIGKILL = 9,
+  GDBSERV_SIGBUS = 10,
+  GDBSERV_SIGSEGV = 11,
+  GDBSERV_SIGSYS = 12,
+  GDBSERV_SIGPIPE = 13,
+  GDBSERV_SIGALRM = 14,
+  GDBSERV_SIGTERM = 15,
+  GDBSERV_SIGURG = 16,
+  GDBSERV_SIGSTOP = 17,
+  GDBSERV_SIGTSTP = 18,
+  GDBSERV_SIGCONT = 19,
+  GDBSERV_SIGCHLD = 20,
+  GDBSERV_SIGTTIN = 21,
+  GDBSERV_SIGTTOU = 22,
+  GDBSERV_SIGIO = 23,
+  GDBSERV_SIGXCPU = 24,
+  GDBSERV_SIGXFSZ = 25,
+  GDBSERV_SIGVTALRM = 26,
+  GDBSERV_SIGPROF = 27,
+  GDBSERV_SIGWINCH = 28,
+  GDBSERV_SIGLOST = 29,
+  GDBSERV_SIGUSR1 = 30,
+  GDBSERV_SIGUSR2 = 31,
+  GDBSERV_SIGPWR = 32,
+  GDBSERV_SIGPOLL = 33,
+  GDBSERV_SIGWIND = 34,
+  GDBSERV_SIGPHONE = 35,
+  GDBSERV_SIGWAITING = 36,
+  GDBSERV_SIGLWP = 37,
+  GDBSERV_SIGDANGER = 38,
+  GDBSERV_SIGGRANT = 39,
+  GDBSERV_SIGRETRACT = 40,
+  GDBSERV_SIGMSG = 41,
+  GDBSERV_SIGSOUND = 42,
+  GDBSERV_SIGSAK = 43,
+  GDBSERV_SIGPRIO = 44,
+  GDBSERV_SIGRT33 = 45,
+  GDBSERV_SIGRT34 = 46,
+  GDBSERV_SIGRT35 = 47,
+  GDBSERV_SIGRT36 = 48,
+  GDBSERV_SIGRT37 = 49,
+  GDBSERV_SIGRT38 = 50,
+  GDBSERV_SIGRT39 = 51,
+  GDBSERV_SIGRT40 = 52,
+  GDBSERV_SIGRT41 = 53,
+  GDBSERV_SIGRT42 = 54,
+  GDBSERV_SIGRT43 = 55,
+  GDBSERV_SIGRT44 = 56,
+  GDBSERV_SIGRT45 = 57,
+  GDBSERV_SIGRT46 = 58,
+  GDBSERV_SIGRT47 = 59,
+  GDBSERV_SIGRT48 = 60,
+  GDBSERV_SIGRT49 = 61,
+  GDBSERV_SIGRT50 = 62,
+  GDBSERV_SIGRT51 = 63,
+  GDBSERV_SIGRT52 = 64,
+  GDBSERV_SIGRT53 = 65,
+  GDBSERV_SIGRT54 = 66,
+  GDBSERV_SIGRT55 = 67,
+  GDBSERV_SIGRT56 = 68,
+  GDBSERV_SIGRT57 = 69,
+  GDBSERV_SIGRT58 = 70,
+  GDBSERV_SIGRT59 = 71,
+  GDBSERV_SIGRT60 = 72,
+  GDBSERV_SIGRT61 = 73,
+  GDBSERV_SIGRT62 = 74,
+  GDBSERV_SIGRT63 = 75,
+  GDBSERV_SIGCANCEL = 76,
+  GDBSERV_SIGRT32 = 77,
+  GDBSERV_SIGRT64 = 78
+};
+
+
+\f
+/* A target event occured.  Report back the details.
+
+   THREAD: On multi-threaded targets, this indicates the thread that
+   the event applies to. On true multi-processor systems, some events
+   are system wide (eg: halting the system by stopping the clock) a
+   NULL thread can be reported.  Libremote will apply a heuristic and
+   select a thread that GDB is most likely to expect.  However, when
+   taking the system out of reset (or reporting the startup halt
+   state) a thread _must_ be supplied.
+
+   EVENT: As defined below, indicates the exact stop reason.
+
+   STOP_ADDR: When non-NULL indicates the address at which the THREAD
+   stopped.  Intermediate layers use this value when determining if a
+   target has stopped at a previously created breakpoint.  It should
+   not be confused with a target architecture program counter (PC,
+   NPC, NNNNNMPC).  Most targets pass NULL.
+
+   SIGVAL: As defined below.  The exact encoding is defined by GDB.
+   See gdb/defs.h ?include/gdb-signal.h?.  */
+
+enum gdbserv_fromtarget_event {
+  /* The target has stopped.  The reason, indicated by SIGVAL could be
+     due to: a THREAD reaching a breakpoint (SIGTRAP); a THREAD
+     encountering a breakpoint instruction (also SIGTRAP); a stop
+     request to stop from the client (SIGINT); or any of a number of
+     other events.  For real hardware targets, it is not always
+     possible to 1:1 map between a SIGVAL and a hardware interrupt
+     event.  If a target chooses to report back such events they
+     should: save all the relevant interrupt information in a local
+     cache; and identify the interrupt event using an approximatly
+     equivalent SIGVAL.  When the target is resumed, the resume SIGVAL
+     can be checked against that saved interrupt event: if SIGVAL is
+     zero, that interrupt event should be discarded; if they match,
+     the interrupt is delivered; and if SIGVAL is some other non-zero
+     value then things are target dependant. */
+  GDBSERV_FROMTARGET_STOPPED,
+  /* The target has exited gracefully. SIGVAL is the exit status as
+     passed to exit(3). */
+  GDBSERV_FROMTARGET_EXITED,
+  /* The target has died from a fatal wound.  SIGVAL is the smoking
+     gun. */
+  GDBSERV_FROMTARGET_TERMINATED
+};
+
+void gdbserv_fromtarget (struct gdbserv *gdbserv,
+                        struct gdbserv_thread *thread,
+                        enum gdbserv_fromtarget_event event,
+                        const struct gdbserv_reg *stop_addr,
+                        int sigval);
+
+/* Wrapper / compatibility functions for gdbserv_fromtarget() */
+void gdbserv_fromtarget_break (struct gdbserv *client, int sigval);
+void gdbserv_fromtarget_thread_break (struct gdbserv *,
+                                     struct gdbserv_thread *thread,
+                                     int sigval);
+void gdbserv_fromtarget_reset (struct gdbserv *client);
+void gdbserv_fromtarget_exit (struct gdbserv *client, int exitval);
+void gdbserv_fromtarget_terminate (struct gdbserv *client, int sigval);
+
+\f
+/* The following send events from the client TO the TARGET. */
+
+/* Start/resume the target.
+
+   Return GDBSERV_TARGET_RC_OK to indicate that the program was
+   successfully resumed.  Return anything else to indicate a problem.
+
+   THREAD: If non-NULL indicates the only thread that should resume
+   execution.  This provides a primative form of thread locking.
+   Typically it is used to step over memory breakpoints in a
+   multi-threaded environment.  Without this, there would be a window
+   of oportunity that would allow other threads to sneek past the
+   breakpoint.
+
+   EVENT: The exact way that the target is to be resumed.
+
+   START_ADDR: If non-NULL, the address at which the target should be
+   resumed.  For targets with multiple PCs (PC, NPC, ...) the target
+   should be set up to continue sequential execution at that address.
+
+   SIGVAL: If non-zero, the GDB signal that should be delivered to the
+   target.  Hardware targets may need to be liberal in their
+   interpretation of SIGVAL.  If START_ADDR is also non-NULL then both
+   operations apply - the START_ADDR is set and then SIGVAL is
+   delivered. */
+
+enum gdbserv_totarget_event {
+  GDBSERV_TOTARGET_SINGLESTEP,
+  GDBSERV_TOTARGET_CYCLESTEP,
+  GDBSERV_TOTARGET_CONTINUE
+};
+
+enum gdbserv_target_rc gdbserv_totarget (struct gdbserv *gdbserv,
+                                        struct gdbserv_thread *thread,
+                                        enum gdbserv_totarget_event event,
+                                        const struct gdbserv_reg *start_addr,
+                                        int sigval);
+
+
+\f
+struct gdbserv_target {
+  /* GDB Client */
+
+  /* Remote Qq packet methods */
+
+  /* This is called when a "q" packet is received from the client. */
+  void (*process_get_gen) (struct gdbserv *);
+  
+  /* This is called when a "Q" packet is received from the client. */
+  void (*process_set_gen) (struct gdbserv *);
+
+  /* This is called when a "qRcmd" packet is received from the client. */
+  void (*process_rcmd) (struct gdbserv *, const char *cmd, int sizeof_cmd);
+
+  /* This is called when an "A" packet is received from the client. */
+  void (*process_set_args) (struct gdbserv *);
+
+  /* Register Processing: old/tested */
+  /* Either implement process_set_reg, process_get_regs,
+     process_set_regs OR get_sizeof_reg, get_reg, set_reg. */
+
+  /* This is called when a "P" packet is received from the client. */
+  int (*process_set_reg) (struct gdbserv *, int reg);
+
+  /* This is called when a "p" packet is received from the client. */
+  int (*process_get_reg) (struct gdbserv *, int reg);
+
+  /* This is called when a "G" packet is received from the client. */
+  int (*process_set_regs) (struct gdbserv *);
+
+  /* This is called when a "g" packet is received from the client. */
+  void (*process_get_regs) (struct gdbserv *);
+
+
+  /* Register Processing: new/untested/WIP */
+
+  /* Input/Output a ``struct gdbserv_reg'' according to the target
+     dependant byte ordering.  See gdbserv_input_reg_{beb,leb} and
+     gdbserv_output_reg_{beb,leb}. Return a negative value to indicate
+     a parse error. */
+  /* Note: These methods are not per-thread - it is assumed that all
+     threads have the same byte order.  Before adding support for
+     per-thread byte ordering, the remote protocol should be changed
+     so that registers can be transfered using network (beb) byte
+     ordering - ``REGNR!VAL'' is a possible packet format. */
+  int (*input_reg) (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int len);
+  void (*output_reg) (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int len);
+
+  /* Return the REG-NR for the ``I''th register in the ``Gg'' packets.
+     Return a negative value when there are no more registers. Called
+     iteratively starting with 0. */
+  int (*gg_reg_nr) (struct gdbserv *, int index);
+
+  /* (optional) Return the REG-NR for ``expedited'' register ``I'' in
+     the ``T'' packet.  Return a negative value when there are no more
+     registers.  Expedited registers help improve the remote protocol
+     performance.  Called iteratively starting with 0. */
+  int (*expedited_reg_nr) (struct gdbserv *, int index);
+
+  /* Return the SIZE of a REG-NR register (as returned by REG_NR() or
+     EXPEDITED_REG_NR()).  2*SIZE characters are assumed to represent
+     that register in the ``Gg'' packets.  Return a negated SIZE if
+     there is a ``hole'' in the G packet - data but no corresponding
+     register. */
+  long (*sizeof_reg) (struct gdbserv *, int regnr);
+
+  /* Update REGNR with the value in REG. Return a negative value if
+     the write breaks. */
+  int (*set_reg) (struct gdbserv *, int regnr, struct gdbserv_reg *reg);
+
+  /* Return REGNR in ``struct gdbserv_reg''. Return a negative value
+     if the write breaks. */
+  int (*get_reg) (struct gdbserv *, int regnr, struct gdbserv_reg *reg);
+
+
+  /* Register Processing: Threaded */
+
+  /* Return the REG-NR for the next register in the ``Gg'' packet.
+     Return a negative value when there are no more registers. Called
+     iteratively starting with -1. */
+  int (*next_gg_reg) (struct gdbserv *, struct gdbserv_thread *,
+                     int reg_nr);
+
+  /* (optional but strongly recommended) Return the next register in
+     list of ``expedited'' registers included in a ``T'' packet.
+     Expedited registers help improve the remote protocol performance.
+     Return a negative value when there are no more registers.  Called
+     iteratively starting with -1. */
+  int (*next_expedited_reg) (struct gdbserv *, struct gdbserv_thread *,
+                            int reg_nr);
+
+  /* Return the total SIZE and PADDING of a REG-NR register.  2*SIZE
+     characters are assumed to represent that register in the ``Gg''
+     packets.  2*PADDING characters are appended (positive) or
+     prepended (negative).  */
+  int (*reg_format) (struct gdbserv *, struct gdbserv_thread *,
+                    int reg_nr, int *size, int *padding);
+
+  /* Update REGNR with the value in REG. Return a negative value if
+     the write breaks. */
+  int (*set_thread_reg) (struct gdbserv *, struct gdbserv_thread *,
+                        int regnr, const struct gdbserv_reg *reg);
+
+  /* Return REGNR in ``struct gdbserv_reg''. Return a negative value
+     if the read breaks. (eg when the register isn't available). */
+  int (*get_thread_reg) (struct gdbserv *, struct gdbserv_thread *,
+                        int regnr, struct gdbserv_reg *reg);
+
+
+  /* Memory Processing: Transfer LEN bytes of raw memory to/from
+     target. Return number of actual bytes transfered or -1 on error. */
+
+  /* This is called when an "m" packet is received from the
+     client. Return the number of bytes successfully read (could be
+     less than LEN) or -1 if the read completly failed. */
+  long (*get_mem) (struct gdbserv *, struct gdbserv_reg *addr, void *data,
+                  long len);
+  long (*get_thread_mem) (struct gdbserv *, struct gdbserv_thread *,
+                         struct gdbserv_reg *addr, void *data, long len);
+
+  /* This is called when an "M" or a "X" packet is received from the client. */
+  long (*set_mem) (struct gdbserv *, struct gdbserv_reg *addr, void *data,
+                  long len);
+  long (*set_thread_mem) (struct gdbserv *, struct gdbserv_thread *,
+                         struct gdbserv_reg *addr, void *data, long len);
+
+
+  /* Other operations. */
+
+  /* This is called when a "c" or "s" packet is received from the client
+     with a address to continue/step from.
+     It is called before the appropriate continue/step callback is invoked. */
+  void (*process_set_pc) (struct gdbserv *, const struct gdbserv_reg *val);
+
+  /* This is called when a "C", "c", "s" or "S" packet is received
+     from the client.  It should invalidate all instruction caches.
+     It is called before the appropriate continue/step callback is invoked. */
+  void (*flush_i_cache) (struct gdbserv *);
+
+  /* For non-threaded targets, this is called when a "C" or "S" packet
+     is received from the client specifying a signal to be delivered
+     to the application.  Threaded targets have the signal passed
+     directly to the resume method.
+     It is called before the appropriate continue/step callback is invoked. */
+  int (*process_signal) (struct gdbserv *, int sigval);
+
+  /* This is called when an "?" packet is received from the client.
+     It is called after the get_trap_number() callback to convert target traps
+     into an equivalent (or approx. equivalent) UNIX signal. */
+  unsigned long (*compute_signal) (struct gdbserv *, unsigned long);
+
+  /* This is called when an "?" packet is received from the client.
+     It returns the target trap number which will be converted to UNIX
+     signals by the compute_signal() callback before being sent to gdb.  */
+  unsigned long (*get_trap_number) (struct gdbserv *);
+
+
+  /* Program state methods */
+
+  /* This is called when a "k" packet is received from the client. */
+  void (*exit_program) (struct gdbserv *);
+
+  /* This is called when a request to halt / suspend / break the
+     target is received from the client.  When/if the target does
+     halt, gdbserv is notified via a call to
+     gdbserv_fromtarget_break().  The break_program() method must not
+     make a direct call to gdbserv_fromtarget_break().  */
+  void (*break_program) (struct gdbserv *);
+
+  /* This is called when a "r" packet is received from the client. */
+  int (*reset_program) (struct gdbserv *);
+
+  /* This is called when a "R" packet is received from the client. */
+  void (*restart_program) (struct gdbserv *);
+
+  /* This is called when a "s" or a "S" packet is received from the
+     client.  For thread variant, a NULL thread indicates that the
+     system should be single stepped. */
+  void (*singlestep_program) (struct gdbserv *);
+  void (*singlestep_thread) (struct gdbserv *, struct gdbserv_thread *,
+                            const struct gdbserv_reg *signnal);
+
+  /* This is called when an "i" packet is received from the client.
+     For thread variant, a NULL thread indicates that the system
+     should be cycle stepped and a non-null SIGGNAL should be
+     delivered. */
+  void (*cyclestep_program) (struct gdbserv *);
+  void (*cyclestep_thread) (struct gdbserv *, struct gdbserv_thread *,
+                           const struct gdbserv_reg *signnal);
+
+  /* This is called when a "c" or a "s" packet is received from the
+     client.  For thread variant, a NULL thread indicates that the
+     system should be continued and a non-null SIGGNAL should be
+     delivered. */
+  void (*continue_program) (struct gdbserv *);
+  void (*continue_thread) (struct gdbserv *, struct gdbserv_thread *,
+                          const struct gdbserv_reg *signnal);
+
+  /* This is called when a "C" or "S" packet is received from the
+     client specifying a signal to be delivered to the application and
+     we don't have a process_signal() callback to handle this
+     situation or it exists but could not/wanted not handle the
+     specific signal.  The step/continue is not performed in this case
+     and the application is terminated. */
+  void (*sigkill_program) (struct gdbserv *);
+
+
+  /* Breakpoint methods */
+
+  /* This is called when a "Z" packet is received from the client. */
+  enum gdbserv_target_rc (*remove_breakpoint) (struct gdbserv *,
+                                              enum gdbserv_target_bp type,
+                                              struct gdbserv_reg *addr,
+                                              struct gdbserv_reg *len);
+
+  /* This is called when a "z" packet is received from the client. */
+  enum gdbserv_target_rc (*set_breakpoint) (struct gdbserv *,
+                                           enum gdbserv_target_bp type,
+                                           struct gdbserv_reg *addr,
+                                           struct gdbserv_reg *len);
+
+
+  /* Thread info methods */
+
+  /* Create a freshly allocated string containing extr thread info. */
+  char *(*thread_info) (struct gdbserv *, struct gdbserv_thread *thread);
+
+  /* A unique ID for the thread. */
+  void (*thread_id) (struct gdbserv *, struct gdbserv_thread *thread,
+                    struct gdbserv_reg *id);
+
+  /* Map a thread ID onto a thread.  Return a positive value if the ID
+     uniquely identifies a thread.  Return ``0'' and select an
+     arbitrary thread if the thread ID is zero.  Return ``-1'' and set
+     the thread to a an arbitrary value if the ID does not uniquely
+     identify a thread or if the thread ID is invalid. */
+  int (*thread_lookup_by_id) (struct gdbserv *,
+                             const struct gdbserv_reg *id,
+                             struct gdbserv_thread **);
+
+  /* Iterate over known threads.  Use NULL to obtain the first
+     thread. */
+  struct gdbserv_thread *(*thread_next) (struct gdbserv *, struct gdbserv_thread *thread_last);
+
+
+  /* misc methods */
+
+  /* This is called when an unidentified/unrecognized packet (i.e., one that
+   does not start with one of the letters used by the remote protocol) is
+   received from the client. */
+  void (*process_target_packet) (struct gdbserv *);
+
+  /* shutdown */
+
+  /* This is called when an EOF is sensed on the socket.
+     This is *not* called when a "D" packet is received from the client.
+     The SERVER code reacts to the "D" packet as a nop (i.e., accepts it but
+     does not do anything) because the client will eventually close the
+     socket and we will sense the EOF. 
+     The second parameter is necessary so that the target can free the
+     memory allocated for the target vector in the attach method, if
+     needed.*/
+  void (*detach) (struct gdbserv *, struct gdbserv_target *);
+
+  /* Instance specific data.  GDBSERV can manage multiple clients each
+     accessing a separate target.  The per-target DATA pointer can
+     hold target instance specific data.  Use gdbserv_target_data() to
+     access this field. */
+  void *data;
+
+  /* Pass event FROM TARGET to server. */
+  void (*from) (struct gdbserv *gdbserv,
+               struct gdbserv_thread *thread,
+               enum gdbserv_fromtarget_event event,
+               const struct gdbserv_reg *stop_addr,
+               int sigval);
+
+  /* Pass event TO TARGET from SERVER. */
+  enum gdbserv_target_rc (*to) (struct gdbserv *gdbserv,
+                               struct gdbserv_thread *thread,
+                               enum gdbserv_totarget_event event,
+                               const struct gdbserv_reg *start_addr,
+                               int sigval);
+};
+
+
+/* Return the target instance specific data from the GDBSERV. */
+
+void *gdbserv_target_data (struct gdbserv *gdbserv);
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbserv-utils.h b/rda/include/gdbserv-utils.h
new file mode 100644 (file)
index 0000000..adcea6c
--- /dev/null
@@ -0,0 +1,103 @@
+/* gdbserv-utils.h
+
+   Copyright 1998, 2000, 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.  */
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdbserv;
+struct gdbserv_reg;
+
+/* Return the ASCII equivalent of C (C>=0 && C<=15). The result will be 
+   lower-case. */
+
+extern unsigned char gdbserv_to_hex (int c);
+extern int gdbserv_hex_to (unsigned char c);
+
+extern unsigned int gdbserv_ulong_to_hex (char *ptr, unsigned long val, int num_bits);
+
+
+extern unsigned int gdbserv_raw_to_hex (char **ptr, char *mem, int nr_bytes);
+
+/* Convert between a REG and the native unsigned long/long-long. */
+
+extern void gdbserv_reg_to_ulong (struct gdbserv *gdbserv,
+                                 const struct gdbserv_reg *reg,
+                                 unsigned long *val);
+
+extern void gdbserv_reg_to_ulonglong (struct gdbserv *gdbserv,
+                                     const struct gdbserv_reg *reg,
+                                     unsigned long long *val);
+
+extern void gdbserv_ulong_to_reg (struct gdbserv *gdbserv,
+                                 unsigned long val,
+                                 struct gdbserv_reg *reg);
+
+extern void gdbserv_ulonglong_to_reg (struct gdbserv *gdbserv,
+                                     unsigned long long val,
+                                     struct gdbserv_reg *reg);
+
+/* Convert between a REG and a buffer representing a numeric type.
+   Handle big endian and little endian cases explicitly.  */
+
+extern void gdbserv_be_bytes_to_reg (struct gdbserv *gdbserv,
+                                    const void *buf,
+                                    int len,
+                                    struct gdbserv_reg *reg);
+
+extern void gdbserv_le_bytes_to_reg (struct gdbserv *gdbserv,
+                                    const void *buf,
+                                    int len,
+                                    struct gdbserv_reg *reg);
+
+extern void gdbserv_be_bytes_from_reg (struct gdbserv *gdbserv,
+                                      void *buf,
+                                      int *lenp,
+                                       const struct gdbserv_reg *reg);
+
+extern void gdbserv_le_bytes_from_reg (struct gdbserv *gdbserv,
+                                      void *buf,
+                                      int *lenp,
+                                       const struct gdbserv_reg *reg);
+
+/* Convert between a REG and a buffer representing a native numeric
+   type.  These are just wrappers for the routines above, but are
+   useful nonetheless since they free the caller from having to
+   worry about byte order issues.  */
+
+extern void gdbserv_host_bytes_to_reg (struct gdbserv *gdbserv,
+                                      const void *buf,
+                                      int len,
+                                      struct gdbserv_reg *reg);
+
+extern void gdbserv_host_bytes_from_reg (struct gdbserv *gdbserv,
+                                        void *buf,
+                                        int *lenp,
+                                         const struct gdbserv_reg *reg);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbserv.h b/rda/include/gdbserv.h
new file mode 100644 (file)
index 0000000..cf348e8
--- /dev/null
@@ -0,0 +1,123 @@
+/* gdbserv.h
+
+   Copyright 1998, 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.  */
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdbserv;
+
+/* A ``struct gdbserv_reg'' is an object for storing an arbitrary
+   numeric value in a system independant way.  Part of an input packet
+   will be parsed into a REG object (using gdbserv_input_reg_...) and
+   then later converted into a specific value (using
+   gdbserv_reg_to_...).  The bytes in BUF are always ordered
+   big-endian. */
+
+enum {
+  GDBSERV_REG_SIZE = 16 /* space for a 128-bit quantity */
+};
+struct gdbserv_reg {
+  int negative_p;
+  int len;
+  unsigned char buf[GDBSERV_REG_SIZE];
+};
+
+
+
+/* Fetch data from the current input packet.
+   Return -1 on error. */
+
+
+/* Number of characters remaining in input packet */
+int gdbserv_input_size (struct gdbserv *gdbserv);
+
+/* NIBBLE: 4 bit quantity represented by a single HEX digit.
+   BYTE: 8 bit quantity represented by two HEX digits. */
+int gdbserv_input_nibble (struct gdbserv *gdbserv);
+int gdbserv_input_byte (struct gdbserv *gdbserv);
+
+/* BYTES: LEN 8 bit stream represented by LEN*2 HEX digits.
+   BINARY: LEN 8 bit stream represented by LEN bytes + escape characters */
+int gdbserv_input_bytes (struct gdbserv *gdbserv, char *buf, int len);
+int gdbserv_input_escaped_binary (struct gdbserv *gdbserv, char *buf, int len);
+
+/* Next character/string in packet.  Return -1 on error. */
+int gdbserv_input_peek (struct gdbserv *gdbserv);
+int gdbserv_input_char (struct gdbserv *gdbserv);
+int gdbserv_input_string (struct gdbserv *gdbserv, char *buf, int len);
+
+/* Peek at input packet comparing next few characters against STRING.
+   Return -1 on non or partial match.  Return strlen (STRING) on full
+   match and skip corresponding number of characters in input
+   packet. */
+int gdbserv_input_string_match (struct gdbserv *gdbserv, const char *string);
+
+/* Set VAL to a SMALL (unsigned) integer encoded in (network byte
+   ordered) HEX.  Return a negative value if there is a parse
+   error. */
+int gdbserv_input_hex_long (struct gdbserv *gdbserv, long *val);
+int gdbserv_input_hex_ulong (struct gdbserv *gdbserv, unsigned long *val);
+
+/* Parse a HEX value of almost arbitrary length into the ``struct
+   gdbserv_reg''.  When BYTE_LEN is zero, it may include a leading
+   minus sign. When BYTE_LEN is non-zero it indicates the exact number
+   of RAW BYTES (HEX digits / 2) that should be transfered to
+   REG. ..._hex_beb () expects a true big-endian hex value.
+   ..._hex_leb () expects a hybrid little-endian hex value - the bytes
+   are ordered little-endian but the hex encoded nibble-pair that make
+   up a byte is ordered big endian (ex: 0x12345678 is leb encoded as
+   78563412). */
+int gdbserv_input_reg_beb (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int byte_len);
+int gdbserv_input_reg_leb (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int byte_len);
+
+
+/* Write data to the current output packet. */
+
+
+/* Integer values converted to HEX. */
+void gdbserv_output_nibble (struct gdbserv *gdbserv, int h);
+void gdbserv_output_byte (struct gdbserv *gdbserv, int h);
+void gdbserv_output_bytes (struct gdbserv *gdbserv, const char *buf, unsigned sizeof_buf); 
+
+/* Character values output verbatum. */
+void gdbserv_output_char (struct gdbserv *gdbserv, char c);
+void gdbserv_output_string (struct gdbserv *gdbserv, const char *buf);
+void gdbserv_output_string_as_bytes (struct gdbserv *gdbserv, const char *buf);
+
+
+/* Output a HEX value of almost arbitrary length in ``struct
+   gdbserv_reg''.  May include a leading minus sign.  When BYTE_LEN is
+   non-zero this specifies the exact number of RAW bytes (two HEX
+   characters per byte) that should be output. */
+/* FIXME: Can't have both a leading minus sign and a non-zero
+   BYTE_LENGTH. */
+void gdbserv_output_reg_beb (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int byte_len);
+void gdbserv_output_reg_leb (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int byte_len);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/gdbsocket.h b/rda/include/gdbsocket.h
new file mode 100644 (file)
index 0000000..ae7a83b
--- /dev/null
@@ -0,0 +1,114 @@
+/* gdbsocket.h
+
+   Copyright 1998, 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.  */
+
+#ifdef __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdbserv;
+struct gdbserv_target;
+struct gdblog;
+
+/* When non-NULL, used for logging the socket interface. */
+extern struct gdblog *gdbsocket_log;
+
+
+/* Generic callback function's signature */
+
+typedef struct gdbserv_target *gdbsocket_attach_ftype (struct gdbserv *gdbserv,
+                                                      void *attatch_data);
+
+/* Open/create all connections in asynchronous mode.  Asynchronous
+   connections will generate a SIGIO when they are ready for data
+   transfer (or attach).  If enabling async, the call would normally
+   occure before any sockets have been created.  By default async is
+   disabled.  See samples/async.  */
+
+void gdbsocket_async (int async_p);
+
+
+/* Start a server listening on tcp port PORT_NR.  When an attatch to
+   that port is received, call ATTATCH(DATA) to see if the connection
+   should be accepted or rejected.  TO_ATTATCH shall return (rejecting
+   the connection) or a ``struct gdbserv_target'' (accepting the
+   connection).  The server allows multiple connections to the same
+   port.  A typical target implementation, however, will only allow
+   one active connection, returning NULL when a connection is already
+   open. */
+
+extern int gdbsocket_startup (int port_nr,
+                             gdbsocket_attach_ftype *to_target_attach,
+                             void *target_attatch_data);
+
+
+/* Shut down the gdbserver.  Force the closure of any active remote
+   sessions.  */
+
+void gdbsocket_shutdown (void);
+
+
+/* ``Re-open'' readfd/writefd as an active gdb-server connection.
+   Interface is shutdown using CLOSE when EOF is detected on readfd.
+   Does not need an active running gdbsocket server.  The readfd and
+   writefd can have the same value.  Returns a negative value if the
+   target rejects the connection, otherwise a cardinal is returned.  */
+
+int gdbsocket_reopen (int fdin, int fdout,
+                     void (*close) (int fdin, int fdout),
+                     gdbsocket_attach_ftype *to_target_attach,
+                     void *target_attach_data);
+
+
+
+/* External SELECT/POLL interface.
+
+   The interface is loosely based on UNIX select().  A set of
+   read/write events to be polled is created using fd_set().
+   POLL/SELECT is then called.  The list is then checked, using
+   fd_isset() for any returned events. */
+
+enum gdbsocket_fd_event {
+  GDBSOCKET_FD_READ,
+  GDBSOCKET_FD_WRITE
+};
+
+typedef void gdbsocket_fd_set_ftype (int fd, void *context, enum gdbsocket_fd_event event);
+typedef int gdbsocket_fd_isset_ftype (int fd, void *context, enum gdbsocket_fd_event event);
+
+/* Iterate through all of GDBSERVER's open file descriptors
+   accumulating a list of events to be polled using FD_SET(). */
+
+void gdbsocket_fd_set (gdbsocket_fd_set_ftype *fd_set, void *context);
+
+/* Iterate through all of GDBSERVER's open file descriptors checking
+   for any returned events using FD_ISSET().  Process each returned
+   event. */
+
+void gdbsocket_fd_isset (gdbsocket_fd_isset_ftype *fd_isset, void *context);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/include/stdio-log.h b/rda/include/stdio-log.h
new file mode 100644 (file)
index 0000000..3f1f8e1
--- /dev/null
@@ -0,0 +1,39 @@
+/* stdio-log.h
+
+   Copyright 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.  */
+
+#if defined __cplusplus
+extern "C" {
+#elif 0
+}
+#endif
+
+struct gdblog;
+
+/* Create a log that sends everything to stdio.  */
+
+extern struct gdblog *stdio_log (FILE *stdio);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/lib/ARCH b/rda/lib/ARCH
new file mode 100644 (file)
index 0000000..d9bf22d
--- /dev/null
@@ -0,0 +1,192 @@
+Architecture:
+
+       (GDB)CLIENT <--> SERVER <--> TARGET
+
+Where:
+
+       CLIENT
+
+               Provides the raw interface between
+               GDBSERVER and the internal server
+               mechanism.
+
+               The client passes any data relevant
+               to the server on.  The SERVER presents
+               CLIENT with raw output to be returned
+               to GDB.
+
+       SERVER
+               Implements true state-machine that
+               is capable of decoding / processing
+               various GDB remote protocol requests.
+
+       TARGET
+               The embedded system proper.  SERVER
+               passes decoded requests onto the TARGET
+               while TARGET notifies the SERVER of any
+               target state changes.
+
+
+Looking at SERVER in more detail, that component consists of three sub
+components INPUT, OUTPUT and STATE.  Visually:
+
+                                    .------------ fromtarget_*
+                                   \|/
+       fromclient_*   -> INPUT -> STATE (M/C) -> target->*
+                          /|\         |
+                            |
+                          \|/         |
+       client->write  <- OUTPUT <----'
+
+where:
+
+       INPUT
+               Filters the raw input stream from the client
+               breaking it up into complete packets and
+               passing them onto STATE.
+
+               This component co-operates with OUTPUT for
+               the ACK/NAK of input packets.
+
+       OUTPUT
+               Wraps up and then passes onto the client
+               raw output packets ready for transmition
+               on the output stream.
+
+               This component  co-operates with INPUT for
+               the ACK/NAK of output packets.
+
+       STATE
+               The state machine proper.
+
+
+
+SENARIOS:
+
+
+ATTACH: Creating a connection into the server/target.
+
+Client receives a conect request from the remote GDB.  A socket
+interface would see this as an attach.  For Cygmon this is the
+``transfer'' command.
+
+The client creates an output object (struct gdbserv_client) and passes
+that and the target side attach function onto GDBSERV.  SERVER will
+then initialize itsself and call ``to_target_attach'' for final
+approval of the request.
+
+       struct gdbserv_client *client;
+       ...
+       client->write = client_write_to_output_port;
+       client->data = ... local state ...
+       server = gdbserv_fromclient_attach (client, to_target_attach,
+                                           target_data);
+
+The target_attach() function is expected to either create and return a
+gdbserv_target object or return NULL.  The latter indicates that the
+connection request is rejected.
+
+Finally gdbserv_fromclient_attach() returns a SERVER state object that
+should be passed to all client->server calls.
+
+
+DATA-IN: Data being sent to the client from the remote GDB
+
+The client passes the data vis:
+
+       len = read (fd, buf, sizeof (buf));
+       gdbserv_fromclient_data (server, buf, len);
+
+
+BREAK-IN: Request to stop sent to the client from the remote GDB
+
+The client passes the request to SERVER:
+
+       server.c:
+
+       volatile
+       break_handler ()
+       {
+         gdbserv_fromclient_break (server);
+       }
+
+If the target is currently running, the server will in turn pass the
+request onto the TARGET:
+
+       ->target->break_program (server);
+
+and the target will record the break request and then return control
+back to the SERVER.  The server returning control to the client.
+
+Later, once the target has halted, the SERVER is notified of the state
+change vis:
+
+       target.c:
+
+         gdbserv_fromtarget_break (server);
+
+
+NB: Often ``break'' is sent across the stream interface as a special
+character sequence.
+
+FIXME: gdbserv-input.c should be able to parse such character
+sequences.
+
+
+DATA-OUT: Data for the remote GDB from SERVER
+
+The ``write'' function specified in the ``struct gdbserv_client''
+object is called.
+
+
+DETACH: Remote GDB dissconnects from the SERVER
+
+The CLIENT notifies SERVER via the gdbserv_fromclient_detach() call.
+
+
+HARD-RESET:  A hard reset is performed on a serial board.
+
+Assuming a standalone system, the client/target side sequences would
+be performed:
+
+       /* create the server */
+       server = gdbserv_fromclient_attach (...);
+       /* notify the server that the target was just reset */
+       gdbserv_fromtarget_reset (server);
+
+
+WRITE-MEMORY: GDB sends the server a write-memory packet.
+
+Eventually SERVER passes the request onto the TARGET with the call:
+
+       ->target->process_set_mem (server, addr, len);
+
+where ADDR and LEN contain the uninterpreted address/length of the
+data to follow.  target_process_set_mem() might be implemented as:
+
+       long long addr;
+       long int;
+       gdbserv_reg_to_ulonglong (server, reg_addr, &addr);
+       gdbserv_reg_to_ulong (server, reg_len, &len);
+       /* just blat local memory */
+       len = gdbserv_input_bytes (server, addr, len);
+       
+
+READ-MEMORY: GDB requests memory from the target.
+
+Eventually target_process_get_mem() function is called.  An
+implementation may look like:
+
+       gdbserv_reg_to_ulonglong (gdbserv, reg_addr, &addr);
+       gdbserv_reg_to_ulong (gdbserv, reg_len, &len);
+       /* assume we're reading raw memory from the local mc */
+       gdbserv_output_bytes (gdbserv, addr, len);
+
+
+TARGET-RESUME: GDB requests that the target resume execution.
+
+Eventually ->target->continue_program() is called.  That function
+should record the request and then wait for SERVER to exit before
+actually continuing the target.
+
+--
diff --git a/rda/lib/Makefile.am b/rda/lib/Makefile.am
new file mode 100644 (file)
index 0000000..eeccc41
--- /dev/null
@@ -0,0 +1,20 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+WARN_CFLAGS = @WARN_CFLAGS@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+
+# Create a libtool convenience archive
+# ... and a plain library archive for non-libtool clients
+noinst_LTLIBRARIES = librda.la
+noinst_LIBRARIES = librda.a
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include \
+       -I$(srcdir)/../../include
+
+THESOURCES=gdbserv-input.c gdbserv-output.c gdbserv-state.c gdbserv-utils.c gdbsocket.c gdblog.c stdio-log.c gdbserv-log.c gdbloop.c gdbsched.c gdbserv-target.c
+
+librda_la_SOURCES = $(THESOURCES)
+librda_a_SOURCES = $(THESOURCES)
diff --git a/rda/lib/Makefile.in b/rda/lib/Makefile.in
new file mode 100644 (file)
index 0000000..e9d0d4a
--- /dev/null
@@ -0,0 +1,405 @@
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+GCJ = @GCJ@
+GCJFLAGS = @GCJFLAGS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+l = @l@
+targ_subdirs = @targ_subdirs@
+
+AUTOMAKE_OPTIONS = foreign
+
+WARN_CFLAGS = @WARN_CFLAGS@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+
+# Create a libtool convenience archive
+# ... and a plain library archive for non-libtool clients
+noinst_LTLIBRARIES = librda.la
+noinst_LIBRARIES = librda.a
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include \
+       -I$(srcdir)/../../include
+
+
+THESOURCES = gdbserv-input.c gdbserv-output.c gdbserv-state.c gdbserv-utils.c gdbsocket.c gdblog.c stdio-log.c gdbserv-log.c gdbloop.c gdbsched.c gdbserv-target.c
+
+librda_la_SOURCES = $(THESOURCES)
+librda_a_SOURCES = $(THESOURCES)
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+LIBRARIES =  $(noinst_LIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+librda_a_LIBADD = 
+librda_a_OBJECTS =  gdbserv-input.$(OBJEXT) gdbserv-output.$(OBJEXT) \
+gdbserv-state.$(OBJEXT) gdbserv-utils.$(OBJEXT) gdbsocket.$(OBJEXT) \
+gdblog.$(OBJEXT) stdio-log.$(OBJEXT) gdbserv-log.$(OBJEXT) \
+gdbloop.$(OBJEXT) gdbsched.$(OBJEXT) gdbserv-target.$(OBJEXT)
+AR = ar
+LTLIBRARIES =  $(noinst_LTLIBRARIES)
+
+librda_la_LDFLAGS = 
+librda_la_LIBADD = 
+librda_la_OBJECTS =  gdbserv-input.lo gdbserv-output.lo gdbserv-state.lo \
+gdbserv-utils.lo gdbsocket.lo gdblog.lo stdio-log.lo gdbserv-log.lo \
+gdbloop.lo gdbsched.lo gdbserv-target.lo
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES =  .deps/gdblog.P .deps/gdbloop.P .deps/gdbsched.P \
+.deps/gdbserv-input.P .deps/gdbserv-log.P .deps/gdbserv-output.P \
+.deps/gdbserv-state.P .deps/gdbserv-target.P .deps/gdbserv-utils.P \
+.deps/gdbsocket.P .deps/stdio-log.P
+SOURCES = $(librda_a_SOURCES) $(librda_la_SOURCES)
+OBJECTS = $(librda_a_OBJECTS) $(librda_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .obj .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstLIBRARIES:
+
+clean-noinstLIBRARIES:
+       -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+distclean-noinstLIBRARIES:
+
+maintainer-clean-noinstLIBRARIES:
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+       $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+       -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+librda.a: $(librda_a_OBJECTS) $(librda_a_DEPENDENCIES)
+       -rm -f librda.a
+       $(AR) cru librda.a $(librda_a_OBJECTS) $(librda_a_LIBADD)
+       $(RANLIB) librda.a
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+       -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+librda.la: $(librda_la_OBJECTS) $(librda_la_DEPENDENCIES)
+       $(LINK)  $(librda_la_LDFLAGS) $(librda_la_OBJECTS) $(librda_la_LIBADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = lib
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign lib/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-noinstLIBRARIES mostlyclean-compile \
+               mostlyclean-libtool mostlyclean-noinstLTLIBRARIES \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-noinstLIBRARIES clean-compile clean-libtool \
+               clean-noinstLTLIBRARIES clean-tags clean-depend \
+               clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-noinstLIBRARIES distclean-compile \
+               distclean-libtool distclean-noinstLTLIBRARIES \
+               distclean-tags distclean-depend distclean-generic \
+               clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-noinstLIBRARIES \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-noinstLTLIBRARIES \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
+clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool mostlyclean-noinstLTLIBRARIES \
+distclean-noinstLTLIBRARIES clean-noinstLTLIBRARIES \
+maintainer-clean-noinstLTLIBRARIES tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/rda/lib/gdblog.c b/rda/lib/gdblog.c
new file mode 100644 (file)
index 0000000..ab35b6e
--- /dev/null
@@ -0,0 +1,80 @@
+/* gdbserv-log.c
+
+   Copyright 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 <stdlib.h>
+
+#include "gdblog.h"
+
+struct gdblog
+{
+  void *context;
+  gdblog_string_ftype *log_string;
+  gdblog_long_ftype *log_long;
+  gdblog_xlong_ftype *log_xlong;
+  gdblog_char_ftype *log_char;
+};
+
+void
+gdblog_string (struct gdblog *log, const char *val)
+{
+  if (log)
+    log->log_string (log->context, val);
+}
+
+void
+gdblog_long (struct gdblog *log, long val)
+{
+  if (log)
+    log->log_long (log->context, val);
+}
+
+void
+gdblog_xlong (struct gdblog *log, long val)
+{
+  if (log)
+    log->log_xlong (log->context, val);
+}
+
+void
+gdblog_char (struct gdblog *log, char val)
+{
+  if (log)
+    log->log_char (log->context, val);
+}
+
+struct gdblog *
+gdblog_new (void *context,
+           gdblog_string_ftype *log_string,
+           gdblog_long_ftype *log_long,
+           gdblog_xlong_ftype *log_xlong,
+           gdblog_char_ftype *log_char)
+{
+  struct gdblog *new_log = malloc (sizeof (struct gdblog));
+  new_log->context = context;
+  new_log->log_string = log_string;
+  new_log->log_long = log_long;
+  new_log->log_xlong = log_xlong;
+  new_log->log_char = log_char;
+  return new_log;
+}
diff --git a/rda/lib/gdbloop.c b/rda/lib/gdbloop.c
new file mode 100644 (file)
index 0000000..156c6db
--- /dev/null
@@ -0,0 +1,162 @@
+/* gdbloop.c
+
+   Copyright 1998, 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 "config.h"
+
+#include <stdio.h>
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#include <unistd.h>
+#include <errno.h>
+#include <assert.h>
+#include <signal.h>
+#include <fcntl.h>
+
+#include "gdblog.h"
+#include "gdbsocket.h"
+#include "gdbsched.h"
+
+#include "gdbloop.h"
+
+/* Poll all of GDBSOCKET's open file descriptors. */
+
+struct fds
+{
+  fd_set read;
+  fd_set write;
+  int nr;
+};
+
+static void
+fds_set (int fd, void *context, enum gdbsocket_fd_event event)
+{
+  struct fds *fds = context;
+  switch (event)
+    {
+    case GDBSOCKET_FD_READ:
+      FD_SET (fd, &fds->read);
+      break;
+    case GDBSOCKET_FD_WRITE:
+      FD_SET (fd, &fds->write);
+      break;
+    }
+  if (fds->nr <= fd)
+    fds->nr = fd + 1;
+}
+
+static int
+fds_isset (int fd, void *context, enum gdbsocket_fd_event event)
+{
+  struct fds *fds = context;
+  switch (event)
+    {
+    case GDBSOCKET_FD_READ:
+      return FD_ISSET (fd, &fds->read);
+    case GDBSOCKET_FD_WRITE:
+      return FD_ISSET (fd, &fds->write);
+    }
+  return 0;
+}
+
+static void
+poll_gdbsocket (long timeout)
+{
+  int s;
+  struct fds fds;
+  
+  /* Collect up the FDs of interest. */
+  FD_ZERO (&fds.read);
+  FD_ZERO (&fds.write);
+  fds.nr = 0;
+  gdbsocket_fd_set (fds_set, &fds);
+  
+  /* Do the select. */
+  gdblog_string (gdbsocket_log, "[select ");
+  gdblog_long (gdbsocket_log, timeout);
+  if (timeout >= 0)
+    {
+      struct timeval timeval;
+      timeval.tv_sec = timeout;
+      timeval.tv_usec = 0;
+      s = select (fds.nr, &fds.read, &fds.write, NULL, &timeval);
+    }
+  else
+    {
+      s = select (fds.nr, &fds.read, &fds.write, NULL, NULL);
+    }
+  gdblog_string (gdbsocket_log, " -> ");
+  gdblog_long (gdbsocket_log, s);
+  gdblog_string (gdbsocket_log, "]\n");
+
+  if (s < 0)
+    {
+      if (errno == EINTR)
+       return;
+      perror ("select");
+      return;
+    }
+  
+  /* Process any pending events. */
+  gdbsocket_fd_isset (fds_isset, &fds);
+}  
+
+void
+gdbloop (long current_time, int timeout)
+{
+  long sched_time;
+
+  /* Compute the time until the next event. */
+  sched_time = gdbsched_dispatch (-1);
+
+  /* Reduce the timeout if the next scheduled event is sooner. */
+  if (sched_time > current_time)
+    {
+      if (timeout < 0
+         || sched_time - current_time < timeout)
+       timeout = sched_time - current_time;
+    }
+  else if (sched_time >= 0)
+    {
+      if (timeout <= 0)
+       timeout = 0;
+    }
+
+  /* check the event queue for events. */
+  poll_gdbsocket (timeout);
+
+  /* Drain the queue of any outstanding events. */
+  gdbsched_dispatch (current_time);
+}
+
+void
+gdbloop_poll (int timeout)
+{
+  gdbloop (time (NULL), timeout);
+}
diff --git a/rda/lib/gdbsched.c b/rda/lib/gdbsched.c
new file mode 100644 (file)
index 0000000..d9d7daf
--- /dev/null
@@ -0,0 +1,174 @@
+/* gdbsched.c
+
+   Copyright 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 "config.h"
+
+#include <stdlib.h>
+
+#include "gdbsched.h"
+#include "gdblog.h"
+#include "gdbsocket.h"
+
+/* Database of scheduled events. */
+
+struct event {
+  long time;
+  struct gdbsched *sched;
+  gdbsched_handler_ftype *handler;
+  struct gdbserv *gdbserv;
+  struct gdbserv_thread *thread;
+  void *context;
+  struct event *next;
+};
+
+struct event *event_db;
+
+/* Unique key generator. */
+struct gdbsched {
+  int i;
+};
+struct gdbsched *sched_db;
+
+struct gdbsched *
+gdbsched_schedule (long time,
+                  gdbsched_handler_ftype *handler,
+                  struct gdbserv *gdbserv,
+                  struct gdbserv_thread *thread,
+                  void *context)
+{
+  struct event **event;
+  struct event *new = malloc (sizeof (struct event));
+  gdblog_string (gdbsocket_log, "[schedule ");
+  new->sched = ++sched_db;
+  new->time = time;
+  new->handler = handler;
+  new->gdbserv = gdbserv;
+  new->thread = thread;
+  new->context = context;
+  /* Insert it. */
+  for (event = &event_db;
+       (*event) != NULL && (*event)->time <= time;
+       event = &(*event)->next);
+  new->next = *event;
+  *event = new;
+  gdblog_long (gdbsocket_log, time);
+  gdblog_string (gdbsocket_log, "]\n");
+  return new->sched;
+}
+
+void
+gdbsched_deschedule (struct gdbsched *sched,
+                    long *time,
+                    gdbsched_handler_ftype **handler,
+                    struct gdbserv **gdbserv,
+                    struct gdbserv_thread **thread,
+                    void **context)
+{
+  struct event **event;
+  long local_time;
+  gdbsched_handler_ftype *local_handler;
+  struct gdbserv *local_gdbserv;
+  struct gdbserv_thread *local_thread;
+  void *local_context;
+
+  gdblog_string (gdbsocket_log, "[deschedule ");
+
+  /* Find the event. */
+  if (sched == NULL)
+    {
+      event = &event_db;
+    }
+  else
+    {
+      for (event = &event_db;
+          (*event) != NULL;
+          event = &(*event)->next)
+       {
+         if ((*event)->sched == sched)
+           break;
+       }
+    }
+  
+  /* Save it's state and delete it. */
+  if ((*event) == NULL)
+    {
+       local_time = -1;
+       local_handler = NULL;
+       local_gdbserv = NULL;
+       local_thread = NULL;
+       local_context = NULL;
+    }
+  else
+    {
+      struct event *dead = (*event);
+      (*event) = dead->next;
+      local_time = dead->time;
+      local_handler = dead->handler;
+      local_gdbserv = dead->gdbserv;
+      local_thread = dead->thread;
+      local_context = dead->context;
+      free (dead);
+    }
+
+  /* Return any applicable values. */
+  if (time != NULL)
+    *time = local_time;
+  if (handler != NULL)
+    *handler = local_handler;
+  if (gdbserv != NULL)
+    *gdbserv = local_gdbserv;
+  if (local_thread != NULL)
+    *thread = local_thread;
+  if (local_context != NULL)
+    *context = local_context;
+  gdblog_long (gdbsocket_log, local_time);
+  gdblog_string (gdbsocket_log, "]");
+}
+
+long
+gdbsched_dispatch (long current_time)
+{
+  long next_time;
+  gdblog_string (gdbsocket_log, "[dispatch @");
+  gdblog_long (gdbsocket_log, current_time);
+  while (event_db != NULL
+        && event_db->time <= current_time)
+    {
+      long time;
+      gdbsched_handler_ftype *handler;
+      struct gdbserv *gdbserv;
+      struct gdbserv_thread *thread;
+      void *context;
+      gdbsched_deschedule (NULL, &time, &handler, &gdbserv, &thread, &context);
+      handler (gdbserv, thread, context);
+    }
+  if (event_db == NULL)
+    next_time = -1;
+  else
+    next_time = event_db->time;
+  gdblog_string (gdbsocket_log, " -> ");
+  gdblog_long (gdbsocket_log, next_time);
+  gdblog_string (gdbsocket_log, "]\n");
+  return next_time;
+}
diff --git a/rda/lib/gdbserv-input.c b/rda/lib/gdbserv-input.c
new file mode 100644 (file)
index 0000000..6e593fa
--- /dev/null
@@ -0,0 +1,548 @@
+/* gdbserv-input.c
+
+   Copyright 1998, 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 <assert.h>
+
+#include "gdbserv.h"
+#include "gdbserv-state.h"
+#include "gdbserv-utils.h"
+#include "gdblog.h"
+#include "gdbserv-log.h"
+
+void
+gdbserv_input_attach (struct gdbserv *gdbserv)
+{
+  gdbserv->input.state = GDBINPUT_STATE_IDLE;
+  gdbserv->input.buf = NULL;
+  gdbserv->input.sizeof_buf = 0; /* allocate buffer on first use */
+  gdbserv->input.len = 0;
+  gdbserv->input.out = 0;
+}
+
+void
+gdbserv_input_detach (struct gdbserv *gdbserv)
+{
+}
+
+static int
+add_char_to_packet (struct gdbserv *gdbserv, int ch)
+{
+  while (1)
+    {
+      switch (gdbserv->input.state)
+       {
+
+       case GDBINPUT_STATE_IDLE:
+         if (ch == '$')
+           {
+             gdbserv->input.state = GDBINPUT_STATE_TERM;
+             gdbserv->input.len = 0;
+             gdbserv->input.out = 0;
+             gdbserv->input.checksum = 0;
+             gdbserv->input.xmitcsum = -1;
+           }
+         else if (ch == 0x03 /* CNTRL-C */ )
+           {
+             /* CNTRL-C packet: No check-sum or anything else.  Hence not
+                very safe. */
+             gdbserv_fromclient_break (gdbserv);
+           }
+         return 0;
+
+       case GDBINPUT_STATE_TERM:
+         /* enlarge receive buffer if necessary/possible */
+         if (gdbserv->input.sizeof_buf == gdbserv->input.len)
+           {
+             char *newbuf;
+             unsigned new_sizeof_buf = gdbserv->input.sizeof_buf + 4000;
+             newbuf = realloc (gdbserv->input.buf, new_sizeof_buf);
+             if (newbuf == NULL)
+               {
+                 gdbserv->client->write (gdbserv, "-", 1);     /* failed */
+                 gdbserv->input.state = GDBINPUT_STATE_IDLE;
+                 return -1;
+               }
+             gdbserv->input.buf = newbuf;
+             gdbserv->input.sizeof_buf = new_sizeof_buf;
+           }
+         assert (gdbserv->input.buf != NULL);
+         assert (gdbserv->input.sizeof_buf > gdbserv->input.len);
+         if (ch == '#')
+           {
+             gdbserv->input.buf[gdbserv->input.len] = 0;
+             gdbserv->input.state = GDBINPUT_STATE_CRC1;
+           }
+         else
+           {
+             gdbserv->input.buf[gdbserv->input.len] = ch;
+             gdbserv->input.len++;
+             gdbserv->input.checksum += ch;
+           }
+         return 0;
+
+       case GDBINPUT_STATE_CRC1:
+         gdbserv->input.xmitcsum = gdbserv_hex_to (ch) << 4;
+         gdbserv->input.state = GDBINPUT_STATE_CRC2;
+         return 0;
+
+       case GDBINPUT_STATE_CRC2:
+         gdbserv->input.xmitcsum |= gdbserv_hex_to (ch);
+         if ((gdbserv->input.checksum & 255) != gdbserv->input.xmitcsum)
+           {
+             gdbserv->client->write (gdbserv, "-", 1); /* failed checksum */
+             gdbserv->input.state = GDBINPUT_STATE_IDLE;
+             return -1;
+           }
+         else
+           {
+             char ack[3];
+             int sizeof_ack = 0;
+             ack[sizeof_ack++] = '+';
+             /* if a sequence char is present, reply the sequence ID */
+             assert (gdbserv->input.buf != NULL);
+             assert (gdbserv->input.sizeof_buf > gdbserv->input.len);
+             if (gdbserv->input.buf[2] == ':')
+               {
+                 unsigned long count = gdbserv->input.len;
+                 unsigned long i;
+                 ack[sizeof_ack++] = gdbserv->input.buf[0];
+                 ack[sizeof_ack++] = gdbserv->input.buf[1];
+                 /* remove sequence chars from buffer */
+                 for (i = 3; i <= count; i++)
+                   gdbserv->input.buf[i - 3] = gdbserv->input.buf[i];
+               }
+             gdbserv->client->write (gdbserv, ack, sizeof_ack);
+             gdbserv->input.state = GDBINPUT_STATE_IDLE;
+             return 1;
+           }
+
+       case GDBINPUT_STATE_ACK:
+         if (ch == '+')
+           {
+             gdbserv_output_discard (gdbserv);
+             gdbserv->input.state = GDBINPUT_STATE_IDLE;
+           }
+         else if (ch == '-')
+           {
+             gdbserv_output_packet (gdbserv);
+           }
+         else if (ch == '$')
+           {
+             gdblog_string (gdbserv_warning_log,
+                            "Unexpected packet start received "
+                            "(ACK missing?)");
+             /* Give up waiting for ACK and go receive the new packet. */
+             gdbserv->input.state = GDBINPUT_STATE_IDLE;
+             continue;
+           }
+         /* else: ignore junk characters. */
+         return 0;
+
+       } /* switch */
+
+    } /* while */
+  return 0;
+}
+
+void
+gdbserv_input_data_packet (struct gdbserv *gdbserv,
+                          const char *data,
+                          int sizeof_data)
+{
+  int i;
+  if (gdbserv_input_log)
+    {
+      gdblog_string (gdbserv_input_log, "[->");
+      gdblog_long (gdbserv_input_log, sizeof_data);
+      gdblog_string (gdbserv_input_log, " ");
+      for (i = 0; i < sizeof_data; i++)
+       {
+         gdblog_char (gdbserv_input_log, data[i]);
+       }
+      gdblog_string (gdbserv_input_log, "]\n");
+    }
+  for (i = 0; i < sizeof_data; i++)
+    {
+      switch (add_char_to_packet (gdbserv, data[i]))
+       {
+       case 0:
+         break;
+       case +1:
+         gdbserv->input.out = 0;
+         gdbserv_data_packet (gdbserv);
+         break;
+       case -1:
+         return;
+       }
+    }
+}
+
+void
+gdbserv_input_wait_for_ack (struct gdbserv *gdbserv)
+{
+  /* FIXME: cagney/2000-03-21: This stub framework lacks a mechanism
+     for a encapsulating console output (via the ``O'' packet).
+     Because of this, some targets just send raw ``O'' packets down
+     the output stream and ignore all acknowledgments. */
+  if ((gdbserv->input.state != GDBINPUT_STATE_IDLE)
+      && (gdbserv->input.state != GDBINPUT_STATE_ACK))
+    {
+      if (gdbserv_warning_log)
+       {
+         gdblog_string (gdbserv_warning_log,
+                        "Unexpected transition to ACK (");
+         gdblog_long (gdbserv_warning_log, gdbserv->input.state);
+         gdblog_string (gdbserv_warning_log, ")\n");
+       }
+    }
+  gdbserv->input.state = GDBINPUT_STATE_ACK;
+}
+
+int
+gdbserv_input_size (struct gdbserv *gdbserv)
+{
+  if (gdbserv->input.out <= gdbserv->input.len)
+    return gdbserv->input.len - gdbserv->input.out;
+  else
+    return -1;
+}
+
+int
+gdbserv_input_char (struct gdbserv *gdbserv)
+{
+  if (gdbserv->input.out < gdbserv->input.len)
+    return (unsigned char) gdbserv->input.buf[gdbserv->input.out++];
+  else
+    return -1;
+}
+
+int
+gdbserv_input_string (struct gdbserv *gdbserv,
+                     char *buf,
+                     int len)
+{
+  int i;
+  for (i = 0; i < (len - 1); i++)
+    {
+      int byte = gdbserv_input_char (gdbserv);
+      if (byte < 0)
+       break;
+      buf[i] = byte;
+    }
+  buf[i] = '\0';
+  return i;
+}
+
+int
+gdbserv_input_string_match (struct gdbserv *gdbserv,
+                           const char *buf)
+{
+  int i;
+  /* compare strings */
+  for (i = 0; buf[i] != '\0'; i++)
+    {
+      if (gdbserv->input.out + i >= gdbserv->input.len)
+       return -1;
+      if (buf[i] != gdbserv->input.buf[gdbserv->input.out + i])
+       return -1;
+    }
+
+  /* match */
+  gdbserv->input.out += i;
+  return i;
+}
+
+int
+gdbserv_input_peek (struct gdbserv *gdbserv)
+{
+  if (gdbserv->input.out < gdbserv->input.len)
+    return (unsigned char) gdbserv->input.buf[gdbserv->input.out];
+  else
+    return -1;
+}
+
+int
+gdbserv_input_byte (struct gdbserv *gdbserv)
+{
+  if (gdbserv->input.out + 1 < gdbserv->input.len)
+    {
+      int h0;
+      int h1;
+      h0 = gdbserv_hex_to (gdbserv->input.buf[gdbserv->input.out + 0]);
+      if (h0 < 0)
+       return -1;
+      h1 = gdbserv_hex_to (gdbserv->input.buf[gdbserv->input.out + 1]);
+      if (h1 < 0)
+       return -1;
+      gdbserv->input.out += 2;
+      return (h0 << 4) | h1;
+    }
+  else
+    return -1;
+}
+
+int
+gdbserv_input_nibble (struct gdbserv *gdbserv)
+{
+  if (gdbserv->input.out < gdbserv->input.len)
+    {
+      int nibble = gdbserv_hex_to (gdbserv->input.buf[gdbserv->input.out]);
+      if (nibble < 0)
+       return -1;
+      gdbserv->input.out++;
+      return nibble;
+    }
+  else
+    return -1;
+}
+
+static int
+unpack_reg_bytes (struct gdbserv *gdbserv,
+                 struct gdbserv_reg *reg,
+                 int buf[],
+                 int byte_len)
+{
+  int len;
+  int buf_len;
+
+  /* Leading sign? */
+  if (gdbserv->input.out < gdbserv->input.len
+      && gdbserv->input.buf[gdbserv->input.out] == '-')
+    {
+      reg->negative_p = 1;
+    }
+  else
+    {
+      reg->negative_p = 0;
+    }
+
+  /* How many characters are allowed? */
+  if (byte_len <= 0)
+    buf_len = sizeof (reg->buf) * 2;
+  else if (byte_len <= sizeof (reg->buf))
+    buf_len = byte_len * 2;
+  else
+    return -1;
+
+  /* unpack the half bytes */
+  for (len = 0; len < buf_len; len++)
+    {
+      int pos = gdbserv->input.out + reg->negative_p + len;
+      if (pos >= gdbserv->input.len)
+       break;
+      buf[len] = gdbserv_hex_to (gdbserv->input.buf[pos]);
+      if (buf[len] < 0)
+       break;
+    }
+
+  /* Correct number of digits found? */
+  if (byte_len > 0 && len != buf_len)
+    return -1;
+
+  gdbserv->input.out += len + reg->negative_p;
+  return len;
+}
+
+int
+gdbserv_input_reg_beb (struct gdbserv *gdbserv,
+                      struct gdbserv_reg *reg,
+                      int byte_len)
+{
+  int buf[sizeof (reg->buf) * 2];
+  int len;
+  int pos;
+
+  /* decode the input stream */
+  len = unpack_reg_bytes (gdbserv, reg, buf, byte_len);
+  if (len <= 0)
+    return -1;
+
+  /* re-pack as bytes, allow for odd starting byte */
+  pos = 0;
+  reg->len = 0;
+  if (len % 2)
+    {
+      reg->buf[reg->len++] = buf[pos++];
+    }
+  while (pos < len)
+    {
+      int byte = 0;
+      byte |= (buf[pos++] << 4);
+      byte |= (buf[pos++] << 0);
+      reg->buf[reg->len++] = byte;
+    }
+
+  /* provided something was found, succeed */
+  if (reg->len > 0)
+    {
+      return reg->len;
+    }
+  else
+    return -1;
+}
+
+int
+gdbserv_input_reg_leb (struct gdbserv *gdbserv,
+                      struct gdbserv_reg *reg,
+                      int byte_len)
+{
+  int buf[sizeof (reg->buf) * 2];
+  int len;
+  int pos;
+
+  /* decode the input stream, check something was found. */
+  len = unpack_reg_bytes (gdbserv, reg, buf, byte_len);
+  if (len <= 0)
+    return -1;
+
+  /* re-pack as bytes BE, allow for odd ending byte */
+  pos = len;
+  reg->len = 0;
+  if (len % 2)
+    {
+      pos -= 1;
+      reg->buf[reg->len++] = buf[pos];
+    }
+  while (pos > 1)
+    {
+      int byte = 0;
+      pos -= 2;
+      byte |= (buf[pos + 0] << 4);
+      byte |= (buf[pos + 1] << 0);
+      reg->buf[reg->len++] = byte;
+    }
+
+  /* provided something was found, succeed */
+  if (reg->len > 0)
+    {
+      return reg->len;
+    }
+  else
+    return -1;
+}
+
+int
+gdbserv_input_bytes (struct gdbserv *gdbserv,
+                    char *buf,
+                    int len)
+{
+  int i;
+  for (i = 0; i < len; i++)
+    {
+      int byte = gdbserv_input_byte (gdbserv);
+      if (byte < 0)
+       break;
+      buf[i] = byte;
+    }
+  return i;
+}
+
+int
+gdbserv_input_escaped_binary (struct gdbserv *gdbserv,
+                             char *buf,
+                             int len)
+{
+  int i;
+  int ch;
+
+  for (i = 0; i < len; i++)
+    {
+      ch = gdbserv_input_char (gdbserv);
+      if (ch < 0)
+       return ch;
+      if (ch == 0x7d)
+       {
+         ch = gdbserv_input_char (gdbserv);
+         if (ch < 0)
+           return ch;
+         buf[i] = 0x20 | (ch & 0xff);
+       }
+      else
+       {
+         buf[i] = ch;
+       }
+    }
+  return i;
+}
+
+int
+gdbserv_input_hex_ulong (struct gdbserv *gdbserv,
+                        unsigned long *l)
+{
+  unsigned long val = 0;
+  int nr = 0;
+  while (gdbserv->input.out < gdbserv->input.len)
+    {
+      int h = gdbserv_hex_to (gdbserv->input.buf[gdbserv->input.out]);
+      if (h < 0)
+       break;
+      val = (val << 4) | h;
+      gdbserv->input.out++;
+      nr++;
+    }
+  if (nr <= 0)
+    return -1;
+  else
+    {
+      *l = val;
+      return 0;
+    }
+}
+
+int
+gdbserv_input_hex_long (struct gdbserv *gdbserv,
+                       long *l)
+{
+  unsigned long val = 0;
+  int nr;
+  int negative = 0;
+  if (gdbserv->input.out < gdbserv->input.len
+      && gdbserv->input.buf[gdbserv->input.out] == '-')
+    {
+      negative = 1;
+      gdbserv->input.out++;
+    }
+  nr = 0;
+  while (gdbserv->input.out < gdbserv->input.len)
+    {
+      int h = gdbserv_hex_to (gdbserv->input.buf[gdbserv->input.out]);
+      if (h < 0)
+       break;
+      val = (val << 4) | h;
+      gdbserv->input.out++;
+      nr++;
+    }
+  if (nr <= 0)
+    return -1;
+  else
+    {
+      if (negative)
+       *l = -val;
+      else
+       *l = val;
+      return 0;
+    }
+}
diff --git a/rda/lib/gdbserv-log.c b/rda/lib/gdbserv-log.c
new file mode 100644 (file)
index 0000000..4d97918
--- /dev/null
@@ -0,0 +1,28 @@
+/* gdbserv-log.c
+
+   Copyright 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.  */
+
+struct gdblog *gdbserv_state_log;
+struct gdblog *gdbserv_input_log;
+struct gdblog *gdbserv_output_log;
+struct gdblog *gdbserv_warning_log;
diff --git a/rda/lib/gdbserv-output.c b/rda/lib/gdbserv-output.c
new file mode 100644 (file)
index 0000000..d7d35e6
--- /dev/null
@@ -0,0 +1,196 @@
+/* gdbserv-output.c
+
+   Copyright 1998, 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 <assert.h>
+#include "gdbserv.h"
+#include "gdbserv-state.h"
+#include "gdbserv-utils.h"
+#include "gdblog.h"
+#include "gdbserv-log.h"
+
+void
+gdbserv_output_attach (struct gdbserv *gdbserv)
+{
+  gdbserv->output.buf[0] = '$';
+  gdbserv->output.len = 1;
+}
+
+void
+gdbserv_output_detach (struct gdbserv *gdbserv)
+{
+  gdbserv->output.len = 0;
+}
+
+void
+gdbserv_output_char (struct gdbserv *gdbserv, char c)
+{
+  if (gdbserv->output.len < sizeof (gdbserv->output.buf))
+    {
+      gdbserv->output.buf[gdbserv->output.len++] = c;
+    }
+}
+
+void
+gdbserv_output_string_as_bytes (struct gdbserv *gdbserv, const char *packet)
+{
+  int i;
+  for (i = 0; i < strlen (packet); i++)
+    {
+      gdbserv_output_byte (gdbserv, packet[i]);
+    }
+}
+
+void
+gdbserv_output_string (struct gdbserv *gdbserv, const char *packet)
+{
+  int i;
+  for (i = 0; i < strlen (packet); i++)
+    gdbserv_output_char (gdbserv, packet[i]);
+}
+
+void
+gdbserv_output_byte (struct gdbserv *gdbserv, int h)
+{
+  gdbserv_output_char (gdbserv, gdbserv_to_hex (h >> 4));
+  gdbserv_output_char (gdbserv, gdbserv_to_hex (h >> 0));
+}
+
+void
+gdbserv_output_nibble (struct gdbserv *gdbserv, int h)
+{
+  gdbserv_output_char (gdbserv, gdbserv_to_hex (h));
+}
+
+void
+gdbserv_output_bytes (struct gdbserv *gdbserv, const char *buf, unsigned sizeof_buf)
+{
+  int i;
+  for (i = 0; i < sizeof_buf; i++)
+    {
+      gdbserv_output_byte (gdbserv, buf[i]);
+    }
+}
+
+void
+gdbserv_output_reg_leb (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int len)
+{
+  int i;
+  if (len == 0)
+    {
+      if (reg->negative_p)
+       gdbserv_output_char (gdbserv, '-');
+      if (reg->len == 0)
+       gdbserv_output_byte (gdbserv, 0);
+      else
+       {
+         for (i = reg->len - 1 ; i >= 0; i--)
+           gdbserv_output_byte (gdbserv, reg->buf[i]);
+       }
+    }
+  else
+    {
+      /* FIXME - discard the negative sign. */
+      assert (!reg->negative_p);
+      for (i = len - 1; i >= 0; i--)
+       {
+         int byte = reg->len - len + i;
+         if (byte < 0 || byte >= reg->len)
+           gdbserv_output_byte (gdbserv, 0);
+         else
+           gdbserv_output_byte (gdbserv, reg->buf[byte]);
+       }
+    }
+}
+
+void
+gdbserv_output_reg_beb (struct gdbserv *gdbserv, struct gdbserv_reg *reg, int len)
+{
+  int i;
+  if (len == 0)
+    {
+      if (reg->negative_p)
+       gdbserv_output_char (gdbserv, '-');
+      if (reg->len == 0)
+       gdbserv_output_byte (gdbserv, 0);
+      else
+       {
+         for (i = 0; i < reg->len; i++)
+           gdbserv_output_byte (gdbserv, reg->buf[i]);
+       }
+    }
+  else
+    {
+      /* FIXME - discard the negative sign. */
+      assert (!reg->negative_p);
+      for (i = 0; i < len; i++)
+       {
+         int byte = reg->len - len + i;
+         if (byte < 0 || byte >= reg->len)
+           gdbserv_output_byte (gdbserv, 0);
+         else
+           gdbserv_output_byte (gdbserv, reg->buf[byte]);
+       }
+    }
+}
+
+void
+gdbserv_output_discard (struct gdbserv *gdbserv)
+{
+  gdbserv->output.len = 1;
+}
+
+void
+gdbserv_output_packet (struct gdbserv *gdbserv)
+{
+  /* compute / append a checksum.  Do not include that in the packet
+     size. */
+  int i;
+  int sizeof_buf;
+  unsigned long checksum = 0;
+  for (i = 1; i < gdbserv->output.len; i++)
+    {
+      checksum += gdbserv->output.buf[i];
+    }
+  sizeof_buf = gdbserv->output.len;
+  gdbserv->output.buf[sizeof_buf++] = '#';
+  gdbserv->output.buf[sizeof_buf++] = gdbserv_to_hex (checksum >> 4);
+  gdbserv->output.buf[sizeof_buf++] = gdbserv_to_hex (checksum >> 0);
+  if (gdbserv_output_log)
+    {
+      int i;
+      gdblog_string (gdbserv_output_log, "[<-");
+      gdblog_long (gdbserv_output_log, sizeof_buf);
+      gdblog_string (gdbserv_output_log, " ");
+      for (i = 0; i < sizeof_buf; i++)
+       {
+         gdblog_char (gdbserv_output_log, gdbserv->output.buf[i]);
+       }
+      gdblog_string (gdbserv_output_log, "]\n");
+    }
+  gdbserv->client->write (gdbserv, gdbserv->output.buf, sizeof_buf);
+  /* assume that it gets through */
+  /* gdbserv_output_discard (gdbserv); */
+  gdbserv_input_wait_for_ack (gdbserv);
+}
diff --git a/rda/lib/gdbserv-state.c b/rda/lib/gdbserv-state.c
new file mode 100644 (file)
index 0000000..0eec045
--- /dev/null
@@ -0,0 +1,1213 @@
+/* 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"
+
+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:
+    }
+}
+
+
+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, sizeof (reg), 0);
+         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;
+           }
+         gdbserv_output_string (gdbserv, ";");
+         if (gdbserv_input_string_match (gdbserv, ";") < 0)
+           {
+             if (gdbserv_input_size (gdbserv) > 0)
+               result = "E03";
+             break;
+           }
+       }
+      if (result != NULL)
+       {
+         gdbserv_output_discard (gdbserv);
+         gdbserv_output_string (gdbserv, result);
+       }
+    }
+}
+
+void
+gdbserv_data_packet (struct gdbserv *gdbserv)
+{
+  char packet_type = gdbserv_input_char (gdbserv);
+  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 */
+
+  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, "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)
+               gdbserv->target->get_reg (gdbserv, reg_nr, &reg);
+             else
+               memset (&reg, sizeof (reg), 0);
+             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 '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;
+}
diff --git a/rda/lib/gdbserv-state.h b/rda/lib/gdbserv-state.h
new file mode 100644 (file)
index 0000000..c10b305
--- /dev/null
@@ -0,0 +1,93 @@
+/* gdbserv-state.h
+
+   Copyright 1998, 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.  */
+
+/* GDBSERV internal data structures.  */
+
+/* Clients/targets SHOULD NOT include this file!!!! */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "gdbserv-input.h"
+#include "gdbserv-output.h"
+#include "gdbserv-client.h"
+#include "gdbserv-target.h"
+
+/* The server's current state. */
+
+enum gdbserv_state {
+  GDBSERV_STATE_UNINITIALIZED = 0,
+  GDBSERV_STATE_RESETTING,
+  GDBSERV_STATE_RUNNING,
+  GDBSERV_STATE_BROKEN,
+  GDBSERV_STATE_EXITING,
+  GDBSERV_STATE_EXITED,
+};
+
+struct gdbserv {
+
+  struct gdbserv_input input;
+  struct gdbserv_output output;
+  struct gdbserv_target *target;
+  struct gdbserv_client *client;
+
+  /* Several GDBSERV objects for a stack of targets (well,
+     technically, they right now form a cycle).  These links take you
+     closer TO and further FROM the target. */
+  struct gdbserv *to;
+  struct gdbserv *from;
+
+  enum gdbserv_state state;
+
+  /* The thread (and signal) that were supplied by the target for the
+     event that triggered the stop. */
+  struct gdbserv_thread *event_thread;
+  int event_sigval;
+
+  /* The thread for examining current state. */
+  struct gdbserv_thread *general_thread;
+
+  /* The thread to resume.  If NULL, the entire system is resumed. */
+  struct gdbserv_thread *continue_thread;
+
+  /* Selected thread for thread query. */
+  struct gdbserv_thread *query_thread;
+
+  /* argv */
+  char **program_argv;
+  unsigned long program_argc;
+  unsigned long last_arg_len;
+  unsigned long last_arg_num;
+  
+};
+
+
+/* Present an unpacked packet to the gdbserv state machine */
+void gdbserv_data_packet (struct gdbserv *gdbserv);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/lib/gdbserv-target.c b/rda/lib/gdbserv-target.c
new file mode 100644 (file)
index 0000000..a73d8a3
--- /dev/null
@@ -0,0 +1,230 @@
+/* gdbserv-target.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 "config.h"
+#include <stdio.h>
+#include <assert.h>
+#include "gdbserv-state.h"
+#include "gdbserv-utils.h"
+#include "gdbserv.h"
+
+void
+gdbserv_fromtarget (struct gdbserv *gdbserv,
+                   struct gdbserv_thread *thread,
+                   enum gdbserv_fromtarget_event event,
+                   const struct gdbserv_reg *stop_addr,
+                   int sigval)
+{
+  gdbserv->from->target->from (gdbserv->from, thread,
+                              event, stop_addr, sigval);
+}
+
+/* compatibility */
+void
+gdbserv_fromtarget_break (struct gdbserv *gdbserv,
+                         int sigval)
+{
+  gdbserv_fromtarget (gdbserv, NULL, GDBSERV_FROMTARGET_STOPPED,
+                     NULL, sigval);
+}
+
+/* compatibility */
+void
+gdbserv_fromtarget_thread_break (struct gdbserv *gdbserv,
+                                struct gdbserv_thread *thread,
+                                int sigval)
+{
+  gdbserv_fromtarget (gdbserv, thread, GDBSERV_FROMTARGET_STOPPED,
+                     NULL, sigval);
+}
+
+/* compatibility */
+void
+gdbserv_fromtarget_exit (struct gdbserv *gdbserv, int exitval)
+{
+  gdbserv_fromtarget (gdbserv, NULL, GDBSERV_FROMTARGET_EXITED,
+                     NULL, exitval);
+}
+
+/* compatibility */
+void
+gdbserv_fromtarget_terminate (struct gdbserv *gdbserv, int exitval)
+{
+  gdbserv_fromtarget (gdbserv, NULL, GDBSERV_FROMTARGET_TERMINATED,
+                     NULL, exitval);
+}
+
+/* compatibility */
+void
+gdbserv_fromtarget_restarted (struct gdbserv *gdbserv)
+{
+  gdbserv_fromtarget (gdbserv, NULL, GDBSERV_FROMTARGET_STOPPED,
+                     NULL, GDBSERV_SIGNONE);
+}
+
+/* compatibility */
+void
+gdbserv_fromtarget_reset (struct gdbserv *gdbserv)
+{
+  gdbserv_fromtarget (gdbserv, NULL, GDBSERV_FROMTARGET_STOPPED,
+                     NULL, GDBSERV_SIGNONE);
+}
+
+
+enum gdbserv_target_rc
+gdbserv_totarget (struct gdbserv *parent,
+                 struct gdbserv_thread *thread,
+                 enum gdbserv_totarget_event event,
+                 const struct gdbserv_reg *start_addr,
+                 int sigval)
+{
+  struct gdbserv_reg tmpsig;
+  struct gdbserv_reg *sig;
+  struct gdbserv *gdbserv = parent->to;
+  struct gdbserv_target *target = parent->to->target;
+  if (target->to != NULL)
+    return target->to (gdbserv, thread, event, start_addr, sigval);
+
+  /* Hand hold older targets. */
+
+  /* If there is a start_addr, then something needs to be done with
+     it.  If the target hasn't provided a full-functional ->to()
+     method then perhaphs they have provided the legacy
+     process_set_pc() */
+  if (start_addr != NULL
+      && target->process_set_pc != NULL)
+    {
+      target->process_set_pc (gdbserv, start_addr);
+      start_addr = NULL;
+    }
+
+  /* By now the target should have been told of the START_ADDR.  If it
+     hasn't then things are seriously wrong - the client is expecting
+     the target to resume at START_ADDR but it ain't going to
+     happen. */
+  assert (start_addr == NULL);
+
+  /* Flush the instruction cache.  We may have deposited a breakpoint,
+     and the icache probably has no way of knowing that a data ref to
+     some location may have changed something that is in the
+     instruction cache.  */
+  if (target->flush_i_cache != NULL)
+    target->flush_i_cache (gdbserv);
+
+  /* Try the threaded version. If there was a signal, convert it to a
+     gdbserv_reg and pass it down.  (Life would probably be easier if
+     the threaded interface took a sigval instead of the ``struct
+     gdbserv_reg''). */
+  if (sigval == 0)
+    sig = NULL;
+  else
+    {
+      gdbserv_ulong_to_reg (gdbserv, sigval, &tmpsig);
+      sig = &tmpsig;
+    }
+  switch (event) {
+    case GDBSERV_TOTARGET_SINGLESTEP:
+      if (target->singlestep_thread != NULL)
+       {
+         target->singlestep_thread (gdbserv, thread, sig);
+         return GDBSERV_TARGET_RC_OK;
+       }
+      break;
+    case GDBSERV_TOTARGET_CYCLESTEP:
+      if (target->cyclestep_thread != NULL)
+       {
+         target->cyclestep_thread (gdbserv, thread, sig);
+         return GDBSERV_TARGET_RC_OK;
+       }
+      break;
+    case GDBSERV_TOTARGET_CONTINUE:
+      if (target->continue_thread != NULL)
+       {
+         target->continue_thread (gdbserv, thread, sig);
+         return GDBSERV_TARGET_RC_OK;
+       }
+      break;
+    }
+
+  /* Non-threaded RDAs get sent the signal as a separate
+     operation. If we have a function to handle signals, call it. */
+  if (sigval != 0)
+    {
+      if (target->process_signal != NULL)
+       {
+         /* If 0 is returned, the signal was processed. */
+         if (target->process_signal (gdbserv, sigval) == 0)
+           sigval = 0;
+       }
+    }
+
+  /* If we reach here and the signal still hasn't been processed then
+     things are pretty serious.  Try killing the entire program.
+     Target's really shouldn't need a sigkill_program() method.  No
+     reason why process_signal() couldn't do it internally.  */
+  if (sigval != 0)
+    {
+      if (target->sigkill_program != NULL)
+       {
+         target->sigkill_program (gdbserv);
+         return GDBSERV_TARGET_RC_OK;
+       }
+    }
+
+  /* If we've completly failed to deliver the signal, then die.
+     Something is seriously wrong for this target. */
+  assert (sigval == 0);
+
+  /* Try resuming the entire program. */
+
+  switch (event)
+    {
+    case GDBSERV_TOTARGET_SINGLESTEP:
+      if (target->singlestep_program != NULL)
+       {
+         target->singlestep_program (gdbserv);
+         return GDBSERV_TARGET_RC_OK;
+       }
+      break;
+    case GDBSERV_TOTARGET_CYCLESTEP:
+      if (target->singlestep_program != NULL)
+       {
+         target->cyclestep_program (gdbserv);
+         return GDBSERV_TARGET_RC_OK;
+       }
+      break;
+    case GDBSERV_TOTARGET_CONTINUE:
+      if (target->continue_program != NULL)
+       {
+         target->continue_program (gdbserv);
+         return GDBSERV_TARGET_RC_OK;
+       }
+      break;
+    }
+
+  /* Oops, nothing works. */
+  return GDBSERV_TARGET_RC_UNKNOWN;
+}
+
+                        
diff --git a/rda/lib/gdbserv-utils.c b/rda/lib/gdbserv-utils.c
new file mode 100644 (file)
index 0000000..7653bf0
--- /dev/null
@@ -0,0 +1,293 @@
+/* gdbserv-utils.c
+
+   Copyright 1998, 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 "config.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "gdbserv.h"
+#include "gdbserv-utils.h"
+
+
+unsigned char
+gdbserv_to_hex (int c)
+{
+  static const unsigned char hexchars[] = "0123456789abcdef";
+  return hexchars[c & 0xf];
+}
+
+
+/* Convert ch from a hex digit to an int. */
+
+int
+gdbserv_hex_to (unsigned char ch)
+{
+  switch (ch)
+    {
+    case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+      return ch-'a'+10;
+    case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':      
+      return ch-'A'+10;
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      return ch-'0';
+    default:
+      return -1;
+    }
+}
+
+unsigned int
+gdbserv_ulong_to_hex (char *ptr, unsigned long ulong_value, int num_bits)
+{
+  int num_chars = 0;
+
+  if (ulong_value == 0)
+    {
+      *(ptr++) = '0';
+      *(ptr++) = '0';
+      return 2;
+    }
+
+  num_bits = (num_bits + 7) / 8;
+  while (num_bits)
+    {
+      int v = (ulong_value >> ((num_bits - 1) * 8));
+      if (v || (num_bits == 1))
+       {
+         v = v & 255;
+         *(ptr++) = gdbserv_to_hex ((v / 16) & 15);
+         *(ptr++) = gdbserv_to_hex (v & 15);
+         num_chars += 2;
+       }
+      num_bits--;
+    }
+
+  return (num_chars);
+}
+
+unsigned int
+gdbserv_raw_to_hex (char **ptr, char *mem, int nr_bytes)
+{
+  int i;
+  for (i = 0; i < nr_bytes; i++)
+    {
+      *(*ptr)++ = gdbserv_to_hex (*mem >> 4);
+      *(*ptr)++ = gdbserv_to_hex (*mem++);
+    }
+  return i;
+}
+
+void
+gdbserv_reg_to_ulong (struct gdbserv *gdbserv,
+                     const struct gdbserv_reg *reg,
+                     unsigned long *val)
+{
+  int i;
+  unsigned long l = 0;
+  for (i = 0; i < reg->len; i++)
+    {
+      l <<= 8;
+      l |= (unsigned char) reg->buf[i];
+    }
+  if (reg->negative_p)
+    (*val) = -l;
+  else
+    (*val) = l;
+}
+
+
+void
+gdbserv_reg_to_ulonglong (struct gdbserv *gdbserv,
+                         const struct gdbserv_reg *reg,
+                         unsigned long long *val)
+{
+  int i;
+  unsigned long long l = 0;
+  for (i = 0; i < reg->len; i++)
+    {
+      l <<= 8;
+      l |= (unsigned char) reg->buf[i];
+    }
+  if (reg->negative_p)
+    (*val) = -l;
+  else
+    (*val) = l;
+}
+
+static void
+unpack_ulongest (struct gdbserv_reg *reg,
+                unsigned long long val)
+{
+  int len;
+  int idx;
+  /* unpack */
+  len = 0;
+  do
+    {
+      reg->buf[sizeof (reg->buf) - len - 1] = val & 0xff;
+      val >>= 8;
+      len++;
+    }
+  while (val != 0);
+  /* left shift */
+  for (idx = 0; idx < len; idx++)
+    {
+      reg->buf[idx] = reg->buf[sizeof (reg->buf) - len + idx];
+    }
+  reg->len = len;
+}
+
+void
+gdbserv_ulong_to_reg (struct gdbserv *gdbserv,
+                     unsigned long val,
+                     struct gdbserv_reg *reg)
+{
+  reg->negative_p = 0;
+  unpack_ulongest (reg, val);
+}
+
+void
+gdbserv_long_to_reg (struct gdbserv *gdbserv,
+                    long val,
+                    struct gdbserv_reg *reg)
+{
+  if (val < 0)
+    {
+      reg->negative_p = 1;
+      val = -val;
+    }
+  else
+    reg->negative_p = 0;
+  unpack_ulongest (reg, val);
+}
+
+void
+gdbserv_ulonglong_to_reg (struct gdbserv *gdbserv,
+                         unsigned long long val,
+                         struct gdbserv_reg *reg)
+{
+  reg->negative_p = 0;
+  unpack_ulongest (reg, val);
+}
+
+void
+gdbserv_longlong_to_reg (struct gdbserv *gdbserv,
+                        long long val,
+                        struct gdbserv_reg *reg)
+{
+  if (val < 0)
+    {
+      reg->negative_p = 1;
+      val = -val;
+    }
+  else
+    reg->negative_p = 0;
+  unpack_ulongest (reg, val);
+}
+
+/* Copy bytes from one buffer to another in reverse order.  Used for
+   converting byte order from big endian to little endian or vice versa.  */
+
+static void
+reverse_copy_bytes (void *dest, const void *src, int len)
+{
+  char *d = dest;
+  const char *s = src;
+  int i;
+
+  for (i = 0; i < len; i++)
+    {
+      d[i] = s[len - i - 1];
+    }
+}
+
+void
+gdbserv_be_bytes_to_reg (struct gdbserv *gdbserv,
+                        const void *buf,
+                        int len,
+                        struct gdbserv_reg *reg)
+{
+  reg->negative_p = 0;
+  reg->len = len;
+  memcpy (reg->buf, buf, len);
+}
+
+void
+gdbserv_be_bytes_from_reg (struct gdbserv *gdbserv,
+                          void *buf,
+                          int *lenp,
+                           const struct gdbserv_reg *reg)
+{
+  *lenp = reg->len;
+  memcpy (buf, reg->buf, reg->len);
+}
+
+void
+gdbserv_le_bytes_to_reg (struct gdbserv *gdbserv,
+                        const void *buf,
+                        int len,
+                        struct gdbserv_reg *reg)
+{
+  reg->negative_p = 0;
+  reg->len = len;
+  reverse_copy_bytes (reg->buf, buf, len);
+}
+
+void
+gdbserv_le_bytes_from_reg (struct gdbserv *gdbserv,
+                          void *buf,
+                          int *lenp,
+                           const struct gdbserv_reg *reg)
+{
+  *lenp = reg->len;
+  reverse_copy_bytes (buf, reg->buf, reg->len);
+}
+
+void
+gdbserv_host_bytes_to_reg (struct gdbserv *gdbserv,
+                          const void *buf,
+                          int len,
+                          struct gdbserv_reg *reg)
+{
+#ifdef WORDS_BIGENDIAN
+  gdbserv_be_bytes_to_reg (gdbserv, buf, len, reg);
+#else
+  gdbserv_le_bytes_to_reg (gdbserv, buf, len, reg);
+#endif
+}
+
+void
+gdbserv_host_bytes_from_reg (struct gdbserv *gdbserv,
+                            void *buf,
+                            int *lenp,
+                             const struct gdbserv_reg *reg)
+{
+#ifdef WORDS_BIGENDIAN
+  gdbserv_be_bytes_from_reg (gdbserv, buf, lenp, reg);
+#else
+  gdbserv_le_bytes_from_reg (gdbserv, buf, lenp, reg);
+#endif
+}
diff --git a/rda/lib/gdbsocket.c b/rda/lib/gdbsocket.c
new file mode 100644 (file)
index 0000000..7cfb5b6
--- /dev/null
@@ -0,0 +1,587 @@
+/* gdbsocket.c
+
+   Copyright 1998, 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 "config.h"
+
+#include <sys/types.h>
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+#include <signal.h>
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <ctype.h>
+
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#include <sys/file.h>
+#include <fcntl.h>
+
+#include "gdbserv-client.h"
+#include "gdbsocket.h"
+#include "gdblog.h"
+
+
+/* Database of servers and their sessions. */
+
+struct session {
+  void (*close) (int readfd, int writefd);
+  int readfd;
+  int writefd;
+  struct gdbserv *gdbserv;
+  struct session *next;
+};
+
+static struct session *session_db;
+
+/* Database of servers accepting connections. */
+
+struct server {
+  int fd;
+  gdbsocket_attach_ftype *to_target_attach;
+  void *target_attach_data;
+  struct server *next;
+};
+
+static struct server *server_db;
+
+
+struct gdblog *gdbsocket_log = NULL;
+
+
+static void
+nonblocking_fd (int fd)
+{
+#if defined(F_SETFL) && (defined (O_ASYNC) || defined (O_NONBLOCK))
+  int flags = fcntl (fd, F_GETFL, 0);
+  if (gdbsocket_log)
+    {
+      gdblog_string (gdbsocket_log, "[");
+      gdblog_long (gdbsocket_log, fd);
+      gdblog_string (gdbsocket_log, ":");
+    }
+#if defined (O_NONBLOCK)
+  flags |= O_NONBLOCK;
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, " O_NONBLOCK");
+#endif
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, "]\n");
+  fcntl (fd, F_SETFL, flags);
+#endif
+}
+
+static int gdbsocket_async_p;
+
+void
+gdbsocket_async (int async_p)
+{
+  gdbsocket_async_p = 1;
+}
+
+static void
+async_fd (int fd)
+{
+  int flags;
+  if (!gdbsocket_async_p)
+    return;
+  gdblog_string (gdbsocket_log, "[");
+  gdblog_long (gdbsocket_log, fd);
+#if defined(F_SETFL) && (defined (O_ASYNC) || defined (O_NONBLOCK))
+  flags = fcntl (fd, F_GETFL, 0);
+#if defined (O_ASYNC)
+  flags |= O_ASYNC;
+  gdblog_string (gdbsocket_log, " O_ASYNC");
+#elif defined (FASYNC)
+  flags |= FASYNC;
+  gdblog_string (gdbsocket_log, " FASYNC");
+#endif
+  fcntl (fd, F_SETFL, flags);
+#endif
+#if defined (F_SETOWN)
+  /* some systems don't set the process to deliver the SIGIO to. */
+  flags = fcntl (fd, F_GETOWN, 0);
+  if (flags == 0)
+    {
+      flags = getpid ();
+      fcntl (fd, F_SETOWN, flags);
+      gdblog_string (gdbsocket_log, " [OWN ");
+      gdblog_long (gdbsocket_log, flags);
+      gdblog_string (gdbsocket_log, "]");
+    }
+#endif
+  gdblog_string (gdbsocket_log, "]\n");
+}
+
+#if 0
+static void
+sync_fd (int fd)
+{
+#if defined(F_SETFL) && (defined (O_ASYNC) || defined (O_NONBLOCK))
+  int flags = fcntl (fd, F_GETFL, 0);
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, "[%d:", fd);
+#if defined (O_ASYNC)
+  flags &= ~O_ASYNC;
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, " O_ASYNC");
+#endif
+#if defined (FASYNC)
+  flags &= ~FASYNC;
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, " FASYNC");
+#endif
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, "]\n");
+  fcntl (fd, F_SETFL, flags);
+#endif
+}
+#endif
+
+
+/* Create a GDB server socket on PORT. */
+
+int
+gdbsocket_startup (int port_nr,
+                  gdbsocket_attach_ftype *to_target_attach,
+                  void *target_attach_data)
+{
+  int on;
+  struct sockaddr_in sockaddr;
+  struct server *server;
+  int server_fd;
+
+  if (gdbsocket_log)
+    {
+      gdblog_string (gdbsocket_log, "[gdbsocket_startup port_nr=");
+      gdblog_long (gdbsocket_log, port_nr);
+    }
+
+  /* Create our socket */
+  server_fd = socket (PF_INET, SOCK_STREAM, 0);
+  if (server_fd < 0)
+    return -1;
+  if (gdbsocket_log)
+    {
+      gdblog_string (gdbsocket_log, " fd=");
+      gdblog_long (gdbsocket_log, server_fd);
+    }
+  
+  /* allow reuse */
+  on = 1;
+  setsockopt (server_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof (on));
+  on = 1;
+  setsockopt (server_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&on, sizeof (on));
+      
+  /* bind it to the requested UDP port */
+  sockaddr.sin_family = PF_INET;
+  sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);
+  sockaddr.sin_port = htons (port_nr);
+  if (bind (server_fd, (struct sockaddr *)&sockaddr, sizeof (sockaddr)) < 0)
+    {
+      int te = errno;
+      close (server_fd);
+      gdblog_string (gdbsocket_log, " BIND ERROR]\n");
+      errno = te;
+      return -1;
+    }
+
+  listen (server_fd, 1);
+
+  /* Don't let a closed pipe kill us */
+  signal (SIGPIPE, SIG_IGN);
+
+  nonblocking_fd (server_fd);
+  async_fd (server_fd);
+
+  /* Add this to the server database. */
+  server = malloc (sizeof (struct server));
+  if (!server)
+    {
+      int te = errno;
+      gdblog_string (gdbsocket_log, " MEMORY ERROR]\n");
+      close (server_fd);
+      errno = te;
+      return -1;
+    }
+  server->fd = server_fd;
+  server->to_target_attach = to_target_attach;
+  server->target_attach_data = target_attach_data;
+  server->next = server_db;
+  server_db = server;
+
+  if (gdbsocket_log)
+    {
+      gdblog_string (gdbsocket_log, "]\n");
+    }
+
+  return server_fd;
+}
+
+void
+gdbsocket_shutdown (void)
+{
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, "[gdbsocket_shutdown");
+  
+  while (session_db != NULL)
+    {
+      struct session *tbd = session_db;
+      session_db = tbd->next;
+      if (gdbsocket_log)
+       {
+         gdblog_string (gdbsocket_log, " session=");
+         gdblog_long (gdbsocket_log, tbd->readfd);
+         gdblog_string (gdbsocket_log, "/");
+         gdblog_long (gdbsocket_log, tbd->writefd);
+       }
+      tbd->close (tbd->readfd, tbd->writefd);
+      free (tbd);
+    }
+
+  while (server_db != NULL)
+    {
+      struct server *tbd = server_db;
+      server_db = tbd->next;
+      if (gdbsocket_log)
+       {
+         gdblog_string (gdbsocket_log, " server=");
+         gdblog_long (gdbsocket_log, tbd->fd);
+       }
+      close (tbd->fd);
+      free (tbd);
+    }
+
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, "]\n");
+}
+
+
+
+/* Poll the server port along with any active connections.  TIMEOUT=0
+   do not block; TIMEOUT<0 -> infinite block; TIMEOUT>0 specifies nr
+   seconds.
+
+   Returns the _NEXT_ session after this one.  If this session is
+   closed (EOF) it is unlinked.  FIXME: cagney/2000-04-24: This
+   behavour needs to be eliminated.  It makes it very hard to process
+   both input and output events. */
+
+static void
+dump_buf (const char *buf, int len)
+{
+  int i;
+  for (i = 0; i < len; i++)
+    {
+      unsigned char ch = buf[i];
+      if ((ch >= 32 && ch < 127) && isprint (ch))
+       gdblog_char (gdbsocket_log, ch & 0x7f);
+      else
+       {
+         gdblog_char (gdbsocket_log, '\\');
+         gdblog_char (gdbsocket_log, '0' + ((ch >> 6) & 0x3));
+         gdblog_char (gdbsocket_log, '0' + ((ch >> 3) & 0x7));
+         gdblog_char (gdbsocket_log, '0' + ((ch >> 0) & 0x7));
+       }
+    }
+}
+
+static struct session **
+process_read (struct session **session)
+{
+  unsigned char buf[2048];
+  int nr;
+  nr = read ((*session)->readfd, buf, sizeof buf);
+  if (nr > 0)
+    {
+      if (gdbsocket_log)
+       {
+         int i;
+         gdblog_string (gdbsocket_log, "[");
+         gdblog_long (gdbsocket_log, (*session)->readfd);
+         gdblog_string (gdbsocket_log, "->");
+         gdblog_long (gdbsocket_log, nr);
+         gdblog_string (gdbsocket_log, " ");
+         dump_buf (buf, nr);
+         gdblog_string (gdbsocket_log, " ]\n");
+       }
+      if (nr == 5 && buf[0] == 0xff && buf[1] == 0xf4
+         && buf[2] == 0xff && buf[3] == 0xfd && buf[4] == 0x06)
+       /* If a user telnets into the gdb server and then hits CNTRL-C
+           the server receives the above 5 byte character sequence.
+           Convert that sequence into a break. */
+       gdbserv_fromclient_break ((*session)->gdbserv);
+      else
+       gdbserv_fromclient_data ((*session)->gdbserv, buf, nr);
+    }
+  else if (nr == 0 || (nr < 0 && ((errno == ESHUTDOWN) || errno==ECONNRESET)))
+    {
+      struct session *tbd = (*session);
+      if (gdbsocket_log)
+       {
+         gdblog_string (gdbsocket_log, "[read ");
+         gdblog_long (gdbsocket_log, tbd->readfd);
+         gdblog_string (gdbsocket_log, " EOF]\n");
+       }
+      gdbserv_fromclient_detach ((*session)->gdbserv);
+      tbd->close (tbd->readfd, tbd->writefd);
+      (*session) = tbd->next;
+      free (tbd);
+      return session;
+    }
+  else if (nr < 0 && errno == EAGAIN)
+    {
+      if (gdbsocket_log)
+       {
+         gdblog_string (gdbsocket_log, "[read ");
+         gdblog_long (gdbsocket_log, (*session)->readfd);
+         gdblog_string (gdbsocket_log, " EAGAIN]\n");
+       }
+    }
+  return &(*session)->next;
+}
+
+
+static void
+raw_write (struct gdbserv *gdbserv,
+          const unsigned char *buf,
+          unsigned len)
+{
+  struct session *server = gdbserv_client_data (gdbserv);
+  int nr = write (server->writefd, buf, len);
+  if (nr < len)
+    {
+      printf ("OOPS!\n");
+    }
+  if (gdbsocket_log)
+    {
+      int i;
+      gdblog_string (gdbsocket_log, "[");
+      gdblog_long (gdbsocket_log, server->writefd);
+      gdblog_string (gdbsocket_log, "<-");
+      gdblog_long (gdbsocket_log, len);
+      gdblog_string (gdbsocket_log, " ");
+      dump_buf (buf, len);
+      gdblog_string (gdbsocket_log, " ]\n");
+    }
+}
+
+
+int
+gdbsocket_reopen (int fdin, int fdout,
+                 void (*close) (int fdin, int fdout),
+                 gdbsocket_attach_ftype *to_target_attach,
+                 void *target_attach_data)
+{
+  struct session **session;
+  struct gdbserv_client *client;
+  /* create/append the new session */
+  for (session = &session_db;
+       (*session) != NULL;
+       session = &(*session)->next)
+    /*NOP*/;
+  (*session) = malloc (sizeof (struct session));
+  memset ((*session), 0, sizeof (struct session));
+  /* fill it in */
+  (*session)->readfd = fdin;
+  (*session)->writefd = fdout;
+  (*session)->close = close;
+  (*session)->next = NULL;
+  client = malloc (sizeof (struct gdbserv_client));
+  client->write = raw_write;
+  client->data = (*session);
+  /* check that the target is willing to handle another accept */
+  (*session)->gdbserv = gdbserv_fromclient_attach (client,
+                                                  to_target_attach,
+                                                  target_attach_data);
+  if ((*session)->gdbserv == NULL)
+    {
+      free (client);
+      free ((*session));
+      (*session) = NULL;
+      return -1;
+    }
+  return 0;
+}
+
+
+static void
+session_close (int readfd, int writefd)
+{
+  close (readfd);
+  if (readfd != writefd)
+    close (writefd);
+}
+
+
+static void
+process_accept (struct server *server)
+{
+  struct sockaddr_in sockaddr;
+  int sizeof_sockaddr = sizeof (sockaddr);
+  int fd = accept (server->fd,
+                  (struct sockaddr*)&sockaddr,
+                  &sizeof_sockaddr);
+  if (fd >= 0)
+    {
+      if (gdbsocket_reopen (fd, fd, session_close,
+                           server->to_target_attach,
+                           server->target_attach_data)
+         < 0)
+       {
+         close (fd);
+         if (gdbsocket_log)
+           {
+             gdblog_string (gdbsocket_log, "[open ");
+             gdblog_long (gdbsocket_log, fd);
+             gdblog_string (gdbsocket_log, " - reject]\n");
+           }
+         return;
+       }
+      /* configure the socket */
+      {
+       int on = 1;
+       /* Do not delay send to coalesce packets */
+       setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (char *)&on, sizeof (on));
+       nonblocking_fd (fd);
+       async_fd (fd);
+      }
+      /* NOTE: There is a small window of oportunity between the time
+         that this process accepts the connection and the time that
+         the connection is marked as asynchronous.  During this window
+         the remote target could (and typically does!) stuff data into
+         the socket.  To avoid any problems, force a SIGIO and hence a
+         re-read. */
+      if (gdbsocket_async_p)
+       kill (getpid (), SIGIO);
+      if (gdbsocket_log)
+       {
+         gdblog_string (gdbsocket_log, "[open ");
+         gdblog_long (gdbsocket_log, fd);
+         gdblog_string (gdbsocket_log, "]\n");
+       }
+    }
+}
+
+void
+gdbsocket_fd_set (gdbsocket_fd_set_ftype *fd_set, void *context)
+{
+  struct session *session;
+  struct server *server;
+
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, "[fd_set");
+
+  /* Wait on all the clients. */
+  for (session = session_db;
+       session != NULL;
+       session = session->next)
+    {
+      if (gdbsocket_log)
+       {
+         gdblog_string (gdbsocket_log, " ");
+         gdblog_long (gdbsocket_log, session->readfd);
+         gdblog_string (gdbsocket_log, "/");
+         gdblog_long (gdbsocket_log, session->writefd);
+       }
+      fd_set (session->readfd, context, GDBSOCKET_FD_READ);
+#if 0
+      fd_set (session->writefd, context, GDBSOCKET_FD_WRITE);
+#endif
+    }
+  
+  /* wait on the server port */
+  for (server = server_db;
+       server != NULL;
+       server = server->next)
+    {
+      fd_set (server->fd, context, GDBSOCKET_FD_READ);
+      if (gdbsocket_log)
+       {
+         gdblog_string (gdbsocket_log, " ");
+         gdblog_long (gdbsocket_log, server->fd);
+       }
+    }
+
+  if (gdbsocket_log)
+    gdblog_string (gdbsocket_log, "]\n");
+}
+
+void
+gdbsocket_fd_isset (gdbsocket_fd_isset_ftype *fd_isset, void *context)
+{
+  struct session **session;
+  struct server *server;
+  /* Is there data available on an existing connection? */
+  session = &session_db;
+  while ((*session) != NULL)
+    {
+      if (fd_isset ((*session)->readfd, context, GDBSOCKET_FD_READ))
+       {
+         session = process_read (session);
+       }
+#if 0
+      /* FIXME: Before this can be enabled, process_read() needs to be
+         changed so that it is easier to detect/handle a read that
+         caused a file to be closed. */
+      if (fd_isset ((*session)->writefd, context, GDBSOCKET_FD_WRITE))
+       {
+         session = process_write (session);
+       }
+#endif
+      else
+       session = &(*session)->next;
+    }
+  
+  /* Is there a request for a new connection? */
+  for (server = server_db;
+       server != NULL;
+       server = server->next)
+    {
+      if (fd_isset (server->fd, context, GDBSOCKET_FD_READ))
+       {
+         process_accept (server);
+       }
+    }
+}
diff --git a/rda/lib/stdio-log.c b/rda/lib/stdio-log.c
new file mode 100644 (file)
index 0000000..6da4956
--- /dev/null
@@ -0,0 +1,71 @@
+/* stdio-log.c
+
+   Copyright 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 "gdblog.h"
+#include "stdio-log.h"
+
+/* Create a log that sends everything to stdio.  */
+
+static void
+do_stdio_log_string (void *context, const char *val)
+{
+  FILE *stdio = context;
+  fprintf (stdio, "%s", val);
+}
+
+static void
+do_stdio_log_long (void *context, long val)
+{
+  FILE *stdio = context;
+  fprintf (stdio, "%ld", val);
+}
+
+static void
+do_stdio_log_xlong (void *context, long val)
+{
+  FILE *stdio = context;
+  fprintf (stdio, "%lx", val);
+}
+
+static void
+do_stdio_log_char (void *context, char val)
+{
+  FILE *stdio = context;
+  fprintf (stdio, "%c", val);
+}
+
+extern struct gdblog *
+stdio_log (FILE *stdio)
+{
+  return gdblog_new (stdio,
+                    do_stdio_log_string,
+                    do_stdio_log_long,
+                    do_stdio_log_xlong,
+                    do_stdio_log_char);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/rda/qe/Makefile.am b/rda/qe/Makefile.am
new file mode 100644 (file)
index 0000000..7a8db1e
--- /dev/null
@@ -0,0 +1,28 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+WARN_CFLAGS = @WARN_CFLAGS@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+
+noinst_PROGRAMS = qe
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include
+
+qe_SOURCES = \
+       inc-gdblog.c \
+       inc-gdbloop.c \
+       inc-gdbsched.c \
+       inc-gdbserv.c \
+       inc-gdbserv-client.c \
+       inc-gdbserv-input.c \
+       inc-gdbserv-log.c \
+       inc-gdbserv-output.c \
+       inc-gdbserv-target.c \
+       inc-gdbserv-utils.c \
+       inc-gdbsocket.c \
+       inc-stdio-log.c \
+       inc-forward.c \
+       inc-backwards.c \
+       qe.c
diff --git a/rda/qe/Makefile.in b/rda/qe/Makefile.in
new file mode 100644 (file)
index 0000000..9339f26
--- /dev/null
@@ -0,0 +1,397 @@
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+GCJ = @GCJ@
+GCJFLAGS = @GCJFLAGS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+l = @l@
+targ_subdirs = @targ_subdirs@
+
+AUTOMAKE_OPTIONS = foreign
+
+WARN_CFLAGS = @WARN_CFLAGS@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+
+noinst_PROGRAMS = qe
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include
+
+qe_SOURCES = \
+       inc-gdblog.c \
+       inc-gdbloop.c \
+       inc-gdbsched.c \
+       inc-gdbserv.c \
+       inc-gdbserv-client.c \
+       inc-gdbserv-input.c \
+       inc-gdbserv-log.c \
+       inc-gdbserv-output.c \
+       inc-gdbserv-target.c \
+       inc-gdbserv-utils.c \
+       inc-gdbsocket.c \
+       inc-stdio-log.c \
+       inc-forward.c \
+       inc-backwards.c \
+       qe.c
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+noinst_PROGRAMS =  qe$(EXEEXT)
+PROGRAMS =  $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+qe_OBJECTS =  inc-gdblog.$(OBJEXT) inc-gdbloop.$(OBJEXT) \
+inc-gdbsched.$(OBJEXT) inc-gdbserv.$(OBJEXT) \
+inc-gdbserv-client.$(OBJEXT) inc-gdbserv-input.$(OBJEXT) \
+inc-gdbserv-log.$(OBJEXT) inc-gdbserv-output.$(OBJEXT) \
+inc-gdbserv-target.$(OBJEXT) inc-gdbserv-utils.$(OBJEXT) \
+inc-gdbsocket.$(OBJEXT) inc-stdio-log.$(OBJEXT) inc-forward.$(OBJEXT) \
+inc-backwards.$(OBJEXT) qe.$(OBJEXT)
+qe_LDADD = $(LDADD)
+qe_DEPENDENCIES = 
+qe_LDFLAGS = 
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  README Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES =  .deps/inc-backwards.P .deps/inc-forward.P \
+.deps/inc-gdblog.P .deps/inc-gdbloop.P .deps/inc-gdbsched.P \
+.deps/inc-gdbserv-client.P .deps/inc-gdbserv-input.P \
+.deps/inc-gdbserv-log.P .deps/inc-gdbserv-output.P \
+.deps/inc-gdbserv-target.P .deps/inc-gdbserv-utils.P \
+.deps/inc-gdbserv.P .deps/inc-gdbsocket.P .deps/inc-stdio-log.P \
+.deps/qe.P
+SOURCES = $(qe_SOURCES)
+OBJECTS = $(qe_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .obj .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign qe/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+       -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+       $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+       -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+qe$(EXEEXT): $(qe_OBJECTS) $(qe_DEPENDENCIES)
+       @rm -f qe$(EXEEXT)
+       $(LINK) $(qe_LDFLAGS) $(qe_OBJECTS) $(qe_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = qe
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign qe/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-noinstPROGRAMS mostlyclean-compile \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+               mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-noinstPROGRAMS clean-compile clean-libtool clean-tags \
+               clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-noinstPROGRAMS distclean-compile \
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-noinstPROGRAMS \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/rda/qe/README b/rda/qe/README
new file mode 100644 (file)
index 0000000..cfa6010
--- /dev/null
@@ -0,0 +1,5 @@
+This directory contains simple Quality Engineering tests for RDA, the
+Red Hat Debug Agent and library.
+
+       inc-* check that the headers can be included independently.
+
diff --git a/rda/qe/inc-backwards.c b/rda/qe/inc-backwards.c
new file mode 100644 (file)
index 0000000..92435d2
--- /dev/null
@@ -0,0 +1,33 @@
+/* inc-backwards.c
+
+   Copyright 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 "gdbsocket.h"
+#include "gdbserv.h"
+#include "gdbserv-utils.h"
+#include "gdbserv-target.h"
+#include "gdbserv-output.h"
+#include "gdbserv-log.h"
+#include "gdbserv-input.h"
+#include "gdbserv-client.h"
+#include "gdblog.h"
diff --git a/rda/qe/inc-forward.c b/rda/qe/inc-forward.c
new file mode 100644 (file)
index 0000000..b3bc676
--- /dev/null
@@ -0,0 +1,33 @@
+/* inc-forward.c
+
+   Copyright 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 "gdblog.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"
diff --git a/rda/qe/inc-gdblog.c b/rda/qe/inc-gdblog.c
new file mode 100644 (file)
index 0000000..3e4dac2
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdblog.c
+
+   Copyright 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 "gdblog.h"
diff --git a/rda/qe/inc-gdbloop.c b/rda/qe/inc-gdbloop.c
new file mode 100644 (file)
index 0000000..df74aaf
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbloop.c
+
+   Copyright 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 "gdbloop.h"
diff --git a/rda/qe/inc-gdbsched.c b/rda/qe/inc-gdbsched.c
new file mode 100644 (file)
index 0000000..bd56307
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbsched.c
+
+   Copyright 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 "gdbsched.h"
diff --git a/rda/qe/inc-gdbserv-client.c b/rda/qe/inc-gdbserv-client.c
new file mode 100644 (file)
index 0000000..deca3fe
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbserv-client.c
+
+   Copyright 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 "gdbserv-client.h"
diff --git a/rda/qe/inc-gdbserv-input.c b/rda/qe/inc-gdbserv-input.c
new file mode 100644 (file)
index 0000000..a3418d8
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbserv-input.c
+
+   Copyright 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 "gdbserv-input.h"
diff --git a/rda/qe/inc-gdbserv-log.c b/rda/qe/inc-gdbserv-log.c
new file mode 100644 (file)
index 0000000..3330940
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbserv-log.c
+
+   Copyright 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 "gdbserv-log.h"
diff --git a/rda/qe/inc-gdbserv-output.c b/rda/qe/inc-gdbserv-output.c
new file mode 100644 (file)
index 0000000..a70b900
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbserv-output.c
+
+   Copyright 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 "gdbserv-output.h"
diff --git a/rda/qe/inc-gdbserv-target.c b/rda/qe/inc-gdbserv-target.c
new file mode 100644 (file)
index 0000000..a076335
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbserv-target.c
+
+   Copyright 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 "gdbserv-target.h"
diff --git a/rda/qe/inc-gdbserv-utils.c b/rda/qe/inc-gdbserv-utils.c
new file mode 100644 (file)
index 0000000..f5008e2
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbserv-utils.c
+
+   Copyright 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 "gdbserv-utils.h"
diff --git a/rda/qe/inc-gdbserv.c b/rda/qe/inc-gdbserv.c
new file mode 100644 (file)
index 0000000..47c2279
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbserv.c
+
+   Copyright 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 "gdbserv.h"
diff --git a/rda/qe/inc-gdbsocket.c b/rda/qe/inc-gdbsocket.c
new file mode 100644 (file)
index 0000000..6822f0f
--- /dev/null
@@ -0,0 +1,25 @@
+/* inc-gdbsocket.c
+
+   Copyright 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 "gdbsocket.h"
diff --git a/rda/qe/inc-stdio-log.c b/rda/qe/inc-stdio-log.c
new file mode 100644 (file)
index 0000000..cc36fef
--- /dev/null
@@ -0,0 +1,26 @@
+/* inc-stdio-log.c
+
+   Copyright 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 "stdio-log.h"
diff --git a/rda/qe/qe.c b/rda/qe/qe.c
new file mode 100644 (file)
index 0000000..8962f66
--- /dev/null
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int
+main(int argc, char **argv, char **envp)
+{
+  printf ("Hello World!");
+  return 0;
+}
diff --git a/rda/samples/Makefile.am b/rda/samples/Makefile.am
new file mode 100644 (file)
index 0000000..e474d9f
--- /dev/null
@@ -0,0 +1,25 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+WARN_CFLAGS = @WARN_CFLAGS@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+
+noinst_PROGRAMS = sample async poll thread
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include
+
+sample_SOURCES = main.c demo-target.c
+sample_DEPLIBS = ../lib/librda.la 
+sample_LDADD = $(sample_DEPLIBS) $(INTLLIBS)
+sample_DEPENDENCIES = $(sample_DEPLIBS) $(INTLDEPS)
+
+async_SOURCES = async.c demo-target.c
+async_LDADD = ../lib/librda.la
+
+poll_SOURCES = poll.c demo-target.c
+poll_LDADD = ../lib/librda.la
+
+thread_SOURCES = thread.c demo-target.c
+thread_LDADD = ../lib/librda.la
diff --git a/rda/samples/Makefile.in b/rda/samples/Makefile.in
new file mode 100644 (file)
index 0000000..5e57da8
--- /dev/null
@@ -0,0 +1,402 @@
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+DATADIRNAME = @DATADIRNAME@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+GCJ = @GCJ@
+GCJFLAGS = @GCJFLAGS@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+l = @l@
+targ_subdirs = @targ_subdirs@
+
+AUTOMAKE_OPTIONS = foreign
+
+WARN_CFLAGS = @WARN_CFLAGS@
+WERROR_CFLAGS = @WERROR_CFLAGS@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
+
+noinst_PROGRAMS = sample async poll thread
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include
+
+sample_SOURCES = main.c demo-target.c
+sample_DEPLIBS = ../lib/librda.la 
+sample_LDADD = $(sample_DEPLIBS) $(INTLLIBS)
+sample_DEPENDENCIES = $(sample_DEPLIBS) $(INTLDEPS)
+
+async_SOURCES = async.c demo-target.c
+async_LDADD = ../lib/librda.la
+
+poll_SOURCES = poll.c demo-target.c
+poll_LDADD = ../lib/librda.la
+
+thread_SOURCES = thread.c demo-target.c
+thread_LDADD = ../lib/librda.la
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES = 
+noinst_PROGRAMS =  sample$(EXEEXT) async$(EXEEXT) poll$(EXEEXT) \
+thread$(EXEEXT)
+PROGRAMS =  $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+sample_OBJECTS =  main.$(OBJEXT) demo-target.$(OBJEXT)
+sample_LDFLAGS = 
+async_OBJECTS =  async.$(OBJEXT) demo-target.$(OBJEXT)
+async_DEPENDENCIES =  ../lib/librda.la
+async_LDFLAGS = 
+poll_OBJECTS =  poll.$(OBJEXT) demo-target.$(OBJEXT)
+poll_DEPENDENCIES =  ../lib/librda.la
+poll_LDFLAGS = 
+thread_OBJECTS =  thread.$(OBJEXT) demo-target.$(OBJEXT)
+thread_DEPENDENCIES =  ../lib/librda.la
+thread_LDFLAGS = 
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES =  .deps/async.P .deps/demo-target.P .deps/main.P .deps/poll.P \
+.deps/thread.P
+SOURCES = $(sample_SOURCES) $(async_SOURCES) $(poll_SOURCES) $(thread_SOURCES)
+OBJECTS = $(sample_OBJECTS) $(async_OBJECTS) $(poll_OBJECTS) $(thread_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .obj .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign samples/Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+       -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+       $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+       -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+sample$(EXEEXT): $(sample_OBJECTS) $(sample_DEPENDENCIES)
+       @rm -f sample$(EXEEXT)
+       $(LINK) $(sample_LDFLAGS) $(sample_OBJECTS) $(sample_LDADD) $(LIBS)
+
+async$(EXEEXT): $(async_OBJECTS) $(async_DEPENDENCIES)
+       @rm -f async$(EXEEXT)
+       $(LINK) $(async_LDFLAGS) $(async_OBJECTS) $(async_LDADD) $(LIBS)
+
+poll$(EXEEXT): $(poll_OBJECTS) $(poll_DEPENDENCIES)
+       @rm -f poll$(EXEEXT)
+       $(LINK) $(poll_LDFLAGS) $(poll_OBJECTS) $(poll_LDADD) $(LIBS)
+
+thread$(EXEEXT): $(thread_OBJECTS) $(thread_DEPENDENCIES)
+       @rm -f thread$(EXEEXT)
+       $(LINK) $(thread_LDFLAGS) $(thread_OBJECTS) $(thread_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags  $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = samples
+
+distdir: $(DISTFILES)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(top_distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign samples/Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-noinstPROGRAMS mostlyclean-compile \
+               mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+               mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-noinstPROGRAMS clean-compile clean-libtool clean-tags \
+               clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-noinstPROGRAMS distclean-compile \
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am:  maintainer-clean-noinstPROGRAMS \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/rda/samples/async.c b/rda/samples/async.c
new file mode 100644 (file)
index 0000000..0f5475d
--- /dev/null
@@ -0,0 +1,136 @@
+/* async.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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>            /* for strsignal() on windows. */
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+#include <signal.h>
+#include <unistd.h>
+
+#include "gdbsocket.h"
+#include "demo-target.h"
+#include "stdio-log.h"
+#include "gdbserv-log.h"
+#include "gdbloop.h"
+#include "gdblog.h"
+#include "gdbsched.h"
+
+/* This is a sample main program that demonstrates use of the RDA library
+   routines running in async / non-stop / sigio mode.  It acts to gdb
+   like a strange generic remote target. */
+
+static volatile int poll_p;
+
+static void
+set_poll_p (int sig)
+{
+  poll_p = 1;
+  gdblog_string (gdbsocket_log, "[");
+  gdblog_string (gdbsocket_log, strsignal (sig));
+  gdblog_string (gdbsocket_log, "]\n");
+  signal (sig, set_poll_p);
+}
+
+int
+main (int argc, char* argv[])
+{
+  int portno;
+  if (argc > 1)
+    portno = atoi(argv[1]);
+  else
+    portno = 2345;
+
+  /* Enable tracing */
+  gdbsocket_log = stdio_log (stderr);
+  gdbserv_warning_log = stdio_log (stderr);
+  /* Whenever an event arrives, call the corresponding handler, that
+     in turn will set the poll flag. */
+  poll_p = 0;
+  signal (SIGIO, set_poll_p);
+  signal (SIGALRM, set_poll_p);
+
+  /* Tell the gdbsocket code that all sockets should be created with
+     O_ASYNC set.  Such sockets will SIGIO whenever there is input
+     available.  Then start the server. */
+  gdbsocket_async (1);
+  gdbsocket_startup (portno, demo_attach, NULL);
+  printf ("Started listening socket on port %d.\n", portno);
+
+  /* Poll for socket traffic. */
+  while (! demo_quit_p)
+    {
+      if (poll_p)
+       {
+         long current_time;
+         long sched_time;
+         long new_timeout;
+         long old_timeout;
+
+         /* Clear the polling flag. Do it first to avoid any problems
+            with race conditions.  If the event-loop is ever modified
+            to handle more complex events then the logic needed to
+            clear this flag will also need to be made correspondingly
+            more complex. */
+         poll_p = 0;
+
+         /* Clear any backlog of events. */
+         current_time = time (NULL);
+         gdbloop (current_time, 0);
+
+         /* Schedule a sig alarm to take care of any new events.  Use
+             a more up-to-date current time. */
+         current_time = time (NULL);
+         sched_time = gdbsched_dispatch (current_time);
+         assert (sched_time > current_time || sched_time < 0);
+         if (sched_time > current_time)
+           new_timeout = sched_time - current_time;
+         else
+           new_timeout = 0;
+         gdblog_string (gdbsocket_log, "[alarm ");
+         gdblog_long (gdbsocket_log, new_timeout);
+         old_timeout = alarm (new_timeout);
+         gdblog_string (gdbsocket_log, " -> ");
+         gdblog_long (gdbsocket_log, old_timeout);
+         gdblog_string (gdbsocket_log, "]\n");
+       }
+
+    }
+
+  gdbsocket_shutdown ();
+  printf ("Shut down sockets.\n");
+
+  return 0;
+}
diff --git a/rda/samples/demo-target.c b/rda/samples/demo-target.c
new file mode 100644 (file)
index 0000000..6b98ed3
--- /dev/null
@@ -0,0 +1,443 @@
+/* demo-target.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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#include "gdbserv.h" 
+#include "gdbserv-target.h" 
+#include "gdbserv-utils.h"
+
+#include "demo-target.h"
+#include "gdbsched.h"
+
+/* This is a sample gdbserv target that demonstrates use of the RDA library
+   routines.  It acts to gdb like a strange generic remote target. */
+
+ /* process_get_gen */
+ /* process_set_gen */
+static void demo_process_rcmd (struct gdbserv* serv, const char* cmd, int sizeof_cmd);
+ /* process_set_args */
+ /* process_set_reg */
+static int  demo_process_set_regs (struct gdbserv *serv);
+static void demo_process_get_regs (struct gdbserv* serv);
+ /* input_reg */
+ /* output_reg */
+ /* gg_reg_nr */
+ /* expedited_reg_nr */
+ /* sizeof_reg */
+ /* set_reg */
+ /* get_reg */
+static long demo_get_mem (struct gdbserv* serv, struct gdbserv_reg* addr, void* data, long len);
+static long demo_set_thread_mem (struct gdbserv *serv,
+                                struct gdbserv_thread *thread,
+                                struct gdbserv_reg *addr,
+                                void *data, long len);
+static void demo_process_set_pc (struct gdbserv *gdbserv,
+                                const struct gdbserv_reg *pc);
+ /* process_signal */
+static void demo_flush_i_cache (struct gdbserv* serv);
+static unsigned long demo_compute_signal (struct gdbserv* serv, unsigned long);
+static unsigned long demo_get_trap_number (struct gdbserv* serv);
+static void demo_exit_program (struct gdbserv* serv);
+static void demo_break_program (struct gdbserv* serv);
+static int demo_reset_program (struct gdbserv* serv);
+static void demo_restart_program (struct gdbserv* serv);
+static void demo_singlestep_program (struct gdbserv* serv);
+static void demo_cyclestep_program (struct gdbserv* serv);
+static void demo_sigkill_program (struct gdbserv* serv);
+static void demo_continue_thread (struct gdbserv *serv,
+                                 struct gdbserv_thread *thread,
+                                 const struct gdbserv_reg *sigval);
+ /* remove_breakpoint */
+ /* set_breakpoint */
+ /* process_target */
+static void demo_detach (struct gdbserv* serv, struct gdbserv_target* target);
+
+
+
+
+
+/* Signal a request to terminate main loop. */
+int demo_quit_p = 0;
+
+/* Simple minded event handler to dispatch break events after an
+   arbitrary time. */
+
+static void
+dispatch_break (struct gdbserv *gdbserv,
+               struct gdbserv_thread *thread,
+               void *context)
+{
+  /* THREAD is probably NULL.  Since we don't know what thread we
+     "stopped" in, we'll let the RDA library figure it out. */
+  gdbserv_fromtarget_thread_break (gdbserv, thread, GDBSERV_SIGTRAP);
+}
+
+static void
+sched_break (struct gdbserv *serv, long timeout)
+{
+  static struct gdbsched *break_event = NULL;
+  long sched_time;
+  assert (timeout >= 0);
+  /* Re-schedule the event being careful to not zap the ``NULL''
+     event. */
+  if (break_event != NULL)
+    gdbsched_deschedule (break_event, NULL, NULL, NULL, NULL, NULL);
+  /* If the timeout is ZERO don't use time() to compute the time that
+     the event should be scheduled.  Instead, force it to NOW.  There
+     could easily be a skew between the time() call below and the
+     event loops current time.  That in turn can cause ``NOW'' to be
+     scheduled in a second or more.... */
+  if (timeout == 0)
+    sched_time = 0;
+  else
+    sched_time = time (NULL) + timeout;
+  break_event = gdbsched_schedule (sched_time, dispatch_break,
+                                  serv, NULL, NULL);
+}
+
+
+/* Track sole connection to a remote gdb client. */
+static struct gdbserv* sole_connection = NULL;
+
+struct gdbserv_target *
+demo_target (struct gdbserv *serv, void *context)
+{
+  struct gdbserv_target *target;
+
+  if (sole_connection != NULL)
+    {
+      fprintf (stderr, "Rejected duplicate connection.\n");
+      return NULL;
+    }
+
+  fprintf (stderr, "Accepted gdb connection.\n");
+  sole_connection = serv;
+
+  target = malloc (sizeof (struct gdbserv_target));
+  memset (target, sizeof (*target), 0);
+
+  /* Callback structure for function pointers that handle processed
+     control packets.  See gdbserv-target.h for docs on the individual
+     functions. */
+
+  target->process_get_gen = NULL;
+  target->process_set_gen = NULL;
+  target->process_rcmd = demo_process_rcmd;
+  target->process_set_args = NULL;
+  target->process_set_reg = NULL;
+  target->process_get_reg = NULL;
+  target->process_set_regs = demo_process_set_regs /* <deprecated?> */;
+  target->process_get_regs = demo_process_get_regs /* (deprecated) */;
+  target->input_reg = NULL;
+  target->output_reg = NULL;
+  target->gg_reg_nr = NULL;
+  target->expedited_reg_nr = NULL;
+  target->sizeof_reg = NULL;
+  target->set_reg = NULL;
+  target->get_reg = NULL;
+  target->get_mem = demo_get_mem;
+  target->set_thread_mem = demo_set_thread_mem;
+  target->process_set_pc = demo_process_set_pc;
+  target->flush_i_cache = demo_flush_i_cache;
+  target->process_signal = NULL;
+  target->compute_signal = demo_compute_signal;
+  target->get_trap_number = demo_get_trap_number;
+  target->exit_program = demo_exit_program;
+  target->break_program = demo_break_program;
+  target->reset_program = demo_reset_program;
+  target->restart_program = demo_restart_program;
+  target->singlestep_program = demo_singlestep_program;
+  target->cyclestep_program = demo_cyclestep_program;
+  target->sigkill_program = demo_sigkill_program;
+  target->continue_thread = demo_continue_thread;
+  target->remove_breakpoint = NULL;
+  target->set_breakpoint = NULL;
+  target->process_target_packet = NULL;
+  target->detach = demo_detach;
+
+  /* DATA can be assigned any value.  That value is accessible via
+     gdbserv_target_data().  This example just happens to use
+     CONTEXT. */
+  target->data = context;
+
+  return target;
+}
+
+/* This function is called from gdbloop_poll when a new incoming
+   connection is attempted.  It may return NULL if the new connection
+   is to be refused, or a gdbserv_target vector if the connection is
+   accepted.  The helper function do_fromtarget_ready() is to notify
+   the server that the target has finished initializing and is ready
+   to talk to GDB.  */
+
+static void
+do_fromtarget_ready (struct gdbserv *gdbserv,
+                    struct gdbserv_thread *ignore2,
+                    void *ignore3)
+{
+  gdbserv_fromtarget (gdbserv, NULL, GDBSERV_FROMTARGET_STOPPED, NULL, 0);
+}
+
+struct gdbserv_target * 
+demo_attach (struct gdbserv *serv, void *context)
+{
+  struct gdbserv_target *target = demo_target (serv, context);
+  if (target == NULL)
+    return NULL;
+  /* Take the target out of reset. */
+  gdbsched_schedule (0, do_fromtarget_ready, serv, NULL, NULL);
+  return target;
+}
+
+
+void
+demo_detach (struct gdbserv* serv, struct gdbserv_target* target)
+{
+  assert (serv == sole_connection);
+
+  fprintf (stderr, "Detached.\n");
+  sole_connection = NULL;
+
+  /* Quit out of main loop for this demo.  In general, this is not necessary, as the
+     next incoming connection could again be handled by demo_attach() above. */
+  demo_quit_p = 1;
+}
+
+
+
+unsigned long
+demo_get_trap_number (struct gdbserv* serv)
+{
+  /* Return a target-dependent trap number. */
+  return 0;
+}
+
+
+unsigned long
+demo_compute_signal (struct gdbserv* serv, unsigned long tgtsig)
+{
+  assert (tgtsig == 0); /* comes from get_trap_number above */
+  /* Return standard signal number */
+  return GDBSERV_SIGTRAP;
+}
+
+
+void
+demo_process_rcmd (struct gdbserv* serv, const char* cmd, int sizeof_cmd)
+{
+  gdbserv_output_bytes (serv, cmd, sizeof_cmd);
+}
+
+
+/*
+ * Get/Set Registers
+ * 
+ * (including a primitive register cache) 
+ */
+
+static struct target_regs {    /* register cache */
+  unsigned int len;
+  char buf[180];
+} target_regs;
+
+static void 
+demo_process_get_regs (struct gdbserv* serv)
+{
+  int i;
+
+  for (i=0; i<180; i++) /* 180 bytes < gdb's PBUFSIZ/2 */
+    gdbserv_output_byte (serv, target_regs.buf[i]);
+}
+
+static int 
+demo_process_set_regs (struct gdbserv *serv)
+{
+  gdbserv_input_bytes (serv, &target_regs.buf[0], sizeof (target_regs.buf));
+  return 0;
+}
+
+void
+demo_exit_program (struct gdbserv* serv)
+{
+  gdbserv_fromtarget_exit (serv, GDBSERV_SIGQUIT);
+}
+
+void
+demo_break_program (struct gdbserv* serv)
+{
+  fprintf (stderr, "<BREAK>\n");
+  /* Enqueue a break response NOW */
+  sched_break (serv, 0);
+}
+
+int
+demo_reset_program (struct gdbserv* serv)
+{
+  gdbserv_fromtarget_reset (serv);
+  return 0;
+}
+
+void
+demo_restart_program (struct gdbserv* serv)
+{
+  sched_break (serv, 1);
+}
+
+
+void
+demo_singlestep_program (struct gdbserv* serv)
+{
+  sched_break (serv, 2);
+}
+
+void
+demo_cyclestep_program (struct gdbserv* serv)
+{
+  sched_break (serv, 1);
+}
+
+void
+demo_sigkill_program (struct gdbserv* serv)
+{
+  gdbserv_fromtarget_exit (serv, GDBSERV_SIGKILL);
+}
+
+void
+demo_continue_thread (struct gdbserv *serv,
+                     struct gdbserv_thread *thread,
+                     const struct gdbserv_reg *sigval)
+{
+  fprintf (stderr, "Resumed fictional target program - send break from gdb or wait a while.\n");
+  /* Enqueue a break response */
+  sched_break (serv, 10);
+}
+
+
+
+/*
+ * Get/Set memory
+ *
+ * (including a primitive memory cache)
+ */
+
+static struct target_mem {     /* memory cache */
+  unsigned long base;
+  unsigned long len;
+  unsigned char *buf;
+} target_mem;
+
+static long
+demo_get_mem (struct gdbserv* serv, 
+             struct gdbserv_reg* addr, 
+             void* data, 
+             long len)
+{
+  long n;
+  unsigned char *d = data;
+  unsigned long request_base;
+
+  gdbserv_reg_to_ulong (serv, addr, &request_base);
+
+  for (n=0; n<len; n++)
+    {
+      if (request_base + n >= target_mem.base &&
+         request_base + n <  target_mem.base + target_mem.len)
+       *d++ = target_mem.buf[request_base + n - target_mem.base];
+      else
+       *d++ = 0;
+    }
+
+  return n;
+}
+
+
+static long
+demo_set_thread_mem (struct gdbserv *serv, 
+                    struct gdbserv_thread *thread,
+                    struct gdbserv_reg *addr, 
+                    void *data, 
+                    long len)
+{
+  unsigned long request_base;
+
+  gdbserv_reg_to_ulong (serv, addr, &request_base);
+  if (target_mem.len == 0)
+    {
+      target_mem.buf  = malloc (len);
+      target_mem.len  = len;
+      gdbserv_reg_to_ulong (serv, addr, &target_mem.base);
+    }
+  else
+    {
+      if (request_base < target_mem.base)
+       {
+         target_mem.len += target_mem.base - request_base;
+         target_mem.base = request_base;
+         target_mem.buf  = realloc (target_mem.buf, target_mem.len);
+       }
+      if (request_base + len > 
+         target_mem.base + target_mem.len)
+       {
+         target_mem.len += 
+           (request_base + len) - (target_mem.base + target_mem.len);
+         target_mem.buf  = realloc (target_mem.buf, target_mem.len);
+       }
+    }
+
+  if (target_mem.buf == NULL)
+    return 0;
+
+  memcpy (target_mem.buf + (request_base - target_mem.base), 
+         data, 
+         len);
+  return  len;
+}
+
+
+void
+demo_process_set_pc (struct gdbserv *gdbserv, const struct gdbserv_reg *pc)
+{
+  unsigned long addr;
+  gdbserv_reg_to_ulong (gdbserv, pc, &addr);
+  fprintf (stderr, "demo target pc set to 0x%lx\n", addr);
+}
+
+
+void
+demo_flush_i_cache (struct gdbserv* serv)
+{
+}
diff --git a/rda/samples/demo-target.h b/rda/samples/demo-target.h
new file mode 100644 (file)
index 0000000..be0d7d0
--- /dev/null
@@ -0,0 +1,46 @@
+/* demo-target.c
+
+   Copyright 2000, 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.  */
+
+#ifndef DEMO_TARGET_H
+#define DEMO_TARGET_H
+
+struct gdbserv;
+
+/* Signal a request to terminate main loop. */
+extern int demo_quit_p;
+
+/* Create a demo target vector.  Used by demo_attach but can also be
+   used by other demo targets that just need to tweek the target
+   interface. */
+
+struct gdbserv_target *demo_target (struct gdbserv *gdbserv, void *data);
+
+/* This function is called from gdbloop_poll when a new incoming
+   connection is attempted.  It may return NULL if the new connection
+   is to be refused, or a gdbserv_target vector if the connection is
+   accepted. */
+
+struct gdbserv_target *demo_attach (struct gdbserv* serv, void* data);
+
+#endif
diff --git a/rda/samples/main.c b/rda/samples/main.c
new file mode 100644 (file)
index 0000000..9401486
--- /dev/null
@@ -0,0 +1,181 @@
+/* main.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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <ctype.h>
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#include "gdbsocket.h"
+#include "demo-target.h"
+#include "stdio-log.h"
+#include "gdbserv-log.h"
+#include "gdbloop.h"
+#include "gdbsched.h"
+#include "gdbserv-target.h"
+
+#include <signal.h>
+
+struct gdbserv_thread;
+
+/* This is a sample main program that demonstrates use of the RDA library
+   routines.  It acts to gdb like a strange generic remote target.  */
+
+void
+do_close (int readfd, int writefd)
+{
+  /* Ignore it for moment. */
+}
+
+void
+fake_exit (struct gdbserv *gdbserv,
+          struct gdbserv_thread *thread,
+          void *context)
+{
+  fprintf (stderr, "Target exiting\n");
+  gdbserv_fromtarget_exit (gdbserv, GDBSERV_SIGQUIT);
+}
+
+void
+usage (void)
+{
+  fprintf (stderr,
+          "Usage: sample [-d] [-|<port>]\n"
+          "Where:\n"
+          "\t-d\tDaemon mode\n"
+          "\t-v\tVerbose/trace\n"
+          "\t-\tUse stdin/stdout\n"
+          "\t<port>\tSocket number\n"
+          );
+}
+
+
+int
+main (int argc, char* argv[])
+{
+  void (*shutdown) (void);
+  int i;
+  int daemon_p;
+  char *port;
+
+  /* Enable tracing */
+  gdbserv_warning_log = stdio_log (stderr);
+  /* This is a workaround for
+     //https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=53191
+
+     SuS says that an action of SIG_IGN for SIGCHLD means that the
+     kernel can automatically reap dead child processes. So when
+     ignoring the SIGCHLD from the traced (and still alive) process,
+     the kernel goes ahead and calls wait4 on behalf of the parent and
+     discards the information which strace requires.
+     
+     This breaks strace and gdbserver, and may break anything else
+     which uses ptrace. gdb is safe because it installs its own
+     SIGCHLD handler.
+     
+     strace can work around this by setting the SIGCHLD action to
+     SIG_DFL. */
+  signal (SIGCHLD, SIG_DFL);
+  /* options? */
+  daemon_p = 0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], "-d") == 0)
+       daemon_p = 1;
+      else if (strcmp (argv[i], "-v") == 0)
+       gdbsocket_log = stdio_log (stderr);
+      else if (strcmp (argv[i], "-?") == 0
+              || strcmp (argv[i], "-h") == 0)
+       {
+         usage ();
+         return 0;
+       }
+      else
+       break;
+    }
+
+  /* Parameter? */
+  if (i >= argc)
+    port = "2345";
+  else
+    port = argv[i];
+
+  shutdown = NULL;
+  if (strcmp (port, "-") == 0)
+    {
+      /* ``-'': use stdin/stdout. */
+      gdbsocket_reopen (STDIN_FILENO, STDOUT_FILENO,
+                       do_close, demo_attach, NULL);
+      fprintf (stderr, "Server started, using stdin/stdout.\n");
+      /* FIXME: thinko: CNTRL-C on stdin gets converted into a signal.
+        Ignore the signal for moment.  Should be doing something like
+        putting the input and output TTY's into raw mode. */
+      signal (SIGINT, SIG_IGN);
+      shutdown = gdbsocket_shutdown;
+    }
+  else if (isdigit (port[0]))
+    {
+      /* ``[0-9]*'': use the specified port. */
+      char *end = port;
+      int portno = strtol (port, &end, 0);
+      if (end[0] == '\0')
+       {
+         gdbsocket_startup (portno, demo_attach, NULL);
+         fprintf (stderr, "Server started, listening on port %d.\n", portno);
+         shutdown = gdbsocket_shutdown;
+       }
+    }
+  if (shutdown == NULL)
+    {
+      usage ();
+      return 1;
+    }
+  if (daemon_p)
+    fprintf (stderr, "Daemon mode\n");
+
+  /* Keep the server alive. */
+  while (!demo_quit_p || daemon_p)
+    {
+      gdbloop_poll (-1);
+    }
+
+  shutdown ();
+  printf ("Server shutdown.\n");
+
+  return 0;
+}
diff --git a/rda/samples/poll.c b/rda/samples/poll.c
new file mode 100644 (file)
index 0000000..c677556
--- /dev/null
@@ -0,0 +1,174 @@
+/* poll.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 "config.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#if TIME_WITH_SYS_TIME
+#include <sys/time.h>
+#include <time.h>
+#elif HAVE_SYS_TIME_H
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#include <sys/types.h>
+#include <poll.h>
+
+#include "gdbsocket.h"
+#include "gdblog.h"
+#include "stdio-log.h"
+#include "gdbserv-log.h"
+#include "gdbsched.h"
+
+#include "demo-target.h"
+
+/* This is a sample main program that demonstrates use of the RDA
+   library routines using UNIX poll.  It acts to gdb like a strange
+   generic remote target.  */
+
+struct pollfds {
+  struct pollfd *fds;
+  int nfds;
+};
+
+static void
+set (int fd, void *context, enum gdbsocket_fd_event event)
+{
+  struct pollfds *pollfds = context;
+  struct pollfd *pollfd;
+  for (pollfd = pollfds->fds; pollfd < pollfds->fds + pollfds->nfds; pollfd++)
+    {
+      if (pollfd->fd == fd)
+       break;
+    }
+  if (pollfd == pollfds->fds + pollfds->nfds)
+    {
+      pollfds->nfds++;
+      /* Be slack.  Let realloc handle need to srink/grow allocated
+         pollfds. */
+      pollfds->fds = realloc (pollfds->fds,
+                             pollfds->nfds * sizeof (struct pollfd));
+      pollfd = &pollfds->fds[pollfds->nfds - 1];
+      pollfd->fd = fd;
+      pollfd->events = 0;
+      pollfd->revents = 0;
+    }
+  switch (event)
+    {
+    case GDBSOCKET_FD_READ:
+      pollfd->events |= POLLIN;
+      break;
+    case GDBSOCKET_FD_WRITE:
+      pollfd->events |= POLLOUT;
+      break;
+    }
+}
+
+static int
+isset (int fd, void *context, enum gdbsocket_fd_event event)
+{
+  struct pollfds *pollfds = context;
+  struct pollfd *pollfd;
+  for (pollfd = pollfds->fds; pollfd < pollfds->fds + pollfds->nfds; pollfd++)
+    {
+      if (pollfd->fd == fd)
+       {
+         switch (event)
+           {
+           case GDBSOCKET_FD_READ:
+             return (pollfd->revents & POLLIN);
+             break;
+           case GDBSOCKET_FD_WRITE:
+             return (pollfd->revents & POLLOUT);
+             break;
+           }
+       }
+    }
+  return 0;
+}
+
+int
+main (int argc, char* argv[])
+{
+  int portno;
+  struct pollfds pollfds;
+  memset (&pollfds, 0, sizeof (pollfds));
+  if (argc > 1)
+    portno = atoi(argv[1]);
+  else
+    portno = 2345;
+
+  /* Enable socket tracing */
+  gdbsocket_log = stdio_log (stderr);
+  gdbserv_warning_log = stdio_log (stderr);
+  gdbsocket_startup (portno, demo_attach, NULL);
+  printf ("Started listening socket on port %d.\n", portno);
+
+  /* Poll for socket traffic. */
+  while (! demo_quit_p)
+    {
+      int s;
+      int seconds = 1;
+  
+      /* Process any outstanding events. NOTE: The code should be
+         using the value returned to determine the length of the
+         poll() but the below is lazy and just waits for a second. */
+      gdbsched_dispatch (time (NULL));
+
+      /* wait on all the open inputs */
+      pollfds.nfds = 0;
+      gdbsocket_fd_set (set, &pollfds);
+  
+      if (gdbsocket_log)
+       {
+         gdblog_string (gdbsocket_log, "[select ");
+         gdblog_long (gdbsocket_log, seconds);
+       }
+      s = poll (pollfds.fds, pollfds.nfds, seconds * 1000);
+
+      if (s < 0)
+       {
+         if (errno == EINTR)
+           break;
+         else
+           {
+             perror ("poll");
+             break;
+           }
+       }
+  
+      /* Process any pending events. */
+      gdbsocket_fd_isset (isset, &pollfds);
+    }
+
+  gdbsocket_shutdown ();
+  printf ("Shut down sockets.\n");
+
+  return 0;
+}
diff --git a/rda/samples/thread.c b/rda/samples/thread.c
new file mode 100644 (file)
index 0000000..79029f0
--- /dev/null
@@ -0,0 +1,332 @@
+/* thread.c
+
+   Copyright 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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "gdbserv.h"
+#include "gdbserv-utils.h"
+#include "gdbserv-target.h"
+#include "gdbserv-log.h"
+#include "gdbsocket.h"
+#include "gdbsched.h"
+#include "gdbloop.h"
+#include "stdio-log.h"
+
+#include "demo-target.h"
+
+/* A simplistic cache for memory and register transfers. */
+
+enum { NR_THREADS = 4 };
+enum { NR_REGS = 8 };
+
+struct mem {
+  unsigned long base;
+  unsigned long len;
+  unsigned char *buf;
+};
+
+struct gdbserv_thread {
+  struct gdbserv_reg reg[NR_REGS];
+  struct mem mem;
+};
+
+/* A mini-thread database */
+struct gdbserv_thread thread_db[NR_THREADS];
+
+
+
+static char *
+thread_info (struct gdbserv *serv, struct gdbserv_thread *thread)
+{
+  char buf[20];
+  char *info;
+  long id =  thread - thread_db;
+  assert (thread != NULL);
+  sprintf (buf, "ID-%ld", id);
+  info = strdup (buf);
+  return info;
+}
+
+static void
+thread_id (struct gdbserv *serv, struct gdbserv_thread *thread, struct gdbserv_reg *thread_id)
+{
+  assert (thread != NULL);
+  gdbserv_ulong_to_reg (serv, thread - thread_db + 1, thread_id);
+}
+
+static int
+thread_lookup_by_id (struct gdbserv *serv,
+                    const struct gdbserv_reg *thread_id,
+                    struct gdbserv_thread **thread)
+{
+  long id;
+  assert (thread != NULL);
+  gdbserv_reg_to_ulong (serv, thread_id, &id);
+  fprintf (stderr, "lookup_by_id %ld\n", id);
+  if (id == 0)
+    {
+      *thread = &thread_db[0];
+      return 0;
+    }
+  else if (id < 0 || id > NR_THREADS)
+    {
+      *thread = &thread_db[0];
+      return -1;
+    }
+  else
+    {
+      *thread = &thread_db[id - 1];
+      return 1;
+    }
+}
+
+static struct gdbserv_thread *
+thread_next (struct gdbserv *serv, struct gdbserv_thread *thread)
+{
+  if (thread == NULL)
+    {
+      return &thread_db[0];
+    }
+  else if (thread >= thread_db + NR_THREADS - 1)
+    {
+      return NULL;
+    }
+  else
+    return thread + 1;
+}
+
+
+/*
+ * Get/Set Registers
+ * 
+ * (including a primitive register cache) 
+ */
+
+static int
+thread_next_reg (struct gdbserv *serv, struct gdbserv_thread *thread,
+                int reg)
+{
+  assert (thread != NULL);
+  if (reg < 0)
+    return 0;
+  if (reg >= NR_REGS - 1)
+    return -1;
+  return reg + 1;
+}
+
+static int
+thread_reg_format (struct gdbserv *serv, struct gdbserv_thread *thread,
+                  int reg, int *size, int *padding)
+{
+  assert (thread != NULL);
+  *size = 4;
+  *padding = 0;
+  return 0;
+}
+
+static int
+thread_set_reg (struct gdbserv *serv,
+               struct gdbserv_thread *thread,
+               int nr,
+               const struct gdbserv_reg *val)
+{
+  assert (thread != NULL);
+  if (nr < 0 || nr >= NR_REGS)
+    return -1;
+  memmove (&thread->reg[nr], val, sizeof (*val));
+  return 0;
+}
+
+static int 
+thread_get_reg (struct gdbserv *serv,
+               struct gdbserv_thread *thread,
+               int nr,
+               struct gdbserv_reg *val)
+{
+  assert (thread != NULL);
+  if (nr < 0 || nr >= NR_REGS)
+    return -1;
+  memmove (val, &thread->reg[nr], sizeof (*val));
+  return 0;
+}
+
+/*
+ * Get/Set memory
+ *
+ * (including a primitive memory cache)
+ */
+
+static long
+thread_get_mem (struct gdbserv *serv, 
+               struct gdbserv_thread *thread,
+               struct gdbserv_reg *addr, 
+               void *data, 
+               long len)
+{
+  long n;
+  unsigned char *d = data;
+  unsigned long request_base;
+
+  gdbserv_reg_to_ulong (serv, addr, &request_base);
+
+  for (n = 0; n < len; n++)
+    {
+      if (request_base + n >= thread->mem.base
+         && request_base + n < thread->mem.base + thread->mem.len)
+       *d++ = thread->mem.buf[request_base + n - thread->mem.base];
+      else
+       *d++ = 0;
+    }
+
+  return n;
+}
+
+
+static long
+thread_set_mem (struct gdbserv *serv, 
+               struct gdbserv_thread *thread,
+               struct gdbserv_reg* addr, 
+               void* data, 
+               long len)
+{
+  unsigned long request_base;
+
+  gdbserv_reg_to_ulong (serv, addr, &request_base);
+  if (thread->mem.len == 0)
+    {
+      thread->mem.buf  = malloc (len);
+      thread->mem.len  = len;
+      gdbserv_reg_to_ulong (serv, addr, &thread->mem.base);
+    }
+  else
+    {
+      if (request_base < thread->mem.base)
+       {
+         thread->mem.len += thread->mem.base - request_base;
+         thread->mem.base = request_base;
+         thread->mem.buf  = realloc (thread->mem.buf, thread->mem.len);
+       }
+      if (request_base + len > 
+         thread->mem.base + thread->mem.len)
+       {
+         thread->mem.len += 
+           (request_base + len) - (thread->mem.base + thread->mem.len);
+         thread->mem.buf  = realloc (thread->mem.buf, thread->mem.len);
+       }
+    }
+
+  if (thread->mem.buf == NULL)
+    return 0;
+
+  memcpy (thread->mem.buf + (request_base - thread->mem.base), 
+         data, len);
+  return  len;
+}
+
+
+void
+select_initial_thread (struct gdbserv *gdbserv,
+                      struct gdbserv_thread *thread,
+                      void *context)
+{
+  gdbserv_fromtarget_thread_break (gdbserv, thread, GDBSERV_SIGNONE);
+}
+
+
+/* This function is called from gdbloop_poll when a new incoming
+   connection is attempted.  It may return NULL if the new connection
+   is to be refused, or a gdbserv_target vector if the connection is
+   accepted. */
+
+struct gdbserv_target* 
+thread_attach (struct gdbserv *serv, void* context)
+{
+  struct gdbserv_target *target;
+
+  /* Grap the demo target. */
+  target = demo_target (serv, context);
+  if (target == NULL)
+    return NULL;
+
+  /* Callback structure for function pointers that handle processed
+     control packets.  See gdbserv-target.h for docs on the individual
+     functions. */
+
+  target->next_gg_reg = thread_next_reg;
+  target->next_expedited_reg = thread_next_reg;
+  target->reg_format = thread_reg_format;
+  target->input_reg = gdbserv_input_reg_beb;
+  target->output_reg = gdbserv_output_reg_beb;
+  target->get_thread_reg = thread_get_reg;
+  target->set_thread_reg = thread_set_reg;
+  target->get_thread_mem = thread_get_mem;
+  target->set_thread_mem = thread_set_mem;
+
+  /* thread support */
+  target->thread_info = thread_info;
+  target->thread_id = thread_id;
+  target->thread_lookup_by_id = thread_lookup_by_id;
+  target->thread_next = thread_next;
+
+  /* Schedule an event to take us out of reset and to attach a
+     thread. */
+  gdbsched_schedule (0, select_initial_thread, serv, &thread_db[0], NULL);
+
+  return target;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int portno;
+  if (argc > 1)
+    portno = atoi (argv[1]);
+  else
+    portno = 2345;
+
+  /* Enable tracing */
+  gdbsocket_log = stdio_log (stderr);
+  gdbserv_warning_log = stdio_log (stderr);
+  gdbsocket_startup (portno, thread_attach, NULL);
+  printf ("Started listening socket on port %d.\n", portno);
+
+  /* Poll for socket traffic. */
+  while (! demo_quit_p)
+    {
+      gdbloop (time (NULL), -1);
+    }
+
+  gdbsocket_shutdown ();
+  printf ("Shut down sockets.\n");
+
+  return 0;
+}
diff --git a/rda/stamp-h.in b/rda/stamp-h.in
new file mode 100644 (file)
index 0000000..9788f70
--- /dev/null
@@ -0,0 +1 @@
+timestamp
diff --git a/rda/unix/ChangeLog b/rda/unix/ChangeLog
new file mode 100644 (file)
index 0000000..5a0c8f0
--- /dev/null
@@ -0,0 +1,930 @@
+2002-08-23  Kevin Buettner  <kevinb@redhat.com>
+
+       * linux-target.c (linux_get_reg, linux_set_reg): Print an
+       error message for out of bound registers.
+
+2002-08-23  Kevin Buettner  <kevinb@redhat.com>
+
+       * linux-target.c (NUM_REGS) [X86_LINUX_TARGET]: Bump to 42.
+       (getregs_setregs_reginfo) [X86_LINUX_TARGET]: Add entry for
+       register ``orig_eax''.
+       (linux_get_reg, linux_set_reg): Make sure ``regno'' value is valid.
+       (linux_detach, linux_attach, decr_pc_after_break): Call fprintf()
+       instead of printf().
+       (linux_detach, linux_attach): Don't always print informational
+       messages.
+       * ptrace-target.c (handle_waitstatus, ptrace_detach, ptrace_attach):
+       Don't always print informational messages.  Use fprintf() instead
+       of printf().
+       (noop_get_trap_number, noop_compute_signal, noop_exit_program)
+       (noop_signlestep_program, noop_break_program): Delete.
+       (ptrace_flush_i_cache): Renamed from noop_flush_i_cache.  Update
+       reference in ptrace_attach().
+       (continue_lwp, singlestep_lwp, attach_lwp, stop_lwp, ps_pstop)
+       (ps_continue, ps_lstop): Use fprintf() instead of printf().
+       * server.c (errno.h): Include.
+       (usage): New function.
+       (main): Add option processing code.
+       * server.h (struct child_process): Add new field,
+       ``debug_informational''.
+       * thread-db.c (ps_plog, select_pending_event, send_pending_signals)
+       (wait_all_threads, thread_db_check_child_state): Use fprintf()
+       instead of printf().
+       (thread_db_detach): Conditionally print informational messages.
+       Use fprintf() instead of printf().
+
+2002-08-21  Kevin Buettner  <kevinb@redhat.com>
+
+       * Makefile.am, configure.in, dummy-target.c, linux-target.c,
+       ptrace-target.c, ptrace-target.h, server.h, solaris-target.c,
+       thread-db.c: Change ``libremote'' references into ``RDA''
+       references.
+       * Makefile.in, configure: Regenerate.
+
+2002-08-15  Kevin Buettner  <kevinb@redhat.com>
+
+       * dummy-target.c, gdb_proc_service.h, gdbserv-thread-db.h,
+       linux-target.c, no-threads.c, ptrace-target.c,
+       ptrace-target.h, server.c, server.h, solaris-target.c,
+       thread-db.c: Update copyright notices.
+
+2002-05-16  Kevin Buettner  <kevinb@redhat.com>
+
+       * config.in (GREGSET_T): Renamed from GDB_GREGSET_T.
+       (FPREGSET_T): Renamed from GDB_FPREGSET_T.
+       * configure.in: Likewise.
+       * gdbserv-thread-db.h: Likewise.
+       * linux-target.c: Likewise.
+       * thread-db.c: Likewise.
+       * gdb_proc_service.h: Remove everything that's not absolutely
+       needed.
+
+2002-02-01  Kevin Buettner  <kevinb@redhat.com>
+
+       * configure.in (arm32): Change to ``yes''.
+       * configure: Regenerate.
+
+2002-01-30  Kevin Buettner  <kevinb@redhat.com>
+
+       * linux-target.c (linux_get_reg) [GETREGS_SETREGS_REGINFO]: Add
+       NOREGS support.
+       (linux_set_reg) [GETREGS_SETREGS_REGINFO]: Likewise.
+
+2002-01-28  Kevin Buettner  <kevinb@redhat.com>
+
+       * linux-target.c (write_reg_bytes): Print return status in
+       ptrace failure message.
+       * ptrace-target.c (ptrace_write_user): Enable existing 
+       Linux/MIPS related kernel bug workaround when MIPS_LINUX_TARGET
+       is defined (which is in addition to _MIPSEL).
+
+2002-01-28  Kevin Buettner  <kevinb@redhat.com>
+
+       * thread-db.c (struct regset_cache): New struct declaration.
+       (thread_db_map_id2thr_cache_valid, fpregset_cache, gregset_cache):
+       New static globals.
+       (thread_db_map_id2thr, thread_db_invalidate_map_id2thr_cache)
+       (initialize_regset_cache, initialize_regset_caches)
+       (thread_db_flush_regset_cache, thread_db_flush_regset_caches)
+       (thread_db_get_regset, thread_db_set_regset)
+       (thread_db_invalidate_regset_cache, thread_db_invalidate_regset_caches)
+       (thread_db_invalidate_caches, thread_db_getfpregs)
+       (thread_db_set_fpregs, thread_db_getgregs, thread_db_setgregs)
+       (td_thr_getfpregs_wrapper, td_thr_getgregs_wrapper)
+       (td_thr_setfpregs_wrapper, td_thr_setgregs_wrapper):
+       New functions.
+       (update_thread_list, thread_db_get_thread_reg)
+       (thread_db_set_thread_reg): Call thread_db_map_id2thr() instead of
+       td_ta_map_id2thr_p().
+       (thread_db_get_thread_reg): Call thread_db_getfpregs() instead
+       of td_thr_getfpregs_p().  Call thread_db_getgregs() instead of
+       td_thr_getgregs_p().
+       (thread_db_set_thread_reg): Likewise.  Also, call
+       thread_db_setfpregs() instead of td_thr_setfpregs_p() and
+       call thread_db_setgregs() instead of td_thr_setgregs_p().
+       (continue_thread, thread_db_continue_program)
+       (thread_db_singlestep_program, thread_db_continue_thread)
+       (singlestep_thread): Call thread_db_flush_regset_caches() at
+       beginning of function and thread_db_invalidate_caches() at
+       end of function.
+       (thread_db_attach): Initialize regset caches.
+
+2002-01-15  Kevin Buettner  <kevinb@redhat.com>
+
+       * config.in (Generated automatically comment): Revise to note
+       that this file was generated automatically at one time, but is
+       no longer.
+       (LINUX_TARGET, SOLARIS_TARGET): Fix comments.
+       (MIPS_LINUX_TARGET): Add.
+       * configure.in (i?86*linux*, powerpc*linux*, arm*linux*, mips*linux*):
+       Eliminate unnecessary duplication.
+       (mips*linux*): Target is MIPS_LINUX_TARGET, not SH_LINUX_TARGET.
+       * gdbserv-thread-db.h (is_gp_reg): New function.
+       (is_fp_reg, is_extended_reg): Revise comments.
+       * linux-target.c (enum regset): Add new constant NOREGS.
+       (is_gp_reg): New function.
+       (PEEKUSER_POKEUSER_REGINFO) [MIPS_LINUX_TARGET]: Define.
+       (SIZEOF_REGMAP, SIZEOF_MAPPEDREG) [MIPS_LINUX_TARGET]: Delete.
+       (NUM_REGS) [MIPS_LINUX_TARGET]: Change from 38 to 70 to account
+       for addition of floating point support.
+       (regmap) [MIPS_LINUX_TARGET]: Delete this array.
+       (is_fp_reg, is_extended_reg) [MIPS_LINUX_TARGET]: Delete.
+       (reginfo) [MIPS_LINUX_TARGET]: Define.
+       (DEBUG): Delete this macro definition.
+       (disp_gdb_mesg, ptrace_get_mem, ptrace_set_mem): Delete function
+       declarations.
+       (linux_get_reg, linux_set_reg) [PEEKUSER_POKEUSER_REGINFO]: Add
+       NOREGS support.
+       (put_regset) [PEEKUSER_POKEUSER_REGINFO]: Add missing return
+       statement.
+       (mips_get_reg): Use read_reg_bytes() to fetch the register.
+       (mips_singlestep_program): Eliminate unused variables ``u_regs_base'',
+       ``temp_reg''.  Fix fprintf related format warning.
+       * ptrace-target.h (ptrace_check_child_state): Declare.
+       * thread-db.c (thread_db_get_thread_reg, thread_db_set_thread_reg):
+       Handle case of target not supporting one or more registers.
+
+2001-10-15  Kevin Buettner  <kevinb@redhat.com>
+
+       * gdbserv-thread-db.h (is_extended_reg, reg_to_xregset)
+       (reg_from_xregset): New functions.
+       (debug_get_pc, decr_pc_after_break): Add declaration.
+       * linux-target.c (sys/procfs.h): Include.
+       (MAX_REG_SIZE): New anonymous enum constant.
+       (enum regset): New enum.
+       (getregs_setregs_reginfo, peekuser_pokeuser_reginfo): New structs.
+       (offsetof, fieldsize): New macros.
+       (ARM_LINUX_TARGET, X86_LINUX_TARGET, PPC_LINUX_TARGET): Deleted
+       old data structures defining register maps for these registers.
+       Replaced with new tables using either getregs_setregs_reginfo
+       or peekuser_pokeuser_reginfo structs.  Other architectures
+       remain the same, though reoranized somewhat.
+       (linux_next_gg_reg, linux_gg_reg_nr): Revise comments.  Use
+       NUM_REGS instead of NUM_G_PACKET_REGS.
+       (get_xregsetsize): New function.
+       (linux_reg_format, linux_sizeof_reg, is_fp_reg, is_extended_reg)
+       [PEEKUSER_POKEUSER_REGINFO, GETREGS_SETREGS_REGINFO]: New functions.
+       (read_reg_bytes, write_reg_bytes, debug_get_reg, debug_get_pc)
+       (linux_get_reg, linux_set_reg, reg_from_regset, reg_to_regset)
+       (reg_from_gregset, reg_to_gregset, reg_from_fpregset, reg_to_fpregset)
+       (reg_from_xregset, reg_to_xregset, get_regset, put_regset, get_gregset)
+       (put_gregset, get_fpregset, put_fpregset, get_xregset, put_xregset)
+       [PEEKUSER_POKEUSER_REGINFO]: New functions.
+       (read_reg_as_ulong, write_reg_as_ulong, debug_get_reg, debug_get_pc)
+       (linux_get_reg, linux_set_reg, regs_from_gregset, regs_to_gregset)
+       (reg_from_fpregset, reg_to_fpregset, reg_from_xregset, reg_to_xregset)
+       (get_gregset, put_gregset, get_fpregset, put_fpregset, get_xregset)
+       (put_xregset) [GETREGS_SETREGS_REGINFO]: New functions.
+       (linux_process_get_regs, linux_process_get_reg, linux_process_set_reg)
+       (linux_process_set_regs, ppc_linux_process_set_reg)
+       (ppc_linux_process_get_reg, ppc_linux_process_set_regs)
+       (ppc_linux_process_get_regs): Deleted.
+       (linux_attach): Reorganize initializations.
+       (generic_linux_set_reg): Renamed to linux_set_reg.
+       (generic_linux_get_reg): Renamed to linux_get_reg.
+       (generic_linux_sizeof_reg): Renamed to linux_sizeof_reg.
+       (generic_linux_gg_reg_nr): Renamed to linux_gg_reg_nr.
+       (generic_linux_next_gg_reg): Renamed to linux_next_gg_reg.
+       (generic_linux_reg_format): Renamed to linux_reg_format.
+       (decr_pc_after_break): Consolidated versions of this function
+       down to two; one for x86 and one for everything else.  Also,
+       add ``serv'' parameter and fix all callers.
+       (debug_get_pc, debug_get_reg): Now only three versions of
+       this function, one for PEEKUSER_POKEUSER_REGINFO code,
+       one for GETREGS_SETREGS_REGINFO code, and one for legacy
+       code.  Also, debug_get_pc() now takes a ``serv'' parameter.
+       Fixed all callers.
+       (ps_lgetregs): Use new get_gregset() interface.
+       (ps_lsetregs): Use new put_gregset() interface.
+       (ps_lgetfpregs, ps_lsetfpregs, ps_lgetxregsize, ps_lgetxregs)
+       (ps_lsetxregs): Implement.
+       * ptrace-target.c (ptrace_read_user, ptrace_write_user): Make
+       ``buff'' argument of type ``void *'' instead of ``char *''.
+       (ptrace_get_gregs): Add new parameter ``alt_pid''.
+       (ptrace_set_gregs): Likewise.
+       (ptrace_get_fpregs): Add new parameter alt_pid.  Also fix call
+       to ptrace() so parameters are in correct order.
+       (ptrace_set_fpregs): Likewise.
+       (ptrace_get_fpxregs, ptrace_set_fpxregs): New functions.
+       * ptrace-target.h (ptrace_write_user, ptrace_read_user)
+       (ptrace_get_gregs, ptrace_set_gregs, ptrace_get_fpregs)
+       (ptrace_set_fpregs, ptrace_get_fpxregs, ptrace_set_fpxregs):
+       Declare.
+       * thread-db.c (td_thr_getxregsize_p, td_thr_getxregs_p)
+       (td_thr_setxregs_p): New function pointers.
+       (thread_db_dlopen): Initialize new function pointers.
+       (send_pending_signals): Add ``process'' parameter so that
+       decr_pc_after_break() can get the ``serv'' argument.  Fix all
+       callers.
+       (thread_db_get_thread_reg, thread_db_set_thread_reg): Add xregset
+       support.
+
+2001-10-14  Kevin Buettner  <kevinb@redhat.com>
+
+       * ptrace-target.c (unistd.h): Include.
+       (close_open_files): New function.
+       (ptrace_create_child):  In newly forked child process, call
+       close_open_files() before invoking execv().
+
+2001-10-13  Kevin Buettner  <kevinb@redhat.com>
+
+       * server.c (signal.h): Include.
+       (chld_handler): New function.
+       (main): Establish chld_handler as the SIGCHLD signal handler.
+       Also, wait 1 second instead of 0 seconds to avoid busy waiting.
+
+2001-09-26  Louis Hamilton  <hamilton@redhat.com>
+
+       * configure.in: Use thread-db.c for ARM.
+       * configure: Regenerated.
+       * linux-target.c (ARM_R11, ARM_R12): Added to regmap[].
+       (ARM_FP, ARM_CPSR): Revised mappings of these ARM registers.
+       (debug_get_reg, debug_get_pc, decr_pc_after_break) [ARM_LINUX_TARGET]:
+       New functions.
+       
+2001-09-20  Kevin Buettner  <kevinb@redhat.com>
+
+       * configure.in: Use thread-db.c for Linux/PPC too.
+       * configure: Regenerated.
+       * linux-target.c (linux_read_reg): Add forward declaration.
+       (debug_get_reg, debug_get_pc, decr_pc_after_break) [PPC_LINUX_TARGET]:
+       New functions.
+
+2001-09-20  Kevin Buettner  <kevinb@redhat.com>
+
+       * linux-target.c (SIZEOF_MAPPEDREG) [PPC_LINUX_TARGET]: Add comment.
+       (PC_REGNUM) [PPC_LINUX_TARGET]: Remove FIXME comment.
+       (is_fp_reg) [PPC_LINUX_TARGET]: Revise upper bound on floating
+       point register numbers.
+       (ppc_linux_getset_reg): Rewritten to use regmap[] to fetch
+       ptrace() offsets.  This'll handle the (previously unsupported)
+       floating point registers, cr, lr, ctr, and xer.
+       (ppc_linux_process_set_regs, ppc_linux_process_get_regs): Don't
+       hardcode loop upper bound.
+       (ppc_linux_process_get_regs): Revise declarator to match
+       process_get_regs member in struct gdbserv_target.
+
+2001-09-18  Andrew Haley  <aph@cambridge.redhat.com>
+
+        * server.c (main): Work around SIGCHLD problem.
+
+2001-08-05  Michael Chastain  <chastain@redhat.com>
+
+       * ptrace-target.c (ptrace_write_user): Ignore ESRCH on MIPS,
+       because mips linux kernel 2.4 has a bug where PTRACE_POKEUSER
+       returns -ESRCH even when it succeeds.
+
+2001-08-03  Michael Keezer  <mkeezer@redhat.com>
+
+        * configure.in: Add am33_2.0 & mn10300.
+        * config.in: Add AM33_LINUX_TARGET & AM33_2_0_LINUX_TARGET.
+        * linux-target.c: am33_2.0 & mn10300 support.
+
+2001-07-23  David Howells  <dhowells@redhat.com>
+
+       * ptrace-target.c: Added big-endian MIPS support.
+       * linux-target.c: ditto.
+       * server.h: ditto.
+
+2001-06-25  Michael Snyder  <msnyder@redhat.com>
+
+       * ptrace-target.c (ptrace_compute_signal): Implement conversion 
+       from native signals to GDB's signal numbering.
+       (ptrace_process_signal): Implement conversion from GDB's signal
+       numbering to native signals.
+       (stop_lwp): Comment out debugging output of SIGSTOP signals.
+       * linix-target.c (linux_fromtarget_break): Call compute_signal.
+       (linux_fromtarget_terminate): Ditto.
+       * thread-db.c (thread_db_check_child_state): Don't do any conversion
+       when passing a signal directly back to the inferior; just copy from
+       stop_signal to signal_to_send.
+       (thread_db_fromtarget_thread_break): Convert signal from native
+       numbering to GDB's numbering.
+
+2001-06-18  Michael Snyder  <msnyder@redhat.com>
+
+       * linux-target.c (generic_linux_set_reg): Fix typo.
+       (decr_pc_after_break): Mute the debugging output.
+
+2001-06-15  Michael Snyder  <msnyder@redhat.com>
+
+       * thread_db.c: Disable noisy debugging output.
+       (select_pending_event): Add new selection criterion, giving
+       preference to a thread that is being single-stepped.  This 
+       avoids the problem of deciding whether to decrement the pc if
+       we don't know whether a SIGTRAP was caused by stepping or by
+       hitting a breakpoint.
+
+2001-06-14  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (thread_db_set_gen, thread_db_get_gen): Rewrite
+       syntax for qSymbol messages.
+       * gdb_proc_service.h: New file.
+       * Makefile.am (INCLUDES): Remove $(srcdir)/../../include.
+       * Makefile.in: Regenerate.
+
+2001-05-31  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (add_thread_to_list): Return explicit value!
+
+2001-05-23  Jackie Smith Cashion <jsmith@redhat.com>
+
+       * linux-target.c: Change MIPS SIZEOF_MAPPEDREG from 1 to 4.
+       (linux_register_offset): For MIPS return regmap[regnum] instead of
+       SIZEOF_MAPPEDREG * regmap[regnum].
+       (mips_get_reg): Pass pid as argument to ptrace_read_user instead of
+       gdbserv pointer.
+       
+2001-05-22  Michael Snyder  <msnyder@redhat.com>
+
+       * no-threads.c: New file.
+       * configure.in: Use thread-db.c only for specified architectures, 
+       (including x86); otherwise default to using no-threads.c.
+       * configure: Regenerate.
+       
+2001-05-10  Martin M. Hunt  <hunt@redhat.com>  
+
+       * linux-target.c (is_fp_reg): New function for mips. 
+       FP not implemented.
+       
+       Merged changes from symbol branch with appropriate modifications.
+
+Mon Mar 26 08:54:41 PST 2001  Brendan Conoboy <blc@redhat.com>
+       * configure.in: Added mipsvr4181el* target
+       * configure: regenerate
+2001-01-26  Rudy Folden <rfolden@redhat.com>
+       
+       * server.c: Changed name from gdbgeneral_xxx to gdbconnect_xx.
+2001-01-24  Rudy Folden <rfolden@redhat.com>
+       * configure: Added mipsel* target.
+       * linux-target.c: Add support for MIPS processor, including single-
+       stepping which doesn't exist in mips ptrace.
+       * ptrace-target.c (ptrace_handle_waitstatus): Added single-stepping
+       instruction restore for mips.
+       (ptrace_attach): Added single stepping initialization code.
+       * server (main): Added generic interfaces, gdbgeneral_startup/shutdown
+       for serial or tcp/ip selection. Also added server_quit_p to X and W 
+       for serial support (no socket shutdown).
+       * server.h (child_process): Added mips instruction save area for
+       single-step support.
+
+       2001-01-10  Rudy Folden <rfolden@redhat.com>
+       * ptrace-target.c (enum): Added U_REGS_OFFSET to processor
+       dependent enums.
+
+2001-04-26  Michael Snyder  <msnyder@redhat.com>
+
+       * linux-target.c (is_fp_reg): New function.
+       (reg_from_fpregset, reg_to_fpregset): New functions.
+       Support for thread_db_get_thread_reg floating point regs.
+       * thread-db.c (thread_db_get_thread_reg, thread_db_set_thread_reg):
+       Infrastructure for support of floating point regs.
+       (Attach_thread): New function, abstracted from below.
+       (find_new_threads_callback): Call attach_thread.
+       (stop_thread): New function, abstracted from stop_all_threads.
+       (stop_all_threads): Call stop_thread.
+       (continue_thread): Test for lwp == 0 before calling continue_lwp.
+       * ptrace-target.c (stop_lwp): New function.
+       * gdbserv-thread-db.h (reg_to_regnum, reg_from_regnu): Declare.
+
+2001-04-25  Michael Snyder  <msnyder@redhat.com>
+
+       Move all ptrace references out of thread-db.c.
+       * gdbserv-thread-db.h: New file.
+       * thread-db.c (struct ps_prochandle): Move to gdbserv-thread-db.h.
+       (gdb_ps_prochandle_t): Ditto.
+       (gdb_ps_read_buf_t, gdb_ps_write_buf_t, gdb_ps_size_t): Ditto.
+       (ps_pstop, ps_pcontinue): Move to ptrace-target.c.
+       (ps_lstop, ps_lcontinue): Ditto.
+       (ps_pdread, ps_pdwrite, ps_ptread, ps_ptwrite): Ditto.
+       (ps_lgetxregsize): Move to linux-target.c.
+       (ps_lgetxregs, ps_lsetxregs, ps_getpid): Ditto.
+       (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, ps_lsetfpregs): Ditto.
+       (find_new_threads_callback): Abstract attach bits into new function
+       attach_lwp, and move that to ptrace-target.c.
+       (wait_all_threads): Call continue_lwp instead of ptrace.
+       (continue_pid): Rename as continue_lwp, move into ptrace-target.c.
+       (singlestep_pid): Rename as continue_lwp, move into ptrace-target.c.
+       (struct symbol_cache): Change value to a paddr_t.
+       (add_symbol_to_list, lookup_cached_symbol): Ditto.
+       * linux-target.c (ps_lgetregs, ps_lsetregs, ps_lgetfpregs, 
+       ps_lsetfpregs, ps_lgetxregsize, ps_lgetxregs, ps_lsetxregs,
+       ps_getpid): Moved to here from thread-db.c.
+       * ptrace-target.c (continue_lwp, singlestep_lwp, attach_lwp,
+       (ps_pstop, ps_pcontinue, ps_lstop, ps_lcontinue, ps_pdread,
+       ps_pdwrite, ps_ptread, ps_ptwrite): Moved here from thread-db.c.
+       (ptrace_handle_waitstatus): Renamed as handle_waitstatus.
+       (ps_lcontinue): Implement (untested).
+       * server.c (main): Check server_quit_p after calling gdbloop_poll.
+
+
+2001-04-24  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (continue_pid, continue_thread): New functions.
+       (singlestep_pid, singlestep_thread): New functions.
+       (continue_all_threads): Use new function continue_thread.
+       (thread_db_continue_program): Ditto.
+       (thread_db_singlestep_program): Ditto.
+       (thread_db_continue_thread): Ditto.
+       (thread_db_singlestep_thread): Ditto.
+       
+       * thread-db.c: Remove some debugging printfs.
+       Add activation and handling of the thread debug signal.
+       (get_thread_signals): Get the debug signal as well as the others.
+       Set target flag to activate the debug signal.
+       (set_target_int_by_name): New function.
+       (struct gdbserv_thread): Rename "sigstopped" flag to just "stopped".
+       (stop_all_threads): Mark the event thread "stopped".
+       (wait_all_threads): Mark the event thread "waited".
+       Don't stash the debug signal (throw it away).
+       (continue_all_threads): Always send the restart signal to any
+       thread that has just been attached.
+       (thread_db_check_child_state): Make two calls to waitpid (one with
+       WCLONE, one without) instead of alternating every other time.
+       Add debug_signal to the list of events to ignore.
+       (thread_db_attach): Add "__pthread_threads_debug" to list of symbols.
+
+2001-04-20  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (thread_db_check_child_state): Add SIGCHLD to the
+       list of signals to ignore.  When a thread exits, make sure that
+       the other threads get restarted.
+
+2001-04-19  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (wait_all_threads): Save exit and term events.
+       Save SIGINT like any other signal event.  
+       (send_pending_signals): Don't send SIGINT.
+       (select_pending_event): Give preference to SIGINT.
+       (thread_db_check_child_state): Move special handling of 
+       cancel and restart signals to after the stop_all_threads
+       and wait_all_threads calls, so we can catch these signals
+       even if they aren't the first signal we get notification of.
+
+2001-04-19  Michael Snyder  <msnyder@redhat.com>
+
+       Major change to select an event so as to avoid starvation.
+       * thread-db.c (select_pending_event): New function.  Choose an
+       event from the list of pending events, and make its thread the
+       event thread.
+       (stop_all_threads): Don't mark the event thread.  That will now
+       be done by select_pending_event.
+       (struct signal_list): Rename to event_list.  Save the thread and
+       the entire wait status, so that all events (not just signals)
+       can be saved.
+       (add_pending_signal): Rename to add_pending_event.
+       (send_pending_signals): Ignore non-signal events.
+       Ignore the selected event (which will be returned to the debugger).
+       Push back breakpoint events (moved here from wait_all_threads).
+       (wait_all_threads): Remove special handling for SIGTRAP (moved
+       into send_pending_signals).  Call select_pending_event.
+       (thread_db_check_child_status): Add initial event to event list.
+
+2001-04-16  Michael Snyder  <msnyder@redhat.com>
+       * thread-db.c (thread_db_continue_thread): Handle the signal param.
+       (thread_db_singlestep_thread): Ditto.
+       (thread_db_check_child_state): Handle exit and termination separately.
+
+2001-04-13  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (find_new_threads_callback): Account for dead threads.
+       (update_thread_list): Keep zombie threads in thread list, but
+       delete them if they've been joined or detached.
+       (stop_all_threads): Don't stop dead threads.
+       (continue_all_threads): Don't continue if not waited.
+       (thread_db_check_child_state): Move handling of terminate and
+       exit earlier.  Handle termination or exit of children specially.
+       (thread_db_get_thread_reg): Test for defunct threads.
+       (thread_db_set_thread_reg): Ditto.
+       * ptrace-target.c (ptrace_xfer_mem): Don't be noisy about ptrace
+       errors caused by illegal memory accesses.
+
+2001-04-12  Andrew Cagney  <ac131313@redhat.com>
+
+       * server.c: Include "gdbloop.h".  Replace gdbsocket_poll with
+       gdbloop_poll.
+       * ptrace-target.c, linux-target.c, solaris-target.c: 
+       * dummy-target.c: Update comments.
+
+2001-04-11  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (struct gdbserv_thread): Add new flag 'stepping'.
+       (stop_all_threads): Add parameter 'process'.
+       Set the process->event_thread here, instead of in check_child_state.
+       (wait_all_threads): Accept process as a parameter instead of eventpid.
+       Handle SIGTRAP differently if the thread was singlestepping.
+       (thread_db_singlestep_program): Clear flags for event thread.
+       (thread_db_singlestep_thread): Ditto.
+       (thread_db_continue_program): Ditto.
+       (thread_db_continue_thread): Ditto.
+       (thread_db_check_child_state): Cancel the stepping flag.
+       Don't set the event thread, this is now done in stop_all_threads.
+       * linux-target.c (debug_get_reg, debug_get_pc): New functions.
+       Purely for debugging output.  Architecture dependent.
+
+2001-04-09  Michael Snyder  <msnyder@redhat.com>
+
+       * thread_db.c (thread_db_continue_thread): Continue the actual
+       thread given, not necessarily the event thread.
+       (thread_db_singlestep_thread): Step the actual thread given, 
+       not necessarily the event thread.
+
+2001-04-09  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (stop_all_threads): Do not send SIGSTOP to a thread
+       if it has already been sigstopped.
+       (thread_db_continue_thread): New function.  Continue a single thread.
+       (thread_db_singlestep_thread): New function.  Step a single thread.
+       (thread_db_attach): Set up continue_thread, singlestep_thread methods.
+       
+2001-04-09  Michael Snyder  <msnyder@redhat.com>
+
+       * linux-target.c (PC_REGNUM): New enum, define.
+       (decr_pc_after_break): New function.  Architecture dependent.
+       This version will probably serve for all targets for which
+       DECR_PC_AFTER_BREAK is one.  Those for which it is zero will
+       want to define a no-op version of this function.
+       * thread-db.c (first_thread_in_list): New function.
+       (update_thread_list, stop_all_threads, wait_all_threads, 
+       continue_all_threads): Use first_thread_in_list in for loops.
+       (wait_all_threads): Handle SIGINT and SIGTRAP specially.
+       Throw away SIGINT for all threads but the event thread.
+       For SIGTRAP in other than the event thread, call decr_pc_after_break
+       (giving the thread a chance to hit the trap again later).
+       (thread_db_continue_program, thread_db_singlestep_program):
+       Continue the event thread before all the others.
+
+2001-04-05  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (add_pending_signal, send_pending_signals):
+       New functions.  Allow wait_all_threads to collect any signals
+       other than SIGSTOP from the threads and defer them.
+       (wait_all_threads): Loop on each thread and call waitpid until
+       we get SIGSTOP.  Any other signals are pended by throwing them
+       into a list, and then sending them back to the threads using kill.
+       (thread_db_get_thread_reg): Remove temporary hack for libthread_db
+       bug.  (thread_db_set_thread_reg): Ditto.
+
+2001-04-04  Michael Snyder  <msnyder@redhat.com>
+
+       * server.h (struct child_process): Add a 'running' flag.
+       * thread_db.c (continue_all_threads): Take gdbserv as argument.
+       Use it to find the current thread, and don't continue that one
+       (leave it up to the parent method to continue the event thread.)
+       (thread_db_continue_program): Child is running -- set a flag.
+       (thread_db_singlestep_program): Ditto.
+       (thread_db_check_child_state): Return immediately unles the child
+       is running.  Because this is a polling routine, we don't want to
+       return any new events unles the child is officially running.
+       Call waitpid with -1 instead of the process->pid, so that we
+       can get events from the threads.  Alternately use __WCLONE.
+       (thread_db_get_thread_reg): If thread is not specified, use
+       the event thread (if possible).  Temporarily hack around a
+       bug in the thread_db library.
+       (thread_db_set_thread_reg): Ditto.
+       
+2001-04-04  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c (continue_all_threads): Zero the attached, stopped,
+       and waited flags only if thread is successfully continued.
+       * linux-target.c: Fix broken endif directive.
+       * configure.in: Test for sys/procfs.h.
+       * config.in: Define HAVE_SYS_PROCFS_H.
+       * configure: Regenerate.
+       * thread-db.c (thread_list_lookup_by_pid): New function.
+       (thread_db_check_child_state): Cache the event thread.
+       (thread_db_fromtarget_thread_break): New function.  Call
+       gdbserv_fromtarget_thread_break with the event thread.
+       (thread_db_attach): Take over the fromtarget_break vector.
+       * server.h (struct child_process): Add event_thread field.
+
+2001-04-02  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c: include errno.h for error reporting.
+       (struct gdbserv_thread): Add flag 'waited'.
+       (thread_db_type_str): New function for thread_extra_info.
+       (find_new_threads_callback): Use errno for error reporting.
+       (thread_db_thread_info): New function, for thread_extra_info.
+       (wait_all_threads): New function.  Call waitpid on all threads
+       that have been attached or sigstopped.  Incomplete -- needs to
+       push back any signals other than SIGSTOP.
+       (continue_all_threads): Send PTRACE_CONT only to threads that
+       have been attached or sigstopped.
+       (check_child_state): Call wait_all_threads.
+       (thread_db_attach): Activate thread_info vector.
+
+2001-03-30  Michael Snyder  <msnyder@redhat.com>
+
+       * linux-target.c (linux_read_reg, linux_write_reg): New functions.
+       Abstract out the code to actually read a register value, so that 
+       it can be shared by several methods.
+       (get_gregset): Use sizeof (GREGSET_T).
+       (generic_linux_gg_reg_nr): New function.  Support new reg methods.
+       (generic_linux_next_gg_reg): Ditto.
+       (generic_linux_sizeof_reg): Ditto.
+       (generic_linux_reg_format): Ditto.
+       (generic_linux_get_reg): New function.  Newer register method,
+       non-thread-aware version.
+       (linux_attach): Use new register method in target vector.
+       * thread-db.c: Remove some developmental ifdef code.
+       (thread_db_get_thread_reg): Fall back on parentvec.get_reg
+       if no thread or no thread_agent available.
+       (thread_db_attach): Replace get_reg vector with get_thread_reg.
+
+       * ptrace-target.c (ptrace_write_user): For X86 target, skip
+       write-protected location in user/context address space.
+       * linux-target.c (linux_process_get_reg): Use linux_read_reg.
+       (linux_process_set_reg): Use linux_write_reg.
+       (put_gregset): New function.  Write child's gregset.
+       (generic_linux_get_reg): Use SIZEOF_MAPPEDREG.
+       (generic_linux_set_reg): New function.  Newer register method.
+       (linux_attach): Add set_reg to target vector, not process_set_reg.
+       * thread-db.c (ps_lsetregs): Implement by calling put_gregset.
+       (thread_db_set_thread_reg): New function.  Implement set_thread_reg.
+       (thread_db_attach): Add set_thread_reg to target vector.
+
+2001-03-29  Michael Snyder  <msnyder@redhat.com>
+
+       * ptrace-target.c (ptrace_read_user, ptrace_write_user):
+       Accept an explicit pid instead of a struct gdbserv.
+       * linux-target.c: Include gdb_proc_service.h for gregset_t
+       (FIXME: better place to get it from?)
+       (linux_register_offset): Return signed long to facilitate 
+       test for -1 error return value.
+       (ppc_linux_xfer_reg, linux_process_get_reg, linux_process_set_reg):
+       Calls to ptrace_read_user and ptrace_write_user now need a pid
+       argument instead of a struct gdbserv.
+       (reg_from_gregset): New function.
+       (reg_to_gregset): New function.
+       (get_gregset): New function.  Read child's gregset.
+       * thread-db.c (ps_lgetregs): Implement by calling get_gregset.
+       (thread_db_dlopen, thread_db_open, thread_db_attach): Change 
+       sense of return: -1 now means failure, 0 means success.
+       (thread_db_get_thread_reg): Call reg_from_gregset.
+
+2001-03-29  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c: Include signal.h, sys/ptrace.h (FIXME ptrace).
+       (struct symbol_cache): Make value (address) unsigned.
+       (add_symbol_to_list, lookup_cached_symbol): Ditto.
+       (struct gdbserv_thread): Add attached, stopped flags to thread.
+       (add_thread_to_list): Return pointer to new thread in list.
+       (delete_thread_from_list): New function.
+       (ps_pglobal_lookup, ps_pdread, ps_pdwrite, ps_ptread, ps_ptwrite):
+       Muffle debugging output.
+       (find_new_threads_callback): Muffle debugging output.
+       Add thread to list only if it isn't already there.
+       Use ptrace to attach to new threads.  (FIXME explicit ptrace).
+       (update_thread_list): New function.  Only place where td_ta_thr_iter
+       is called.  Builds up the thread list, prunes it of any dead threads.
+       (thread_db_thread_next): Call update_thread_list.
+       (get_thread_signals): Read the values of the cancel and restart
+       signals from the target using hardcoded symbol names.
+       (stop_all_threads): New function.  First cut.  Deliver SIGSTOP
+       to all threads except the event thread and any new threads that
+       have just been attached.
+       (continue_all_threads): New function.  First cut.  Deliver
+       PTRACE_CONT to all threads except the main thread.  Needs work.
+       (thread_db_continue_program): New function.  
+       (thread_db_singlestep_program): New function.
+       (thread_db_get_thread_reg): New function, incomplete.
+       (thread_db_attach): Take over continue_program, singlestep_program.
+       Muffle some debugging output.
+
+2001-03-26  Michael Snyder  <msnyder@redhat.com>
+
+       * thread-db.c: New file.  Linux thread debugging layer.
+       * linux-target.c (linux_attach): Call thread_db_attach.
+       * ptrace-target.c: Export ptrace_handle_waitstatus for
+       thread-db.c (FIXME).
+       * configure.in: Add thread-db.c to linux target modules.
+       (GREGSET_T, FPREGSET_T, HAVE_LWPID_T, HAVE_PSADDR_T,
+       HAVE_PRGREGSET_T, HAVE_PRFPREGSET_T, LINUX_TARGET): Define.
+       * config.in (GREGSET_T, FPREGSET_T, HAVE_LWPID_T, 
+       HAVE_PSADDR_T, HAVE_PRGREGSET_T, HAVE_PRFPREGSET_T, LINUX_TARGET): 
+       Default undefine.
+       * configure: Regenerate.
+       * Makefile.am (INCLUDES): Add $(srcdir)/../../include
+       (devo/include), so that header files can be shared with gdb.
+       (server_LDFLAGS): Add -ldl -rdynamic (FIXME configure).
+       * Makefile.in: Regenerate.
+
+2001-03-22  Andrew Cagney  <ac131313@redhat.com>
+
+       * server.c (main): Pass gdbserver.attach and process to
+       gdbserver_startup instead of gdbserver_poll.
+
+2001-03-16  Michael Snyder  <msnyder@redhat.com>
+
+       * linux-target.c (linux_detach): Pass new parameter to ptrace_detach.
+       Fix file header comment typo.  Update copyright.
+
+2001-03-16  Elena Zannoni  <ezannoni@cygnus.com>
+
+        * dummy-target.c (dummy_detach): Add new parameter.
+        * linux-target.c (linux_detach): Ditto.
+        * ptrace-target.c (ptrace_detach): Ditto.
+        * solaris-target.c (solaris_detach): Ditto.
+
+2001-03-14  Andrew Cagney  <ac131313@redhat.com>
+
+       * ChangeLog: Move to here from ../native.
+       * Makefile.am: Ditto.
+       * aclocal.m4: Ditto.
+       * configure.in: Ditto.
+       * dummy-target.c: Ditto.
+       * linux-target.c: Ditto.
+       * ptrace-target.c: Ditto.
+       * ptrace-target.h: Ditto.
+       * server.c: Ditto.
+       * server.h: Ditto.
+       * solaris-target.c: Ditto.
+       * Makefile.in: Regenerate.
+       * config.in: Ditto.
+       * configure: Ditto.
+
+2001-03-14  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.am (INCLUDES): Update. Headers moved to ../include.
+       * Makefile.in: Regenerate.
+
+2000-11-27  Michael Snyder  <msnyder@happy.cygnus.com>
+
+       * ptrace-target.c (ptrace_xfer_mem): Return -1 on error.
+
+2000-11-21  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * ptrace-target.c (noop_flush_i_cache): Comment out superfluous
+       debugging output.
+       * linux-target.c (linux_process_get_reg): Return value of 
+       linux_register_offset is unsigned (can't be less than zero).
+       (linux_process_rcmd): Just use '1' and '0' to control debug output.
+
+2000-11-06  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * dummy-target.c (dummy_attach): Fix order of memset args.
+       * linux-target.c (linux_attach): Ditto.
+       * ptrace-target.c (ptrace_attach): Ditto.
+       * solaris-target.c (solaris_attach): Ditto.
+
+2000-10-19  Belinda Brazelle <brazelle@redhat.com>
+
+       * linux-target.c: Add support for Arm processor.
+
+2000-10-12  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * ptrace-target.c (ptrace_handle_waitstatus): Save exitstatus
+       in process->stop_signal.
+
+2000-09-14  Michael Snyder  <msnyder@michael.wirespeed.com>
+
+       * linux-target.c: Define regmap etc. for SH target.
+       * configure.in: Add defines for SH target.
+       * configure: Rebuild.
+
+2000-09-13  Michael Snyder  <msnyder@michael.wirespeed.com>
+
+       * server.h (fromtarget_terminate): New field.  Also fix up 
+       some overlooked function prototypes in the existing fields.
+       (struct client_process): Rename to struct child_process.
+       * linux-target.c (linux_fromtarget_terminate): New function.
+       Called from main when child terminates abnormally.
+       (linux_process_rcmd): New function.  Catches "qRcmd" requests, 
+       which are currently used just to turn on debug output.
+       * ptrace-target.c (ptrace_handle_waitstatus): Set stop_signal
+       for the WIFSTOPPED case.  (ptrace_process_signal): Return zero
+       instead of the signal number, to let libremote know that we have
+       handled the signal.  (ptrace_xfer_memory): Fix off-by-one error.
+       * solaris-target.c (solaris_fromtarget_terminate): New function.
+       * server.c (main): Call fromtarget_terminate for the 'T' case.
+       Do not request a one-second delay from gdbsocket_poll.
+
+2000-09-08  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * solaris-target.c: New file.  Just a prototype, doesn't actually
+       work.  Used to confirm configurability to multiple targets.
+       * dummy-target.c: New file.  Dummy back-end for implementing new
+       targets such as solaris-target.c (above), before actually having
+       a working back-end.  The dummy target works just like the sample
+       target in the samples directory.
+       * configure.in: Add AC_SUBST(TARGET_MODULES) to add the 
+       appropriate target modules to the Makefile.  Add solaris target.
+       * configure: Regenerate.
+       * Makefile.am: Move *-target.c into EXTRA_server_SOURCES.
+       Add TARGET_MODULES to server_LDADD.  Define server_DEPENDENCIES.
+       * Makefile.in: Regenerate.
+       * ptrace-target.h: New file.  Defines needed only by ptrace.
+       * server.h: Remove ptrace-specific defines to ptrace-target.h.
+       (struct server_vector): New, for target entry points.
+       (struct nativeserver): Rename to struct client_process.
+       * server.c: Use client_process for entry points, and server_vector.
+       * linux-target.c: Include ptrace-target.h.  
+       (ppc_linux_get_reg): Rename to ppc_linux_process_get_reg.
+       (ppc_linux_set_reg): Rename to ppc_linux_process_set_reg.
+       (ppc_linux_get_regs): Rename to ppc_linux_process_get_regs.
+       (ppc_linux_set_regs): Rename to ppc_linux_process_set_regs.
+       (linux_get_reg): Rename to linux_process_get_reg.
+       (linux_set_reg): Rename to linux_process_set_reg.
+       (linux_get_regs): Rename to linux_process_get_regs.
+       (linux_set_regs): Rename to linux_process_set_regs.
+       (gdbserver_check_child_state): Rename to linux_check_child_state.
+       (gdbserver_fromtarget_break): Rename to linux_fromtarget_break.
+       (gdbserver_fromtarget_exit): Rename to linux_fromtarget_exit.
+       (struct server_vector gdbserver): New, defines entry points.
+       * ptrace-target.c: Include ptrace-target.h.
+       * aclocal.m4: New file.
+
+2000-09-08  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * linux-target.c (linux_get_reg, linux_set_reg): Remove direct
+       calls to ptrace; instead use service call into ptrace-target.c.
+       (linux_get_regs, linux_set_regs): Remove ifdef PPC; instead use
+       an ifdef in linux_attach to set up the target vector pointers.
+       (linux_attach): If PPC_LINUX_TARGET, use PPC versions of register
+       functions instead of generic ones.  Define process_set_reg, so
+       that the "P" command is now handled.
+
+2000-09-07  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * ptrace-target.c (ptrace_read_user, ptrace_write_user): New 
+       functions.  Exported so that linux-target does not have to 
+       call ptrace directly.  (ptrace_get_gregs, ptrace_set_gregs, 
+       ptrace_get_fpregs, ptrace_set_fpregs): New functions.
+       Exported for use by targets that use these methods.
+       (ptrace_xfer_mem): Use ptrace_arg3_type instead of long.
+       Add address to error messages.  
+       * linux-target.c: Start using config macros, port to alpha and ppc.
+       (ppc_linux_xfer_reg, ppc_linux_getset_reg, ppc_linux_get_reg,
+       ppc_linux_set_reg, ppc_linux_get_regs, ppc_linux_set_regs):
+       New functions.  Explicit knowledge of ppc linux register layout.
+       (linux_get_reg): Catch undefined regmap offsets.
+       (linux_set_reg): Ditto.
+       (linux_get_regs): Conditionally call ppc_linux_get_regs.
+       (linux_set_regs): Ditto.
+       * configure.in: Add PPC target, and export target defines.
+       * configure: Regenerate.
+       * config.in: Add new target defines.
+
+2000-09-06  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * Makefile.am: Define CC and CFLAGS.
+       * Makefile.in: Regenerate.
+       * configure.in: New file.  Detect all manner of things.
+       * config.in: New file.  Input file for config.h.
+       * configure: Generate.
+       * ptrace-target.c (ptrace_xfer_type): Move def'n into server.h.
+       (PTRACE_XFER_SIZE): Ditto.
+       * linux-target.c (ptrace_xfer_type): Move def'n into server.h.
+       (ptrace_arg3_type): Ditto.
+       * server.h: Use config macros to determine definitions of 
+       ptrace_xfer_type, ptrace_arg1_type, ptrace_arg2_type, 
+       ptrace_arg3_type, ptrace_arg4_type.
+
+2000-09-05  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * server.c (main): Detect exit status, and call fromtarget_exit
+       instead of fromtarget_break.
+       * linux-target.c (gdbserver_fromtarget_exit): New function.
+       * ptrace-target.c (ptrace_kill_program, ptrace_sigkill_program):
+       New functions.  Send signals to the child.
+       (ptrace_exit_program): New function.
+
+2000-09-05  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * linux-target.c (linux_attach): Activate process_signal vector.
+       (gdbserver_check_child_state): Send real received signal, instead
+       of faking SIGTRAP.
+       * ptrace-target.c (ptrace_break_program): New function.  Implement
+       control-c interrupt from host.
+       (ptrace_process_signal): Implement continuation signal.
+       (ptrace_singlestep_program): Ditto.
+       (ptrace_continue_program): Ditto.
+       (ptrace_get_trap_number): New function.  Return signal to libremote.
+       (ptrace_compute_signal): Ditto.
+       (ptrace_attach): Activate break_program, process_signal, compute_signal
+       and get_trap_number vectors.
+       server.h (struct nativeserver): add signal_to_send field.
+       Rename stop_sig to stop_signal.
+
+2000-09-05  Michael Snyder  <msnyder@cleaver.cygnus.com>
+
+       * ptrace-target.c (ptrace_singlestep_program): Make ptrace args long.
+       FIXME: needs to be configurable.
+       * linux-target.c (linux_get_reg, linux_set_reg): Make regaddr and
+       regval configurable types.  FIXME needs real configury.
+
+2000-09-01  Michael Snyder  <msnyder@cleaver.cygnus.com>
+       New directory "native" for native gdbserver in libremote.
+       * server.c: New file.  Entry point and main event loop.
+       * server.h: New file.  Shared declarations.
+       * linux-target.c: New file.  Linux version of libremote native stub.
+       * ptrace-target.c: New file.  Ptrace operations for libremote stub.
+       * Makefile.am: New file.  Automake source.
+       * Makefile.in: New file.  Automake-generated makefile source.
+       Note: this work is incomplete and only partially working.
+       
+
diff --git a/rda/unix/Makefile.am b/rda/unix/Makefile.am
new file mode 100644 (file)
index 0000000..51ec186
--- /dev/null
@@ -0,0 +1,15 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+noinst_PROGRAMS = rda
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include 
+
+rda_SOURCES = server.c 
+EXTRA_rda_SOURCES = linux-target.c solaris-target.c \
+       ptrace-target.c dummy-target.c
+TARGET_MODULES = @TARGET_MODULES@
+rda_LDADD = $(TARGET_MODULES) ../lib/librda.la
+rda_DEPENDENCIES = $(server_OBJECTS) $(TARGET_MODULES)
+rda_LDFLAGS = -ldl -rdynamic
diff --git a/rda/unix/Makefile.in b/rda/unix/Makefile.in
new file mode 100644 (file)
index 0000000..eecb448
--- /dev/null
@@ -0,0 +1,415 @@
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CC = @CC@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+
+AUTOMAKE_OPTIONS = foreign
+
+noinst_PROGRAMS = rda
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include 
+
+rda_SOURCES = server.c 
+EXTRA_rda_SOURCES = linux-target.c solaris-target.c \
+       ptrace-target.c dummy-target.c
+
+TARGET_MODULES = @TARGET_MODULES@
+rda_LDADD = $(TARGET_MODULES) ../lib/librda.la
+rda_DEPENDENCIES = $(server_OBJECTS) $(TARGET_MODULES)
+rda_LDFLAGS = -ldl -rdynamic
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = 
+noinst_PROGRAMS =  rda$(EXEEXT)
+PROGRAMS =  $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+rda_OBJECTS =  server.o
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  ./stamp-h.in ChangeLog Makefile.am Makefile.in aclocal.m4 \
+config.in configure configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES =  .deps/dummy-target.P .deps/linux-target.P \
+.deps/ptrace-target.P .deps/server.P .deps/solaris-target.P
+SOURCES = $(rda_SOURCES) $(EXTRA_rda_SOURCES)
+OBJECTS = $(rda_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in 
+       cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+       @if test ! -f $@; then \
+               rm -f stamp-h; \
+               $(MAKE) stamp-h; \
+       else :; fi
+stamp-h: $(srcdir)/config.in $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \
+            $(SHELL) ./config.status
+       @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+       @if test ! -f $@; then \
+               rm -f $(srcdir)/stamp-h.in; \
+               $(MAKE) $(srcdir)/stamp-h.in; \
+       else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+       @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+       -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+       -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+rda$(EXEEXT): $(rda_OBJECTS) $(rda_DEPENDENCIES)
+       @rm -f rda$(EXEEXT)
+       $(LINK) $(rda_LDFLAGS) $(rda_OBJECTS) $(rda_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       -rm -rf $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+       mkdir $(distdir)/=build
+       mkdir $(distdir)/=inst
+       dc_install_base=`cd $(distdir)/=inst && pwd`; \
+       cd $(distdir)/=build \
+         && ../configure --srcdir=.. --prefix=$$dc_install_base \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) dist
+       -rm -rf $(distdir)
+       @banner="$(distdir).tar.gz is ready for distribution"; \
+       dashes=`echo "$$banner" | sed s/./=/g`; \
+       echo "$$dashes"; \
+       echo "$$banner"; \
+       echo "$$dashes"
+dist: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+dist-all: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+distdir: $(DISTFILES)
+       -rm -rf $(distdir)
+       mkdir $(distdir)
+       -chmod 777 $(distdir)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+all-recursive-am: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) config.h
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-hdr mostlyclean-noinstPROGRAMS \
+               mostlyclean-compile mostlyclean-libtool \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-hdr clean-noinstPROGRAMS clean-compile clean-libtool \
+               clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-hdr distclean-noinstPROGRAMS distclean-compile \
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+       -rm -f config.status
+
+maintainer-clean-am:  maintainer-clean-hdr \
+               maintainer-clean-noinstPROGRAMS \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+       -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck all-recursive-am install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/rda/unix/aclocal.m4 b/rda/unix/aclocal.m4
new file mode 100644 (file)
index 0000000..a53db13
--- /dev/null
@@ -0,0 +1,564 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Do all the work for Automake.  This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "[$]*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   if test "[$]*" != "X $srcdir/configure conftestfile" \
+      && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "[$]2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+   $1=$2
+   AC_MSG_RESULT(found)
+else
+   $1="$3/missing $2"
+   AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated.  We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+  case " <<$>>CONFIG_HEADERS " in
+  *" <<$>>am_file "*<<)>>
+    echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+    ;;
+  esac
+  am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode is disabled by default
+  AC_ARG_ENABLE(maintainer-mode,
+[  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer],
+      USE_MAINTAINER_MODE=$enableval,
+      USE_MAINTAINER_MODE=no)
+  AC_MSG_RESULT($USE_MAINTAINER_MODE)
+  AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi])
+
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+  [  --disable-libtool-lock  avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<<  --enable-shared[=PKGS]  build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<<  --enable-static[=PKGS]  build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<<  --enable-fast-install[=PKGS]  optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+changequote(,)dnl
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -B"
+       break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -p"
+       break
+      else
+       ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$host" in
+*-*-beos* | *-*-cygwin*)
+  # These system don't have libm
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, main, LIBM="-lm")
+  ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case "$enable_ltdl_convenience" in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, main,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    INCLTDL=
+  fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
diff --git a/rda/unix/config.in b/rda/unix/config.in
new file mode 100644 (file)
index 0000000..003ccc8
--- /dev/null
@@ -0,0 +1,120 @@
+/* config.in.  At one time this was generated automatically from
+  configure.in by autoheader.  It is now being maintained by hand.  */
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if system has <errno.h> */
+#undef HAVE_ERRNO_H
+
+/* Define if system has <ptrace.h> */
+#undef HAVE_PTRACE_H
+
+/* Define if system has <signal.h> */
+#undef HAVE_SIGNAL_H
+
+/* Define if system has <string.h> */
+#undef HAVE_STRING_H
+
+/* Define if system has <strings.h> */
+#undef HAVE_STRINGS_H
+
+/* Define if system has <sys/procfs.h> */
+#undef HAVE_SYS_PROCFS_H
+
+/* Define if system has <asm/reg.h> */
+#undef HAVE_ASM_REG_H
+
+/* Define if system has <sys/ptrace.h> */
+#undef HAVE_SYS_PTRACE_H
+
+/* Define if system has <sys/reg.h> */
+#undef HAVE_SYS_REG_H
+
+/* Define if system has <sys/user.h> */
+#undef HAVE_SYS_USER_H
+
+/* Define if system has <sys/wait.h> */
+#undef HAVE_SYS_WAIT_H
+
+/* Define for ptrace systems, to the size of a ptrace word. */
+#undef PTRACE_XFER_SIZE
+
+/* Define if ptrace transfer type is long or unsigned long. */
+#undef PTRACE_XFER_TYPE_LONG
+
+/* Define if ptrace transfer type is long long or unsigned long long. */
+#undef PTRACE_XFER_TYPE_LONG_LONG
+
+/* Define if ptrace arg1 type is long or unsigned long. */
+#undef PTRACE_ARG1_TYPE_LONG
+
+/* Define if ptrace arg1 type is long long or unsigned long long. */
+#undef PTRACE_ARG1_TYPE_LONG_LONG
+
+/* Define if ptrace arg2 type is long or unsigned long. */
+#undef PTRACE_ARG2_TYPE_LONG
+
+/* Define if ptrace arg2 type is long long or unsigned long long. */
+#undef PTRACE_ARG2_TYPE_LONG_LONG
+
+/* Define if ptrace arg3 type is long or unsigned long. */
+#undef PTRACE_ARG3_TYPE_LONG
+
+/* Define if ptrace arg3 type is long long or unsigned long long. */
+#undef PTRACE_ARG3_TYPE_LONG_LONG
+
+/* Define if ptrace arg4 type is long or unsigned long. */
+#undef PTRACE_ARG4_TYPE_LONG
+
+/* Define if ptrace arg4 type is long long or unsigned long long. */
+#undef PTRACE_ARG4_TYPE_LONG_LONG
+
+
+/* Define if target is x86 Linux */
+#undef X86_LINUX_TARGET
+
+/* Define if target is powerpc Linux */
+#undef PPC_LINUX_TARGET
+
+/* Define if target is m68k Linux */
+#undef M68K_LINUX_TARGET
+
+/* Define if target is alpha Linux */
+#undef ALPHA_LINUX_TARGET
+
+/* Define if target is arm Linux */
+#undef ARM_LINUX_TARGET
+
+/* Define if target is SH (3? 4?) Linux */
+#undef SH_LINUX_TARGET
+
+/* Define if target is MIPS Linux */
+#undef MIPS_LINUX_TARGET
+
+/* Define if target is any Linux */
+#undef LINUX_TARGET
+
+/* Define if target is any Solaris */
+#undef SOLARIS_TARGET
+
+/* Define the type name of a gregset */
+#undef GREGSET_T
+
+/* Define the type name of an fpregset */
+#undef FPREGSET_T
+
+/* Define if system headers will define lwpid_t */
+#undef HAVE_LWPID_T
+
+/* Define if system headers will define psaddr_t */
+#undef HAVE_PSADDR_T
+
+/* Define if system headers will define prgregset_t */
+#undef HAVE_PRGREGSET_T
+
+/* Define if system headers will define prfpregset_t */
+#undef HAVE_PRFPREGSET_T
diff --git a/rda/unix/configure b/rda/unix/configure
new file mode 100755 (executable)
index 0000000..a94ff77
--- /dev/null
@@ -0,0 +1,2530 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+  --enable-shared[=PKGS]  build shared libraries [default=yes]"
+ac_help="$ac_help
+  --enable-static[=PKGS]  build static libraries [default=yes]"
+ac_help="$ac_help
+  --enable-fast-install[=PKGS]  optimize for fast installation [default=yes]"
+ac_help="$ac_help
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+  --disable-libtool-lock  avoid locking (might break parallel builds)"
+ac_help="$ac_help
+  --enable-arm32=yes to force arm to 32 bit compilation"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=server.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+#    configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+#    same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+#    as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:587: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:608: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+  case $nonopt in
+  NONE) target_alias=$host_alias ;;
+  *) target_alias=$nonopt ;;
+  esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:626: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+  case $nonopt in
+  NONE) build_alias=$host_alias ;;
+  *) build_alias=$nonopt ;;
+  esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+# case "$target" in
+#    sh-*) CC=sh-linux-gnu-gcc;;
+# esac
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:663: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:716: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   if test "$*" != "X $srcdir/configure conftestfile" \
+      && test "$*" != "X conftestfile $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { echo "configure: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+   fi
+
+   test "$2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+  program_transform_name=
+else
+  # Double any \ or $.  echo might interpret backslashes.
+  cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+  rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:773: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+       @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=rda
+
+VERSION=0.1
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:819: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+   ACLOCAL=aclocal
+   echo "$ac_t""found" 1>&6
+else
+   ACLOCAL="$missing_dir/missing aclocal"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:832: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+   AUTOCONF=autoconf
+   echo "$ac_t""found" 1>&6
+else
+   AUTOCONF="$missing_dir/missing autoconf"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:845: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+   AUTOMAKE=automake
+   echo "$ac_t""found" 1>&6
+else
+   AUTOMAKE="$missing_dir/missing automake"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:858: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+   AUTOHEADER=autoheader
+   echo "$ac_t""found" 1>&6
+else
+   AUTOHEADER="$missing_dir/missing autoheader"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:871: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+   MAKEINFO=makeinfo
+   echo "$ac_t""found" 1>&6
+else
+   MAKEINFO="$missing_dir/missing makeinfo"
+   echo "$ac_t""missing" 1>&6
+fi
+
+
+
+
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:889: checking whether to enable maintainer-specific portions of Makefiles" >&5
+    # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+  enableval="$enable_maintainer_mode"
+  USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+  
+
+if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+  MAINT=$MAINTAINER_MODE_TRUE
+  
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_fast_install=yes
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:983: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1013: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1043: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1094: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1126: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1137 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1168: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1173: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1201: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1244: checking for ld used by GCC" >&5
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1268: checking for GNU ld" >&5
+else
+  echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1271: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1306: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1322: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -B"
+       break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -p"
+       break
+      else
+       ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1358: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+  :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 1402 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:1403: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1424: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1429 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:1538: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1543 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:1554: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_cygwin=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:1571: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1576 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:1583: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_mingw32=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:1602: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+  ac_cv_exeext=.exe
+else
+  rm -f conftest*
+  echo 'int main () { return 0; }' > conftest.$ac_ext
+  ac_cv_exeext=
+  if { (eval echo configure:1612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+    for file in conftest.*; do
+      case $file in
+      *.c | *.o | *.obj) ;;
+      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+      esac
+    done
+  else
+    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+  fi
+  rm -f conftest*
+  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+
+arm32=yes
+# Check whether --enable-arm32 or --disable-arm32 was given.
+if test "${enable_arm32+set}" = set; then
+  enableval="$enable_arm32"
+  case "${enableval}" in
+  yes) arm32=yes ;;
+  no)  arm32=no ;;
+  *)
+esac
+fi
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1653: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 1668 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1674: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 1685 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1691: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 1702 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1708: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+for ac_hdr in errno.h ptrace.h signal.h string.h strings.h sys/procfs.h \
+       asm/reg.h sys/ptrace.h sys/reg.h sys/user.h sys/wait.h 
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1737: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1742 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1747: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+case "$target" in
+  i?86*linux* | \
+  powerpc*linux* | \
+  arm*linux* | \
+  mips*linux*)
+    TARGET_MODULES="linux-target.o thread-db.o ptrace-target.o" 
+    cat >> confdefs.h <<\EOF
+#define LINUX_TARGET 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define GREGSET_T prgregset_t
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define FPREGSET_T prfpregset_t
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_LWPID_T 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_PSADDR_T 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_PRGREGSET_T 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_PRFPREGSET_T 1
+EOF
+
+    ;;
+  *linux*)
+    TARGET_MODULES="linux-target.o no-threads.o ptrace-target.o" 
+    cat >> confdefs.h <<\EOF
+#define LINUX_TARGET 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define GREGSET_T prgregset_t
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define FPREGSET_T prfpregset_t
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_LWPID_T 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_PSADDR_T 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_PRGREGSET_T 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define HAVE_PRFPREGSET_T 1
+EOF
+
+    ;;
+  *solaris*)
+    TARGET_MODULES="solaris-target.o dummy-target.o" 
+    cat >> confdefs.h <<\EOF
+#define SOLARIS_TARGET 1
+EOF
+
+# Place-holders -- not necessarily correct...
+    cat >> confdefs.h <<\EOF
+#define GREGSET_T gregset_t
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define FPREGSET_T fpregset_t
+EOF
+
+    ;;
+esac
+
+
+
+case "$target" in
+  *solaris*)
+        cat >> confdefs.h <<\EOF
+#define SPARC32_SOLARIS_TARGET 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_SIZE 4
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG1_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG2_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG3_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG4_TYPE_LONG 1
+EOF
+
+    ;;
+  sh*linux*)
+    cat >> confdefs.h <<\EOF
+#define SH_LINUX_TARGET 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_SIZE 4
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG1_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG2_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG3_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG4_TYPE_LONG 1
+EOF
+
+    ;;
+  mips*linux*)
+    cat >> confdefs.h <<\EOF
+#define MIPS_LINUX_TARGET 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_SIZE 4
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG1_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG2_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG3_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG4_TYPE_LONG 1
+EOF
+
+    ;;
+  i?86*linux*)
+    cat >> confdefs.h <<\EOF
+#define X86_LINUX_TARGET 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_SIZE 4
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG1_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG2_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG3_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG4_TYPE_LONG 1
+EOF
+
+    ;;
+  powerpc*linux*)
+    cat >> confdefs.h <<\EOF
+#define PPC_LINUX_TARGET 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_SIZE 4
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG1_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG2_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG3_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG4_TYPE_LONG 1
+EOF
+
+    ;;
+  m68k*linux*)
+    cat >> confdefs.h <<\EOF
+#define M68K_LINUX_TARGET 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_SIZE 4
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG1_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG2_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG3_TYPE_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG4_TYPE_LONG 1
+EOF
+
+    ;;
+  alpha*linux*)
+    cat >> confdefs.h <<\EOF
+#define ALPHA_LINUX_TARGET 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_SIZE 8
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_TYPE_LONG_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG1_TYPE_LONG_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG2_TYPE_LONG_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG3_TYPE_LONG_LONG 1
+EOF
+
+    cat >> confdefs.h <<\EOF
+#define PTRACE_ARG4_TYPE_LONG_LONG 1
+EOF
+
+    ;;
+  arm*linux*)
+       if test "$arm32" = "yes"; then
+           cat >> confdefs.h <<\EOF
+#define ARM_LINUX_TARGET 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_SIZE 4
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_TYPE_LONG 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_ARG1_TYPE_LONG 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_ARG2_TYPE_LONG 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_ARG3_TYPE_LONG 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_ARG4_TYPE_LONG 1
+EOF
+
+       else
+           cat >> confdefs.h <<\EOF
+#define ARM_LINUX_TARGET 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_SIZE 8
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_XFER_TYPE_LONG_LONG 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_ARG1_TYPE_LONG_LONG 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_ARG2_TYPE_LONG_LONG 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_ARG3_TYPE_LONG_LONG 1
+EOF
+
+           cat >> confdefs.h <<\EOF
+#define PTRACE_ARG4_TYPE_LONG_LONG 1
+EOF
+
+       fi
+       ;;
+esac
+
+if test -f /usr/include/foo.h; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_AC_DEFINE 1
+EOF
+
+fi
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@RANLIB@%$RANLIB%g
+s%@CC@%$CC%g
+s%@LN_S@%$LN_S%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@EXEEXT@%$EXEEXT%g
+s%@CPP@%$CPP%g
+s%@TARGET_MODULES@%$TARGET_MODULES%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='\([     ][      ]*\)[^  ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='\([     ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/rda/unix/configure.in b/rda/unix/configure.in
new file mode 100644 (file)
index 0000000..8528cdd
--- /dev/null
@@ -0,0 +1,158 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(server.h)
+AC_CANONICAL_SYSTEM
+# case "$target" in
+#    sh-*) CC=sh-linux-gnu-gcc;;
+# esac
+AM_INIT_AUTOMAKE(rda,0.1)
+AM_CONFIG_HEADER(config.h:config.in)
+
+dnl automake support
+AM_MAINTAINER_MODE
+AM_PROG_LIBTOOL
+AC_EXEEXT
+AC_LANG_C
+
+arm32=yes
+AC_ARG_ENABLE(arm32,
+[  --enable-arm32=yes to force arm to 32 bit compilation],
+[case "${enableval}" in
+  yes) arm32=yes ;;
+  no)  arm32=no ;;
+  *)
+esac])
+
+dnl headers
+AC_CHECK_HEADERS(errno.h ptrace.h signal.h string.h strings.h sys/procfs.h \
+       asm/reg.h sys/ptrace.h sys/reg.h sys/user.h sys/wait.h )
+
+dnl define ptrace_xfer_type
+dnl define ptrace_arg3_type
+
+case "$target" in
+  i?86*linux* | \
+  powerpc*linux* | \
+  arm*linux* | \
+  mips*linux*)
+    TARGET_MODULES="linux-target.o thread-db.o ptrace-target.o" 
+    AC_DEFINE(LINUX_TARGET)
+    AC_DEFINE(GREGSET_T,  prgregset_t)
+    AC_DEFINE(FPREGSET_T, prfpregset_t)
+    AC_DEFINE(HAVE_LWPID_T)
+    AC_DEFINE(HAVE_PSADDR_T)
+    AC_DEFINE(HAVE_PRGREGSET_T)
+    AC_DEFINE(HAVE_PRFPREGSET_T)
+    ;;
+  *linux*)
+    TARGET_MODULES="linux-target.o no-threads.o ptrace-target.o" 
+    AC_DEFINE(LINUX_TARGET)
+    AC_DEFINE(GREGSET_T,  prgregset_t)
+    AC_DEFINE(FPREGSET_T, prfpregset_t)
+    AC_DEFINE(HAVE_LWPID_T)
+    AC_DEFINE(HAVE_PSADDR_T)
+    AC_DEFINE(HAVE_PRGREGSET_T)
+    AC_DEFINE(HAVE_PRFPREGSET_T)
+    ;;
+  *solaris*)
+    TARGET_MODULES="solaris-target.o dummy-target.o" 
+    AC_DEFINE(SOLARIS_TARGET)
+# Place-holders -- not necessarily correct...
+    AC_DEFINE(GREGSET_T,  gregset_t)
+    AC_DEFINE(FPREGSET_T, fpregset_t)
+    ;;
+esac
+
+AC_SUBST(TARGET_MODULES)
+
+case "$target" in
+  *solaris*)
+    dnl FIXME: differentiate between flavors of Solaris!
+    AC_DEFINE(SPARC32_SOLARIS_TARGET)
+    AC_DEFINE(PTRACE_XFER_SIZE, 4)
+    AC_DEFINE(PTRACE_XFER_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG1_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG2_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG3_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG4_TYPE_LONG)
+    ;;
+  sh*linux*)
+    AC_DEFINE(SH_LINUX_TARGET)
+    AC_DEFINE(PTRACE_XFER_SIZE, 4)
+    AC_DEFINE(PTRACE_XFER_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG1_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG2_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG3_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG4_TYPE_LONG)
+    ;;
+  mips*linux*)
+    AC_DEFINE(MIPS_LINUX_TARGET)
+    AC_DEFINE(PTRACE_XFER_SIZE, 4)
+    AC_DEFINE(PTRACE_XFER_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG1_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG2_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG3_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG4_TYPE_LONG)
+    ;;
+  i?86*linux*)
+    AC_DEFINE(X86_LINUX_TARGET)
+    AC_DEFINE(PTRACE_XFER_SIZE, 4)
+    AC_DEFINE(PTRACE_XFER_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG1_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG2_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG3_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG4_TYPE_LONG)
+    ;;
+  powerpc*linux*)
+    AC_DEFINE(PPC_LINUX_TARGET)
+    AC_DEFINE(PTRACE_XFER_SIZE, 4)
+    AC_DEFINE(PTRACE_XFER_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG1_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG2_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG3_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG4_TYPE_LONG)
+    ;;
+  m68k*linux*)
+    AC_DEFINE(M68K_LINUX_TARGET)
+    AC_DEFINE(PTRACE_XFER_SIZE, 4)
+    AC_DEFINE(PTRACE_XFER_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG1_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG2_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG3_TYPE_LONG)
+    AC_DEFINE(PTRACE_ARG4_TYPE_LONG)
+    ;;
+  alpha*linux*)
+    AC_DEFINE(ALPHA_LINUX_TARGET)
+    AC_DEFINE(PTRACE_XFER_SIZE, 8)
+    AC_DEFINE(PTRACE_XFER_TYPE_LONG_LONG)
+    AC_DEFINE(PTRACE_ARG1_TYPE_LONG_LONG)
+    AC_DEFINE(PTRACE_ARG2_TYPE_LONG_LONG)
+    AC_DEFINE(PTRACE_ARG3_TYPE_LONG_LONG)
+    AC_DEFINE(PTRACE_ARG4_TYPE_LONG_LONG)
+    ;;
+  arm*linux*)
+       if test "$arm32" = "yes"; then
+           AC_DEFINE(ARM_LINUX_TARGET)
+           AC_DEFINE(PTRACE_XFER_SIZE, 4)
+           AC_DEFINE(PTRACE_XFER_TYPE_LONG)
+           AC_DEFINE(PTRACE_ARG1_TYPE_LONG)
+           AC_DEFINE(PTRACE_ARG2_TYPE_LONG)
+           AC_DEFINE(PTRACE_ARG3_TYPE_LONG)
+           AC_DEFINE(PTRACE_ARG4_TYPE_LONG)
+       else
+           AC_DEFINE(ARM_LINUX_TARGET)
+           AC_DEFINE(PTRACE_XFER_SIZE, 8)
+           AC_DEFINE(PTRACE_XFER_TYPE_LONG_LONG)
+           AC_DEFINE(PTRACE_ARG1_TYPE_LONG_LONG)
+           AC_DEFINE(PTRACE_ARG2_TYPE_LONG_LONG)
+           AC_DEFINE(PTRACE_ARG3_TYPE_LONG_LONG)
+           AC_DEFINE(PTRACE_ARG4_TYPE_LONG_LONG)
+       fi
+       ;;
+esac
+
+if test -f /usr/include/foo.h; then
+  AC_DEFINE(HAVE_AC_DEFINE, 1, [define if have AC_DEFINE])
+fi
+
+dnl Outputs
+AC_OUTPUT(Makefile)
diff --git a/rda/unix/dummy-target.c b/rda/unix/dummy-target.c
new file mode 100644 (file)
index 0000000..85dccfa
--- /dev/null
@@ -0,0 +1,386 @@
+/* dummy-target.c
+
+   Copyright 2000, 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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "gdbserv.h" 
+#include "gdbserv-target.h" 
+#include "gdbserv-utils.h"
+
+#include "server.h"
+
+/* This is a sample gdbserv target that demonstrates use of the RDA
+   library routines.  It acts to gdb like a strange generic remote target. */
+
+ /* process_get_gen */
+ /* process_set_gen */
+static void server_process_rcmd (struct gdbserv* serv, 
+                               const char* cmd, int sizeof_cmd);
+ /* process_set_args */
+ /* process_set_reg */
+static int  server_process_set_regs (struct gdbserv* serv);
+static void server_process_get_regs (struct gdbserv* serv);
+ /* input_reg */
+ /* output_reg */
+ /* gg_reg_nr */
+ /* expedited_reg_nr */
+ /* sizeof_reg */
+ /* set_reg */
+ /* get_reg */
+static long server_get_mem (struct gdbserv* serv, 
+                          struct gdbserv_reg* addr, 
+                          void* data, 
+                          long len);
+static long server_set_mem (struct gdbserv* serv, 
+                          struct gdbserv_reg* addr, 
+                          void* data, 
+                          long len);
+ /* process_set_pc */
+ /* process_signal */
+static void server_flush_i_cache (struct gdbserv* serv);
+static unsigned long server_compute_signal (struct gdbserv* serv, 
+                                          unsigned long);
+static unsigned long server_get_trap_number (struct gdbserv* serv);
+static void server_exit_program (struct gdbserv* serv);
+static void server_break_program (struct gdbserv* serv);
+static int  server_reset_program (struct gdbserv* serv);
+static void server_restart_program (struct gdbserv* serv);
+static void server_singlestep_program (struct gdbserv* serv);
+static void server_cyclestep_program (struct gdbserv* serv);
+static void server_sigkill_program (struct gdbserv* serv);
+static void server_continue_program (struct gdbserv* serv);
+ /* remove_breakpoint */
+ /* set_breakpoint */
+ /* process_target */
+static void server_detach (struct gdbserv* serv, struct gdbserv_target* target);
+
+
+
+
+
+int server_ticks_before_break_p = 0;
+
+/* Track sole connection to a remote gdb client. */
+static struct gdbserv* sole_connection = NULL;
+
+/* This function is called from gdbloop_poll() when a new incoming
+   connection is attempted.  It may return NULL if the new connection
+   is to be refused, or a gdbserv_target vector if the connection is
+   accepted. */
+struct gdbserv_target* 
+dummy_attach (struct gdbserv* serv, void* context)
+{
+  struct gdbserv_target *target;
+  /* Enable server tracing. */
+  gdbserv_state_trace = stderr;
+  /* gdbserv_input_trace = stderr; */
+  /* gdbserv_output_trace = stderr; */
+
+  if (sole_connection != NULL)
+    {
+      fprintf (stderr, "Rejected duplicate connection.\n");
+      return NULL;
+    }
+
+  fprintf (stderr, "Accepted gdb connection.\n");
+  sole_connection = serv;
+
+  target = malloc (sizeof (struct gdbserv_target));
+  memset (target, 0, sizeof (*target));
+
+  /* Callback structure for function pointers that handle processed
+     control packets.  See gdbserv-target.h for docs on the individual
+     functions. */
+
+  target->process_get_gen       = NULL;
+  target->process_set_gen       = NULL;
+  target->process_rcmd          = server_process_rcmd;
+  target->process_set_args      = NULL;
+  target->process_set_reg       = NULL;
+  target->process_get_reg       = NULL;
+  target->process_set_regs      = server_process_set_regs /* (deprecated) */;
+  target->process_get_regs      = server_process_get_regs /* (deprecated) */;
+  target->input_reg             = NULL;
+  target->output_reg            = NULL;
+  target->gg_reg_nr             = NULL;
+  target->expedited_reg_nr      = NULL;
+  target->sizeof_reg            = NULL;
+  target->set_reg               = NULL;
+  target->get_reg               = NULL;
+  target->get_mem               = server_get_mem;
+  target->set_mem               = server_set_mem;
+  target->process_set_pc        = NULL;
+  target->flush_i_cache         = server_flush_i_cache;
+  target->process_signal        = NULL;
+  target->compute_signal        = server_compute_signal;
+  target->get_trap_number       = server_get_trap_number;
+  target->exit_program          = server_exit_program;
+  target->break_program         = server_break_program;
+  target->reset_program         = server_reset_program;
+  target->restart_program       = server_restart_program;
+  target->singlestep_program    = server_singlestep_program;
+  target->cyclestep_program     = server_cyclestep_program;
+  target->sigkill_program       = server_sigkill_program;
+  target->continue_program      = server_continue_program;
+  target->remove_breakpoint     = NULL;
+  target->set_breakpoint        = NULL;
+  target->process_target_packet = NULL;
+  target->detach                = server_detach;
+
+  /* DATA can be assigned any value.  That value is accessible via
+     gdbserv_target_data().  This example just happens to use
+     CONTEXT. */
+  target->data = context;
+
+  return target;
+}
+
+static void
+server_detach (struct gdbserv* serv, struct gdbserv_target* target)
+{
+  assert (serv == sole_connection);
+
+  fprintf (stderr, "Detached.\n");
+  sole_connection = NULL;
+
+  /* Quit out of main loop for this demo.  In general, this is not
+     necessary, as the next incoming connection could again be handled
+     by server_attach() above.  */
+  server_quit_p = 1;
+}
+
+
+
+static unsigned long
+server_get_trap_number (struct gdbserv* serv)
+{
+  /* Return a target-dependent trap number. */
+  return 0;
+}
+
+
+static unsigned long
+server_compute_signal (struct gdbserv* serv, unsigned long tgtsig)
+{
+  assert (tgtsig == 0); /* comes from get_trap_number above */
+  /* Return standard signal number */
+  return GDBSERV_SIGTRAP;
+}
+
+
+static void
+server_process_rcmd (struct gdbserv* serv, const char* cmd, int sizeof_cmd)
+{
+  gdbserv_output_bytes (serv, cmd, sizeof_cmd);
+}
+
+/*
+ * Get/Set Registers
+ * 
+ * (including a primitive register cache) 
+ */
+
+static struct target_regs {    /* register cache */
+  unsigned int len;
+  unsigned char buf[180];
+} target_regs;
+
+static void 
+server_process_get_regs (struct gdbserv* serv)
+{
+  int i;
+
+  for (i=0; i<180; i++) /* 180 bytes < gdb's PBUFSIZ/2 */
+    gdbserv_output_byte (serv, target_regs.buf[i]);
+}
+
+static int 
+server_process_set_regs (struct gdbserv *serv)
+{
+  gdbserv_input_bytes (serv, (char *) &target_regs.buf, 
+                      sizeof (target_regs.buf));
+  return 0;
+}
+
+static void
+server_exit_program (struct gdbserv* serv)
+{
+  gdbserv_fromtarget_exit (serv, GDBSERV_SIGQUIT);
+}
+
+static void
+server_break_program (struct gdbserv* serv)
+{
+  /* Enqueue a break response */
+  server_ticks_before_break_p = 1;
+}
+
+static int
+server_reset_program (struct gdbserv* serv)
+{
+  gdbserv_fromtarget_reset (serv);
+  return 0;
+}
+
+static void
+server_restart_program (struct gdbserv* serv)
+{
+  /* Enqueue a break response */
+  server_ticks_before_break_p = 1;
+}
+
+
+static void
+server_singlestep_program (struct gdbserv* serv)
+{
+  /* Enqueue a break response */
+  server_ticks_before_break_p = 2;
+}
+
+static void
+server_cyclestep_program (struct gdbserv* serv)
+{
+  /* Enqueue a break response */
+  server_ticks_before_break_p = 1;
+}
+
+static void
+server_sigkill_program (struct gdbserv* serv)
+{
+  gdbserv_fromtarget_exit (serv, GDBSERV_SIGKILL);
+}
+
+static void 
+server_continue_program (struct gdbserv* serv)
+{
+  fprintf (stderr, "Resumed fictional target program - send break from gdb or wait a while.\n");
+  /* Enqueue a break response */
+  server_ticks_before_break_p = 10;
+}
+
+/*
+ * Get/Set memory
+ *
+ * (including a primitive memory cache)
+ */
+
+static struct target_mem {     /* memory cache */
+  unsigned long base;
+  unsigned long len;
+  unsigned char *buf;
+} target_mem;
+
+static long
+server_get_mem (struct gdbserv* serv, 
+             struct gdbserv_reg* addr, 
+             void* data, 
+             long len)
+{
+  long n;
+  unsigned char *d = data;
+  unsigned long request_base;
+
+  gdbserv_reg_to_ulong (serv, addr, &request_base);
+
+  for (n=0; n<len; n++)
+    {
+      if (request_base + n >= target_mem.base &&
+         request_base + n <  target_mem.base + target_mem.len)
+       *d++ = target_mem.buf[request_base + n - target_mem.base];
+      else
+       *d++ = 0;
+    }
+
+  return n;
+}
+
+static long
+server_set_mem (struct gdbserv* serv, 
+             struct gdbserv_reg* addr, 
+             void* data, 
+             long len)
+{
+  unsigned long request_base;
+
+  gdbserv_reg_to_ulong (serv, addr, &request_base);
+  if (target_mem.len == 0)
+    {
+      target_mem.buf  = malloc (len);
+      target_mem.len  = len;
+      gdbserv_reg_to_ulong (serv, addr, &target_mem.base);
+    }
+  else
+    {
+      if (request_base < target_mem.base)
+       {
+         target_mem.len += target_mem.base - request_base;
+         target_mem.base = request_base;
+         target_mem.buf  = realloc (target_mem.buf, target_mem.len);
+       }
+      if (request_base + len > 
+         target_mem.base + target_mem.len)
+       {
+         target_mem.len += 
+           (request_base + len) - (target_mem.base + target_mem.len);
+         target_mem.buf  = realloc (target_mem.buf, target_mem.len);
+       }
+    }
+
+  memcpy (target_mem.buf + (request_base - target_mem.base), 
+         data, 
+         len);
+  return  len;
+}
+
+
+static void
+server_flush_i_cache (struct gdbserv* serv)
+{
+}
+
+
+int
+dummy_check_child_state (struct nativeserver *process)
+{
+  return 0;    /* simulate an event right away */
+}
+
+void
+dummy_break ()
+{
+  gdbserv_fromtarget_break (sole_connection, GDBSERV_SIGTRAP);
+}
+
+
+void
+dummy_exit ()
+{
+  gdbserv_fromtarget_exit (sole_connection, GDBSERV_SIGTRAP);
+}
+
+
diff --git a/rda/unix/gdb_proc_service.h b/rda/unix/gdb_proc_service.h
new file mode 100644 (file)
index 0000000..b2d2956
--- /dev/null
@@ -0,0 +1,46 @@
+/* Define types needed to interface with libthread_db.so.
+
+   Copyright 2000, 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 <sys/types.h>
+
+#ifdef HAVE_SYS_PROCFS_H
+#include <sys/procfs.h>
+#endif
+
+typedef enum
+{
+  PS_OK,                       /* Success.  */
+  PS_ERR,                      /* Generic error.  */
+  PS_BADPID,                   /* Bad process handle.  */
+  PS_BADLID,                   /* Bad LWP id.  */
+  PS_BADADDR,                  /* Bad address.  */
+  PS_NOSYM,                    /* Symbol not found.  */
+  PS_NOFREGS                   /* FPU register set not available.  */
+} ps_err_e;
+
+typedef unsigned long paddr_t;
+
+#ifndef HAVE_PSADDR_T
+typedef unsigned long psaddr_t;
+#endif
diff --git a/rda/unix/gdbserv-thread-db.h b/rda/unix/gdbserv-thread-db.h
new file mode 100644 (file)
index 0000000..0e2c367
--- /dev/null
@@ -0,0 +1,99 @@
+/* gdbserv-thread-db.h
+
+   Copyright 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.  */
+
+/* Structure that identifies the target process.  */
+struct ps_prochandle
+{
+  pid_t  pid;
+  struct gdbserv *serv;
+};
+
+typedef struct ps_prochandle * gdb_ps_prochandle_t;
+typedef void *                 gdb_ps_read_buf_t;
+typedef void *                 gdb_ps_write_buf_t;
+typedef size_t                 gdb_ps_size_t;
+
+extern int thread_db_noisy;
+
+/* Determine if register is a member of GREGSET_T.  */
+extern int is_gp_reg (int regnum);
+
+/* Determine if register is a floating point register, specifically
+   a member of FPREGSET_T.  */
+extern int is_fp_reg (int regnum);
+
+/* Determine if register is an "extended register" (the meaning of which
+   is architecture and perhaps even OS or libc dependent).  */
+extern int is_extended_reg (int regnum);
+
+/* Insert a register into a gregset. */
+extern int reg_to_gregset (struct gdbserv *serv,
+                          const struct gdbserv_reg *reg,
+                          int regno,
+                          GREGSET_T gregset);
+
+/* Extract a register from a gregset. */
+extern int reg_from_gregset (struct gdbserv *serv,
+                            struct gdbserv_reg *reg,
+                            int regno,
+                            const GREGSET_T gregset);
+
+/* Insert a register into an fpregset. */
+extern int reg_to_fpregset (struct gdbserv *serv,
+                           const struct gdbserv_reg *reg,
+                           int regno,
+                           FPREGSET_T *fpregset);
+
+/* Extract a register from an fpregset. */
+extern int reg_from_fpregset (struct gdbserv *serv,
+                             struct gdbserv_reg *reg,
+                             int regno,
+                             const FPREGSET_T *fpregset);
+
+/* Insert a register into an extended regset. */
+extern int reg_to_xregset (struct gdbserv *serv, 
+                          const struct gdbserv_reg *reg, 
+                          int regno, 
+                          void *xregset);
+
+/* Extract a register from an extended regset. */
+extern int reg_from_xregset (struct gdbserv *serv, 
+                            struct gdbserv_reg *reg, 
+                            int regno, 
+                            const void *xregset);
+
+/* Resume a stopped LWP. */
+extern int continue_lwp (lwpid_t lid, int signal);
+
+/* Step a stopped LWP. */
+extern int singlestep_lwp (lwpid_t lid, int signal);
+
+/* Attach an LWP. */
+extern int attach_lwp (lwpid_t lid);
+
+/* Fetch the value of PC for debugging purposes.  */
+extern unsigned long debug_get_pc (struct gdbserv *serv, pid_t pid);
+
+/* Adjust PC value after trap has been hit.  */
+extern int decr_pc_after_break (struct gdbserv *serv, pid_t pid);
diff --git a/rda/unix/linux-target.c b/rda/unix/linux-target.c
new file mode 100644 (file)
index 0000000..06ee2ac
--- /dev/null
@@ -0,0 +1,2644 @@
+/* linux-target.c
+
+   Copyright 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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#if !defined(_MIPSEL) && !defined(_MIPSEB)
+#include <stdint.h>
+#else
+#include <asm-mips/inst.h>
+#endif
+
+#include <sys/ptrace.h>
+#include <sys/procfs.h>
+#include "gdbserv.h"
+#include "gdbserv-target.h"
+#include "gdbserv-utils.h"
+
+#include "gdb_proc_service.h"
+#include "gdbserv-thread-db.h"
+
+#include "server.h"
+#include "ptrace-target.h"
+
+/* This is a linux native gdbserv target that uses the RDA library to
+   implement a remote gdbserver on a linux host.  It controls the
+   process to be debugged on the linux host, allowing GDB to pull the
+   strings from any host on the network (or on a serial port).  */
+
+/*
+ * Messy target-dependent register stuff
+ */
+
+#if defined (HAVE_SYS_REG_H)
+#include <sys/reg.h>
+#elif defined (HAVE_ASM_REG_H)
+#include <asm/reg.h>
+#else
+/* Desperation -- try asm/ptrace.h */
+#include <asm/ptrace.h>
+#endif
+#include <errno.h>
+#include <string.h>
+
+enum
+{
+  /* Maximum size of a register in bytes.  */
+  MAX_REG_SIZE = 64
+};
+
+enum regset
+{
+  /* Not available.  */
+  NOREGS,
+
+  /* General purpose register.  */
+  GREGS,
+
+  /* Floating point register.  */
+  FPREGS,
+
+  /* Extended floating point register.  (Probably MMX, SSE, or Altivec...) */
+  FPXREGS
+};
+
+/* struct getregs_setregs_reginfo is used to construct register tables
+   for architectures which need to use PTRACE_GETREGS, PTRACE_SETREGS,
+   PTRACE_GETFPREGS, PTRACE_SETFPREGS, etc.  to access all of the
+   registers.  */
+
+struct getregs_setregs_reginfo
+{
+  /* The register set used to fetch this register, one of GREGS, FPREGS,
+     or FPXREGS.  */
+  enum regset whichregs;
+
+  /* Register set specific offset needed for accessing the register
+     in question.  */
+  int offset;
+
+  /* Size of the field being accessed in "ptrace" struct.  */
+  int ptrace_size;
+
+  /* Size of field needed by gdb's remote protocol. */
+  int proto_size;
+};
+
+/* struct peekuser_pokeuser_reginfo is used to construct register
+   tables for architectures which can access all of the registers
+   via the PTRACE_PEEKUSER and PTRACE_POKEUSER operations.  */
+
+struct peekuser_pokeuser_reginfo
+{
+  /* Offset to use with PTRACE_PEEKUSER or PTRACE_POKEUSER.  This
+     offset should not require any further adjustment.  */
+  int ptrace_offset;
+
+  /* Size of field being accessed via PTRACE_PEEKUSER or PTRACE_POKEUSER.
+     Note that a large enough value could cause multiple peek/poke
+     operations to occur.  */
+  int ptrace_size;
+
+  /* Register set (either GREGS or FPREGS) that this register
+     belongs to.  */
+  enum regset whichregs;
+
+  /* Offset into regset struct at which register is stored.  */
+  int regset_field_offset;
+
+  /* Size of field in regset struct.  */
+  int regset_field_size;
+
+  /* Size of field as required by gdb's remote protocol.  */
+  int proto_size;
+};
+
+/* Obtain the offset of MEMBER from a struct of type TYPE.  */
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((int) ((char *) &((TYPE *) 0)->MEMBER))
+#endif
+
+/* Obtain the size of the field MEMBER from a struct of type TYPE.  */
+#define fieldsize(TYPE, MEMBER) (sizeof (((TYPE *)0)->MEMBER))
+
+/* Each architecture must define the following:
+
+  1) An anonymous enum which defines the number of registers
+     (NUM_REGS) accessible via a g/G packet.  Note that this may be
+     larger or smaller than the total number of registers actually
+     available on an architecture.  It can be larger in the case of
+     an architecture variant which, e.g, doesn't have floating point
+     registers.  It could be smaller when there are certain control
+     registers which aren't exposed via GDB's debug interface.
+
+  2) An anonymous enum which defines the index of the PC register (PC_REGNUM).
+
+  3) A table named ``reginfo[]'' which describes the register set.  Indices
+     into this table are GDB protocol register numbers.  Elements of the
+     table are either peekuser_pokeuser_reginfo or getregs_setregs_reginfo
+     structs depending upon which ptrace() operations are required to
+     access all of the registers.  Some ptrace() implementations contain
+     support for both {get,set}regset and {peek,poke}user operations, but
+     those which implement both sets of operations rarely provide support
+     for fetching all of the registers via one set of operations.  Usually,
+     if the PTRACE_GETREGS operation is implemented, this means that
+     struct getregs_setregs_reginfo will need to be used to define reginfo[].
+     Otherwise, peekuser_pokeuser_reginfo[] should be used.  If it's the
+     case that both sets of operations provide complete access to all of
+     the registers of interest, then a slight preference should be given
+     to using the peekuser_pokeuser_reginfo struct since this code should
+     be somewhat more efficient.  (Though this could change if a register
+     cache is implemented.)
+
+  4) Either
+
+       #define PEEKUSER_POKEUSER_REGINFO 1
+
+     or
+
+       #define GETREGS_SETREGS_REGINFO 1
+
+     Actually, there's a third option which is to define neither of
+     these, but this is only used by architectures which still use
+     the old, decrepit mechanism which doesn't work with threads
+     very well, nor handle registers of different sizes, etc.  So,
+     do be sure to define one of the above.  Someday, we'll hopefully
+     have all of the architectures converted over so that we won't
+     even need to mention this third option.
+
+*/
+
+     
+
+
+#if defined (ARM_LINUX_TARGET)
+
+/* ARM needs to use PTRACE_GETREGS / PTRACE_SETREGS and
+   PTRACE_GETFPREGS / PTRACE_SETFPREGS to access all of the registers. 
+   */
+#define GETREGS_SETREGS_REGINFO 1
+
+enum 
+{ 
+  PC_REGNUM = 15,
+  NUM_REGS = 26
+};
+
+static struct getregs_setregs_reginfo reginfo[] =
+{
+  { GREGS, 0 * 4, 4, 4 },                                      /* r0 */
+  { GREGS, 1 * 4, 4, 4 },                                      /* r1 */
+  { GREGS, 2 * 4, 4, 4 },                                      /* r2 */
+  { GREGS, 3 * 4, 4, 4 },                                      /* r3 */
+  { GREGS, 4 * 4, 4, 4 },                                      /* r4 */
+  { GREGS, 5 * 4, 4, 4 },                                      /* r5 */
+  { GREGS, 6 * 4, 4, 4 },                                      /* r6 */
+  { GREGS, 7 * 4, 4, 4 },                                      /* r7 */
+  { GREGS, 8 * 4, 4, 4 },                                      /* r8 */
+  { GREGS, 9 * 4, 4, 4 },                                      /* r9 */
+  { GREGS, 10 * 4, 4, 4 },                                     /* r10 */
+  { GREGS, 11 * 4, 4, 4 },                                     /* r11 */
+  { GREGS, 12 * 4, 4, 4 },                                     /* r12, sp */
+  { GREGS, 13 * 4, 4, 4 },                                     /* r13, lr */
+  { GREGS, 14 * 4, 4, 4 },                                     /* r14, fp */
+  { GREGS, 15 * 4, 4, 4 },                                     /* r15, pc */
+  { FPREGS, offsetof (struct user_fpregs, fpregs[0]),
+            fieldsize (struct user_fpregs, fpregs[0]), 12},    /* f0 */
+  { FPREGS, offsetof (struct user_fpregs, fpregs[1]),
+            fieldsize (struct user_fpregs, fpregs[1]), 12},    /* f1 */
+  { FPREGS, offsetof (struct user_fpregs, fpregs[2]),
+            fieldsize (struct user_fpregs, fpregs[2]), 12},    /* f2 */
+  { FPREGS, offsetof (struct user_fpregs, fpregs[3]),
+            fieldsize (struct user_fpregs, fpregs[3]), 12},    /* f3 */
+  { FPREGS, offsetof (struct user_fpregs, fpregs[4]),
+            fieldsize (struct user_fpregs, fpregs[4]), 12},    /* f4 */
+  { FPREGS, offsetof (struct user_fpregs, fpregs[5]),
+            fieldsize (struct user_fpregs, fpregs[5]), 12},    /* f5 */
+  { FPREGS, offsetof (struct user_fpregs, fpregs[6]),
+            fieldsize (struct user_fpregs, fpregs[6]), 12},    /* f6 */
+  { FPREGS, offsetof (struct user_fpregs, fpregs[7]),
+            fieldsize (struct user_fpregs, fpregs[7]), 12},    /* f7 */
+  /* We'd actually like to take the address of the fpsr field, but
+     unfortunately, this is a bitfield and it's not possible to take
+     its address.  fpregs[8] *should* yield the same address.  */
+  { FPREGS, offsetof (struct user_fpregs, fpregs[8]), 4, 4},   /* fps */
+  { GREGS, 16 * 4, 4, 4 }                                      /* cpsr */
+};
+
+/* End of ARM_LINUX_TARGET */
+
+#elif defined (X86_LINUX_TARGET)
+
+/* X86 needs to use PTRACE_GETREGS / PTRACE_SETREGS, PTRACE_GETFPREGS /
+   PTRACE_SETFPREGS, and PTRACE_GETFPXREGS / PTRACE_SETFPXREGS to
+   access all of the registers.   */
+#define GETREGS_SETREGS_REGINFO 1
+
+enum 
+{ 
+  PC_REGNUM = 8,
+  NUM_REGS = 42
+};
+
+
+static struct getregs_setregs_reginfo reginfo[] =
+{
+  { GREGS, EAX * 4, 4, 4 },
+  { GREGS, ECX * 4, 4, 4 },
+  { GREGS, EDX * 4, 4, 4 },
+  { GREGS, EBX * 4, 4, 4 },
+  { GREGS, UESP * 4, 4, 4 },
+  { GREGS, EBP * 4, 4, 4 },
+  { GREGS, ESI * 4, 4, 4 },
+  { GREGS, EDI * 4, 4, 4 },
+  { GREGS, EIP * 4, 4, 4 },
+  { GREGS, EFL * 4, 4, 4 },
+  { GREGS, CS * 4, 4, 4 },
+  { GREGS, SS * 4, 4, 4 },
+  { GREGS, DS * 4, 4, 4 },
+  { GREGS, ES * 4, 4, 4 },
+  { GREGS, FS * 4, 4, 4 },
+  { GREGS, GS * 4, 4, 4 },
+  /* 8 floating point registers */
+  { FPREGS, offsetof (struct user_fpregs_struct, st_space[0]) + 0*10, 10, 10 },
+  { FPREGS, offsetof (struct user_fpregs_struct, st_space[0]) + 1*10, 10, 10 },
+  { FPREGS, offsetof (struct user_fpregs_struct, st_space[0]) + 2*10, 10, 10 },
+  { FPREGS, offsetof (struct user_fpregs_struct, st_space[0]) + 3*10, 10, 10 },
+  { FPREGS, offsetof (struct user_fpregs_struct, st_space[0]) + 4*10, 10, 10 },
+  { FPREGS, offsetof (struct user_fpregs_struct, st_space[0]) + 5*10, 10, 10 },
+  { FPREGS, offsetof (struct user_fpregs_struct, st_space[0]) + 6*10, 10, 10 },
+  { FPREGS, offsetof (struct user_fpregs_struct, st_space[0]) + 7*10, 10, 10 },
+  /* FCTRL */
+  { FPREGS, offsetof  (struct user_fpregs_struct, cwd),
+            fieldsize (struct user_fpregs_struct, cwd), 4},
+  /* FSTAT */
+  { FPREGS, offsetof  (struct user_fpregs_struct, swd),
+            fieldsize (struct user_fpregs_struct, swd), 4},
+  /* FTAG */
+  { FPREGS, offsetof  (struct user_fpregs_struct, twd),
+            fieldsize (struct user_fpregs_struct, twd), 4},
+  /* FISEG or FCS */
+  { FPREGS, offsetof  (struct user_fpregs_struct, fcs),
+            fieldsize (struct user_fpregs_struct, fcs), 4},
+  /* FIOFF or FCOFF */
+  { FPREGS, offsetof  (struct user_fpregs_struct, fip),
+            fieldsize (struct user_fpregs_struct, fip), 4},
+  /* FOSEG or FDS */
+  { FPREGS, offsetof  (struct user_fpregs_struct, fos),
+            fieldsize (struct user_fpregs_struct, fos), 4},
+  /* FOOFF or FDOFF */
+  { FPREGS, offsetof  (struct user_fpregs_struct, foo),
+            fieldsize (struct user_fpregs_struct, foo), 4},
+  /* FOP */
+  { FPXREGS, offsetof  (struct user_fpxregs_struct, fop),
+             fieldsize (struct user_fpxregs_struct, fop), 4},
+  /* 8 XMM registers */
+  { FPXREGS, offsetof (struct user_fpxregs_struct, xmm_space[0 * 4]), 16, 16 },
+  { FPXREGS, offsetof (struct user_fpxregs_struct, xmm_space[1 * 4]), 16, 16 },
+  { FPXREGS, offsetof (struct user_fpxregs_struct, xmm_space[2 * 4]), 16, 16 },
+  { FPXREGS, offsetof (struct user_fpxregs_struct, xmm_space[3 * 4]), 16, 16 },
+  { FPXREGS, offsetof (struct user_fpxregs_struct, xmm_space[4 * 4]), 16, 16 },
+  { FPXREGS, offsetof (struct user_fpxregs_struct, xmm_space[5 * 4]), 16, 16 },
+  { FPXREGS, offsetof (struct user_fpxregs_struct, xmm_space[6 * 4]), 16, 16 },
+  { FPXREGS, offsetof (struct user_fpxregs_struct, xmm_space[7 * 4]), 16, 16 },
+  /* MXCSR */
+  { FPXREGS, offsetof  (struct user_fpxregs_struct, mxcsr),
+             fieldsize (struct user_fpxregs_struct, mxcsr), 4},
+  /* ORIG_EAX - needed by gdb for signal handling.  */
+  { GREGS, ORIG_EAX * 4, 4, 4 } };
+
+/* End of X86_LINUX_TARGET */
+
+#elif defined (SH_LINUX_TARGET)
+
+/* Needs to be converted to use either GETREGS_SETREGS_REGINFO or
+   PEEKUSER_POKEUSER_REGINFO machinery.  */
+
+enum
+{
+  SIZEOF_REGMAP = 23,
+  SIZEOF_MAPPEDREG = 4,
+  NUM_REGS = 24,
+  PC_REGNUM = 16
+};
+
+static int regmap[SIZEOF_REGMAP] =
+{
+  REG_REG0,    REG_REG0+1,  REG_REG0+2,  REG_REG0+3, 
+  REG_REG0+4,  REG_REG0+5,  REG_REG0+6,  REG_REG0+7, 
+  REG_REG0+8,  REG_REG0+9,  REG_REG0+10, REG_REG0+11, 
+  REG_REG0+12, REG_REG0+13, REG_REG0+14, REG_REG15, 
+  REG_PC,      REG_PR,      REG_GBR,     -1,
+  REG_MACH,    REG_MACL,    REG_SR,
+};
+
+extern int
+is_fp_reg (int regnum)
+{
+  return 0;
+}
+
+int
+is_gp_reg (int regnum)
+{
+  return !is_fp_reg (regnum);
+}
+
+extern int
+is_extended_reg (int regnum)
+{
+  return 0;
+}
+
+/* End of SH_LINUX_TARGET */
+
+#elif defined(MIPS_LINUX_TARGET)
+
+#define PEEKUSER_POKEUSER_REGINFO 1
+
+enum
+{
+  NUM_REGS = 70,
+  PC_REGNUM = 37
+};
+
+
+static struct peekuser_pokeuser_reginfo reginfo[] =
+{
+  /* MIPS has differing elf_gregset_t and gregset_t structs.  (The
+     former contains some leading padding that the latter does not.)
+     elf_gregset_t is used to access registers from a core file whereas
+     gregset_t is used by the thread library in its interfaces.  Since
+     we're concerned about the latter, we'll use the gregset_t offsets
+     in the table below.  */
+  { 0,             4, GREGS,  0 * 4,  4, 4 },      /* zero */
+  { 1,             4, GREGS,  1 * 4,  4, 4 },      /* at */
+  { 2,             4, GREGS,  2 * 4,  4, 4 },      /* v0 */
+  { 3,             4, GREGS,  3 * 4,  4, 4 },      /* v1 */
+  { 4,             4, GREGS,  4 * 4,  4, 4 },      /* a0 */
+  { 5,             4, GREGS,  5 * 4,  4, 4 },      /* a1 */
+  { 6,             4, GREGS,  6 * 4,  4, 4 },      /* a2 */
+  { 7,             4, GREGS,  7 * 4,  4, 4 },      /* a3 */
+  { 8,             4, GREGS,  8 * 4,  4, 4 },      /* t0 */
+  { 9,             4, GREGS,  9 * 4,  4, 4 },      /* t1 */
+  { 10,            4, GREGS,  10 * 4, 4, 4 },      /* t2 */
+  { 11,            4, GREGS,  11 * 4, 4, 4 },      /* t3 */
+  { 12,            4, GREGS,  12 * 4, 4, 4 },      /* t4 */
+  { 13,            4, GREGS,  13 * 4, 4, 4 },      /* t5 */
+  { 14,            4, GREGS,  14 * 4, 4, 4 },      /* t6 */
+  { 15,            4, GREGS,  15 * 4, 4, 4 },      /* t7 */
+  { 16,            4, GREGS,  16 * 4, 4, 4 },      /* s0 */
+  { 17,            4, GREGS,  17 * 4, 4, 4 },      /* s1 */
+  { 18,            4, GREGS,  18 * 4, 4, 4 },      /* s2 */
+  { 19,            4, GREGS,  19 * 4, 4, 4 },      /* s3 */
+  { 20,            4, GREGS,  20 * 4, 4, 4 },      /* s4 */
+  { 21,            4, GREGS,  21 * 4, 4, 4 },      /* s5 */
+  { 22,            4, GREGS,  22 * 4, 4, 4 },      /* s6 */
+  { 23,            4, GREGS,  23 * 4, 4, 4 },      /* s7 */
+  { 24,            4, GREGS,  24 * 4, 4, 4 },      /* t8 */
+  { 25,            4, GREGS,  25 * 4, 4, 4 },      /* t9 */
+  { 26,            4, GREGS,  26 * 4, 4, 4 },      /* k0 */
+  { 27,            4, GREGS,  27 * 4, 4, 4 },      /* k1 */
+  { 28,            4, GREGS,  28 * 4, 4, 4 },      /* gp */
+  { 29,            4, GREGS,  29 * 4, 4, 4 },      /* sp */
+  { 30,            4, GREGS,  30 * 4, 4, 4 },      /* s8/fp */
+  { 31,            4, GREGS,  31 * 4, 4, 4 },      /* ra */
+  { 0,             4, NOREGS, 0,      4, 4 },      /* sr */
+  { MMLO,          4, GREGS,  33 * 4, 4, 4 },      /* lo */
+  { MMHI,          4, GREGS,  32 * 4, 4, 4 },      /* hi */
+
+  /* glibc's ucontext.h doesn't specify the order of the following
+     three registerss.  But there is space allocated for them.  (Well,
+     for something, anyway - the g_pad[] array is has three elements.)
+     We use the same order for these fields as that specified in the
+     kernel header for elf_gregset_t; see the EF_ constants in
+     asm-mips/reg.h.  Note, however, that the kernel header sandwiches
+     the status register (sr, above) in between ``bad'' and ``cause''.  */
+
+  { BADVADDR,      4, GREGS,  35 * 4, 4, 4 },      /* bad */
+  { CAUSE,         4, GREGS,  36 * 4, 4, 4 },      /* cause */
+  { PC,            4, GREGS,  34 * 4, 4, 4 },      /* pc */
+
+  /* Linux/MIPS floating point is a bit of a mess.  On the one hand,
+     the elf_fpregset_t contains space for 32 doubles plus the control
+     word.  But on the other hand, the ptrace interface is only able to
+     fetch the 32 32-bit wide registers.  This means that we only get
+     16 double precision floats via ptrace().  It also means that only
+     slightly more than half of elf_fpregset_t is unused.  */
+
+  { FPR_BASE + 0,  4, FPREGS, 0 * 4,  4, 4 },      /* $f0 */
+  { FPR_BASE + 1,  4, FPREGS, 1 * 4,  4, 4 },      /* $f1 */
+  { FPR_BASE + 2,  4, FPREGS, 2 * 4,  4, 4 },      /* $f2 */
+  { FPR_BASE + 3,  4, FPREGS, 3 * 4,  4, 4 },      /* $f3 */
+  { FPR_BASE + 4,  4, FPREGS, 4 * 4,  4, 4 },      /* $f4 */
+  { FPR_BASE + 5,  4, FPREGS, 5 * 4,  4, 4 },      /* $f5 */
+  { FPR_BASE + 6,  4, FPREGS, 6 * 4,  4, 4 },      /* $f6 */
+  { FPR_BASE + 7,  4, FPREGS, 7 * 4,  4, 4 },      /* $f7 */
+  { FPR_BASE + 8,  4, FPREGS, 8 * 4,  4, 4 },      /* $f8 */
+  { FPR_BASE + 9,  4, FPREGS, 9 * 4,  4, 4 },      /* $f9 */
+  { FPR_BASE + 10, 4, FPREGS, 10 * 4, 4, 4 },      /* $f10 */
+  { FPR_BASE + 11, 4, FPREGS, 11 * 4, 4, 4 },      /* $f11 */
+  { FPR_BASE + 12, 4, FPREGS, 12 * 4, 4, 4 },      /* $f12 */
+  { FPR_BASE + 13, 4, FPREGS, 13 * 4, 4, 4 },      /* $f13 */
+  { FPR_BASE + 14, 4, FPREGS, 14 * 4, 4, 4 },      /* $f14 */
+  { FPR_BASE + 15, 4, FPREGS, 15 * 4, 4, 4 },      /* $f15 */
+  { FPR_BASE + 16, 4, FPREGS, 16 * 4, 4, 4 },      /* $f16 */
+  { FPR_BASE + 17, 4, FPREGS, 17 * 4, 4, 4 },      /* $f17 */
+  { FPR_BASE + 18, 4, FPREGS, 18 * 4, 4, 4 },      /* $f18 */
+  { FPR_BASE + 19, 4, FPREGS, 19 * 4, 4, 4 },      /* $f19 */
+  { FPR_BASE + 20, 4, FPREGS, 20 * 4, 4, 4 },      /* $f20 */
+  { FPR_BASE + 21, 4, FPREGS, 21 * 4, 4, 4 },      /* $f21 */
+  { FPR_BASE + 22, 4, FPREGS, 22 * 4, 4, 4 },      /* $f22 */
+  { FPR_BASE + 23, 4, FPREGS, 23 * 4, 4, 4 },      /* $f23 */
+  { FPR_BASE + 24, 4, FPREGS, 24 * 4, 4, 4 },      /* $f24 */
+  { FPR_BASE + 25, 4, FPREGS, 25 * 4, 4, 4 },      /* $f25 */
+  { FPR_BASE + 26, 4, FPREGS, 26 * 4, 4, 4 },      /* $f26 */
+  { FPR_BASE + 27, 4, FPREGS, 27 * 4, 4, 4 },      /* $f27 */
+  { FPR_BASE + 28, 4, FPREGS, 28 * 4, 4, 4 },      /* $f28 */
+  { FPR_BASE + 29, 4, FPREGS, 29 * 4, 4, 4 },      /* $f29 */
+  { FPR_BASE + 30, 4, FPREGS, 30 * 4, 4, 4 },      /* $f30 */
+  { FPR_BASE + 31, 4, FPREGS, 31 * 4, 4, 4 },      /* $f31 */
+  { FPC_CSR,       4, FPREGS, 64 * 4, 4, 4 }       /* fsr */
+};
+
+static void mips_singlestep_program (struct gdbserv *serv);
+
+/* End of MIPS_LINUX_TARGET */
+
+#elif M68K_LINUX_TARGET
+
+/* Needs to be converted to use either GETREGS_SETREGS_REGINFO or
+   PEEKUSER_POKEUSER_REGINFO machinery.  */
+
+#error m68k
+enum 
+{
+  SIZEOF_REGMAP = 29,          /* with FP regs */
+  SIZEOF_MAPPEDREG = 4,
+  NUM_REGS = 29,
+  PC_REGNUM = 17
+};
+
+static int regmap[SIZEOF_REGMAP] =
+{
+  PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
+  PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
+  PT_SR, PT_PC,
+#if defined (PT_FP0)
+  PT_FP0,  PT_FP1,  PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7,
+  PT_FPCR, PT_FPSR, PT_FPIAR
+#else
+  -1,      -1,      -1,     -1,     -1,     -1,     -1,     -1,
+  -1,      -1,      -1
+#endif /* floating point regs */
+};
+
+extern int
+is_fp_reg (int regnum)
+{
+  if (regnum < SIZEOF_REGMAP)
+    {
+      switch (regmap[regnum]) {
+#if defined (PT_FP0)
+      case PT_FP0: case PT_FP1: case PT_FP2: case PT_FP3:
+      case PT_FP4: case PT_FP5: case PT_FP6: case PT_FP7:
+      case PT_FPCR: case PT_FPSR: case PT_FPIAR:
+       return 1;
+#endif
+      default:
+       return 0;
+      }
+    }
+  return 0;
+}
+
+int
+is_gp_reg (int regnum)
+{
+  return !is_fp_reg (regnum);
+}
+
+int
+is_extended_reg (int regnum)
+{
+  return 0;
+}
+
+/* End of M68_LINUX_TARGET */
+
+#elif defined (PPC_LINUX_TARGET)
+
+#define PEEKUSER_POKEUSER_REGINFO 1
+
+enum
+{
+  NUM_REGS = 71,
+  PC_REGNUM = 64
+};
+
+static struct peekuser_pokeuser_reginfo reginfo[] =
+{
+  { PT_R0 * 4,          4, GREGS,  PT_R0 * 4,  4, 4 },
+  { PT_R1 * 4,          4, GREGS,  PT_R1 * 4,  4, 4 },
+  { PT_R2 * 4,          4, GREGS,  PT_R2 * 4,  4, 4 },
+  { PT_R3 * 4,          4, GREGS,  PT_R3 * 4,  4, 4 },
+  { PT_R4 * 4,          4, GREGS,  PT_R4 * 4,  4, 4 },
+  { PT_R5 * 4,          4, GREGS,  PT_R5 * 4,  4, 4 },
+  { PT_R6 * 4,          4, GREGS,  PT_R6 * 4,  4, 4 },
+  { PT_R7 * 4,          4, GREGS,  PT_R7 * 4,  4, 4 },
+  { PT_R8 * 4,          4, GREGS,  PT_R8 * 4,  4, 4 },
+  { PT_R9 * 4,          4, GREGS,  PT_R9 * 4,  4, 4 },
+  { PT_R10 * 4,         4, GREGS,  PT_R10 * 4, 4, 4 },
+  { PT_R11 * 4,         4, GREGS,  PT_R11 * 4, 4, 4 },
+  { PT_R12 * 4,         4, GREGS,  PT_R12 * 4, 4, 4 },
+  { PT_R13 * 4,         4, GREGS,  PT_R13 * 4, 4, 4 },
+  { PT_R14 * 4,         4, GREGS,  PT_R14 * 4, 4, 4 },
+  { PT_R15 * 4,         4, GREGS,  PT_R15 * 4, 4, 4 },
+  { PT_R16 * 4,         4, GREGS,  PT_R16 * 4, 4, 4 },
+  { PT_R17 * 4,         4, GREGS,  PT_R17 * 4, 4, 4 },
+  { PT_R18 * 4,         4, GREGS,  PT_R18 * 4, 4, 4 },
+  { PT_R19 * 4,         4, GREGS,  PT_R19 * 4, 4, 4 },
+  { PT_R20 * 4,         4, GREGS,  PT_R20 * 4, 4, 4 },
+  { PT_R21 * 4,         4, GREGS,  PT_R21 * 4, 4, 4 },
+  { PT_R22 * 4,         4, GREGS,  PT_R22 * 4, 4, 4 },
+  { PT_R23 * 4,         4, GREGS,  PT_R23 * 4, 4, 4 },
+  { PT_R24 * 4,         4, GREGS,  PT_R24 * 4, 4, 4 },
+  { PT_R25 * 4,         4, GREGS,  PT_R25 * 4, 4, 4 },
+  { PT_R26 * 4,         4, GREGS,  PT_R26 * 4, 4, 4 },
+  { PT_R27 * 4,         4, GREGS,  PT_R27 * 4, 4, 4 },
+  { PT_R28 * 4,         4, GREGS,  PT_R28 * 4, 4, 4 },
+  { PT_R29 * 4,         4, GREGS,  PT_R29 * 4, 4, 4 },
+  { PT_R30 * 4,         4, GREGS,  PT_R30 * 4, 4, 4 },
+  { PT_R31 * 4,         4, GREGS,  PT_R31 * 4, 4, 4 },
+  { (PT_FPR0 + 0) * 4,  8, FPREGS, 0 * 4,      8, 8 },
+  { (PT_FPR0 + 2) * 4,  8, FPREGS, 2 * 4,      8, 8 },
+  { (PT_FPR0 + 4) * 4,  8, FPREGS, 4 * 4,      8, 8 },
+  { (PT_FPR0 + 6) * 4,  8, FPREGS, 6 * 4,      8, 8 },
+  { (PT_FPR0 + 8) * 4,  8, FPREGS, 8 * 4,      8, 8 },
+  { (PT_FPR0 + 10) * 4, 8, FPREGS, 10 * 4,     8, 8 },
+  { (PT_FPR0 + 12) * 4, 8, FPREGS, 12 * 4,     8, 8 },
+  { (PT_FPR0 + 14) * 4, 8, FPREGS, 14 * 4,     8, 8 },
+  { (PT_FPR0 + 16) * 4, 8, FPREGS, 16 * 4,     8, 8 },
+  { (PT_FPR0 + 18) * 4, 8, FPREGS, 18 * 4,     8, 8 },
+  { (PT_FPR0 + 20) * 4, 8, FPREGS, 20 * 4,     8, 8 },
+  { (PT_FPR0 + 22) * 4, 8, FPREGS, 22 * 4,     8, 8 },
+  { (PT_FPR0 + 24) * 4, 8, FPREGS, 24 * 4,     8, 8 },
+  { (PT_FPR0 + 26) * 4, 8, FPREGS, 26 * 4,     8, 8 },
+  { (PT_FPR0 + 28) * 4, 8, FPREGS, 28 * 4,     8, 8 },
+  { (PT_FPR0 + 30) * 4, 8, FPREGS, 30 * 4,     8, 8 },
+  { (PT_FPR0 + 32) * 4, 8, FPREGS, 32 * 4,     8, 8 },
+  { (PT_FPR0 + 34) * 4, 8, FPREGS, 34 * 4,     8, 8 },
+  { (PT_FPR0 + 36) * 4, 8, FPREGS, 36 * 4,     8, 8 },
+  { (PT_FPR0 + 38) * 4, 8, FPREGS, 38 * 4,     8, 8 },
+  { (PT_FPR0 + 40) * 4, 8, FPREGS, 40 * 4,     8, 8 },
+  { (PT_FPR0 + 42) * 4, 8, FPREGS, 42 * 4,     8, 8 },
+  { (PT_FPR0 + 44) * 4, 8, FPREGS, 44 * 4,     8, 8 },
+  { (PT_FPR0 + 46) * 4, 8, FPREGS, 46 * 4,     8, 8 },
+  { (PT_FPR0 + 48) * 4, 8, FPREGS, 48 * 4,     8, 8 },
+  { (PT_FPR0 + 50) * 4, 8, FPREGS, 50 * 4,     8, 8 },
+  { (PT_FPR0 + 52) * 4, 8, FPREGS, 52 * 4,     8, 8 },
+  { (PT_FPR0 + 54) * 4, 8, FPREGS, 54 * 4,     8, 8 },
+  { (PT_FPR0 + 56) * 4, 8, FPREGS, 56 * 4,     8, 8 },
+  { (PT_FPR0 + 58) * 4, 8, FPREGS, 58 * 4,     8, 8 },
+  { (PT_FPR0 + 60) * 4, 8, FPREGS, 60 * 4,     8, 8 },
+  { (PT_FPR0 + 62) * 4, 8, FPREGS, 62 * 4,     8, 8 },
+  { PT_NIP * 4,         4, GREGS,  PT_NIP * 4, 4, 4 },
+  { PT_MSR * 4,         4, GREGS,  PT_MSR * 4, 4, 4 },
+  { PT_CCR * 4,         4, GREGS,  PT_CCR * 4, 4, 4 },
+  { PT_LNK * 4,         4, GREGS,  PT_LNK * 4, 4, 4 },
+  { PT_CTR * 4,         4, GREGS,  PT_CTR * 4, 4, 4 },
+  { PT_XER * 4,         4, GREGS,  PT_XER * 4, 4, 4 },
+  { PT_MQ * 4,          4, GREGS,  PT_MQ * 4,  4, 4 }
+};
+
+/* End of PPC_LINUX_TARGET */
+#elif defined (ALPHA_LINUX_TARGET)
+
+/* Needs to be converted to use either GETREGS_SETREGS_REGINFO or
+   PEEKUSER_POKEUSER_REGINFO machinery.  */
+
+enum 
+{
+  SIZEOF_REGMAP = 66, 
+  SIZEOF_MAPPEDREG = 8,
+  NUM_REGS = 66,
+  PC_REGNUM = 64
+};
+
+static int regmap[SIZEOF_REGMAP] = 
+{
+  EF_V0,  EF_T0,  EF_T1, EF_T2,  EF_T3, EF_T4, EF_T5, EF_T6, 
+  EF_T7,  EF_S0,  EF_S1, EF_S2,  EF_S3, EF_S4, EF_S5, EF_S6, 
+  EF_A0,  EF_A1,  EF_A2, EF_A3,  EF_A4, EF_A5, EF_T8, EF_T9, 
+  EF_T10, EF_T11, EF_RA, EF_T12, EF_AT, EF_GP, EF_SP, -1, /* zero */
+  /* f0   f1      f2     f3      f4     f5     f6     f7          */
+  -1,     -1,     -1,    -1,     -1,    -1,    -1,    -1, 
+  /* f8   f9      f10    f11     f12    f13    f14    f15         */
+  -1,     -1,     -1,    -1,     -1,    -1,    -1,    -1, 
+  /* f16  f17     f18    f19     f20    f21    f22    f23         */
+  -1,     -1,     -1,    -1,     -1,    -1,    -1,    -1, 
+  /* f24  f25     f26    f27     f28    f29    f30    fpcr        */
+  -1,     -1,     -1,    -1,     -1,    -1,    -1,    -1, 
+  EF_PC,  -1   /* vpf */
+};
+
+int
+is_fp_reg (int regnum)
+{
+  if (regnum >= 32 && regnum < 64)
+    return 1;
+  else 
+    return 0;
+}
+
+int
+is_gp_reg (int regnum)
+{
+  return !is_fp_reg (regnum);
+}
+
+int
+is_extended_reg (int regnum)
+{
+  return 0;
+}
+
+/* End of ALPHA_LINUX_TARGET */
+#else
+#error Need a _LINUX_TARGET define for your architecture
+#endif
+
+/* The following functions should work either PEEKUSER_POKEUSER_REGINFO,
+   GETREGS_SETREGS_REGINFO, or the old mechanism.  */
+
+/* Function: next_gg_reg
+   This generic version useful only for targets whose
+   register numbers are the same as their position in the g/G packet.
+   Return next register number or -1 for end. */
+
+static int
+linux_next_gg_reg (struct gdbserv *serv, 
+                          struct gdbserv_thread *thread, 
+                          int lastreg)
+{
+  /* This function is an iterator.
+     If called with -1, it returns the first register number.
+     Else it returns the next register number until there are no more, 
+     whereupon it returns -1.  */
+
+  if (lastreg < 0)
+    return 0;
+  else if (lastreg >= NUM_REGS - 1)
+    return -1;
+  else 
+    return lastreg + 1;
+}
+
+/* Function: gg_reg_nr
+   This generic version useful only for targets whose
+   register numbers are the same as their position in the g/G packet.
+   Return register number or -1 for a bad index. */
+
+static int
+linux_gg_reg_nr (struct gdbserv *serv, int index)
+{
+  /* This function returns the register number of the "i'th" register
+     in the g/G packet.  In the default case that's just i. */
+
+  if (index >= 0 && index < NUM_REGS)
+    return index;
+  else
+    return -1;
+}
+
+/* Function: get_xregsetsize
+   Fetch the size of the extended register set.  */
+
+static int
+get_xregsetsize (struct gdbserv *serv, int pid)
+{
+#if defined (X86_LINUX_TARGET)
+  return sizeof (elf_fpxregset_t);
+#else
+  return -1;
+#endif
+}
+
+
+#if defined (PEEKUSER_POKEUSER_REGINFO) || defined (GETREGS_SETREGS_REGINFO)
+/* The following functions will only work with the PEEKUSER_POKEUSER_REGINFO
+   and GETREGS_SETREGS_REGINFO mechanisms.  */
+
+/* Function: reg_format
+   This generic version useful only for targets whose
+   registers are all the same size.
+   Return zero for success, -1 for failure (never fails). */
+
+static int
+linux_reg_format (struct gdbserv *serv, 
+                         struct gdbserv_thread *thread,
+                         int regno, int *size, int *padding)
+{
+  /* Size and formatting (padding) of thread in g/G packet. */
+  *size = reginfo[regno].proto_size;
+  *padding = 0;
+  return 0;
+}
+
+/* Function: sizeof_reg
+   This generic version useful only for targets whose
+   registers are all the same size.
+   Returns size of a register. */
+   
+static long linux_sizeof_reg (struct gdbserv *serv, int regno)
+{
+  return reginfo[regno].proto_size;
+}
+
+/* Return 1 if REGNUM represents a general purpose register which has
+   space allocated for it in GREGSET_T.  Otherwise, return 0.  */
+
+int
+is_gp_reg (int regnum)
+{
+  if (regnum >= 0 && regnum < NUM_REGS)
+    return reginfo[regnum].whichregs == GREGS;
+  else
+    return 0;
+}
+
+/* Return 1 if REGNUM represents a floating point register, 0 otherwise.  
+   For these purposes, floating point status registers (and perhaps certain
+   other registers) are considered to be floating point registers when
+   they appear in the fpregset_t struct.  */
+   
+int
+is_fp_reg (int regnum)
+{
+  if (regnum >= 0 && regnum < NUM_REGS)
+    return reginfo[regnum].whichregs == FPREGS;
+  else
+    return 0;
+}
+
+/* Return 1 if REGNUM represents a register in the extended register
+   set, 0 otherwise.  The definition of what consitutes an extended
+   register is implementation specific.  For x86 though, an extended
+   register is one of the extended floating point registers.  */
+
+int
+is_extended_reg (int regnum)
+{
+  if (regnum >= 0 && regnum < NUM_REGS)
+    return reginfo[regnum].whichregs == FPXREGS;
+  else
+    return 0;
+}
+
+#endif /* defined (PEEKUSER_POKEUSER_REGINFO) || defined (GETREGS_SETREGS_REGINFO) */
+
+#if defined (PEEKUSER_POKEUSER_REGINFO)
+
+/* Functions which implement the PEEKUSER_POKEUSER_REGINFO machinery...  */
+
+/* Fetch the register indicated by REGNO into the buffer REG_BYTES.
+   The caller must ensure that a sufficiently large buffer has been
+   allocated.
+   Returns 0 for success, -1 for failure.  */
+
+static int
+read_reg_bytes (int pid, int regno, void *reg_bytes)
+{
+  ptrace_arg3_type regaddr;
+  int regsize;
+  int status;
+
+  if (regno < 0 || regno >= NUM_REGS)
+    return -1;
+
+  regaddr = reginfo[regno].ptrace_offset;
+  regsize = reginfo[regno].ptrace_size;
+  status = ptrace_read_user (pid, regaddr, regsize, reg_bytes);
+
+  /* A non-zero status is the errno value from the ptrace call */
+  if (status != 0)
+    {
+      fprintf (stderr, "Error: PT_READ_U at 0x%08lx in process %d\n",
+              (long) regaddr, pid);
+      return -1;
+    }
+  return 0;
+}
+
+/* Fetch the register indicated by REGNO into the buffer REG_BYTES.
+   The caller must ensure that a sufficiently large buffer has been
+   allocated.
+   Returns 0 for success, -1 for failure.  */
+
+static int
+write_reg_bytes (int pid, int regno, const void *reg_bytes)
+{
+  ptrace_arg3_type regaddr;
+  int regsize;
+  int status;
+
+  if (regno < 0 || regno >= NUM_REGS)
+    return -1;
+
+  regaddr = reginfo[regno].ptrace_offset;
+  regsize = reginfo[regno].ptrace_size;
+  status = ptrace_write_user (pid, regaddr, regsize, reg_bytes);
+
+  /* A non-zero status is the errno value from the ptrace call */
+  if (status != 0)
+    {
+      fprintf (stderr, "Error: PT_WRITE_U status=%d at 0x%08lx in process %d\n",
+              status, (long) regaddr, pid);
+      return -1;
+    }
+  return 0;
+}
+
+
+/* Fetch and return the value of register REGNO.  Helper function for
+   debug_get_pc().  This is the PEEKUSER_POKEUSER_REGINFO version.  */
+static unsigned long
+debug_get_reg (pid_t pid, int regno)
+{
+  ptrace_xfer_type value;
+
+  if (read_reg_bytes (pid, regno, &value) < 0)
+    return 0;
+  else
+    return (unsigned long) value;
+}
+
+/* Fetch and return the value of the PC.  Needed by thread-db.c.  */
+unsigned long
+debug_get_pc (struct gdbserv *serv, pid_t pid)
+{
+  return debug_get_reg (pid, PC_REGNUM);
+}
+
+/* Function: get_reg
+   This version is for targets for which all registers may
+   be fetched using PTRACE_PEEKUSER.
+   Return -1 for failure, zero for success. */
+
+static int
+linux_get_reg (struct gdbserv *serv, int regno, struct gdbserv_reg *reg)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  char tmp_buf[MAX_REG_SIZE];
+  int status;
+
+  if (regno < 0 || regno >= NUM_REGS)
+    {
+      fprintf (stderr, "Error: linux_get_reg: Register %d out of bounds.\n", regno);
+      return -1;
+    }
+
+  memset (tmp_buf, 0, reginfo[regno].proto_size);
+
+  if (reginfo[regno].whichregs != NOREGS)
+    {
+      /* Get the register value. */
+      status = read_reg_bytes (process->pid, regno, tmp_buf);
+      if (status < 0)
+       return -1;      /* fail */
+    }
+
+  /* Copy the bytes to the gdbserv_reg struct.  */
+  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+
+  return 0;    /* success */
+  
+}
+
+/* Function: set_reg
+   This version is for targets which are capable of setting any register
+   via PTRACE_POKEUSER.
+   Return -1 for failure, zero for success. */
+
+static int
+linux_set_reg (struct gdbserv *serv, int regno, struct gdbserv_reg *reg)
+{
+  if (regno < 0 || regno >= NUM_REGS)
+    {
+      fprintf (stderr, "Error: linux_set_reg: Register %d out of bounds.\n", regno);
+      return -1;
+    }
+
+  if (reginfo[regno].whichregs != NOREGS)
+    {
+      struct child_process *process = gdbserv_target_data (serv);
+      char tmp_buf[MAX_REG_SIZE];
+      int status;
+      int len;
+
+      /* Clear out a temporary buffer into which to fetch the bytes that
+        we'll be setting.  We do this in case ptrace_size != proto_size.  */
+      memset (tmp_buf, 0, reginfo[regno].ptrace_size);
+
+      /* Copy the bytes from the gdbserv_reg struct to our temporary buffer.  */
+      gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
+
+      if (len != reginfo[regno].proto_size)
+       return -1;
+
+      /* Write the child's register. */
+      status = write_reg_bytes (process->pid, regno, tmp_buf);
+      if (status < 0)
+       return -1;      /* Fail */
+    }
+
+  return 0;    /* success */
+}
+
+/* gregset functions */
+
+/* Helper function for reg_from_gregset / reg_from_fpregset  */
+
+int
+reg_from_regset (struct gdbserv *serv, 
+                struct gdbserv_reg *reg, 
+                int regno, 
+                const void *regset,
+                enum regset whichregs)
+{
+  char tmp_buf[MAX_REG_SIZE];
+  char *regbytes;
+
+  if (regno < 0 || regno >= NUM_REGS 
+      || reginfo[regno].whichregs != whichregs)
+    {
+      return -1;
+    }
+
+  regbytes = ((char *) regset) + reginfo[regno].regset_field_offset;
+
+  memset (tmp_buf, 0, reginfo[regno].proto_size);
+  memcpy (tmp_buf, regbytes, reginfo[regno].regset_field_size);
+
+  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+
+  return 0;
+}
+
+/* Helper function for reg_to_gregset / reg_to_fpregset.
+   Insert register into the regset indicated by WHICHREGS by REGNO.
+   Return -1 for failure, zero for success. */
+
+int
+reg_to_regset (struct gdbserv *serv, 
+              const struct gdbserv_reg *reg, 
+              int regno, 
+              void *regset,
+              enum regset whichregs)
+{
+  char tmp_buf[MAX_REG_SIZE];
+  char *regbytes;
+  int len;
+
+  if (regno < 0 || regno >= NUM_REGS 
+      || reginfo[regno].whichregs != whichregs)
+    {
+      return -1;
+    }
+
+  memset (tmp_buf, 0, reginfo[regno].regset_field_size);
+  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
+
+  if (len != reginfo[regno].proto_size)
+    return -1;
+
+  regbytes = ((char *) regset) + reginfo[regno].regset_field_offset;
+
+  memcpy (regbytes, tmp_buf, reginfo[regno].regset_field_size);
+
+  return 0;
+}
+
+/* Function: reg_from_gregset
+   Extract register from gregset by regnum.
+   Return -1 for failure, zero for success. */
+
+int
+reg_from_gregset (struct gdbserv *serv, 
+                 struct gdbserv_reg *reg, 
+                 int regno, 
+                 const GREGSET_T gregset)
+{
+  return reg_from_regset (serv, reg, regno, gregset, GREGS);
+}
+
+/* Function: reg_to_gregset
+   Insert register into gregset by regnum.
+   Return -1 for failure, zero for success. */
+
+int
+reg_to_gregset (struct gdbserv *serv, 
+               const struct gdbserv_reg *reg, 
+               int regno, 
+               GREGSET_T gregset)
+{
+  return reg_to_regset (serv, reg, regno, gregset, GREGS);
+}
+
+/* Function: reg_from_fpregset
+   Extract register from fpregset by regnum.
+   Return -1 for failure, zero for success. */
+
+int
+reg_from_fpregset (struct gdbserv *serv, 
+                  struct gdbserv_reg *reg, 
+                  int regno, 
+                  const FPREGSET_T *fpregset)
+{
+  return reg_from_regset (serv, reg, regno, fpregset, FPREGS);
+}
+
+/* Function: reg_to_fpregset
+   Insert register into fpregset by regnum.
+   Return -1 for failure, zero for success. */
+
+int
+reg_to_fpregset (struct gdbserv *serv, 
+                const struct gdbserv_reg *reg, 
+                int regno, 
+                FPREGSET_T *fpregset)
+{
+  return reg_to_regset (serv, reg, regno, fpregset, FPREGS);
+}
+
+/* Function: reg_from_xregset
+   Extract register from extended regset by regnum.
+   Return -1 for failure, zero for success.  */
+
+int
+reg_from_xregset (struct gdbserv *serv, 
+                 struct gdbserv_reg *reg, 
+                 int regno, 
+                 const void *xregset)
+{
+  return -1;   /* Unimplemented.  */
+}
+
+/* Function: reg_to_xregset
+   Insert register into extended regset by regnum.
+   Return -1 for failure, zero for success.  */
+
+int
+reg_to_xregset (struct gdbserv *serv, 
+               const struct gdbserv_reg *reg, 
+               int regno, 
+               void *xregset)
+{
+  return -1;   /* Unimplemented.  */
+}
+
+/* Helper function for get_gregset / get_fpregset */
+
+static int
+get_regset (struct gdbserv *serv, int pid, void *regset,
+            enum regset whichregs)
+{
+  int regno;
+
+  for (regno = 0; regno < NUM_REGS; regno++)
+    {
+      if (reginfo[regno].whichregs == whichregs)
+       {
+         char tmp_buf[MAX_REG_SIZE];
+         struct gdbserv_reg reg;
+         int status;
+
+         memset (tmp_buf, 0, reginfo[regno].proto_size);
+
+         /* Get the register value. */
+         status = read_reg_bytes (pid, regno, tmp_buf);
+         if (status < 0)
+           return -1;  /* fail */
+
+         /* Copy the bytes to the gdbserv_reg struct.  */
+         gdbserv_host_bytes_to_reg (serv, tmp_buf,
+                                    reginfo[regno].proto_size, &reg);
+
+         /* Now insert them into the regset.  */
+         reg_to_regset (serv, &reg, regno, regset, whichregs);
+       }
+    }
+
+  return 0;
+}
+/* Helper function for put_gregset / put_fpregset.
+   Write the regset indicated by WHICHREGS for PID.
+   Return -1 for failure, zero for success. */
+
+static int
+put_regset (struct gdbserv *serv,
+            int pid,
+           const void *regset,
+            enum regset whichregs)
+{
+  int regno;
+
+  for (regno = 0; regno < NUM_REGS; regno++)
+    {
+      if (reginfo[regno].whichregs == whichregs)
+       {
+         char tmp_buf[MAX_REG_SIZE];
+         struct gdbserv_reg reg;
+         int len;
+         int status;
+
+         /* Fetch the reg from the regset.  */
+         reg_from_regset (serv, &reg, regno, regset, whichregs);
+
+         /* Clear out a temporary buffer into which to put the bytes that
+            we'll be setting.  We do this in case ptrace_size != proto_size.  */
+         memset (tmp_buf, 0, reginfo[regno].ptrace_size);
+
+         /* Copy the bytes from the gdbserv_reg struct to our temporary buffer.  */
+         gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, &reg);
+         if (len != reginfo[regno].proto_size)
+           return -1;
+
+         /* Write the child's register. */
+         status = write_reg_bytes (pid, regno, tmp_buf);
+         if (status < 0)
+           return -1;  /* Fail */
+       }
+    }
+  return 0;
+}
+
+/* Function: get_gregset
+   Read the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+get_gregset (struct gdbserv *serv, int pid, GREGSET_T gregset)
+{
+  return get_regset (serv, pid, gregset, GREGS);
+}
+
+/* Function: put_gregset
+   write the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+put_gregset (struct gdbserv *serv, int pid, const GREGSET_T gregset)
+{
+  return put_regset (serv, pid, gregset, GREGS);
+}
+
+static int
+get_fpregset (struct gdbserv *serv, int pid, FPREGSET_T *fpregset)
+{
+  return get_regset (serv, pid, fpregset, FPREGS);
+}
+
+/* Function: put_fpregset
+   write the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+put_fpregset (struct gdbserv *serv, int pid, const FPREGSET_T *fpregset)
+{
+  return put_regset (serv, pid, fpregset, FPREGS);
+}
+
+/* Function: get_fpregset
+   Read the fpregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+get_xregset (struct gdbserv *serv, int pid, void *fpregset)
+{
+  return -1;
+}
+
+/* Function: put_xregset
+   write the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+put_xregset (struct gdbserv *serv, int pid, const void *fpregset)
+{
+  return -1;
+}
+
+#elif defined (GETREGS_SETREGS_REGINFO)
+
+/* Functions which implement the GETREGS_SETREGS_REGINFO machinery...  */
+
+/* Forward declarations for get_gregset() and put_gregset().  */
+static int get_gregset (struct gdbserv *serv, int pid, GREGSET_T gregset);
+static int put_gregset (struct gdbserv *serv, int pid, const GREGSET_T gregset);
+
+/* Fetch register REGNO as an unsigned long and return it via the REGVAL
+   pointer.  Return 0 for success and -1 for failure.  */
+static int
+read_reg_as_ulong (struct gdbserv *serv, pid_t pid, int regno,
+                   unsigned long *regval)
+{
+  struct gdbserv_reg reg;
+  GREGSET_T gregset;
+  int status;
+
+  status = get_gregset (serv, pid, gregset);
+  if (status < 0)
+    return status;
+
+  status = reg_from_gregset (serv, &reg, regno, gregset);
+  if (status < 0)
+    return status;
+
+  gdbserv_reg_to_ulong (serv, &reg, regval);
+  return status;
+}
+
+/* Write the unsigned long value REGVAL to register REGNO.  Return 0
+   for success and -1 for failure.  */
+static int
+write_reg_as_ulong (struct gdbserv *serv, pid_t pid, int regno,
+                    unsigned long regval)
+{
+  struct gdbserv_reg reg;
+  GREGSET_T gregset;
+  int status;
+
+  status = get_gregset (serv, pid, gregset);
+  if (status < 0)
+    return status;
+
+  gdbserv_ulong_to_reg (serv, regval, &reg);
+
+  status = reg_to_gregset (serv, &reg, regno, gregset);
+  if (status < 0)
+    return status;
+
+  status = put_gregset (serv, pid, gregset);
+
+  return status;
+}
+
+/* Fetch and return the value of register REGNO.  Helper function for
+   debug_get_pc().  This is the GETREGS_SETREGS_REGINFO version.  */
+static unsigned long
+debug_get_reg (struct gdbserv *serv, pid_t pid, int regno)
+{
+  int status;
+  unsigned long regval;
+
+  status = read_reg_as_ulong (serv, pid, regno, &regval);
+  if (status < 0)
+    return 0;
+  else
+    return regval;
+}
+
+/* Fetch and return the value of the PC.  Needed by thread-db.c.  */
+unsigned long
+debug_get_pc (struct gdbserv *serv, pid_t pid)
+{
+  return debug_get_reg (serv, pid, PC_REGNUM);
+}
+
+/* Function: get_reg
+   This version is for targets which need to fetch registers
+   en masse via ptrace().
+   Return -1 for failure, zero for success. */
+
+static int
+linux_get_reg (struct gdbserv *serv, int regno, struct gdbserv_reg *reg)
+{
+  int ret;
+  elf_gregset_t gregs;
+  elf_fpregset_t fpregs;
+  void *fpxregs;
+  char *buf;
+  char tmp_buf[MAX_REG_SIZE];
+
+  if (regno < 0 || regno >= NUM_REGS)
+    {
+      fprintf (stderr, "Error: linux_get_reg: Register %d out of bounds.\n", regno);
+      return -1;
+    }
+
+  /* Fetch the appropriate register set.  */
+  if (reginfo[regno].whichregs == GREGS)
+    {
+      ret = ptrace_get_gregs (serv, 0, &gregs);
+      if (ret != 0)
+        {
+         /* FIXME: Do we need a perror() here?  */
+         return -1;
+       }
+      buf = (char *) &gregs;
+    }
+  else if (reginfo[regno].whichregs == FPREGS)
+    {
+      ret = ptrace_get_fpregs (serv, 0, &fpregs);
+      if (ret != 0)
+       return -1;
+      buf = (char *) &fpregs;
+    }
+  else if (reginfo[regno].whichregs == FPXREGS)
+    {
+      struct child_process *process = gdbserv_target_data (serv);
+      int xregsize = get_xregsetsize (serv, process->pid);
+
+      assert (xregsize >= 0);
+
+      fpxregs = alloca (xregsize);
+      ret = ptrace_get_fpxregs (serv, 0, fpxregs);
+      if (ret != 0)
+       return -1;
+      buf = (char *) fpxregs;
+    }
+  else if (reginfo[regno].whichregs == NOREGS)
+    {
+      /* Do nothing.  */
+    }
+  else
+    {
+      return -1;
+    }
+
+  /* Adjust buf to point at the starting byte of the register.  */
+  buf += reginfo[regno].offset;
+
+  /* We go through these memset / memcpy shenanigans in case
+     proto_size != ptrace_size.  */
+  memset (tmp_buf, 0, reginfo[regno].proto_size);
+  if (reginfo[regno].ptrace_size > 0)
+    memcpy (tmp_buf, buf, reginfo[regno].ptrace_size);
+
+  /* Copy the bytes to the gdbserv_reg struct.  */
+  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+
+  return 0;
+}
+
+/* Function: linux_set_reg
+   This version is for targets which need to set registers en masse.
+   Return -1 for failure, zero for success. */
+
+static int
+linux_set_reg (struct gdbserv *serv, int regno, struct gdbserv_reg *reg)
+{
+  int ret;
+  elf_gregset_t gregs;
+  elf_fpregset_t fpregs;
+  void *fpxregs = NULL;
+  char *buf;
+  char tmp_buf[MAX_REG_SIZE];
+  int len;
+
+  if (regno < 0 || regno >= NUM_REGS)
+    {
+      fprintf (stderr, "Error: linux_set_reg: Register %d out of bounds.\n", regno);
+      return -1;
+    }
+
+  /* Fetch the appropriate register set.  */
+  if (reginfo[regno].whichregs == GREGS)
+    {
+      ret = ptrace_get_gregs (serv, 0, &gregs);
+      if (ret != 0)
+       return ret;
+      buf = (char *) &gregs;
+    }
+  else if (reginfo[regno].whichregs == FPREGS)
+    {
+      ret = ptrace_get_fpregs (serv, 0, &fpregs);
+      if (ret != 0)
+       return ret;
+      buf = (char *) &fpregs;
+    }
+  else if (reginfo[regno].whichregs == FPXREGS)
+    {
+      struct child_process *process = gdbserv_target_data (serv);
+      int xregsize = get_xregsetsize (serv, process->pid);
+
+      assert (xregsize >= 0);
+
+      fpxregs = alloca (xregsize);
+      ret = ptrace_get_fpxregs (serv, 0, fpxregs);
+      if (ret != 0)
+       return ret;
+      buf = (char *) fpxregs;
+    }
+  else if (reginfo[regno].whichregs == NOREGS)
+    {
+      /* Nothing to do, return immediately.  */
+      return 0;
+    }
+  else
+    {
+      return -1;
+    }
+
+  /* Adjust buf to point at the starting byte of the register.  */
+  buf += reginfo[regno].offset;
+
+  /* Clear out a temporary buffer into which to fetch the bytes that
+     we'll be setting.  We do this in case ptrace_size != proto_size.  */
+  memset (tmp_buf, 0, reginfo[regno].ptrace_size);
+
+  /* Copy the bytes from the gdbserv_reg struct to our temporary buffer.  */
+  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
+
+  if (len != reginfo[regno].proto_size)
+    return -1;
+
+  /* Copy the bytes to the appropriate position in the ptrace struct.  */
+  memcpy (buf, tmp_buf, reginfo[regno].ptrace_size);
+
+  /* Write the register set to the process.  */
+  if (reginfo[regno].whichregs == GREGS)
+    {
+      ret = ptrace_set_gregs (serv, 0, &gregs);
+      if (ret != 0)
+       return ret;
+    }
+  else if (reginfo[regno].whichregs == FPREGS)
+    {
+      ret = ptrace_set_fpregs (serv, 0, &fpregs);
+      if (ret != 0)
+       return ret;
+    }
+  else if (reginfo[regno].whichregs == FPXREGS)
+    {
+      ret = ptrace_set_fpxregs (serv, 0, &fpxregs);
+      if (ret != 0)
+       return ret;
+    }
+  else
+    {
+      /* Can't happen.  */
+      return -1;
+    }
+
+  return 0;
+}
+
+/* gregset functions */
+
+/* Function: reg_from_gregset
+   Extract register from gregset by regnum.
+   Return -1 for failure, zero for success. */
+
+int
+reg_from_gregset (struct gdbserv *serv, 
+                 struct gdbserv_reg *reg, 
+                 int regno, 
+                 const GREGSET_T gregset)
+{
+  char tmp_buf[MAX_REG_SIZE];
+  char *regbytes;
+
+  if (regno < 0 || regno >= NUM_REGS 
+      || reginfo[regno].whichregs != GREGS)
+    {
+      return -1;
+    }
+
+  regbytes = ((char *) gregset) + reginfo[regno].offset;
+
+  memset (tmp_buf, 0, reginfo[regno].proto_size);
+  memcpy (tmp_buf, regbytes, reginfo[regno].ptrace_size);
+
+  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+
+  return 0;
+}
+
+/* Function: reg_to_gregset
+   Insert register into gregset by regnum.
+   Return -1 for failure, zero for success. */
+
+int
+reg_to_gregset (struct gdbserv *serv, 
+               const struct gdbserv_reg *reg, 
+               int regno, 
+               GREGSET_T gregset)
+{
+  char tmp_buf[MAX_REG_SIZE];
+  char *regbytes;
+  int len;
+
+  if (regno < 0 || regno >= NUM_REGS 
+      || reginfo[regno].whichregs != GREGS)
+    {
+      return -1;
+    }
+
+  regbytes = ((char *) gregset) + reginfo[regno].offset;
+
+  memset (tmp_buf, 0, reginfo[regno].ptrace_size);
+  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
+
+  if (len != reginfo[regno].proto_size)
+    return -1;
+
+  memcpy (regbytes, tmp_buf, reginfo[regno].ptrace_size);
+
+  return 0;
+}
+
+/* Function: reg_from_fpregset
+   Extract register from fpregset by regnum.
+   Return -1 for failure, zero for success. */
+
+int
+reg_from_fpregset (struct gdbserv *serv, 
+                  struct gdbserv_reg *reg, 
+                  int regno, 
+                  const FPREGSET_T *fpregset)
+{
+  char tmp_buf[MAX_REG_SIZE];
+  char *regbytes;
+
+  if (regno < 0 || regno >= NUM_REGS 
+      || reginfo[regno].whichregs != FPREGS)
+    {
+      return -1;
+    }
+
+  regbytes = ((char *) fpregset) + reginfo[regno].offset;
+
+  memset (tmp_buf, 0, reginfo[regno].proto_size);
+  memcpy (tmp_buf, regbytes, reginfo[regno].ptrace_size);
+
+  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+
+  return 0;
+}
+
+/* Function: reg_to_fpregset
+   Insert register into fpregset by regnum.
+   Return -1 for failure, zero for success. */
+
+int
+reg_to_fpregset (struct gdbserv *serv, 
+                const struct gdbserv_reg *reg, 
+                int regno, 
+                FPREGSET_T *fpregset)
+{
+  char tmp_buf[MAX_REG_SIZE];
+  char *regbytes;
+  int len;
+
+  if (regno < 0 || regno >= NUM_REGS 
+      || reginfo[regno].whichregs != FPREGS)
+    {
+      return -1;
+    }
+
+  regbytes = ((char *) fpregset) + reginfo[regno].offset;
+
+  memset (tmp_buf, 0, reginfo[regno].ptrace_size);
+  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
+
+  if (len != reginfo[regno].proto_size)
+    return -1;
+
+  memcpy (regbytes, tmp_buf, reginfo[regno].ptrace_size);
+
+  return 0;
+}
+
+/* Function: reg_from_xregset
+   Extract register from extended regset by regnum.
+   Return -1 for failure, zero for success. */
+
+int
+reg_from_xregset (struct gdbserv *serv, 
+                 struct gdbserv_reg *reg, 
+                 int regno, 
+                 const void *xregset)
+{
+  char tmp_buf[MAX_REG_SIZE];
+  char *regbytes;
+
+  if (regno < 0 || regno >= NUM_REGS 
+      || reginfo[regno].whichregs != FPXREGS)
+    {
+      return -1;
+    }
+
+  regbytes = ((char *) xregset) + reginfo[regno].offset;
+
+  memset (tmp_buf, 0, reginfo[regno].proto_size);
+  memcpy (tmp_buf, regbytes, reginfo[regno].ptrace_size);
+
+  gdbserv_host_bytes_to_reg (serv, tmp_buf, reginfo[regno].proto_size, reg);
+
+  return 0;
+}
+
+/* Function: reg_to_xregset
+   Insert register into extended regset by regnum.
+   Return -1 for failure, zero for success.  */
+
+int
+reg_to_xregset (struct gdbserv *serv, 
+               const struct gdbserv_reg *reg, 
+               int regno, 
+               void *xregset)
+{
+  char tmp_buf[MAX_REG_SIZE];
+  char *regbytes;
+  int len;
+
+  if (regno < 0 || regno >= NUM_REGS 
+      || reginfo[regno].whichregs != FPXREGS)
+    {
+      return -1;
+    }
+
+  regbytes = ((char *) xregset) + reginfo[regno].offset;
+
+  memset (tmp_buf, 0, reginfo[regno].ptrace_size);
+  gdbserv_host_bytes_from_reg (serv, tmp_buf, &len, reg);
+
+  if (len != reginfo[regno].proto_size)
+    return -1;
+
+  memcpy (regbytes, tmp_buf, reginfo[regno].ptrace_size);
+
+  return 0;
+}
+
+/* Function: get_gregset
+   Read the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+get_gregset (struct gdbserv *serv, int pid, GREGSET_T gregset)
+{
+  int status;
+
+  status = ptrace_get_gregs (serv, pid, gregset);
+  return status;
+}
+
+/* Function: put_gregset
+   write the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+put_gregset (struct gdbserv *serv, int pid, const GREGSET_T gregset)
+{
+  int status;
+
+  status = ptrace_set_gregs (serv, pid, gregset);
+
+  return status;
+}
+
+/* Function: get_fpregset
+   Read the fpregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+get_fpregset (struct gdbserv *serv, int pid, FPREGSET_T *fpregset)
+{
+  int status;
+
+  status = ptrace_get_fpregs (serv, pid, fpregset);
+  return status;
+}
+
+/* Function: put_fpregset
+   write the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+put_fpregset (struct gdbserv *serv, int pid, const FPREGSET_T *fpregset)
+{
+  int status;
+
+  status = ptrace_set_fpregs (serv, pid, fpregset);
+
+  return status;
+}
+
+/* Function: get_fpregset
+   Read the fpregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+get_xregset (struct gdbserv *serv, int pid, void *xregset)
+{
+  int status;
+
+  status = ptrace_get_fpxregs (serv, pid, xregset);
+  return status;
+}
+
+/* Function: put_xregset
+   write the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+put_xregset (struct gdbserv *serv, int pid, const void *xregset)
+{
+  int status;
+
+  status = ptrace_set_fpxregs (serv, pid, xregset);
+
+  return status;
+}
+
+#else /* ---------------------------------------------------------- */
+
+/* These functions may be used for architectures whose registers
+   are of uniform size and whose registers are all accessible via
+   PTRACE_PEEKUSER and PTRACE_POKEUSER.  */
+
+/* Register offset in user struct, or -1 if bad reg num.  */
+static long
+linux_register_offset (int regnum)
+{
+  if (regnum < 0 || regnum >= SIZEOF_REGMAP)
+    return -1;
+  else if (regmap[regnum] < 0)
+    return -1;
+  else
+#if defined(_MIPSEL) || defined(_MIPSEB)
+    /* MIPS implementations of PTRACE_PEEKUSER address register 0
+       at offset 0, register 1 at offset 1, etc. Do NOT multiply
+       the register number by the register size. */
+
+    return regmap[regnum];
+#else
+    return SIZEOF_MAPPEDREG * regmap[regnum];
+#endif
+}
+
+/* fetch registers vector.
+
+   NOTE: registers do not generalize well in ptrace, so 
+   we're gonna handle them separately per target. */
+
+
+enum { U_REGS_OFFSET = 0 };    /* FIXME??? */
+
+/* Function: linux_read_reg
+   Return -1 for failure, zero for success. */
+
+static int
+linux_read_reg (int pid, int regno, ptrace_xfer_type *regval)
+{
+  unsigned long u_regs_base = U_REGS_OFFSET;
+  ptrace_arg3_type regaddr;
+
+  if ((regaddr = linux_register_offset (regno)) < 0)
+    return -1; /* fail */
+
+  regaddr += U_REGS_OFFSET;
+  errno = 0;
+  ptrace_read_user (pid, regaddr, sizeof (*regval), regval);
+
+  if (errno)
+    {
+      fprintf (stderr, "PT_READ_U 0x%08lx from 0x%08lx in process %d\n",
+              (long) *regval, (long) regaddr, pid);
+      return -1;
+    }
+  else
+    return 0;
+}
+
+/* Function: linux_write_reg
+   Return -1 for failure, zero for success. */
+
+static int
+linux_write_reg (int pid, int regno, ptrace_xfer_type regval)
+{
+  unsigned long u_regs_base = U_REGS_OFFSET;
+  ptrace_arg3_type regaddr;
+
+  if ((regaddr = linux_register_offset (regno)) < 0)
+    return -1; /* fail */
+
+  regaddr += U_REGS_OFFSET;
+  errno = 0;
+  ptrace_write_user (pid, regaddr, sizeof (regval), &regval);
+  if (errno)
+    {
+      fprintf (stderr, "PT_WRITE_U 0x%08lx from 0x%08lx in process %d\n",
+              (long) regval, (long) regaddr, pid);
+      return -1;
+    }
+  else
+    return 0;
+}
+
+/* Helper function for debug_get_pc().  It fetches and returns the
+   value of REGNO.  */
+static unsigned long
+debug_get_reg (pid_t pid, int regno)
+{
+  ptrace_xfer_type value;
+
+  if (linux_read_reg (pid, regno, &value) < 0)
+    return 0;
+  else
+    return (unsigned long) value;
+}
+
+/* Return the value of PC.  Needed by thread-db.c.  */
+unsigned long
+debug_get_pc (struct gdbserv *serv, pid_t pid)
+{
+  return debug_get_reg (pid, PC_REGNUM);
+}
+
+/* Function: reg_format
+
+   This is an old, decrepit version that we want to eliminate.  If you
+   find yourself needing to fix a bug in it, consider changing your
+   target to use one of the preferred mechanisms instead.
+
+   Return zero for success, -1 for failure (never fails). */
+
+static int
+linux_reg_format (struct gdbserv *serv, 
+                         struct gdbserv_thread *thread,
+                         int reg, int *size, int *padding)
+{
+  /* Size and formatting (padding) of thread in g/G packet. */
+  *size = SIZEOF_MAPPEDREG;
+  *padding = 0;
+  return 0;
+}
+
+/* Function: linux_sizeof_reg
+
+   This is an old, decrepit version that we want to eliminate.  If you
+   find yourself needing to fix a bug in it, consider changing your
+   target to use one of the preferred mechanisms instead.
+
+   Returns size of a register. */
+   
+static long linux_sizeof_reg (struct gdbserv *serv, int regno)
+{
+  return SIZEOF_MAPPEDREG;
+}
+
+/* Function: linux_get_reg
+
+   This is an old, decrepit version that we want to eliminate.  If you
+   find yourself needing to fix a bug in it, consider changing your
+   target to use one of the preferred mechanisms instead.
+
+   Return -1 for failure, zero for success.  */
+
+static int
+linux_get_reg (struct gdbserv *serv, int regno, struct gdbserv_reg *reg)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  ptrace_xfer_type regval;
+
+  /* Get the register value. */
+  if (linux_read_reg (process->pid, regno, &regval) < 0)
+    {
+      fprintf (stderr, "Error: linux_get_reg: Register %d out of bounds.\n", regno);
+      return -1;
+    }
+
+  /* Shove it into the gdbserv_reg struct. */
+  if (SIZEOF_MAPPEDREG == 4)
+    gdbserv_ulong_to_reg (serv, (unsigned long) regval, reg);
+  else
+    gdbserv_ulonglong_to_reg (serv, (unsigned long long) regval, reg);
+  return 0;    /* success */
+  
+}
+
+/* Function: linux_set_reg
+
+   This is an old, decrepit version that we want to eliminate.  If you
+   find yourself needing to fix a bug in it, consider changing your
+   target to use one of the preferred mechanisms instead.
+
+   Return -1 for failure, zero for success. */
+
+static int
+linux_set_reg (struct gdbserv *serv, int regno, struct gdbserv_reg *reg)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  ptrace_xfer_type regval;
+
+  if (regno < 0 || regno >= NUM_REGS)
+    {
+      fprintf (stderr, "Error: linux_set_reg: Register %d out of bounds.\n", regno);
+      return -1;
+    }
+
+  /* Get the register value out of the struct gdbserv_reg. */
+  if (sizeof (regval) == 4)
+    gdbserv_reg_to_ulong (serv, reg, (unsigned long *) &regval);
+  else
+    gdbserv_reg_to_ulonglong (serv, reg, (unsigned long long *) &regval);
+
+  /* Write the child's register. */
+  if (linux_write_reg (process->pid, regno, regval) < 0)
+    return -1; /* Fail */
+
+  return 0;    /* success */
+  
+}
+
+/* gregset functions */
+
+/* Function: reg_from_gregset
+   Extract register from gregset by regnum.
+   Return -1 for failure, zero for success. */
+
+extern int
+reg_from_gregset (struct gdbserv *serv, 
+                 struct gdbserv_reg *reg, 
+                 int regno, 
+                 const GREGSET_T gregset)
+{
+  unsigned long offset = linux_register_offset (regno);
+  unsigned long long value;
+
+  if (offset < 0)
+    return -1;         /* failure */
+
+  if (SIZEOF_MAPPEDREG == 4)
+    {
+      value = *((unsigned long *) (((char *) gregset) + offset));
+    }
+  else if (SIZEOF_MAPPEDREG == 8)
+    {
+      value = *((unsigned long long *) (((char *) gregset) + offset));
+    }
+  else
+    {
+      return -1;       /* failure */
+    }  
+  gdbserv_ulonglong_to_reg (serv, value, reg);
+  return 0;
+}
+
+/* Function: reg_to_gregset
+   Insert register into gregset by regnum.
+   Return -1 for failure, zero for success. */
+
+extern int
+reg_to_gregset (struct gdbserv *serv, 
+               const struct gdbserv_reg *reg, 
+               int regno, 
+               GREGSET_T gregset)
+{
+  unsigned long offset = linux_register_offset (regno);
+  unsigned long long value;
+
+  if (offset < 0)
+    return -1;         /* failure */
+
+  gdbserv_reg_to_ulonglong (serv, reg, &value);
+  if (SIZEOF_MAPPEDREG == 4)
+    {
+      *((unsigned long *) (((char *) gregset) + offset)) = value;
+    }
+  else if (SIZEOF_MAPPEDREG == 8)
+    {
+      *((unsigned long long *) (((char *) gregset) + offset)) = value;
+    }
+  else
+    {
+      return -1;       /* failure */
+    }
+  return 0;
+}
+
+/* Function: reg_from_fpregset
+   Extract register from fpregset by regnum.
+   Return -1 for failure, zero for success.  */
+
+extern int
+reg_from_fpregset (struct gdbserv *serv, 
+                  struct gdbserv_reg *reg, 
+                  int regno, 
+                  const FPREGSET_T *fpregset)
+{
+  return -1;   /* Unimplemented.  */
+}
+
+/* Function: reg_to_fpregset
+   Insert register into fpregset by regnum.
+   Return -1 for failure, zero for success. */
+
+extern int
+reg_to_fpregset (struct gdbserv *serv, 
+                const struct gdbserv_reg *reg, 
+                int regno, 
+                FPREGSET_T *fpregset)
+{
+  return -1;   /* Unimplemented.  */
+}
+
+/* Function: reg_from_xregset
+   Extract register from extended regset by regnum.
+   Return -1 for failure, zero for success.  */
+
+int
+reg_from_xregset (struct gdbserv *serv, 
+                 struct gdbserv_reg *reg, 
+                 int regno, 
+                 const void *xregset)
+{
+  return -1;   /* Unimplemented.  */
+}
+
+/* Function: reg_to_xregset
+   Insert register into extended regset by regnum.
+   Return -1 for failure, zero for success.  */
+
+int
+reg_to_xregset (struct gdbserv *serv, 
+               const struct gdbserv_reg *reg, 
+               int regno, 
+               void *xregset)
+{
+  return -1;   /* Unimplemented.  */
+}
+
+/* Function: get_gregset
+   Read the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+get_gregset (struct gdbserv *serv, int pid, GREGSET_T gregset)
+{
+  if (ptrace_read_user (pid, 0, sizeof (GREGSET_T), (char *) gregset) != 0)
+    return -1;
+  return 0;
+}
+
+/* Function: put_gregset
+   write the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+put_gregset (struct gdbserv *serv, int pid, const GREGSET_T gregset)
+{
+  if (ptrace_write_user (pid, 0, sizeof (GREGSET_T), 
+                        (char *) gregset) != 0)
+    return -1;
+  return 0;
+}
+
+static int
+get_fpregset (struct gdbserv *serv, int pid, FPREGSET_T *fpregset)
+{
+  return -1;   /* Unimplemented.  */
+}
+
+/* Function: put_fpregset
+   write the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+put_fpregset (struct gdbserv *serv, int pid, const FPREGSET_T *fpregset)
+{
+  return -1;   /* Unimplemented.  */
+}
+
+/* Function: get_fpregset
+   Read the fpregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+get_xregset (struct gdbserv *serv, int pid, void *fpregset)
+{
+  return -1;
+}
+
+/* Function: put_xregset
+   write the gregset for pid.
+   Return -1 for failure, zero for success. */
+
+static int
+put_xregset (struct gdbserv *serv, int pid, const void *fpregset)
+{
+  return -1;
+}
+
+#endif /* Target specific register functions for other architectures */
+
+
+/* Track sole connection to a remote gdb client. */
+/* FIXME: needed? */
+static struct gdbserv *linux_connect_lock = NULL;
+
+
+
+/* target vector: */
+
+/* private sub-vector for ptrace target: */
+static struct gdbserv_target *ptrace_target;   /* FIXME global */
+
+/* Detach vector -- shut down this target connection.
+ */
+
+static void
+linux_detach (struct gdbserv *serv, struct gdbserv_target *target)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  assert (linux_connect_lock == serv);
+
+  ptrace_target->detach (serv, target);
+  if (process->debug_informational)
+    fprintf (stderr, "linux - detached.\n");
+  linux_connect_lock = NULL;
+
+  /* Quit out of main loop for this demo.  In general, this is not 
+     necessary, as the next incoming connection could again be handled 
+     by linux_attach() above.  */
+  server_quit_p = 1;
+}
+
+
+/* Process Rcmd vector
+ * (apparently a target-specific remote command).
+ */
+
+static void
+linux_process_rcmd (struct gdbserv *serv, const char *cmd, int cmdsize)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  if (!strcmp (cmd, "1"))
+    {
+      process->debug_backend = 1;
+    }
+  else if (!strcmp (cmd, "0"))
+    {
+      process->debug_backend = 0;
+    }
+}
+
+/* This function is called from gdbloop_poll when a new incoming
+   connection is attempted.  It may return NULL if the new connection
+   is to be refused, or a gdbserv_target vector if the connection is
+   accepted.  */
+
+static struct gdbserv_target *
+linux_attach (struct gdbserv *serv, void *data)
+{
+  struct gdbserv_target *linux_target;
+  struct child_process *process = data;
+  extern struct gdbserv_target *ptrace_attach (struct gdbserv *, void *);
+  extern int thread_db_attach (); /* FIXME header <^ */
+
+  /* Enable server tracing. */
+  /*  gdbserv_state_trace = stderr;*/
+
+  if (linux_connect_lock != NULL)
+    {
+      fprintf (stderr, "linux: rejected duplicate connection.\n");
+      return NULL;
+    }
+
+  if ((ptrace_target = ptrace_attach (serv, data)) == NULL)
+    {
+      fprintf (stderr, "Linux: unable to open %s\n", process->argv[0]);
+      return NULL;
+    }
+
+  if (process->debug_informational)
+    fprintf (stderr, "linux: accepted gdb connection.\n");
+  linux_connect_lock = serv;
+
+  linux_target = malloc (sizeof (struct gdbserv_target));
+  memset (linux_target, 0, sizeof (*linux_target));
+
+  /* Callback structure for function pointers that handle processed
+     control packets.  See gdbserv-target.h for docs on the individual
+     functions. */
+
+  linux_target->process_rcmd          = linux_process_rcmd;
+  linux_target->process_set_args      = NULL;
+  /* Replace the process_get_reg(s) method with get_regs. */
+  linux_target->process_set_reg       = NULL;
+  linux_target->process_set_regs      = NULL;
+  linux_target->process_get_reg       = NULL;
+  linux_target->process_get_regs      = NULL;
+  linux_target->get_reg               = linux_get_reg;
+  linux_target->set_reg               = linux_set_reg;
+  linux_target->sizeof_reg            = linux_sizeof_reg;
+  linux_target->gg_reg_nr             = linux_gg_reg_nr;
+#if __LITTLE_ENDIAN == __BYTE_ORDER
+  linux_target->output_reg            = gdbserv_output_reg_leb;
+  linux_target->input_reg             = gdbserv_input_reg_leb;
+#elif __BIG_ENDIAN == __BYTE_ORDER
+  linux_target->output_reg            = gdbserv_output_reg_beb;
+  linux_target->input_reg             = gdbserv_input_reg_beb;
+#else
+#error unknown endianness
+#endif
+  linux_target->next_gg_reg           = linux_next_gg_reg;
+  linux_target->reg_format            = linux_reg_format;
+
+  linux_target->expedited_reg_nr      = NULL;
+  linux_target->get_mem               = ptrace_target->get_mem;
+  linux_target->set_mem               = ptrace_target->set_mem;
+  linux_target->process_set_pc        = NULL;
+  linux_target->flush_i_cache         = ptrace_target->flush_i_cache;
+  linux_target->process_signal        = ptrace_target->process_signal;
+  linux_target->compute_signal        = ptrace_target->compute_signal;
+  linux_target->get_trap_number       = ptrace_target->get_trap_number;
+  linux_target->exit_program          = ptrace_target->exit_program;
+  linux_target->break_program         = ptrace_target->break_program;
+  linux_target->reset_program         = NULL;
+  linux_target->restart_program       = NULL;
+#if defined(_MIPSEL) || defined(_MIPSEB)
+  linux_target->singlestep_program    = mips_singlestep_program;
+#else
+  linux_target->singlestep_program    = ptrace_target->singlestep_program;
+#endif
+  linux_target->cyclestep_program     = NULL;
+  linux_target->sigkill_program       = NULL;
+  linux_target->continue_program      = ptrace_target->continue_program;
+  linux_target->remove_breakpoint     = NULL;
+  linux_target->set_breakpoint        = NULL;
+  linux_target->process_target_packet = NULL;
+  linux_target->detach                = linux_detach;
+
+  linux_target->data = data;
+  process->serv = serv;
+#if defined(_MIPSEL) || defined(_MIPSEB)
+  process->is_ss = 0;
+#endif
+
+  /* Attach to thread_db module. */
+  /* FIXME: unconditional call to extern function? */
+  if ((thread_db_attach (serv, linux_target)) < 0)
+    { /* failed */
+      fprintf (stderr, "Failed to open thread_db library.\n");
+    }
+
+  return linux_target;
+}
+
+static int
+linux_check_child_state (struct child_process *process)
+{
+  return ptrace_check_child_state (process);
+}
+
+static void
+linux_fromtarget_break (struct child_process *process)
+{
+  int gdb_signal = ptrace_target->compute_signal (process->serv,
+                                                 process->stop_signal);
+  gdbserv_fromtarget_break (process->serv, gdb_signal);
+}
+
+static void
+linux_fromtarget_exit (struct child_process *process)
+{
+  gdbserv_fromtarget_exit (process->serv, process->stop_signal);
+}
+
+static void
+linux_fromtarget_terminate (struct child_process *process)
+{
+  int gdb_signal = ptrace_target->compute_signal (process->serv,
+                                                 process->stop_signal);
+
+  gdbserv_fromtarget_terminate (process->serv, gdb_signal);
+}
+
+/* This struct contains the vectors that connect us to main:
+ */
+struct server_vector gdbserver = 
+{
+  linux_attach, 
+  linux_check_child_state, 
+  linux_fromtarget_break, 
+  linux_fromtarget_exit,
+  linux_fromtarget_terminate
+};
+
+/* Function: decr_pc_after_break
+   [Must be implemented explicitly for each supported architecture.]
+
+   For multi-thread linux, if several threads hit a breakpoint
+   "simultaneously", we will want to set at least one of them up
+   so that it will hit the same breakpoint again the next time it
+   gets to run (assuming the breakpoint hasn't been removed by then).
+
+   Depending on the target architecture, that may mean setting
+   the PC back to point at the trap instruction.  
+
+   Return -1 for failure, zero for success. */
+
+#ifdef X86_LINUX_TARGET
+
+/* For ia32 we do need to decrement the PC to point at the trap. */
+int
+decr_pc_after_break (struct gdbserv *serv, pid_t pid)
+{
+  extern int thread_db_noisy;
+  unsigned long pc;
+  int status;
+
+  status = read_reg_as_ulong (serv, pid, PC_REGNUM, &pc);
+  if (status < 0)
+    return -1;
+
+  pc -= 1;
+  if (thread_db_noisy)
+    fprintf (stderr, "<decr_pc_after_break: pid %d, addr 0x%08x>\n", pid, pc);
+  status = write_reg_as_ulong (serv, pid, PC_REGNUM, pc);
+  return status;
+}
+
+#else
+int
+decr_pc_after_break (struct gdbserv *serv, pid_t pid)
+{
+  return 0;
+}
+#endif
+
+
+#if defined(_MIPSEL) || defined(_MIPSEB)
+
+/* 
+ * Worker function to get and return a register
+ */
+
+static ptrace_xfer_type
+mips_get_reg(struct gdbserv *serv, int regno)
+{
+  ptrace_xfer_type value;
+  struct child_process *process = gdbserv_target_data (serv);
+  pid_t pid = process->pid;
+
+  if (read_reg_bytes (pid, regno, &value) < 0)
+    return 0;
+  else
+    return value;
+}
+
+/*
+ * mips singlestep
+ *
+ * necessary since no support in ptrace.
+ */
+
+static void
+mips_singlestep_program (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  ptrace_arg3_type targ;
+  ptrace_xfer_type mips_pc;
+
+  union mips_instruction insn;
+  int is_branch, is_cond, i;
+
+  ptrace_xfer_type bp_inst = 0x0000000d;
+
+  /* FIXME: handle signals! */
+  if (process->debug_backend)
+    fprintf (stderr, "mips_singlestep_program %ld\n", process->signal_to_send);
+  process->stop_signal = 0;
+  process->stop_status = 0;
+
+  errno = 0;
+
+  /* Following is equiv to  ptrace (PTRACE_SINGLESTEP, process->pid, 1L, process->signal_to_send); */
+
+  /* get the current PC */
+  mips_pc = mips_get_reg(serv, PC_REGNUM);                     
+  targ = mips_pc;
+
+  /* get the word there (opcode) */
+
+  insn.word = ptrace (PTRACE_PEEKTEXT, process->pid, mips_pc, 0L);
+
+  is_branch = is_cond = 0;
+
+  /* set flag so handle_waitstatus can restore breakpoint stuff */
+  process->is_ss = 1;                                  
+
+  switch (insn.i_format.opcode) {
+  /*
+   * jr and jalr are in r_format format.
+   */
+  case spec_op:
+    switch (insn.r_format.func) {
+    case jalr_op:
+    case jr_op:
+       targ = mips_get_reg(serv, insn.r_format.rs);
+       is_branch = 1;
+       break;
+    }
+    break;
+
+  /*
+   * This group contains:
+   * bltz_op, bgez_op, bltzl_op, bgezl_op,
+   * bltzal_op, bgezal_op, bltzall_op, bgezall_op.
+   */
+  case bcond_op:
+    is_branch = is_cond = 1;
+    targ += 4 + (insn.i_format.simmediate << 2);
+    break;
+
+  /*
+   * These are unconditional and in j_format.
+   */
+  case jal_op:
+  case j_op:
+    is_branch = 1;
+    targ += 4;
+    targ >>= 28;
+    targ <<= 28;
+    targ |= (insn.j_format.target << 2);
+    break;
+
+  /*
+   * These are conditional.
+   */
+  case beq_op:
+  case beql_op:
+  case bne_op:
+  case bnel_op:
+  case blez_op:
+  case blezl_op:
+  case bgtz_op:
+  case bgtzl_op:
+  case cop0_op:
+  case cop1_op:
+  case cop2_op:
+  case cop1x_op:
+    is_branch = is_cond = 1;
+    targ += 4 + (insn.i_format.simmediate << 2);
+    break;
+  }
+       
+  if (is_branch) {
+    i = 0;
+    if (is_cond && targ != (mips_pc + 8)) {
+       process->ss_info[i].ss_addr = mips_pc + 8;
+       process->ss_info[i++].ss_val = ptrace (PTRACE_PEEKTEXT, process->pid, mips_pc+8, 0L);
+       ptrace (PTRACE_POKETEXT, process->pid, mips_pc+8, bp_inst);
+    }
+    process->ss_info[i].ss_addr = targ;
+    process->ss_info[i].ss_val = ptrace (PTRACE_PEEKTEXT, process->pid, targ, 0L);
+    ptrace (PTRACE_POKETEXT, process->pid, targ, bp_inst);
+  } else {
+    process->ss_info[0].ss_addr = mips_pc + 4;
+    process->ss_info[0].ss_val = ptrace (PTRACE_PEEKTEXT, process->pid, mips_pc+4, 0L);
+    process->ss_info[1].ss_addr = 0;
+    ptrace (PTRACE_POKETEXT, process->pid, mips_pc+4, bp_inst);
+  }
+
+  process->signal_to_send = 0;
+  ptrace (PTRACE_CONT, process->pid, 1L, process->signal_to_send); 
+}
+#endif /* _MIPSEL */
+
+
+/* proc_service callback functions */
+
+ps_err_e
+ps_lgetregs (gdb_ps_prochandle_t ph,           /* Get LWP general regs */
+            lwpid_t     lwpid,
+            GREGSET_T gregset)
+{
+  if (get_gregset (ph->serv, lwpid, gregset) < 0)
+    {
+      fprintf (stderr, "<<< ERROR ps_lgetregs %d >>>\n", lwpid);
+      return PS_ERR;
+    }
+  return PS_OK;
+}
+
+ps_err_e
+ps_lsetregs (gdb_ps_prochandle_t ph,           /* Set LWP general regs */
+            lwpid_t           lwpid,
+            const GREGSET_T gregset)
+{
+  if (put_gregset (ph->serv, lwpid, gregset) < 0)
+    {
+      fprintf (stderr, "<<< ERROR ps_lsetregs %d >>>\n", lwpid);
+      return PS_ERR;
+    }
+  return PS_OK;
+}
+
+ps_err_e
+ps_lgetfpregs (gdb_ps_prochandle_t ph,         /* Get LWP float regs */
+              lwpid_t       lwpid,
+              FPREGSET_T *fpregset)
+{
+  if (get_fpregset (ph->serv, lwpid, fpregset) < 0)
+    {
+      fprintf (stderr, "<<< ERROR ps_lgetfpregs %d >>>\n", lwpid);
+      return PS_ERR;
+    }
+  return PS_OK;
+}
+
+ps_err_e
+ps_lsetfpregs (gdb_ps_prochandle_t ph,         /* Set LWP float regs */
+              lwpid_t             lwpid,
+              const FPREGSET_T *fpregset)
+{
+  if (put_fpregset (ph->serv, lwpid, fpregset) < 0)
+    {
+      fprintf (stderr, "<<< ERROR ps_lsetfpregs %d >>>\n", lwpid);
+      return PS_ERR;
+    }
+  return PS_OK;
+}
+
+ps_err_e
+ps_lgetxregsize (gdb_ps_prochandle_t ph,       /* Get XREG size */
+                lwpid_t lwpid,
+                int *xregsize)
+{
+  *xregsize = get_xregsetsize (ph->serv, lwpid);
+  if (*xregsize > 0)
+    return PS_OK;
+  else
+    return PS_ERR;
+}
+
+ps_err_e
+ps_lgetxregs (gdb_ps_prochandle_t ph,          /* Get XREGS */
+             lwpid_t lwpid,
+             caddr_t xregset)
+{
+  if (get_xregset (ph->serv, lwpid, xregset) < 0)
+    {
+      fprintf (stderr, "<<< ERROR ps_lgetxregs %d >>>\n", lwpid);
+      return PS_ERR;
+    }
+  return PS_OK;
+}
+
+ps_err_e
+ps_lsetxregs (gdb_ps_prochandle_t ph,          /* Set XREGS */
+             lwpid_t lwpid,
+             caddr_t xregset)
+{
+  if (put_xregset (ph->serv, lwpid, xregset) < 0)
+    {
+      fprintf (stderr, "<<< ERROR ps_lsetxregs %d >>>\n", lwpid);
+      return PS_ERR;
+    }
+  return PS_OK;
+}
+
+/*
+ * ps_getpid
+ *
+ * return the main pid for the child process
+ * (special for Linux -- not used on Solaris)
+ */
+
+pid_t
+ps_getpid (gdb_ps_prochandle_t ph)
+{
+  return ph->pid;
+}
diff --git a/rda/unix/no-threads.c b/rda/unix/no-threads.c
new file mode 100644 (file)
index 0000000..0b96ba4
--- /dev/null
@@ -0,0 +1,35 @@
+/* no-threads.c
+
+   Copyright 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 "gdbserv.h"
+#include "gdbserv-target.h"
+
+/* Make lots of noise (debugging output). */
+int thread_db_noisy = 0;
+
+int
+thread_db_attach (struct gdbserv *serv, struct gdbserv_target *target)
+{
+  return 0;
+}
diff --git a/rda/unix/ptrace-target.c b/rda/unix/ptrace-target.c
new file mode 100644 (file)
index 0000000..84ac4df
--- /dev/null
@@ -0,0 +1,1427 @@
+/* ptrace-target.c
+
+   Copyright 200, 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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "server.h"
+#include "ptrace-target.h"
+
+#include <sys/wait.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+
+#include "gdbserv.h" 
+#include "gdbserv-target.h" 
+#include "gdbserv-utils.h"
+#include "gdb_proc_service.h"
+#include "gdbserv-thread-db.h"
+
+/* This is unix ptrace gdbserv target that uses the RDA library to implement
+   a remote gdbserver on a unix ptrace host.  It controls the process
+   to be debugged on the linux host, allowing GDB to pull the strings
+   from any host on the network (or on a serial port).  */
+
+/* Track sole connection to a remote gdb client. */
+/* FIXME: needed? */
+static struct gdbserv* ptrace_connect_lock = NULL;
+
+/* Close all open file descriptors except for stdin, stdout, and
+   stderr.  */
+
+static void
+close_open_files (void)
+{
+  long max_open_files = sysconf (_SC_OPEN_MAX);
+  int fd;
+
+  for (fd = 3; fd < max_open_files; fd++)
+    {
+      close (fd);
+    }
+}
+
+/* ptrace_create_child:
+
+   Fork the child process and capture it via ptrace.
+   
+   Args: char *exec_path;      \* path to executable file *\
+        char **all_args;       \* argv array for child.   *\
+*/
+
+/* Local Functions: */
+
+static int
+ptrace_create_child (struct child_process *process)
+{
+  int pid;
+
+  pid = fork ();
+  if (pid < 0)
+    {
+      /*perror_with_name ("fork");*/
+      fprintf (stderr, "PTRACE: fork failed!\n");
+      return 0;
+    }
+
+  if (pid == 0)
+    {
+      close_open_files ();
+      if (process->debug_backend)
+       fprintf (stderr, "PTRACE_TRACEME\n");
+      errno = 0;
+      ptrace (PTRACE_TRACEME, 0L, 0L, 0L);
+      if (errno != 0)
+       {
+         fprintf (stderr, "PTRACE: child cannot be traced!\n");
+         goto fail;
+       }
+      if (process->executable != NULL && process->argv != NULL)
+       execv (process->executable, process->argv);
+      else
+       sleep (-1);     /* FIXME ??? */
+
+      fprintf (stderr, "Cannot exec %s: %s.\n", process->executable,
+              errno > 0 && errno < sys_nerr ? 
+              strerror (errno) : "unknown error");
+    fail:
+      fflush (stderr);
+      _exit (0177);
+    }
+
+  return pid;
+}
+
+/* Decode the waitstatus returned by waitpid, and return the appropriate
+   stop status and stop_signal to gdb.  FIXME: this is not specific to 
+   ptrace, but there's no better place to put it (server.c?) */
+
+extern int
+handle_waitstatus (struct child_process *process, union wait w)
+{
+  if (WIFEXITED (w))
+    {
+      if (process->debug_informational)
+       fprintf (stderr, "\nChild %d exited with retcode = %d\n", 
+                process->pid, WEXITSTATUS (w));
+      process->stop_status = 'W';
+      return (process->stop_signal = WEXITSTATUS (w));
+    }
+  else if (!WIFSTOPPED (w))
+    {
+      if (process->debug_informational)
+       fprintf (stderr, "\nChild %d terminated with signal = %d\n", 
+                process->pid, WTERMSIG (w));
+      process->stop_status = 'X';
+      return (process->stop_signal = WTERMSIG (w));
+    }
+
+#if defined(_MIPSEL) || defined(_MIPSEB)
+  /*
+   * If we were single_stepping, restore the opcodes hoisted
+   * for the breakpoint[s].
+   */
+  if (process->is_ss)
+    {
+      ptrace (PTRACE_POKETEXT, process->pid, process->ss_info[0].ss_addr, process->ss_info[0].ss_val);
+      process->ss_info[0].ss_addr = 0;
+      
+      if (process->ss_info[1].ss_addr) {
+       ptrace (PTRACE_POKETEXT, process->pid, process->ss_info[1].ss_addr, process->ss_info[1].ss_val);
+       process->ss_info[1].ss_addr = 0;
+      }
+      process->is_ss = 0;
+    }
+#endif /* _MIPSEL */
+
+  process->stop_status = 'T';
+  process->stop_signal = WSTOPSIG (w);
+  return process->stop_signal;
+}
+
+static void
+ptrace_kill_program (struct child_process *process, int signum)
+{
+  if (process->debug_backend)
+    fprintf (stderr, "KILL %d, %d\n", process->pid, signum);
+  kill (process->pid, signum);
+}
+
+/*
+ * Exported functions
+ */
+
+/* Read user memory
+ *
+ * Returns 0 for success, errno for failure
+ */
+
+extern int
+ptrace_read_user (int pid, 
+                 ptrace_arg3_type addr, 
+                 int len, 
+                 void *buff)
+{
+  int i;
+
+  /* Require: addr is on the proper boundary, and 
+     len is a proper multiple of PTRACE_XFER_SIZE.  
+     Caller's responsibility.  */
+
+  for (i = 0; i < len; i+= PTRACE_XFER_SIZE)
+    {
+      errno = 0;
+      *(ptrace_xfer_type *) &((char *)buff)[i] =
+       ptrace (PTRACE_PEEKUSER, pid, addr + i, 0);
+      if (errno != 0)
+       return errno;
+    }
+  return 0;
+}
+
+/* Write user memory
+ *
+ * Returns 0 for success, errno for failure
+ */
+
+extern int
+ptrace_write_user (int pid, 
+                  ptrace_arg3_type addr, 
+                  int len, 
+                  const void *buff)
+{
+  int i;
+
+  /* Require: addr is on the proper boundary, and 
+     len is a proper multiple of PTRACE_XFER_SIZE.  
+     Caller's responsibility.  */
+
+  for (i = 0; i < len; i+= PTRACE_XFER_SIZE)
+    {
+#ifdef X86_LINUX_TARGET
+      if (addr + i == 44)
+       continue;       /* Forbidden address/register, not writable. */
+#endif
+      errno = 0;
+      ptrace (PTRACE_POKEUSER, pid, addr + i, 
+             * (ptrace_xfer_type *) &((char *)buff)[i]);
+#if defined(_MIPSEL) || defined(MIPS_LINUX_TARGET)
+      /* mips linux kernel 2.4 has a bug where PTRACE_POKEUSER
+        returns -ESRCH even when it succeeds */
+      if (errno == ESRCH)
+       errno = 0;
+#endif
+      if (errno != 0)
+       return errno;
+    }
+  return 0;
+}
+
+#if defined (PTRACE_GETREGS) || defined (PT_GETREGS)
+
+/* get general regs */
+
+int
+ptrace_get_gregs (struct gdbserv *serv, int alt_pid, void *buff)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  int pid = alt_pid == 0 ? process->pid : alt_pid;
+
+  /* Require: buff is of the appropriate size for the target arch. */
+
+  errno = 0;
+  ptrace (PTRACE_GETREGS, pid, 0, (ptrace_arg4_type) buff);
+  return errno;
+}
+#endif
+
+#if defined (PTRACE_SETREGS) || defined (PT_SETREGS)
+/* set general regs */
+
+int
+ptrace_set_gregs (struct gdbserv *serv, int alt_pid, const void *buff)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  int pid = alt_pid == 0 ? process->pid : alt_pid;
+
+  /* Require: buff is of the appropriate size for the target arch. */
+
+  errno = 0;
+  ptrace (PTRACE_SETREGS, pid, 0, (ptrace_arg4_type) buff);
+  return errno;
+}
+#endif
+
+
+/* get floating point regs */
+
+extern int
+ptrace_get_fpregs (struct gdbserv *serv, int alt_pid, void *buff)
+{
+#if defined (PTRACE_GETFPREGS) || defined (PT_GETFPREGS)
+  struct child_process *process = gdbserv_target_data (serv);
+  int pid = alt_pid == 0 ? process->pid : alt_pid;
+
+  /* Require: buff is of the appropriate size for the target arch. */
+
+  errno = 0;
+  ptrace (PTRACE_GETFPREGS, pid, 0, (ptrace_arg4_type) buff);
+  return errno;
+#else
+  return -1;
+#endif
+}
+
+
+/* set floating point regs */
+
+extern int
+ptrace_set_fpregs (struct gdbserv *serv, int alt_pid, const void *buff)
+{
+#if defined (PTRACE_SETFPREGS) || defined (PT_SETFPREGS)
+  struct child_process *process = gdbserv_target_data (serv);
+  int pid = alt_pid == 0 ? process->pid : alt_pid;
+
+  /* Require: buff is of the appropriate size for the target arch. */
+
+  errno = 0;
+  ptrace (PTRACE_SETFPREGS, pid, 0, (ptrace_arg4_type) buff);
+  return errno;
+#else
+  return -1;
+#endif
+}
+
+
+/* get extended floating point regs */
+
+int
+ptrace_get_fpxregs (struct gdbserv *serv, int alt_pid, void *buff)
+{
+#if defined (PTRACE_GETFPXREGS) || defined (PT_GETFPXREGS)
+  struct child_process *process = gdbserv_target_data (serv);
+  int pid = alt_pid == 0 ? process->pid : alt_pid;
+
+  /* Require: buff is of the appropriate size for the target arch. */
+
+  errno = 0;
+  ptrace (PTRACE_GETFPXREGS, pid, 0, (ptrace_arg4_type) buff);
+  return errno;
+#else
+  return -1;
+#endif
+}
+
+
+/* set extended floating point regs */
+
+int
+ptrace_set_fpxregs (struct gdbserv *serv, int alt_pid, const void *buff)
+{
+#if defined (PTRACE_SETFPXREGS) || defined (PT_SETFPXREGS)
+  struct child_process *process = gdbserv_target_data (serv);
+  int pid = alt_pid == 0 ? process->pid : alt_pid;
+
+  /* Require: buff is of the appropriate size for the target arch. */
+
+  errno = 0;
+  ptrace (PTRACE_SETFPXREGS, pid, 0, (ptrace_arg4_type) buff);
+  return errno;
+#else
+  return -1;
+#endif
+}
+
+/* target vector: */
+
+static void
+ptrace_flush_i_cache (struct gdbserv *serv)
+{
+  /* Calls to ptrace() take care of this for us automatically when
+     needed.  I.e, nothing to do...  */
+  return;
+}
+
+/* sigkill vector
+ */
+
+static void
+ptrace_sigkill_program (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  ptrace_kill_program (process, SIGKILL);
+}
+
+/* exit program vector
+ */
+static void
+ptrace_exit_program (struct gdbserv *serv)
+{
+  ptrace_sigkill_program (serv);
+  gdbserv_fromtarget_exit (serv, GDBSERV_SIGQUIT);
+}
+
+/* break program vector
+ */
+
+static void
+ptrace_break_program (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  if (process->debug_backend)
+    fprintf (stderr, " -- send SIGINT to child %d\n", process->pid);
+  kill (process->pid, SIGINT);
+}
+
+/* get_trap_number vector
+ */
+
+static unsigned long
+ptrace_get_trap_number (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  return process->stop_signal;
+}
+
+/* compute signal vector
+ * No translation necessary -- using unix native signals .
+ */
+
+static unsigned long
+ptrace_compute_signal (struct gdbserv *serv, unsigned long tgtsig)
+{
+  if (tgtsig == 0)
+    return GDBSERV_SIGNONE;
+#ifdef SIGHUP
+  if (tgtsig == SIGHUP)
+    return GDBSERV_SIGHUP;
+#endif
+#ifdef SIGINT
+  if (tgtsig == SIGINT)
+    return GDBSERV_SIGINT;
+#endif
+#ifdef SIGQUIT
+  if (tgtsig == SIGQUIT)
+    return GDBSERV_SIGQUIT;
+#endif
+#ifdef SIGILL
+  if (tgtsig == SIGILL)
+    return GDBSERV_SIGILL;
+#endif
+#ifdef SIGTRAP
+  if (tgtsig == SIGTRAP)
+    return GDBSERV_SIGTRAP;
+#endif
+#ifdef SIGABRT
+  if (tgtsig == SIGABRT)
+    return GDBSERV_SIGABRT;
+#endif
+#ifdef SIGIOT
+  if (tgtsig == SIGIOT)
+    return GDBSERV_SIGABRT;
+#endif
+#ifdef SIGEMT
+  if (tgtsig == SIGEMT)
+    return GDBSERV_SIGEMT;
+#endif
+#ifdef SIGFPE
+  if (tgtsig == SIGFPE)
+    return GDBSERV_SIGFPE;
+#endif
+#ifdef SIGKILL
+  if (tgtsig == SIGKILL)
+    return GDBSERV_SIGKILL;
+#endif
+#ifdef SIGBUS
+  if (tgtsig == SIGBUS)
+    return GDBSERV_SIGBUS;
+#endif
+#ifdef SIGSEGV
+  if (tgtsig == SIGSEGV)
+    return GDBSERV_SIGSEGV;
+#endif
+#ifdef SIGSYS
+  if (tgtsig == SIGSYS)
+    return GDBSERV_SIGSYS;
+#endif
+#ifdef SIGPIPE
+  if (tgtsig == SIGPIPE)
+    return GDBSERV_SIGPIPE;
+#endif
+#ifdef SIGALRM
+  if (tgtsig == SIGALRM)
+    return GDBSERV_SIGALRM;
+#endif
+#ifdef SIGTERM
+  if (tgtsig == SIGTERM)
+    return GDBSERV_SIGTERM;
+#endif
+#ifdef SIGURG
+  if (tgtsig == SIGURG)
+    return GDBSERV_SIGURG;
+#endif
+#ifdef SIGSTOP
+  if (tgtsig == SIGSTOP)
+    return GDBSERV_SIGSTOP;
+#endif
+#ifdef SIGTSTP
+  if (tgtsig == SIGTSTP)
+    return GDBSERV_SIGTSTP;
+#endif
+#ifdef SIGCONT
+  if (tgtsig == SIGCONT)
+    return GDBSERV_SIGCONT;
+#endif
+#ifdef SIGCHLD
+  if (tgtsig == SIGCHLD)
+    return GDBSERV_SIGCHLD;
+#endif
+#ifdef SIGCLD
+  if (tgtsig == SIGCLD)
+    return GDBSERV_SIGCHLD;
+#endif
+#ifdef SIGTTIN
+  if (tgtsig == SIGTTIN)
+    return GDBSERV_SIGTTIN;
+#endif
+#ifdef SIGTTOU
+  if (tgtsig == SIGTTOU)
+    return GDBSERV_SIGTTOU;
+#endif
+#ifdef SIGIO
+  if (tgtsig == SIGIO)
+    return GDBSERV_SIGIO;
+#endif
+#ifdef SIGXCPU
+  if (tgtsig == SIGXCPU)
+    return GDBSERV_SIGXCPU;
+#endif
+#ifdef SIGXFSZ
+  if (tgtsig == SIGXFSZ)
+    return GDBSERV_SIGXFSZ;
+#endif
+#ifdef SIGVTALRM
+  if (tgtsig == SIGVTALRM)
+    return GDBSERV_SIGVTALRM;
+#endif
+#ifdef SIGPROF
+  if (tgtsig == SIGPROF)
+    return GDBSERV_SIGPROF;
+#endif
+#ifdef SIGWINCH
+  if (tgtsig == SIGWINCH)
+    return GDBSERV_SIGWINCH;
+#endif
+#ifdef SIGLOST
+  if (tgtsig == SIGLOST)
+    return GDBSERV_SIGLOST;
+#endif
+#ifdef SIGUSR1
+  if (tgtsig == SIGUSR1)
+    return GDBSERV_SIGUSR1;
+#endif
+#ifdef SIGUSR2
+  if (tgtsig == SIGUSR2)
+    return GDBSERV_SIGUSR2;
+#endif
+#ifdef SIGPWR
+  if (tgtsig == SIGPWR)
+    return GDBSERV_SIGPWR;
+#endif
+#ifdef SIGPOLL
+  if (tgtsig == SIGPOLL)
+    return GDBSERV_SIGPOLL;
+#endif
+#ifdef SIGWIND
+  if (tgtsig == SIGWIND)
+    return GDBSERV_SIGWIND;
+#endif
+#ifdef SIGPHONE
+  if (tgtsig == SIGPHONE)
+    return GDBSERV_SIGPHONE;
+#endif
+#ifdef SIGWAITING
+  if (tgtsig == SIGWAITING)
+    return GDBSERV_SIGWAITING;
+#endif
+#ifdef SIGLWP
+  if (tgtsig == SIGLWP)
+    return GDBSERV_SIGLWP;
+#endif
+#ifdef SIGDANGER
+  if (tgtsig == SIGDANGER)
+    return GDBSERV_SIGDANGER;
+#endif
+#ifdef SIGGRANT
+  if (tgtsig == SIGGRANT)
+    return GDBSERV_SIGGRANT;
+#endif
+#ifdef SIGRETRACT
+  if (tgtsig == SIGRETRACT)
+    return GDBSERV_SIGRETRACT;
+#endif
+#ifdef SIGMSG
+  if (tgtsig == SIGMSG)
+    return GDBSERV_SIGMSG;
+#endif
+#ifdef SIGSOUND
+  if (tgtsig == SIGSOUND)
+    return GDBSERV_SIGSOUND;
+#endif
+#ifdef SIGSAC
+  if (tgtsig == SIGSAC)
+    return GDBSERV_SIGSAC;
+#endif
+#ifdef SIGPRIO
+  if (tgtsig == SIGPRIO)
+    return GDBSERV_SIGPRIO;
+#endif
+#ifdef SIGSTKFLT
+  if (tgtsig == SIGSTKFLT)
+    return GDBSERV_SIGSEGV;    /* ? */
+#endif
+#ifdef SIGPWR
+  if (tgtsig == SIGPWR)
+    return GDBSERV_SIGPWR;
+#endif
+#if defined (SIGRTMIN) && defined (SIGRTMAX)
+    if (tgtsig == SIGRTMIN)
+      return GDBSERV_SIGRT32;
+    if (tgtsig == SIGRTMIN + 32)
+      return GDBSERV_SIGRT64;
+    if (tgtsig > SIGRTMIN && tgtsig <  SIGRTMAX)
+      return GDBSERV_SIGRT33 + tgtsig - 1;
+    return GDBSERV_SIGNONE;    /* ? */
+#endif
+}
+
+/* singlestep vector
+ */
+
+static void
+ptrace_singlestep_program (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  /* FIXME: handle signals! */
+  if (process->debug_backend)
+    fprintf (stderr, "PTRACE_SINGLESTEP %d signal %d\n", 
+            process->pid, process->signal_to_send);
+  process->stop_signal = 0;
+  process->stop_status = 0;
+
+  errno = 0;
+  ptrace (PTRACE_SINGLESTEP, process->pid, 1L, process->signal_to_send);
+  if (errno)
+    fprintf (stderr, "singlestep: ptrace error %s in %d\n",
+            strerror (errno), process->pid);
+  process->signal_to_send = 0;
+}
+
+/*
+ * Continue vector
+ */
+
+static void 
+ptrace_continue_program (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  /* FIXME: handle signals! */
+  if (process->debug_backend)
+    fprintf (stderr, "PTRACE_CONT %d signal %d\n", 
+            process->pid, process->signal_to_send);
+  process->stop_signal = 0;
+  process->stop_status = 0;
+
+  errno = 0;
+  ptrace (PTRACE_CONT, process->pid, 1L, process->signal_to_send);
+  if (errno)
+    fprintf (stderr, "continue: ptrace error %s in %d\n", 
+            strerror (errno), process->pid);
+  process->signal_to_send = 0;
+}
+
+/* Set continue-signal vector 
+ */
+
+static int
+ptrace_process_signal (struct gdbserv *serv, int sig)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  /* Save the signal value for later use by continue/singlestep.  */
+  switch (sig) {
+  case GDBSERV_SIGNONE:
+    process->signal_to_send = 0;               break;
+#ifdef SIGHUP
+  case GDBSERV_SIGHUP:
+    process->signal_to_send = SIGHUP;          break;
+#endif
+#ifdef SIGINT
+  case GDBSERV_SIGINT:
+    process->signal_to_send = SIGINT;          break;
+#endif
+#ifdef SIGQUIT
+  case GDBSERV_SIGQUIT:
+    process->signal_to_send = SIGQUIT;         break;
+#endif
+#ifdef SIGILL
+  case GDBSERV_SIGILL:
+    process->signal_to_send = SIGILL;          break;
+#endif
+#ifdef SIGTRAP
+  case GDBSERV_SIGTRAP:
+    process->signal_to_send = SIGTRAP;         break;
+#endif
+#ifdef SIGABRT
+  case GDBSERV_SIGABRT:
+    process->signal_to_send = SIGABRT;         break;
+#endif
+#ifdef SIGEMT
+  case GDBSERV_SIGEMT:
+    process->signal_to_send = SIGEMT;          break;
+#endif
+#ifdef SIGFPE
+  case GDBSERV_SIGFPE:
+    process->signal_to_send = SIGFPE;          break;
+#endif
+#ifdef SIGKILL
+  case GDBSERV_SIGKILL:
+    process->signal_to_send = SIGKILL;         break;
+#endif
+#ifdef SIGBUS
+  case GDBSERV_SIGBUS:
+    process->signal_to_send = SIGBUS;          break;
+#endif
+#ifdef SIGSEGV
+  case GDBSERV_SIGSEGV:
+    process->signal_to_send = SIGSEGV;         break;
+#endif
+#ifdef SIGSYS
+  case GDBSERV_SIGSYS:
+    process->signal_to_send = SIGSYS;          break;
+#endif
+#ifdef SIGPIPE
+  case GDBSERV_SIGPIPE:
+    process->signal_to_send = SIGPIPE;         break;
+#endif
+#ifdef SIGALRM
+  case GDBSERV_SIGALRM:
+    process->signal_to_send = SIGALRM;         break;
+#endif
+#ifdef SIGTERM
+  case GDBSERV_SIGTERM:
+    process->signal_to_send = SIGTERM;         break;
+#endif
+#ifdef SIGURG
+  case GDBSERV_SIGURG:
+    process->signal_to_send = SIGURG;          break;
+#endif
+#ifdef SIGSTOP
+  case GDBSERV_SIGSTOP:
+    process->signal_to_send = SIGSTOP;         break;
+#endif
+#ifdef SIGTSTP
+  case GDBSERV_SIGTSTP:
+    process->signal_to_send = SIGTSTP;         break;
+#endif
+#ifdef SIGCONT
+  case GDBSERV_SIGCONT:
+    process->signal_to_send = SIGCONT;         break;
+#endif
+#ifdef SIGCHLD
+  case GDBSERV_SIGCHLD:
+    process->signal_to_send = SIGCHLD;         break;
+#endif
+#if defined (SIGCLD) && !defined (SIGCHLD)
+  case GDBSERV_SIGCHLD:
+    process->signal_to_send = SIGCLD;          break;
+#endif
+#ifdef SIGTTIN
+  case GDBSERV_SIGTTIN:
+    process->signal_to_send = SIGTTIN;         break;
+#endif
+#ifdef SIGTTOU
+  case GDBSERV_SIGTTOU:
+    process->signal_to_send = SIGTTOU;         break;
+#endif
+#ifdef SIGIO
+  case GDBSERV_SIGIO:
+    process->signal_to_send = SIGIO;           break;
+#endif
+#ifdef SIGXCPU
+  case GDBSERV_SIGXCPU:
+    process->signal_to_send = SIGXCPU;         break;
+#endif
+#ifdef SIGXFSZ
+  case GDBSERV_SIGXFSZ:
+    process->signal_to_send = SIGXFSZ;         break;
+#endif
+#ifdef SIGVTALRM
+  case GDBSERV_SIGVTALRM:
+    process->signal_to_send = SIGVTALRM;       break;
+#endif
+#ifdef SIGPROF
+  case GDBSERV_SIGPROF:
+    process->signal_to_send = SIGPROF;         break;
+#endif
+#ifdef SIGWINCH
+  case GDBSERV_SIGWINCH:
+    process->signal_to_send = SIGWINCH;                break;
+#endif
+#ifdef SIGLOST
+  case GDBSERV_SIGLOST:
+    process->signal_to_send = SIGLOST;         break;
+#endif
+#ifdef SIGUSR1
+  case GDBSERV_SIGUSR1:
+    process->signal_to_send = SIGUSR1;         break;
+#endif
+#ifdef SIGUSR2
+  case GDBSERV_SIGUSR2:
+    process->signal_to_send = SIGUSR2;         break;
+#endif
+#ifdef SIGPWR
+  case GDBSERV_SIGPWR:
+    process->signal_to_send = SIGPWR;          break;
+#endif
+#ifdef SIGPOLL
+  case GDBSERV_SIGPOLL:
+    process->signal_to_send = SIGPOLL;         break;
+#endif
+#ifdef SIGWIND
+  case GDBSERV_SIGWIND:
+    process->signal_to_send = SIGWIND;         break;
+#endif
+#ifdef SIGPHONE
+  case GDBSERV_SIGPHONE:
+    process->signal_to_send = SIGPHONE;                break;
+#endif
+#ifdef SIGWAITING
+  case GDBSERV_SIGWAITING:
+    process->signal_to_send = SIGWAITING;      break;
+#endif
+#ifdef SIGLWP
+  case GDBSERV_SIGLWP:
+    process->signal_to_send = SIGLWP;          break;
+#endif
+#ifdef SIGDANGER
+  case GDBSERV_SIGDANGER:
+    process->signal_to_send = SIGDANGER;       break;
+#endif
+#ifdef SIGGRANT
+  case GDBSERV_SIGGRANT:
+    process->signal_to_send = SIGGRANT;                break;
+#endif
+#ifdef SIGRETRACT
+  case GDBSERV_SIGRETRACT:
+    process->signal_to_send = SIGRETRACT;      break;
+#endif
+#ifdef SIGMSG
+  case GDBSERV_SIGMSG:
+    process->signal_to_send = SIGMSG;          break;
+#endif
+#ifdef SIGSOUND
+  case GDBSERV_SIGSOUND:
+    process->signal_to_send = SIGSOUND;                break;
+#endif
+#ifdef SIGSAK
+  case GDBSERV_SIGSAK:
+    process->signal_to_send = SIGSAK;          break;
+#endif
+#ifdef SIGPRIO
+  case GDBSERV_SIGPRIO:
+    process->signal_to_send = SIGPRIO;         break;
+#endif
+#if defined (SIGRTMIN) && defined (SIGRTMAX)
+  case GDBSERV_SIGRT32:
+    process->signal_to_send = SIGRTMIN;                break;
+  case GDBSERV_SIGRT33:
+    process->signal_to_send = SIGRTMIN+1;      break;
+  case GDBSERV_SIGRT34:
+    process->signal_to_send = SIGRTMIN+2;      break;
+  case GDBSERV_SIGRT35:
+    process->signal_to_send = SIGRTMIN+3;      break;
+  case GDBSERV_SIGRT36:
+    process->signal_to_send = SIGRTMIN+4;      break;
+  case GDBSERV_SIGRT37:
+    process->signal_to_send = SIGRTMIN+5;      break;
+  case GDBSERV_SIGRT38:
+    process->signal_to_send = SIGRTMIN+6;      break;
+  case GDBSERV_SIGRT39:
+    process->signal_to_send = SIGRTMIN+7;      break;
+  case GDBSERV_SIGRT40:
+    process->signal_to_send = SIGRTMIN+8;      break;
+  case GDBSERV_SIGRT41:
+    process->signal_to_send = SIGRTMIN+9;      break;
+  case GDBSERV_SIGRT42:
+    process->signal_to_send = SIGRTMIN+10;     break;
+  case GDBSERV_SIGRT43:
+    process->signal_to_send = SIGRTMIN+11;     break;
+  case GDBSERV_SIGRT44:
+    process->signal_to_send = SIGRTMIN+12;     break;
+  case GDBSERV_SIGRT45:
+    process->signal_to_send = SIGRTMIN+13;     break;
+  case GDBSERV_SIGRT46:
+    process->signal_to_send = SIGRTMIN+14;     break;
+  case GDBSERV_SIGRT47:
+    process->signal_to_send = SIGRTMIN+15;     break;
+  case GDBSERV_SIGRT48:
+    process->signal_to_send = SIGRTMIN+16;     break;
+  case GDBSERV_SIGRT49:
+    process->signal_to_send = SIGRTMIN+17;     break;
+  case GDBSERV_SIGRT50:
+    process->signal_to_send = SIGRTMIN+18;     break;
+  case GDBSERV_SIGRT51:
+    process->signal_to_send = SIGRTMIN+19;     break;
+  case GDBSERV_SIGRT52:
+    process->signal_to_send = SIGRTMIN+20;     break;
+  case GDBSERV_SIGRT53:
+    process->signal_to_send = SIGRTMIN+21;     break;
+  case GDBSERV_SIGRT54:
+    process->signal_to_send = SIGRTMIN+22;     break;
+  case GDBSERV_SIGRT55:
+    process->signal_to_send = SIGRTMIN+23;     break;
+  case GDBSERV_SIGRT56:
+    process->signal_to_send = SIGRTMIN+24;     break;
+  case GDBSERV_SIGRT57:
+    process->signal_to_send = SIGRTMIN+25;     break;
+  case GDBSERV_SIGRT58:
+    process->signal_to_send = SIGRTMIN+26;     break;
+  case GDBSERV_SIGRT59:
+    process->signal_to_send = SIGRTMIN+27;     break;
+  case GDBSERV_SIGRT60:
+    process->signal_to_send = SIGRTMIN+28;     break;
+  case GDBSERV_SIGRT61:
+    process->signal_to_send = SIGRTMIN+29;     break;
+  case GDBSERV_SIGRT62:
+    process->signal_to_send = SIGRTMIN+30;     break;
+  case GDBSERV_SIGRT63:
+    process->signal_to_send = SIGRTMIN+31;     break;
+  case GDBSERV_SIGRT64:
+    process->signal_to_send = SIGRTMIN+32;     break;
+#endif
+  }
+  /* Since we will handle the signal, we don't want gdbserv
+     to handle it by calling kill!  Return zero.  */
+  return 0;
+}
+
+/* Read memory vector
+ */
+
+static long
+ptrace_xfer_mem (struct gdbserv *serv, 
+                struct gdbserv_reg *addr, 
+                void *data, 
+                long len, 
+                int read)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  ptrace_arg3_type request_base;
+  ptrace_arg3_type xfer_base;
+  ptrace_arg3_type temp_addr;
+  ptrace_xfer_type *buf;
+  long xfer_count;
+  int i;
+
+  /* Get request address.  */
+  gdbserv_reg_to_ulong (serv, addr, &request_base);
+  /* Round down to a PTRACE word boundary. */
+  xfer_base = request_base & - PTRACE_XFER_SIZE;
+  /* Round length up to a PTRACE word boundary. */
+  xfer_count = (((request_base + len) - xfer_base) + PTRACE_XFER_SIZE - 1)
+    / PTRACE_XFER_SIZE;
+  /* Allocate space for xfer.  */
+  buf = (ptrace_xfer_type *) alloca (xfer_count * PTRACE_XFER_SIZE);
+
+  /* Perform memory xfer.  */
+  if (read)
+    {
+      for (i = 0; i < xfer_count; i++)
+       {
+         temp_addr = xfer_base + i * PTRACE_XFER_SIZE;
+
+         errno = 0;
+         buf[i] = ptrace (PTRACE_PEEKTEXT, process->pid, temp_addr, 0L);
+
+         if (process->debug_backend)
+           fprintf (stderr, "PTRACE_PEEKTEXT-1 0x%08lx in %d, 0x%08lx\n", 
+                    (long) temp_addr, process->pid, (long) buf[i]);
+         if (errno)
+           {
+             if (errno != EIO)
+               fprintf (stderr, 
+                        "xfer_mem(1): ptrace error at 0x%08lx in %d: %s\n", 
+                        (long) temp_addr, process->pid, strerror (errno));
+             return -1;
+           }
+       }
+  
+      /* Copy results to caller's buffer space.  */
+      memcpy (data, (char *) buf + (request_base - xfer_base), len);
+    }
+  else /* write */
+    {
+      /* If the xfer buffer overlaps the write-request buffer, 
+        we must first read the values that are there before 
+        replacing with the desired values (otherwise these bytes
+        would be uninitialized).  */
+      if ((unsigned long long) xfer_base < 
+         (unsigned long long) request_base)
+       {
+         errno = 0;
+         buf[0] = ptrace (PTRACE_PEEKTEXT, 
+                          process->pid, xfer_base, 0L);
+         if (process->debug_backend)
+           fprintf (stderr, "PTRACE_PEEKTEXT-2 0x%08lx in %d, 0x%08lx\n", 
+                    (long) xfer_base, process->pid, (long) buf[0]);
+
+         if (errno)
+           {
+             if (errno != EIO)
+               fprintf (stderr, 
+                        "xfer_mem(2): ptrace error at 0x%08lx in %d: %s\n", 
+                        (long) xfer_base, process->pid, strerror (errno));
+             return -1;
+           }
+       }
+      if ((xfer_count > 0) &&
+         ((unsigned long long) (xfer_base + xfer_count * PTRACE_XFER_SIZE) > 
+          (unsigned long long) (request_base + len)))
+       {
+         temp_addr = xfer_base + (xfer_count - 1) * PTRACE_XFER_SIZE;
+         errno = 0;
+         buf[xfer_count - 1] =
+           ptrace (PTRACE_PEEKTEXT, process->pid, temp_addr, 0L);
+         if (process->debug_backend)
+           fprintf (stderr, "PTRACE_PEEKTEXT-3 0x%08lx in %d, 0x%08lx\n", 
+                    (long) temp_addr, process->pid, 
+                    (long) buf[xfer_count - 1]);
+
+         if (errno)
+           {
+             if (errno != EIO)
+               fprintf (stderr, 
+                        "xfer_mem(3): ptrace error at 0x%08lx in %d: %s\n", 
+                        (long) temp_addr, process->pid, strerror (errno));
+             return -1;
+           }
+       }
+
+      /* Now copy user buffer to xfer buffer.  */
+      memcpy ((char *) buf + (request_base - xfer_base), data, len);
+      /* Now write out the data.  */
+      for (i = 0; i < xfer_count; i++)
+       {
+         temp_addr = xfer_base + i * PTRACE_XFER_SIZE;
+
+         errno = 0;
+         ptrace (PTRACE_POKETEXT, process->pid, temp_addr, buf[i]);
+
+         if (process->debug_backend)
+           fprintf (stderr, "PTRACE_POKETEXT 0x%08lx in %d, 0x%08lx\n", 
+                    (long) temp_addr, process->pid, (long) buf[i]);
+
+         if (errno)
+           {
+             if (errno != EIO)
+               fprintf (stderr, 
+                        "xfer_mem(4): ptrace error at 0x%08lx in %d: %s\n", 
+                        (long) temp_addr, process->pid, strerror (errno));
+             return -1;
+           }
+       }
+    }
+
+  return len;
+}
+
+static long
+ptrace_set_mem (struct gdbserv *serv, 
+               struct gdbserv_reg *addr, 
+               void *data, 
+               long len)
+{
+  return ptrace_xfer_mem (serv, addr, data, len, 0);
+}
+
+static long
+ptrace_get_mem (struct gdbserv *serv, 
+               struct gdbserv_reg *addr, 
+               void *data, 
+               long len)
+{
+  return ptrace_xfer_mem (serv, addr, data, len, 1);
+}
+
+
+
+
+/* Detach vector -- shut down this target connection.
+ */
+
+static void
+ptrace_detach (struct gdbserv *serv, struct gdbserv_target *target)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  assert (ptrace_connect_lock == serv);
+
+  if (process->debug_informational)
+    fprintf (stderr, "ptrace - detached.\n");
+  ptrace_connect_lock = NULL;
+
+  /* Quit out of main loop for this demo.  In general, this is not
+     necessary, as the next incoming connection could again be handled
+     by ptrace_attach() above.  */
+  server_quit_p = 1;
+}
+
+/* This function is called from gdbloop_poll when a new incoming
+   connection is attempted.  It may return NULL if the new connection
+   is to be refused, or a gdbserv_target vector if the connection is
+   accepted.  */
+
+struct gdbserv_target* 
+ptrace_attach (struct gdbserv *serv, void *data)
+{
+  struct gdbserv_target *ptrace_target;
+  struct child_process *process = data;
+  union wait w;
+  int pid;
+
+
+  /* Enable server tracing. */
+  /*  gdbserv_state_trace = stderr;*/
+
+  if (ptrace_connect_lock != NULL)
+    {
+      fprintf (stderr, "ptrace: rejected duplicate connection.\n");
+      return NULL;
+    }
+
+  if (process->debug_informational)
+    fprintf (stderr, "ptrace: accepted gdb connection.\n");
+  ptrace_connect_lock = serv;
+
+  process->pid = ptrace_create_child (process);
+
+  do {
+    pid = wait (&w);
+  } while (pid != process->pid);
+
+  handle_waitstatus (process, w);
+
+  if (process->pid > 0)
+    {
+      if (process->debug_informational)
+       fprintf (stderr, "ptrace: created child process %d, %s\n", 
+                process->pid, process->executable);
+    }
+  else
+    {
+      fprintf (stderr, "PTRACE: failed to create child process %s!\n",
+              process->executable);
+      return NULL;
+    }
+
+  ptrace_target = malloc (sizeof (struct gdbserv_target));
+  memset (ptrace_target, 0, sizeof (*ptrace_target));
+
+  /* Callback structure for function pointers that handle processed
+     control packets.  See gdbserv-target.h for docs on the individual
+     functions. */
+
+  ptrace_target->process_get_gen       = NULL;
+  ptrace_target->process_set_gen       = NULL;
+  ptrace_target->process_rcmd          = NULL;
+  ptrace_target->process_set_args      = NULL;
+  ptrace_target->process_set_reg       = NULL;
+  ptrace_target->process_get_reg       = NULL;
+  ptrace_target->process_set_regs      = NULL;
+  ptrace_target->process_get_regs      = NULL;
+  ptrace_target->input_reg             = NULL;
+  ptrace_target->output_reg            = NULL;
+  ptrace_target->gg_reg_nr             = NULL;
+  ptrace_target->expedited_reg_nr      = NULL;
+  ptrace_target->sizeof_reg            = NULL;
+  ptrace_target->set_reg               = NULL;
+  ptrace_target->get_reg               = NULL;
+  ptrace_target->get_mem               = ptrace_get_mem;
+  ptrace_target->set_mem               = ptrace_set_mem;
+  ptrace_target->process_set_pc        = NULL;
+  ptrace_target->flush_i_cache         = ptrace_flush_i_cache;
+  ptrace_target->process_signal        = ptrace_process_signal;
+  ptrace_target->compute_signal        = ptrace_compute_signal;
+  ptrace_target->get_trap_number       = ptrace_get_trap_number;
+  ptrace_target->exit_program          = ptrace_exit_program;
+  ptrace_target->break_program         = ptrace_break_program;
+  ptrace_target->reset_program         = NULL;
+  ptrace_target->restart_program       = NULL;
+  ptrace_target->singlestep_program    = ptrace_singlestep_program;
+  ptrace_target->cyclestep_program     = NULL;
+  ptrace_target->sigkill_program       = ptrace_sigkill_program;
+  ptrace_target->continue_program      = ptrace_continue_program;
+  ptrace_target->remove_breakpoint     = NULL;
+  ptrace_target->set_breakpoint        = NULL;
+  ptrace_target->process_target_packet = NULL;
+  ptrace_target->detach                = ptrace_detach;
+
+  ptrace_target->data = data;  /* Save ptr to child_process struct.  */
+
+#if defined(_MIPSEL) || defined(_MIPSEB)
+  process->is_ss = 0;
+#endif
+
+  return ptrace_target;
+}
+
+/* This function is called from the main loop, and waits for an event
+   (such as a signal or exception) from the running child process. */
+
+int
+ptrace_check_child_state (struct child_process *process)
+{
+  struct gdbserv *serv = process->serv;
+  int ret;
+  union wait w;
+
+  ret = waitpid (process->pid, (int *) &w, WNOHANG);
+
+  if (ret > 0) /* found an event */
+    {
+      ret = handle_waitstatus (process, w);
+      if (process->debug_backend)
+       fprintf (stderr, "wait returned %d\n", ret);
+      return 1;
+    }
+  return 0;
+}
+
+/* Exported service functions */
+
+/* Function: continue_lwp
+   Send PTRACE_CONT to an lwp. 
+   Returns -1 for failure, zero for success. */
+
+extern int
+continue_lwp (lwpid_t lwpid, int signal)
+{
+  if (thread_db_noisy)
+    fprintf (stderr, "<ptrace (PTRACE_CONT, %d, 0, %d)>\n", lwpid, signal);
+
+  if (ptrace (PTRACE_CONT, lwpid, 0, signal) < 0)
+    {
+      fprintf (stderr, "<<< ERROR: PTRACE_CONT %d failed >>>\n", lwpid);
+      return -1;
+    }
+  return 0;
+}
+
+/* Function: singlestep_lwp
+   Send PTRACE_SINGLESTEP to an lwp.
+   Returns -1 for failure, zero for success. */
+
+extern int
+singlestep_lwp (lwpid_t lwpid, int signal)
+{
+  if (thread_db_noisy)
+    fprintf (stderr, "<ptrace (PTRACE_SINGLESTEP, %d, 0, %d)>\n", lwpid, signal);
+
+  if (ptrace (PTRACE_SINGLESTEP, lwpid, 0, signal) < 0)
+    {
+      fprintf (stderr, "<<< ERROR: PTRACE_SINGLESTEP %d failed >>>\n", lwpid);
+      return -1;
+    }
+  return 0;
+}
+
+/* Function: attach_lwp
+   Send PTRACE_ATTACH to an lwp.
+   Returns -1 for failure, zero for success. */
+
+extern int
+attach_lwp (lwpid_t lwpid)
+{
+  errno = 0;
+  if (ptrace (PTRACE_ATTACH, lwpid, 0, 0) == 0)
+    {
+      if (thread_db_noisy)
+       fprintf (stderr, "<ptrace (PTRACE_ATTACH, %d, 0, 0)>\n", lwpid);
+      return 0;
+    }
+  else
+    {
+      fprintf (stderr, "<<< ERROR ptrace attach %d failed, %s >>>\n",
+              lwpid, strerror (errno));
+      return -1;
+    }
+}
+
+/* Function: stop_lwp
+   Use SIGSTOP to force an lwp to stop. 
+   Returns -1 for failure, zero for success. */
+
+extern int
+stop_lwp (lwpid_t lwpid)
+{
+  if (kill (lwpid, SIGSTOP) == 0)
+    {
+#if 0 /* Too noisy! */
+      if (thread_db_noisy)
+       fprintf (stderr, "<kill (%d, SIGSTOP)>\n", lwpid);
+#endif
+      return 0;
+    }
+  else
+    {
+      fprintf (stderr, "<<< ERROR -- kill (%d, SIGSTOP) failed >>>\n", lwpid);
+      return -1;
+    }
+}
+
+/* proc_service callback functions */
+
+ps_err_e
+ps_pstop (gdb_ps_prochandle_t ph)              /* Process stop */
+{
+  fprintf (stderr, "<ps_pstop [UN-IMPLEMENTED]>\n");
+  return PS_ERR; /* unimplemented. */
+}
+
+ps_err_e
+ps_pcontinue (gdb_ps_prochandle_t ph)          /* Process continue */
+{
+  fprintf (stderr, "<ps_pcontinue [UN-IMPLEMENTED]>\n");
+  return PS_ERR; /* unimplemented. */
+}
+
+ps_err_e
+ps_lstop (gdb_ps_prochandle_t ph,              /* LWP stop */
+         lwpid_t lwpid)
+{
+  fprintf (stderr, "<ps_lstop [UN-IMPLEMENTED]>\n");
+  return PS_ERR; /* unimplemented. */
+}
+
+ps_err_e
+ps_lcontinue (gdb_ps_prochandle_t ph,          /* LWP continue */
+             lwpid_t lwpid)
+{
+  if (continue_lwp (lwpid, 0) < 0)
+    return PS_OK;
+  else
+    return PS_ERR;
+}
+
+ps_err_e
+ps_pdread (gdb_ps_prochandle_t ph,     /* read from data segment */
+          paddr_t             addr,
+          gdb_ps_read_buf_t   buf,
+          gdb_ps_size_t       size)
+{
+  long bytes_read;
+  struct gdbserv_reg addr_reg;
+
+  /* Use unsigned long long for maximum portability. */
+  gdbserv_ulonglong_to_reg (ph->serv, (unsigned long long) addr, &addr_reg);
+
+  bytes_read = ptrace_get_mem (ph->serv, &addr_reg, buf, (long) size);
+
+  if (bytes_read == (long) size)
+    return PS_OK;
+  else
+    return PS_ERR;
+}
+
+ps_err_e
+ps_pdwrite (gdb_ps_prochandle_t ph,    /* write to data segment */
+           paddr_t             addr,
+           gdb_ps_write_buf_t  buf,
+           gdb_ps_size_t       size)
+{
+  long bytes_written;
+  struct gdbserv_reg addr_reg;
+
+  /* Use unsigned long long for maximum portability. */
+  gdbserv_ulonglong_to_reg (ph->serv, (unsigned long long) addr, &addr_reg);
+
+  bytes_written = ptrace_set_mem (ph->serv, &addr_reg, buf, (long) size);
+
+  if (bytes_written == (long) size)
+    return PS_OK;
+  else
+    return PS_ERR;
+}
+
+ps_err_e
+ps_ptread (gdb_ps_prochandle_t ph,     /* read from text segment */
+          paddr_t             addr,
+          gdb_ps_read_buf_t   buf,
+          gdb_ps_size_t       size)
+{
+  long bytes_read;
+  struct gdbserv_reg addr_reg;
+
+  /* Use unsigned long long for maximum portability. */
+  gdbserv_ulonglong_to_reg (ph->serv, (unsigned long long) addr, &addr_reg);
+
+  bytes_read = ptrace_get_mem (ph->serv, &addr_reg, buf, (long) size);
+
+  if (bytes_read == (long) size)
+    return PS_OK;
+  else
+    return PS_ERR;
+}
+
+ps_err_e
+ps_ptwrite (gdb_ps_prochandle_t ph,    /* write to text segment */
+           paddr_t             addr,
+           gdb_ps_write_buf_t  buf,
+           gdb_ps_size_t       size)
+{
+  long bytes_written;
+  struct gdbserv_reg addr_reg;
+
+  /* Use unsigned long long for maximum portability. */
+  gdbserv_ulonglong_to_reg (ph->serv, (unsigned long long) addr, &addr_reg);
+
+  bytes_written = ptrace_set_mem (ph->serv, &addr_reg, buf, (long) size);
+
+  if (bytes_written == (long) size)
+    return PS_OK;
+  else
+    return PS_ERR;
+}
+
diff --git a/rda/unix/ptrace-target.h b/rda/unix/ptrace-target.h
new file mode 100644 (file)
index 0000000..4f36438
--- /dev/null
@@ -0,0 +1,78 @@
+/* ptrace-target.h
+
+   Copyright 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 <sys/ptrace.h>
+#include <sys/user.h>
+
+/* Shared definitions for an RDA based native gdb server using ptrace. */
+
+#ifdef PTRACE_XFER_TYPE_LONG
+typedef long ptrace_xfer_type;
+#endif
+
+#ifdef PTRACE_XFER_TYPE_LONG_LONG
+typedef long long ptrace_xfer_type;
+#endif
+
+#ifdef PTRACE_ARG1_TYPE_LONG
+typedef long ptrace_arg1_type;
+#endif
+
+#ifdef PTRACE_ARG1_TYPE_LONG_LONG
+typedef long long ptrace_arg1_type;
+#endif
+
+#ifdef PTRACE_ARG2_TYPE_LONG
+typedef long ptrace_arg2_type;
+#endif
+
+#ifdef PTRACE_ARG2_TYPE_LONG_LONG
+typedef long long ptrace_arg2_type;
+#endif
+
+#ifdef PTRACE_ARG3_TYPE_LONG
+typedef long ptrace_arg3_type;
+#endif
+
+#ifdef PTRACE_ARG3_TYPE_LONG_LONG
+typedef long long ptrace_arg3_type;
+#endif
+
+#ifdef PTRACE_ARG4_TYPE_LONG
+typedef long ptrace_arg4_type;
+#endif
+
+#ifdef PTRACE_ARG4_TYPE_LONG_LONG
+typedef long long ptrace_arg4_type;
+#endif
+
+int ptrace_write_user (int, ptrace_arg3_type, int, const void *);
+int ptrace_read_user (int, ptrace_arg3_type, int, void *);
+int ptrace_get_gregs (struct gdbserv *serv, int alt_pid, void *buff);
+int ptrace_set_gregs (struct gdbserv *serv, int alt_pid, const void *buff);
+int ptrace_get_fpregs (struct gdbserv *serv, int alt_pid, void *buff);
+int ptrace_set_fpregs (struct gdbserv *serv, int alt_pid,  const void *buff);
+int ptrace_get_fpxregs (struct gdbserv *serv, int alt_pid, void *buff);
+int ptrace_set_fpxregs (struct gdbserv *serv, int alt_pid, const void *buff);
+int ptrace_check_child_state (struct child_process *process);
diff --git a/rda/unix/server.c b/rda/unix/server.c
new file mode 100644 (file)
index 0000000..6df7bbc
--- /dev/null
@@ -0,0 +1,159 @@
+/* server-main.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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "gdbsocket.h"
+#include "gdbloop.h"
+#include "server.h"
+
+/* Signal a request to terminate main loop. */
+int server_quit_p = 0;
+
+/* FIXME -- move to header file.  */
+struct gdbserv_target *linux_attach (struct gdbserv* serv, void* data);
+
+/* We have an empty SIGCHLD handler in order to make sure that
+   the timed, but blocking call to select will be interrupted
+   by SIGCHLD signals.  */
+
+static void
+chld_handler (int sig)
+{
+}
+
+/* Print a usage message and exit.  */
+static void
+usage (char *progname)
+{
+  fprintf (stderr,
+    "Usage: %s [-h] [-v] tcp-port-num executable-file [arguments ...]\n\n"
+    "Start the Red Hat debug agent listening on port ``tcp-port-num'' for\n"
+    "debugging``executable-file'' with optional arguments.\n\n"
+    "Options and arguments:\n"
+    "  -h               Print this usage message.\n"
+    "  -v               Increase verbosity.  One -v flag enables informational\n"
+    "                   messages.  Two -v flags turn on internal debugging\n"
+    "                   messages.\n"
+    "  tcp-port-num     Port number to which debugger connects for purpose\n"
+    "                   of communicating with the debug agent using the GDB\n"
+    "                   remote protocol.\n"
+    "  executable-file  Name of program to debug.\n"
+    "  arguments ...    Command line arguments with which to start program\n"
+    "                   being debugged.\n",
+    progname);
+  exit (1);
+}
+
+int
+main (int argc, char **argv)
+{
+  int portno;
+  char *endptr;
+  int verbose = 0;
+  int optidx;
+  struct child_process *process;
+
+  /* Parse options.  */
+  for (optidx = 1; optidx < argc; optidx++)
+    {
+      if (argv[optidx][0] == '-' && argv[optidx][1] != '\0')
+       {
+         switch (argv[optidx][1])
+           {
+             case 'h':
+               usage (argv[0]);
+               /* not reached */
+               break;
+             case 'v':
+               verbose++;
+               break;
+             default:
+               usage (argv[0]);
+               /* not reached */
+               break;
+           }
+       }
+      else
+       break;
+    }
+
+  if (argc - optidx < 2)
+    usage (argv[0]);
+
+  errno = 0;
+  portno = strtol (argv[optidx], &endptr, 10);
+  if (errno != 0 || endptr == argv[optidx])
+    usage (argv[0]);
+
+  process = malloc (sizeof (struct child_process));
+  memset (process, 0, sizeof (struct child_process));
+  process->argv       = &argv[optidx + 1];
+  process->executable =  argv[optidx + 1];
+
+  if (verbose > 1)
+    process->debug_backend = 1;
+  if (verbose)
+    process->debug_informational = 1;
+
+  signal (SIGCHLD, chld_handler);
+
+  gdbsocket_startup (portno, gdbserver.attach, process);
+  if (process->debug_informational)
+    fprintf (stderr, "Started listening socket on port %d.\n", portno);
+
+  /* Poll for socket traffic. */
+  while (! server_quit_p)
+    {
+      gdbloop_poll (1 /* second */);
+      if (! server_quit_p)
+       {
+         if (gdbserver.check_child_state (process))
+           {
+             switch (process->stop_status) {
+             case 'T':
+               gdbserver.fromtarget_break (process);
+               break;
+             case 'X':
+               gdbserver.fromtarget_terminate (process);
+               break;
+             case 'W':
+               gdbserver.fromtarget_exit (process);
+               break;
+             }
+           }
+       }
+    }
+  gdbsocket_shutdown ();
+  if (process->debug_informational)
+    fprintf (stderr, "Shut down sockets.\n");
+
+  return 0;
+}
diff --git a/rda/unix/server.h b/rda/unix/server.h
new file mode 100644 (file)
index 0000000..b48ba97
--- /dev/null
@@ -0,0 +1,78 @@
+/* server.h
+
+   Copyright 2000, 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.  */
+
+/* Shared definitions for an RDA based native gdb server.  */
+
+#if defined(_MIPSEL) || defined(_MIPSEB)
+/*
+ * We single-step by setting breakpoints. When an exception
+ * is handled, we need to restore the previous instructions
+ *
+ * This is where we save the original instructions.
+ */
+
+struct ss_save {
+       unsigned int ss_addr;
+        unsigned int ss_val;
+};
+#endif
+
+/* Definition of a "process", or an instance of the server.
+ * Theoretically one server could run an arbitrary number of these.
+ */
+struct child_process {
+  struct gdbserv *serv;
+  char *executable;
+  char **argv;
+  int  pid;
+  struct gdbserv_thread *event_thread;
+  int  stop_status;
+  int  stop_signal;
+  long signal_to_send;
+  int  debug_backend;
+  int  debug_informational;
+  int  running;
+#if defined(_MIPSEL) || defined(_MIPSEB)
+   int  is_ss;                 /* we are single stepping */
+   struct ss_save ss_info[2];  /* single stepping saved information */
+#endif
+};
+
+/* Definition of the entry points to the server, 
+ * needed by main.
+ */
+struct server_vector {
+  struct gdbserv_target * (*attach) (struct gdbserv *serv, void *data);
+  int (*check_child_state)     (struct child_process *process);
+  void (*fromtarget_break)     (struct child_process *process);
+  void (*fromtarget_exit)      (struct child_process *process);
+  void (*fromtarget_terminate) (struct child_process *process);
+};
+
+extern struct server_vector gdbserver;
+
+/* Global flag used by the server to tell main to quit out of its loop.
+ */
+extern int server_quit_p;
+
diff --git a/rda/unix/solaris-target.c b/rda/unix/solaris-target.c
new file mode 100644 (file)
index 0000000..0400b55
--- /dev/null
@@ -0,0 +1,218 @@
+/* solaris-target.c
+
+   Copyright 2000, 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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "gdbserv.h" 
+#include "gdbserv-target.h" 
+#include "gdbserv-utils.h"
+
+#include "server.h"
+
+/* This is a Solaris native gdbserv target that uses the RDA library to
+   implement a remote gdbserver on a solaris host.  It controls the
+   process to be debugged on the solaris host, allowing GDB to pull the
+   strings from any host on the network (or on a serial port).  */
+
+
+
+/* Track sole connection to a remote gdb client. */
+/* FIXME: needed? */
+static struct gdbserv *solaris_connect_lock = NULL;
+
+
+
+/* target vector: */
+
+/* private sub-vector for dummy target: */
+static struct gdbserv_target *dummy_target;    /* FIXME global */
+
+/* Detach vector -- shut down this target connection.
+ */
+
+static void
+solaris_detach (struct gdbserv *serv, struct gdbserv_target *target)
+{
+  assert (solaris_connect_lock == serv);
+
+  dummy_target->detach (serv);
+  fprintf (stderr, "linux - detached.\n");
+  solaris_connect_lock = NULL;
+
+  /* Quit out of main loop for this demo.  In general, this is not
+     necessary, as the next incoming connection could again be handled
+     by solaris_attach() above.  */
+  server_quit_p = 1;
+}
+
+/* fetch registers vector.
+
+   NOTE: registers do not generalize well in ptrace, so
+   we're gonna handle them separately per target.
+
+   */
+
+static int
+solaris_process_get_reg (struct gdbserv *serv, int regno)
+{
+  if (dummy_target->get_reg)
+    return dummy_target->process_get_reg (serv, regno);
+}
+
+static void
+solaris_process_get_regs (struct gdbserv *serv)
+{
+  dummy_target->process_get_regs (serv);
+}
+
+static int
+solaris_process_set_reg (struct gdbserv *serv, int regno)
+{
+  if (dummy_target->set_reg)
+  return dummy_target->process_set_reg (serv, regno);
+}
+
+static int
+solaris_process_set_regs (struct gdbserv *serv)
+{
+  return dummy_target->process_set_regs (serv);
+}
+
+
+
+/* This function is called from gdbloop_poll() when a new incoming
+   connection is attempted.  It may return NULL if the new connection
+   is to be refused, or a gdbserv_target vector if the connection is
+   accepted.  */
+
+struct gdbserv_target *
+solaris_attach (struct gdbserv *serv, void *data)
+{
+  struct gdbserv_target *solaris_target;
+  struct child_process *process = data;
+  extern struct gdbserv_target *dummy_attach (struct gdbserv *, void *);
+
+  /* Enable server tracing. */
+  /*  gdbserv_state_trace = stderr;*/
+
+  if (solaris_connect_lock != NULL)
+    {
+      fprintf (stderr, "linux: rejected duplicate connection.\n");
+      return NULL;
+    }
+
+  if ((dummy_target = dummy_attach (serv, data)) == NULL)
+    {
+      fprintf (stderr, "Linux: unable to open %s\n", process->argv[0]);
+      return NULL;
+    }
+
+  fprintf (stderr, "linux: accepted gdb connection.\n");
+  solaris_connect_lock = serv;
+
+  solaris_target = malloc (sizeof (struct gdbserv_target));
+  memset (solaris_target, 0, sizeof (*solaris_target));
+
+  /* Callback structure for function pointers that handle processed
+     control packets.  See gdbserv-target.h for docs on the individual
+     functions. */
+
+  solaris_target->process_get_gen       = NULL;
+  solaris_target->process_set_gen       = NULL;
+  solaris_target->process_rcmd          = NULL;
+  solaris_target->process_set_args      = NULL;
+  solaris_target->process_set_reg       = NULL;
+  solaris_target->process_get_reg       = NULL;
+  solaris_target->process_set_regs      = solaris_process_set_regs;
+  solaris_target->process_get_regs      = solaris_process_get_regs;
+  solaris_target->input_reg             = NULL;
+  solaris_target->output_reg            = NULL;
+  solaris_target->gg_reg_nr             = NULL;
+  solaris_target->expedited_reg_nr      = NULL;
+  solaris_target->sizeof_reg            = NULL;
+  solaris_target->set_reg               = NULL;
+  solaris_target->get_reg               = NULL;
+  solaris_target->get_mem               = dummy_target->get_mem;
+  solaris_target->set_mem               = dummy_target->set_mem;
+  solaris_target->process_set_pc        = NULL;
+  solaris_target->flush_i_cache         = dummy_target->flush_i_cache;
+  solaris_target->process_signal        = dummy_target->process_signal;
+  solaris_target->compute_signal        = dummy_target->compute_signal;
+  solaris_target->get_trap_number       = dummy_target->get_trap_number;
+  solaris_target->exit_program          = dummy_target->exit_program;
+  solaris_target->break_program         = dummy_target->break_program;
+  solaris_target->reset_program         = NULL;
+  solaris_target->restart_program       = NULL;
+  solaris_target->singlestep_program    = dummy_target->singlestep_program;
+  solaris_target->cyclestep_program     = NULL;
+  solaris_target->sigkill_program       = NULL;
+  solaris_target->continue_program      = dummy_target->continue_program;
+  solaris_target->remove_breakpoint     = NULL;
+  solaris_target->set_breakpoint        = NULL;
+  solaris_target->process_target_packet = NULL;
+  solaris_target->detach                = solaris_detach;
+
+  solaris_target->data = data;
+  process->serv = serv;
+  return solaris_target;
+}
+
+static int
+solaris_check_child_state (struct child_process *process)
+{
+  return dummy_check_child_state (process);
+}
+
+static void
+solaris_fromtarget_break (struct child_process *process)
+{
+  gdbserv_fromtarget_break (process->serv, process->stop_signal);
+}
+
+static void
+solaris_fromtarget_exit (struct child_process *process)
+{
+  gdbserv_fromtarget_exit (process->serv, process->stop_signal);
+}
+
+static void
+solaris_fromtarget_terminate (struct child_process *process)
+{
+  gdbserv_fromtarget_terminate (process->serv, process->stop_signal);
+}
+
+/* This struct contains the vectors that connect us to main:
+ */
+struct server_vector gdbserver = 
+{
+  solaris_attach, 
+  solaris_check_child_state, 
+  solaris_fromtarget_break, 
+  solaris_fromtarget_exit,
+  solaris_fromtarget_terminate
+};
diff --git a/rda/unix/thread-db.c b/rda/unix/thread-db.c
new file mode 100644 (file)
index 0000000..fedd646
--- /dev/null
@@ -0,0 +1,2283 @@
+/* thread-db.c
+
+   Copyright 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 "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <thread_db.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/wait.h>
+
+#include "gdbserv.h"
+#include "gdbserv-target.h"
+#include "server.h"
+#include "gdb_proc_service.h"
+#include "gdbserv-thread-db.h"
+
+/* Make lots of noise (debugging output). */
+int thread_db_noisy = 0;
+int proc_service_noisy = 0;
+
+/*
+ * A tiny local symbol table.
+ *
+ * This is used by ps_pglobal_lookup, and is really just a 
+ * local cache of symbols whose values we have obtained from gdb.
+ *
+ * Since the cache is expected to be small, and infrequently used,
+ * there is no effort to sort or hash it.  Symbols may be added 
+ * in an "undefined" state, and then defined later.
+ */
+
+struct symbol_cache {
+  char *name;
+  paddr_t value;
+  int  defined_p;
+  struct symbol_cache *next;
+} *symbol_list;
+
+/* The "defined_p" field may have one of the following three values. */
+enum { UNDEFINED, REQUESTED, DEFINED };
+
+/* Function: add_symbol_to_list
+   Add a symbol to the symbol cache.  First checks to see if 
+   an entry is already in there, and re-uses it if so.  This way
+   the cache may be used for symbols awaiting lookup as well as
+   for those that have already been defined by the debugger. */
+
+static void
+add_symbol_to_list (char *name, paddr_t value, int defined_p)
+{
+  struct symbol_cache *tmp;
+
+  for (tmp = symbol_list; tmp; tmp = tmp->next)
+    {
+      if (strcmp (name, tmp->name) == 0)
+       {
+         /* Symbol is already in cache -- set its value and definedness. */
+         tmp->value = value;
+         if (defined_p == DEFINED)
+           tmp->defined_p = defined_p;
+         return;
+       }
+    }
+
+  /* Symbol is not in cache -- add it. */
+  tmp = malloc (sizeof (struct symbol_cache));
+
+  tmp->value = value;
+  tmp->defined_p = defined_p;
+  tmp->name = malloc (strlen (name) + 1);
+  strcpy (tmp->name, name);
+  /* LIFO */
+  tmp->next = symbol_list;
+  symbol_list = tmp;
+}
+
+/* Function: free_symbol_list
+   Empty the symbol cache. */
+
+static void
+free_symbol_list (void)
+{
+  struct symbol_cache *tmp;
+
+  for (tmp = symbol_list; tmp; tmp = symbol_list)
+    {
+      symbol_list = tmp->next;
+      free (tmp->name);
+      free (tmp);
+    }
+}
+
+/* Function: sync_symbol_list
+   Return all "requested" symbols to the "undefined" state
+   (so they can be "requested" again).  Called when a new
+   source of symbols becomes available (eg. a new shared object). */
+
+static void
+sync_symbol_list (void)
+{
+  struct symbol_cache *tmp;
+
+  for (tmp = symbol_list; tmp; tmp = tmp->next)
+    if (tmp->defined_p == REQUESTED)
+      tmp->defined_p = UNDEFINED;
+}
+
+/* Function: lookup_cached_symbol
+   If symbol is defined and cached, return its value in VALUE.
+   Return:  0 if not found, 1 if found.  */
+
+static int 
+lookup_cached_symbol (char *name, paddr_t *value)
+{
+  struct symbol_cache *tmp;
+
+  for (tmp = symbol_list; tmp; tmp = tmp->next)
+    if (strcmp (name, tmp->name) == 0 && tmp->defined_p == DEFINED)
+      {
+       *value = tmp->value;    /* known and defined */
+       return 1;
+      }
+
+  return 0;    /* not found */
+}
+
+/* Function: next_undefined_symbol
+   Find a symbol in the cache that needs lookup by GDB.
+   On returning a symbol, mark it REQUESTED, so that it won't
+   be requested again until a new source of symbols opens up
+   (eg. a new shared object). */
+
+static char *
+next_undefined_symbol (void)
+{
+  struct symbol_cache *tmp;
+  /* Make a pass thru the list, and return the first symbol that
+     hasn't been either requested or defined. */
+  for (tmp = symbol_list; tmp; tmp = tmp->next)
+    if (tmp->defined_p == UNDEFINED)
+      {
+       tmp->defined_p = REQUESTED;
+       return tmp->name;
+      }
+  return NULL;
+}
+
+/*
+ * A tiny local thread list.
+ *
+ * This local list of threads is used for gdbserv operations that
+ * require a struct gdbserv_thread.  Its first use will be to 
+ * implement "info threads" for gdb.
+ */
+
+/* Define the struct gdbserv_thread object. */
+
+struct gdbserv_thread {
+  td_thrinfo_t ti;
+  int attached : 1;
+  int stopped : 1;
+  int waited : 1;
+  int stepping : 1;
+  struct gdbserv_thread *next;
+} *thread_list;
+
+/* Function: add_thread_to_list 
+   Add a thread (provided by libthread_db) to the local list. */
+
+static struct gdbserv_thread *
+add_thread_to_list (td_thrinfo_t *ti)
+{
+  struct gdbserv_thread *new = malloc (sizeof (struct gdbserv_thread));
+
+  /* First cut -- add to start of list. */
+  memcpy (&new->ti, ti, sizeof (td_thrinfo_t));
+  new->next = thread_list;
+  thread_list = new;
+  return new;
+}
+
+static struct gdbserv_thread *
+first_thread_in_list (void)
+{
+  return thread_list;
+}
+
+static struct gdbserv_thread *
+next_thread_in_list (struct gdbserv_thread *thread)
+{
+  if (thread == NULL)
+    return thread_list;
+  else
+    return thread->next;
+}
+
+static void
+delete_thread_from_list (struct gdbserv_thread *thread)
+{
+  struct gdbserv_thread *tmp;
+
+  for (tmp = thread_list; tmp; tmp = tmp->next)
+    {
+      if (tmp->next == thread)
+       {
+         tmp->next = tmp->next->next;          /* unlink */
+         free (thread);                        /* discard */
+         return;                               /* finished */
+       }
+    }
+  /* Special case -- delete first element of list. */
+  if (thread == thread_list)
+    {
+      thread_list = thread->next;              /* unlink */
+      free (thread);                           /* discard */
+      return;                                  /* finished */
+    }
+  /* If we reach this point, the thread wasn't in the list. */
+}
+
+static void
+free_thread_list (void)
+{
+  struct gdbserv_thread *tmp;
+
+  for (tmp = thread_list; tmp; tmp = thread_list)
+    {
+      thread_list = tmp->next;
+      free (tmp);
+    }
+}
+
+static struct gdbserv_thread *
+thread_list_lookup_by_tid (thread_t tid)
+{
+  struct gdbserv_thread *tmp;
+
+  for (tmp = thread_list; tmp; tmp = tmp->next)
+    if (tmp->ti.ti_tid == tid)
+      break;
+
+  return tmp;
+}
+
+static struct gdbserv_thread *
+thread_list_lookup_by_lid (lwpid_t pid)
+{
+  struct gdbserv_thread *tmp;
+
+  for (tmp = thread_list; tmp; tmp = tmp->next)
+    if (tmp->ti.ti_lid == pid)
+      break;
+
+  return tmp;
+}
+
+/* A copy of the next lower layer's target vector, before we modify it. */
+static struct gdbserv_target parentvec;
+
+/* A pointer to the current target vector. */
+static struct gdbserv_target *currentvec;
+
+/* 
+ * proc_service callback functions, called by thread_db.
+ */
+
+void
+ps_plog (const char *fmt, ...)
+{
+  fprintf (stderr, "<ps_plog: %s>\n", fmt);
+  return;
+}
+
+/* Look up a symbol in GDB's global symbol table.
+   Return the symbol's address.
+   FIXME: it would be more correct to look up the symbol in the context 
+   of the LD_OBJECT_NAME provided.  However we're probably fairly safe 
+   as long as there aren't name conflicts with other libraries.  */
+
+ps_err_e
+ps_pglobal_lookup (gdb_ps_prochandle_t ph,
+                  const char *ld_object_name,  /* the library name */
+                  const char *ld_symbol_name,  /* the symbol name */
+                  paddr_t    *ld_symbol_addr)  /* return the symbol addr */
+{
+  paddr_t value;
+
+  if (lookup_cached_symbol ((char *) ld_symbol_name, &value) == 0)
+    {
+      /* Symbol not in cache -- ask GDB to look it up. 
+        Add the symbol to the cache as undefined. */
+      add_symbol_to_list ((char *) ld_symbol_name, 0, UNDEFINED);
+      return PS_NOSYM;
+    }
+  else
+    {
+      /* Symbol is in the cache and defined -- return its value. */
+      *ld_symbol_addr = value;
+      return PS_OK;
+    }
+}
+
+
+/* Connection to the libthread_db library.  */
+static struct ps_prochandle  proc_handle;
+static td_thragent_t *thread_agent = NULL;
+
+/* Pointers to the libthread_db functions.  */
+static td_err_e (*td_init_p) (void);
+
+static td_err_e (*td_ta_new_p)           (struct ps_prochandle *ps, 
+                                         td_thragent_t **ta);
+static td_err_e (*td_ta_delete_p)        (td_thragent_t *ta);
+static td_err_e (*td_ta_map_id2thr_p)    (const td_thragent_t *ta, 
+                                         thread_t pt, 
+                                         td_thrhandle_t *__th);
+static td_err_e (*td_ta_map_lwp2thr_p)   (const td_thragent_t *ta, 
+                                         lwpid_t lwpid, 
+                                         td_thrhandle_t *th);
+static td_err_e (*td_ta_thr_iter_p)      (const td_thragent_t *ta, 
+                                         td_thr_iter_f *callback, 
+                                         void *cbdata, 
+                                         td_thr_state_e state, 
+                                         int ti_pri, 
+                                         sigset_t *ti_sigmask, 
+                                         unsigned int ti_user_flags);
+static td_err_e (*td_ta_event_addr_p)    (const td_thragent_t *ta, 
+                                         td_event_e event, 
+                                         td_notify_t *ptr);
+static td_err_e (*td_ta_set_event_p)     (const td_thragent_t *ta, 
+                                         td_thr_events_t *event);
+static td_err_e (*td_ta_event_getmsg_p)  (const td_thragent_t *ta, 
+                                         td_event_msg_t *msg);
+static td_err_e (*td_thr_validate_p)     (const td_thrhandle_t *th);
+static td_err_e (*td_thr_get_info_p)     (const td_thrhandle_t *th, 
+                                         td_thrinfo_t *infop);
+static td_err_e (*td_thr_getfpregs_p)    (const td_thrhandle_t *th, 
+                                         FPREGSET_T *regset);
+static td_err_e (*td_thr_getgregs_p)     (const td_thrhandle_t *th, 
+                                         GREGSET_T gregs);
+static td_err_e (*td_thr_setfpregs_p)    (const td_thrhandle_t *th, 
+                                         const FPREGSET_T *fpregs);
+static td_err_e (*td_thr_setgregs_p)     (const td_thrhandle_t *th, 
+                                         GREGSET_T gregs);
+static td_err_e (*td_thr_getxregsize_p)  (const td_thrhandle_t *th,
+                                          int *sizep);
+static td_err_e (*td_thr_getxregs_p)     (const td_thrhandle_t *th, 
+                                         void *xregs);
+static td_err_e (*td_thr_setxregs_p)     (const td_thrhandle_t *th, 
+                                         void *xregs);
+static td_err_e (*td_thr_event_enable_p) (const td_thrhandle_t *th, 
+                                         int event);
+
+/* Function: thread_db_state_str
+   Convert a thread_db state code to a string.
+   If state code is unknown, return an <unknown> message. */
+
+static char *
+thread_db_state_str (td_thr_state_e statecode)
+{
+  static char buf[64];
+
+  switch (statecode) {
+  case TD_THR_ANY_STATE:       return "<any state>";
+  case TD_THR_UNKNOWN:         return "<officially unknown>";
+  case TD_THR_STOPPED:         return "<stopped>";
+  case TD_THR_RUN:             return "<running>";
+  case TD_THR_ACTIVE:          return "<active> ";
+  case TD_THR_ZOMBIE:          return "<zombie> ";
+  case TD_THR_SLEEP:           return "<sleep>  ";
+  case TD_THR_STOPPED_ASLEEP:  return "<stopped asleep>";
+  default:
+    sprintf (buf, "<unknown state code %d>", statecode);
+    return buf;
+  }
+}
+
+static char *
+thread_db_type_str (td_thr_type_e type)
+{
+  switch (type) {
+  case TD_THR_USER:            return "<user>  ";
+  case TD_THR_SYSTEM:          return "<system>";
+  default:                      return "<unknown>";
+  }
+}
+
+/* Function: thread_db_err_string
+   Convert a thread_db error code to a string.
+   If errcode is unknown, then return an <unknown> message. */
+
+static char *
+thread_db_err_str (td_err_e errcode)
+{
+  static char buf[64];
+
+  switch (errcode) {
+  case TD_OK:          return "generic 'call succeeded'";
+  case TD_ERR:         return "generic error";
+  case TD_NOTHR:       return "no thread to satisfy query";
+  case TD_NOSV:                return "no sync handle to satisfy query";
+  case TD_NOLWP:       return "no lwp to satisfy query";
+  case TD_BADPH:       return "invalid process handle";
+  case TD_BADTH:       return "invalid thread handle";
+  case TD_BADSH:       return "invalid synchronization handle";
+  case TD_BADTA:       return "invalid thread agent";
+  case TD_BADKEY:      return "invalid key";
+  case TD_NOMSG:       return "no event message for getmsg";
+  case TD_NOFPREGS:    return "FPU register set not available";
+  case TD_NOLIBTHREAD: return "application not linked with libthread";
+  case TD_NOEVENT:     return "requested event is not supported";
+  case TD_NOCAPAB:     return "capability not available";
+  case TD_DBERR:       return "debugger service failed";
+  case TD_NOAPLIC:     return "operation not applicable to";
+  case TD_NOTSD:       return "no thread-specific data for this thread";
+  case TD_MALLOC:      return "malloc failed";
+  case TD_PARTIALREG:  return "only part of register set was written/read";
+  case TD_NOXREGS:     return "X register set not available for this thread";
+  default:
+    sprintf (buf, "unknown thread_db error '%d'", errcode);
+    return buf;
+  }
+}
+
+/* flag which indicates if the map_id2thr cache is valid.  See below.  */
+static int thread_db_map_id2thr_cache_valid;
+
+/* Function: thread_db_map_id2thr
+   Calling td_ta_map_id2thr() is expensive.  This function invokes
+   td_ta_map_id2thr() and caches the value for future reference.  The
+   cache may be invalidated by calling thread_db_invalidate_cache().
+   Returns: TD_OK on success, an appropriate error code otherwise.  */
+
+static td_err_e
+thread_db_map_id2thr (const td_thragent_t *ta, thread_t pt,
+                      td_thrhandle_t *th)
+{
+  static td_thrhandle_t cached_handle;
+  static thread_t input_pt;
+
+  if (pt == input_pt && thread_db_map_id2thr_cache_valid)
+    {
+      *th = cached_handle;
+      return TD_OK;
+    }
+  else
+    {
+      td_err_e status;
+
+      status = td_ta_map_id2thr_p (ta, pt, th);
+      if (status == TD_OK)
+       {
+         thread_db_map_id2thr_cache_valid = 1;
+         input_pt = pt;
+         cached_handle = *th;
+       }
+      else
+       thread_db_map_id2thr_cache_valid = 0;
+      return status;
+    }
+}
+
+/* Invalidate the map_id2thr cache.  */
+static void
+thread_db_invalidate_map_id2thr_cache (void)
+{
+  thread_db_map_id2thr_cache_valid = 0;
+}
+
+/* The regset cache object.  This object keeps track of the most
+   recently fetched or set gregset (of a particular type) and whether
+   or not it needs to still needs to be synchronized with the target.  */
+struct regset_cache
+{
+  /* Are the cache contents valid?  */
+  int valid;
+
+  /* Does cache need to be flushed?  */
+  int needs_flush;
+
+  /* Handle corresponding to cached regset.  */
+  td_thrhandle_t handle;
+
+  /* Size of memory area used to hold regset.  */
+  int regset_size;
+
+  /* Memory area used to hold regset.  */
+  void *regset_buffer;
+
+  /* Functions used to get/set regset.  */
+  td_err_e (*getregset) (const td_thrhandle_t *th, void *regset);
+  td_err_e (*setregset) (const td_thrhandle_t *th, const void *regset);
+};
+
+/* Declare fpregset and gregset cache objects.  */
+static struct regset_cache fpregset_cache;
+static struct regset_cache gregset_cache;
+
+/* Wrappers for td_thr_getfpregs_p, td_thr_setfpregs_p, td_thr_getgregs_p,
+   and td_thr_setgregs_p.  These simply allow us to pass a void * for the
+   regset parameter.  */
+
+static td_err_e
+td_thr_getfpregs_wrapper (const td_thrhandle_t *th, void *fpregs)
+{
+  return td_thr_getfpregs_p (th, fpregs);
+}
+
+static td_err_e td_thr_getgregs_wrapper (const td_thrhandle_t *th, void *gregs)
+{
+  return td_thr_getgregs_p (th, gregs);
+}
+
+static td_err_e td_thr_setfpregs_wrapper (const td_thrhandle_t *th,
+                                          const void *fpregs)
+{
+  return td_thr_setfpregs_p (th, fpregs);
+}
+
+static td_err_e td_thr_setgregs_wrapper (const td_thrhandle_t *th,
+                                         const void *gregs)
+{
+  void * gregs_nonconst = (void *) gregs;
+
+  return td_thr_setgregs_p (th, gregs_nonconst);
+}
+
+/* Initialize a regset cache object.  */
+static void
+initialize_regset_cache (struct regset_cache *regset_cache,
+                         const int regset_size,
+                        void * const regset_buffer,
+                        td_err_e (* const getregset) (const td_thrhandle_t *th,
+                                                      void *regset),
+                         td_err_e (* const setregset) (const td_thrhandle_t *th,
+                                                      const void *regset))
+{
+  regset_cache->valid = 0;
+  regset_cache->needs_flush = 0;
+  regset_cache->regset_size = regset_size;
+  regset_cache->regset_buffer = regset_buffer;
+  regset_cache->getregset = getregset;
+  regset_cache->setregset = setregset;
+}
+
+/* Initialize the fpregset and gregset cache objects.  Space for
+   the regset buffer is statically allocated to avoid calls to malloc().  */
+static void
+initialize_regset_caches (void)
+{
+  static FPREGSET_T fpregset;
+  static GREGSET_T gregset;
+
+  initialize_regset_cache (&fpregset_cache, sizeof fpregset, &fpregset,
+                           td_thr_getfpregs_wrapper, td_thr_setfpregs_wrapper);
+  initialize_regset_cache (&gregset_cache, sizeof gregset, gregset,
+                           td_thr_getgregs_wrapper, td_thr_setgregs_wrapper);
+}
+
+/* Synchronize a cached regset with the target.  */
+static td_err_e
+thread_db_flush_regset_cache (struct regset_cache *regset_cache)
+{
+  td_err_e status = TD_OK;
+  if (regset_cache->valid && regset_cache->needs_flush)
+    {
+      status = regset_cache->setregset (&regset_cache->handle,
+                                       regset_cache->regset_buffer);
+      if (status != TD_OK)
+       regset_cache->valid = 0;
+      regset_cache->needs_flush = 0;
+    }
+  return status;
+}
+
+/* Synchronize the gregset and fpregset caches with the target.  */
+static td_err_e
+thread_db_flush_regset_caches (void)
+{
+  td_err_e status;
+  td_err_e ret_status = TD_OK;
+
+  status = thread_db_flush_regset_cache (&fpregset_cache);
+  if (status != TD_OK)
+    ret_status = status;
+
+  status = thread_db_flush_regset_cache (&gregset_cache);
+  if (status != TD_OK)
+    ret_status = status;
+
+  return status;
+}
+
+/* Fetch a regset, using a previously cached copy if possible.  */
+static td_err_e
+thread_db_get_regset (struct regset_cache *regset_cache,
+                     const td_thrhandle_t *th,
+                    void *regset)
+{
+  if (regset_cache->valid
+      && memcmp (&regset_cache->handle, th, sizeof *th) == 0)
+    {
+      /* Cache is valid and handles match.  Copy the cached regset.  */
+      memcpy (regset, regset_cache->regset_buffer, regset_cache->regset_size);
+      return TD_OK;
+    }
+  else
+    {
+      td_err_e status;
+
+      /* Handles don't match.  Write out old cache contents before
+         fetching contents w/ new handle if necessary.  */
+      if (regset_cache->valid && regset_cache->needs_flush)
+       {
+         status = regset_cache->setregset (&regset_cache->handle,
+                                           regset_cache->regset_buffer);
+         if (status != TD_OK)
+           {
+             regset_cache->needs_flush = 0;
+             regset_cache->valid = 0;
+             return status;
+           }
+       }
+      
+
+      /* Fetch the regset.  */
+      status = regset_cache->getregset (th, regset);
+      if (status == TD_OK)
+        {
+         /* Preserve it in the cache.  */
+         regset_cache->needs_flush = 0;
+         regset_cache->valid = 1;
+         memcpy (&regset_cache->handle, th, sizeof (*th));
+         memcpy (regset_cache->regset_buffer, regset,
+                 regset_cache->regset_size);
+       }
+      else
+       regset_cache->valid = 0;
+      return status;
+    }
+}
+
+/* Set a regset deferring synchronization with the target until
+   later.  */
+static td_err_e
+thread_db_set_regset (struct regset_cache *regset_cache,
+                     const td_thrhandle_t *th,
+                    const void *regset)
+{
+  td_err_e ret_status = TD_OK;
+
+  if (regset_cache->valid && regset_cache->needs_flush
+      && memcmp (&regset_cache->handle, th, sizeof *th) != 0)
+    {
+      /* Cached regset needs to be flushed because handles don't
+         match.  */
+      ret_status = thread_db_flush_regset_cache (regset_cache);
+    }
+
+  memcpy (&regset_cache->handle, th, sizeof *th);
+  memcpy (regset_cache->regset_buffer, regset, regset_cache->regset_size);
+  regset_cache->valid = 1;
+  regset_cache->needs_flush = 1;
+
+  return ret_status;
+}
+
+/* Mark a regset cache as invalid.  */
+static void
+thread_db_invalidate_regset_cache (struct regset_cache *regset_cache)
+{
+  regset_cache->valid = 0;
+}
+
+/* Mark the gregset and fpregset caches as invalid.  */
+static void
+thread_db_invalidate_regset_caches (void)
+{
+  thread_db_invalidate_regset_cache (&fpregset_cache);
+  thread_db_invalidate_regset_cache (&gregset_cache);
+}
+
+/* Invalidate all caches.  */
+static void
+thread_db_invalidate_caches (void)
+{
+  thread_db_invalidate_regset_caches ();
+  thread_db_invalidate_map_id2thr_cache ();
+}
+
+/* Fetch the floating point registers via the fpregset cache.  */
+static td_err_e
+thread_db_getfpregs (const td_thrhandle_t *th, FPREGSET_T *fpregset)
+{
+  return thread_db_get_regset (&fpregset_cache, th, fpregset);
+}
+
+/* Set the floating point registers via the fpregset cache.  */
+static td_err_e
+thread_db_setfpregs (const td_thrhandle_t *th, const FPREGSET_T *fpregset)
+{
+  return thread_db_set_regset (&fpregset_cache, th, fpregset);
+}
+
+/* Fetch the general purpose registers via the gregset cache.  */
+static td_err_e
+thread_db_getgregs (const td_thrhandle_t *th, GREGSET_T gregset)
+{
+  return thread_db_get_regset (&gregset_cache, th, gregset);
+}
+
+/* Set the general purpose registers via the gregset cache.  */
+static td_err_e
+thread_db_setgregs (const td_thrhandle_t *th, const GREGSET_T gregset)
+{
+  return thread_db_set_regset (&gregset_cache, th, gregset);
+}
+
+/* Function: thread_db_dlopen
+   Attach to the libthread_db library.  
+   This function does all the dynamic library stuff (dlopen, dlsym).
+   Return: -1 for failure, zero for success.  */
+
+static int
+thread_db_dlopen (void)
+{
+  void *dlhandle;
+
+#ifndef LIBTHREAD_DB_SO
+#define LIBTHREAD_DB_SO "libthread_db.so.1"
+#endif
+
+  if ((dlhandle = dlopen (LIBTHREAD_DB_SO, RTLD_NOW)) == NULL)
+    return -1;         /* fail */
+
+  /* Initialize pointers to the dynamic library functions we will use.
+   */
+
+  if ((td_init_p = dlsym (dlhandle, "td_init")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_ta_new_p = dlsym (dlhandle, "td_ta_new")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_ta_delete_p = dlsym (dlhandle, "td_ta_delete")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_ta_map_id2thr_p = dlsym (dlhandle, "td_ta_map_id2thr")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_ta_map_lwp2thr_p = dlsym (dlhandle, "td_ta_map_lwp2thr")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_ta_thr_iter_p = dlsym (dlhandle, "td_ta_thr_iter")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_thr_validate_p = dlsym (dlhandle, "td_thr_validate")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_thr_get_info_p = dlsym (dlhandle, "td_thr_get_info")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_thr_getfpregs_p = dlsym (dlhandle, "td_thr_getfpregs")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_thr_getgregs_p = dlsym (dlhandle, "td_thr_getgregs")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_thr_setfpregs_p = dlsym (dlhandle, "td_thr_setfpregs")) == NULL)
+    return -1;         /* fail */
+
+  if ((td_thr_setgregs_p = dlsym (dlhandle, "td_thr_setgregs")) == NULL)
+    return -1;         /* fail */
+
+  /* These are not essential.  */
+  td_ta_event_addr_p    = dlsym (dlhandle, "td_ta_event_addr");
+  td_ta_set_event_p     = dlsym (dlhandle, "td_ta_set_event");
+  td_ta_event_getmsg_p  = dlsym (dlhandle, "td_ta_event_getmsg");
+  td_thr_event_enable_p = dlsym (dlhandle, "td_thr_event_enable");
+  td_thr_getxregsize_p  = dlsym (dlhandle, "td_thr_getxregsize");
+  td_thr_getxregs_p     = dlsym (dlhandle, "td_thr_getxregs");
+  td_thr_setxregs_p     = dlsym (dlhandle, "td_thr_setxregs");
+
+  return 0;            /* success */
+}
+
+/* Function: thread_db_open
+   Open a channel to the child's thread library.
+   Returns: -1 for failure, 0 for success
+   FIXME: closure.
+   FIXME: where should we be called from?  We will not succeed
+   until the thread shlib is loaded.  The call from attach will not
+   succeed even if the target is statically linked, 'cause there's 
+   no symbol lookup handshake on attach.  Therefore I can't handle
+   a statically linked threaded process.  */
+
+static int
+thread_db_open (struct gdbserv *serv, int pid)
+{ /* FIXME: once we have the serv, we can derive the pid. 
+     No, not true -- not when we're called from attach. 
+     But then, there isn't much use in the call from attach unles
+     I make GDB respond to symbol callbacks from there somehow. */
+  td_err_e ret;
+
+  if (thread_agent == NULL)
+    {
+      proc_handle.pid = pid;
+      proc_handle.serv = serv;
+      
+      ret = td_ta_new_p (&proc_handle, &thread_agent);
+      if (ret == TD_OK)
+       {
+         return -1;    /* success */
+       }
+      else if (thread_db_noisy)
+       {
+         fprintf (stderr, "< -- failed, thread_agent = 0x%08x>\n", 
+                  (long) thread_agent);
+       }
+      return 0;                /* failure */
+    }
+  return -1;           /* success */
+}
+
+/* Function: thread_db_detach
+   FIXME: gdbserv kills the inferior and exits when gdb detaches.
+   This is the best place I have from which to shut down the 
+   thread_db interface, but it's not really where this should
+   be done. */
+
+void
+thread_db_detach (struct gdbserv *serv, struct gdbserv_target *target)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  /* FIXME: this isn't really enough, and detach isn't really the
+     right place for this anyway.  Do this in exit_program. */
+  td_ta_delete_p (thread_agent);
+  thread_agent = NULL;
+  currentvec = NULL;
+
+  if (process->debug_informational)
+    fprintf (stderr, "<thread_db_detach>\n");
+  if (parentvec.detach)
+    parentvec.detach (serv, target);
+}
+
+static void
+attach_thread (struct gdbserv_thread *thread)
+{
+  if (thread->ti.ti_lid   != 0 &&
+      thread->ti.ti_state != TD_THR_ZOMBIE)    /* Don't attach a zombie. */
+    {
+      if (attach_lwp (thread->ti.ti_lid) == 0)
+       thread->attached = 1;
+      else
+       thread->attached = 0;
+    }
+}
+
+/* Function: find_new_threads_callback
+   Enter threads into a local thread database. */
+
+static int
+find_new_threads_callback (const td_thrhandle_t *thandle, void *data)
+{
+  struct gdbserv_thread *thread;
+  td_thrinfo_t ti;
+  td_err_e     ret;
+
+  if ((ret = td_thr_get_info_p (thandle, &ti)) != TD_OK)
+    {
+      fprintf (stderr, "<find_new_threads_callback: get_info failed! %s>\n", 
+              thread_db_err_str (ret));
+      return -1;
+    }
+
+  /* Enter the thread into a local list
+     (unless it is TD_THR_UNKNOWN, which means its defunct). */
+  if ((thread = thread_list_lookup_by_tid (ti.ti_tid)) == NULL)
+    {
+      if (ti.ti_state != TD_THR_UNKNOWN)
+       {
+         thread = add_thread_to_list (&ti);
+         /* Now make sure we've attached to it.  
+            Skip the main pid (already attached). */
+         if (thread->ti.ti_lid != proc_handle.pid)
+           {
+             attach_thread (thread);
+           }
+       }
+    }
+  else
+    {
+      /* Already in list -- cache new thread info */
+      memcpy (&thread->ti, &ti, sizeof (ti));
+    }
+
+  return 0;
+}
+
+/* Function: update_thread_list
+
+   First run td_ta_thr_iter to find all threads.
+   Then walk the list and validate that each thread is still running.
+   If not, prune it from the list. */
+
+static void
+update_thread_list (void)
+{
+  struct gdbserv_thread *thread, *next;
+  td_thrhandle_t handle;
+
+  /* First make sure all libthread threads are in the list. */
+  td_ta_thr_iter_p (thread_agent, find_new_threads_callback, 
+                   (void *) 0, 
+                   TD_THR_ANY_STATE, 
+                   TD_THR_LOWEST_PRIORITY,
+                   TD_SIGNO_MASK,
+                   TD_THR_ANY_USER_FLAGS);
+
+  /* Next, remove any defunct threads from the list. */
+  for (thread = first_thread_in_list ();
+       thread;
+       thread = next)
+    {
+      /* Thread may be deleted, so find its successor first! */
+      next = next_thread_in_list (thread);
+
+      /* Now ask if thread is still valid, and if not, delete it. */
+      if (thread_db_map_id2thr (thread_agent, 
+                               thread->ti.ti_tid, 
+                               &handle) != TD_OK
+          || td_thr_validate_p (&handle) != TD_OK)
+       {
+         if (thread->ti.ti_state == TD_THR_UNKNOWN)
+           {
+             /* Thread is no longer "valid".
+                By the time this happens, it's too late for us to 
+                detach from it.  Just delete it from the list.  */
+             
+             delete_thread_from_list (thread);
+           }
+       }
+    }
+}
+
+/* Function: thread_db_thread_next
+   Exported to gdbserv to implement "info threads" request from GDB. */
+
+static struct gdbserv_thread *
+thread_db_thread_next (struct gdbserv *serv, struct gdbserv_thread *thread)
+{
+  if (thread == NULL)
+    {
+      /* First request -- build up thread list using td_ta_thr_iter. */
+      /* NOTE: this should be unnecessary, once we begin to keep the
+        list up to date all the time. */
+      update_thread_list ();
+    }
+  return next_thread_in_list (thread);
+}
+
+
+/* Function: thread_db_get_gen
+   Handle 'q' requests:
+     qSymbol
+*/
+
+static void
+thread_db_get_gen (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  char tempname[1024], *symbol_query;
+  unsigned long tempval;
+  int len;
+
+  if (gdbserv_input_string_match (serv, "Symbol:") >= 0)
+    {
+      /* Message: qSymbol:<optional value>:<optional name hexified>
+        Reply:   OK
+        Reply:   qSymbol:<name hexified>
+
+        This message from GDB has three possible forms:
+
+        1) "qSymbol::" (no value, no name).
+        This means the start of a symbol query session.
+        GDB is offering to serve up symbols.
+        The target should reply with the FIRST symbol whose value 
+        it wants (or "OK" if it doesn't want any).
+
+        2) "qSymbol:<value>:<name hexified>
+        This means "here is the value of the symbol you requested".
+        The target should reply with the NEXT symbol whose value
+        it wants (or "OK" if it doesn't want any more).
+
+        3) "qSymbol::<name hexified>" (no value)
+        This means "I have no value for the symbol you requested".
+        The target should reply with the NEXT symbol whose value
+        it wants (or "OK" if it doesn't want any more).
+      */
+        
+      if (gdbserv_input_string_match (serv, ":") >= 0)
+       {
+         /* So far we've matched "qSymbol::".  We're looking at either 
+            form #1 ("qSymbol::", open a symbol lookup session), or
+            form #2 ("qSymbol::<name>", a reply that "this symbol is
+            not defined".  */
+
+         len = gdbserv_input_bytes (serv, tempname, sizeof (tempname));
+
+         if (len == 0)
+           {
+             /* Form #1, open a new symbol lookup session.
+                Prepare to request the first symbol in the list. */
+             sync_symbol_list ();
+           }
+         else
+           {
+             /* Form #2, this symbol not currently defined.
+                Nothing to do, since we already have it marked undefined. */
+           }
+       }
+      else if (gdbserv_input_hex_ulong (serv, &tempval) >= 0 &&
+              gdbserv_input_string_match (serv, ":") >= 0 &&
+              (len = gdbserv_input_bytes (serv, tempname, sizeof (tempname))) 
+              > 0)
+       {
+         /* Message contains a symbol and a value (form #3). */
+
+         tempname[len] = '\0';
+         add_symbol_to_list (tempname, (paddr_t) tempval, DEFINED);
+         if (thread_agent != NULL)
+           {
+             /* We now have a new symbol in the cache, which was
+                requested by the last td_ta_new call.  Delete the
+                current (not-completely-valid) thread agent, so that
+                a new one will have to be opened.  */
+             td_ta_delete_p (thread_agent);
+             thread_agent = NULL;
+           }
+       }
+
+      /* Now the reply depends on whether there is another 
+        symbol in need of lookup.  */
+      thread_db_open (serv, process->pid);
+      if ((symbol_query = next_undefined_symbol ()) == NULL)
+       {
+         gdbserv_output_string (serv, "OK");
+       }
+      else
+       {
+         gdbserv_output_string (serv, "qSymbol:");
+         gdbserv_output_bytes (serv, symbol_query, strlen (symbol_query));
+       }
+    }
+  else if (parentvec.process_get_gen)
+    parentvec.process_get_gen (serv);
+}
+
+/* Function: thread_db_set_gen
+   Handle 'Q' requests:
+*/
+
+void
+thread_db_set_gen (struct gdbserv *serv)
+{
+    if (parentvec.process_set_gen)
+      parentvec.process_set_gen (serv);
+}
+
+void
+thread_db_thread_id (struct gdbserv *serv, 
+                    struct gdbserv_thread *thread,
+                    struct gdbserv_reg *id)
+{
+  gdbserv_ulonglong_to_reg (serv, 
+                           (unsigned long long) thread->ti.ti_tid, 
+                           id);
+}
+
+static int
+thread_db_thread_lookup_by_id (struct gdbserv *serv,
+                              const struct gdbserv_reg *thread_id,
+                              struct gdbserv_thread **thread)
+{
+  unsigned long id;
+
+  gdbserv_reg_to_ulong (serv, thread_id, &id);
+  if (id == 0)                 /* any thread */
+    {
+      *thread = next_thread_in_list (NULL);    /* FIXME curthread? */
+      return 0;
+    }
+  else
+    {
+      *thread = thread_list_lookup_by_tid ((thread_t) id);
+      if (*thread == NULL)     /* bad thread id */
+       {
+         *thread = next_thread_in_list (NULL); /* FIXME curthread? */
+         return -1;
+       }
+      else
+       {
+         return 1;             /* success */
+       }
+    }
+}
+
+static char *
+thread_db_thread_info (struct gdbserv *serv, struct gdbserv_thread *thread)
+{
+  char *info = malloc (128);
+
+  sprintf (info, "PID %d Type %s State %s",
+          thread->ti.ti_lid, 
+          thread_db_type_str (thread->ti.ti_type),
+          thread_db_state_str (thread->ti.ti_state));
+  return info;
+}
+
+/* Function: get_target_int_by_name
+   Read the value of a target integer, given its name and size.
+   Returns -1 for failure, zero for success. */
+
+static int
+get_target_int_by_name (char *name, void *value, int size)
+{
+  paddr_t addr;
+
+  if (ps_pglobal_lookup (&proc_handle, NULL, name, &addr) == PS_OK)
+    {
+      if (ps_pdread (&proc_handle, addr,
+                    (gdb_ps_read_buf_t) value,
+                    (gdb_ps_size_t) size) == PS_OK)
+       return 0;
+    }
+  return -1;           /* fail */
+}
+
+/* Function: set_target_int_by_name
+   Read the value of a target integer, given its name and size.
+   Returns -1 for failure, zero for success. */
+
+static int
+set_target_int_by_name (char *name, void *value, int size)
+{
+  paddr_t addr;
+
+  if (ps_pglobal_lookup (&proc_handle, NULL, name, &addr) == PS_OK)
+    {
+      if (ps_pdwrite (&proc_handle, addr,
+                     (gdb_ps_write_buf_t) value,
+                     (gdb_ps_size_t) size) == PS_OK)
+       return 0;
+    }
+  return -1;           /* fail */
+}
+
+/* Function: get_thread_signals
+   Obtain the values of the "cancel", "restart" and "debug" signals 
+   used by linux threads, and store them in a set of global variables
+   for use by check_child_state and friends. */
+
+static int cancel_signal;
+static int restart_signal;
+static int debug_signal;
+static int got_thread_signals;
+
+static void
+get_thread_signals (void)
+{
+  int cancel, restart, debug, debug_flag;
+
+  if (!got_thread_signals)
+    {
+      if (get_target_int_by_name ("__pthread_sig_cancel", 
+                                 &cancel, sizeof (cancel)) == 0 &&
+         get_target_int_by_name ("__pthread_sig_restart",
+                                 &restart, sizeof (restart)) == 0 &&
+         get_target_int_by_name ("__pthread_sig_debug", 
+                                 &debug, sizeof (debug)) == 0)
+       {
+         restart_signal = restart;
+         cancel_signal  = cancel;
+         debug_signal   = debug;
+         got_thread_signals = 1;
+       }
+      debug_flag = 1;
+      set_target_int_by_name ("__pthread_threads_debug", 
+                             &debug_flag, sizeof (debug_flag));
+    }
+}
+
+/* Function: stop_thread 
+   Use SIGSTOP to force a thread to stop. */
+
+static void
+stop_thread (struct gdbserv_thread *thread)
+{
+  if (thread->ti.ti_lid != 0)
+    {
+      if (stop_lwp (thread->ti.ti_lid) == 0)
+       thread->stopped = 1;
+      else
+       thread->stopped = 0;
+    }
+}
+
+/* Function: stop_all_threads
+   Use SIGSTOP to make sure all child threads are stopped.
+   Do not send SIGSTOP to the event thread, or to any 
+   new threads that have just been attached. */
+
+static void
+stop_all_threads (struct child_process *process)
+{
+  struct gdbserv_thread *thread;
+
+  for (thread = first_thread_in_list ();
+       thread;
+       thread = next_thread_in_list (thread))
+    {
+      if (thread->ti.ti_lid == process->pid)
+       {
+         /* HACK mark him signalled. */
+         thread->stopped = 1;
+         continue;     /* This thread is already stopped. */
+       }
+      /* All threads must be stopped, unles
+        a) they have only just been attached, or 
+        b) they're already stopped. */
+      if (!thread->attached && !thread->stopped &&
+         thread->ti.ti_state != TD_THR_ZOMBIE &&
+         thread->ti.ti_state != TD_THR_UNKNOWN)
+       {
+         stop_thread (thread);
+       }
+    }
+}
+
+/* A list of signals that have been prematurely sucked out of the threads.
+   Because of the complexities of linux threads, we must send SIGSTOP to
+   every thread, and then call waitpid on the thread to retrieve the 
+   SIGSTOP event.  Sometimes another signal is pending on the thread,
+   and we get that one by mistake.  Throw all such signals into this
+   list, and send them back to their respective threads once we're
+   finished calling waitpid. */
+
+static struct event_list {
+  struct gdbserv_thread *thread;
+  union wait waited;
+  int selected;
+} *pending_events;
+static int pending_events_listsize;
+static int pending_events_top;
+
+/* Function: add_pending_event
+   Helper function for wait_all_threads.
+
+   When we call waitpid for each thread (trying to consume the SIGSTOP
+   events that we sent from stop_all_threads), we sometimes inadvertantly
+   get other events that we didn't send.  We pend these to a list, and 
+   then resend them to the child threads after our own SIGSTOP events
+   have been consumed.  
+
+   This list will be used to choose which of the possible events 
+   will be returned to the debugger by check_child_status. */
+
+static void
+add_pending_event (struct gdbserv_thread *thread, union wait waited)
+{
+  if (pending_events_top >= pending_events_listsize)
+    {
+      pending_events_listsize += 64;
+      pending_events = 
+       realloc (pending_events, 
+                pending_events_listsize * sizeof (*pending_events));
+    }
+  pending_events [pending_events_top].thread = thread;
+  pending_events [pending_events_top].waited = waited;
+  pending_events [pending_events_top].selected = 0;
+  pending_events_top ++;
+}
+
+/* Function: select_pending_event
+   Helper function for wait_all_threads.
+
+   Having collected a list of events from various threads, 
+   choose one "favored event" to be returned to the debugger. */
+
+
+static void
+select_pending_event (struct child_process *process)
+{
+  int i = 0;
+  int num_wifstopped_events = 0;
+  int random_key;
+
+  /* Select the event that will be returned to the debugger. */
+
+  /* Selection criterion #0:
+     If there are no events, don't do anything!  (paranoia) */
+  if (pending_events_top == 0)
+    return;
+
+  /* Selection criterion #1: 
+     If the thread pointer is null, then the thread library is
+     not in play yet, so this is the only thread and the only event. */
+  if (pending_events[0].thread == NULL)
+    {
+      i = 0;
+      goto selected;
+    }
+
+  /* Selection criterion #2:
+     Exit and terminate events take priority. */
+  for (i = 0; i < pending_events_top; i++)
+    if (WIFEXITED (pending_events[i].waited) ||
+       WIFSIGNALED (pending_events[i].waited))
+      {
+       goto selected;
+      }
+
+  /* Selection criterion #3: 
+     Give priority to a stepping SIGTRAP. */
+  for (i = 0; i < pending_events_top; i++)
+    if (pending_events[i].thread->stepping &&
+       WIFSTOPPED (pending_events[i].waited) &&
+       WSTOPSIG (pending_events[i].waited) == SIGTRAP)
+      {
+       /* We don't actually know whether this sigtrap was the result
+          of a singlestep, or of executing a trap instruction.  But
+          GDB has a better chance of figuring it out than we do. */
+       goto selected;
+      }
+
+  /* Selection criterion #4:
+     Count the WIFSTOPPED events and choose one at random. */
+  for (i = 0; i < pending_events_top; i++)
+    if (WIFSTOPPED (pending_events[i].waited))
+      num_wifstopped_events ++;
+
+  random_key = (int) 
+    ((num_wifstopped_events * (double) rand ()) / (RAND_MAX + 1.0));
+
+  for (i = pending_events_top - 1; i >= 0; i--)
+    if (WIFSTOPPED (pending_events[i].waited))
+      {
+       if (random_key == --num_wifstopped_events)
+         {
+           goto selected;
+         }
+       else if (WSTOPSIG (pending_events[i].waited) == SIGINT)
+         {
+           goto selected;      /* Give preference to SIGINT. */
+         }
+      }
+
+  /* Selection criterion #4 (should never get here):
+     If all else fails, take the first event in the list. */
+  i = 0;
+
+ selected:     /* Got our favored event. */
+  pending_events[i].selected = 1;
+  process->event_thread = pending_events[i].thread;
+  if (pending_events[i].thread)
+    process->pid = pending_events[i].thread->ti.ti_lid;
+
+  handle_waitstatus (process, pending_events[i].waited);
+  if (thread_db_noisy)
+    fprintf (stderr, "<select_pending_event: pid %d '%c' %d>\n",
+           process->pid, process->stop_status, process->stop_signal);
+  return;
+}
+
+/* Function: send_pending_signals
+   Helper function for wait_all_threads.
+
+   When we call waitpid for each thread (trying to consume the SIGSTOP
+   events that we sent from stop_all_threads), we sometimes inadvertantly
+   get other events that we didn't send.  We pend these to a list, and 
+   then resend them to the child threads after our own SIGSTOP events
+   have been consumed. 
+
+   Some events in the list require special treatment:
+    * One event is "selected" to be returned to the debugger. 
+      Skip that one.
+    * Trap events may represent breakpoints.  We can't just resend
+      the signal.  Instead we must arrange for the breakpoint to be
+      hit again when the thread resumes.  */
+
+static void
+send_pending_signals (struct child_process *process)
+{
+  int i;
+  int signum;
+
+  for (i = 0; i < pending_events_top; i++)
+    {
+      if (WIFSTOPPED (pending_events[i].waited) &&
+         ! pending_events[i].selected)
+       {
+         signum = WSTOPSIG (pending_events[i].waited);
+         if (signum == SIGTRAP &&
+             pending_events[i].thread->stepping == 0)
+           {
+             /* Breakpoint.  Push it back.  */
+             if (thread_db_noisy)
+               fprintf (stderr, "<send_pending_events: pushing back SIGTRAP for %d>\n",
+                       pending_events[i].thread->ti.ti_lid);
+             decr_pc_after_break (process->serv,
+                                  pending_events[i].thread->ti.ti_lid);
+           }
+         else /* FIXME we're letting SIGINT go thru as normal */
+           {
+             /* Put the signal back into the child's queue. */
+             kill (pending_events[i].thread->ti.ti_lid, 
+                   WSTOPSIG (pending_events[i].waited));
+           }
+       }
+    }
+  pending_events_top = 0;
+}
+
+/* Function: wait_all_threads
+   Use waitpid to close the loop on all threads that have been
+   attached or SIGSTOP'd.  Skip the eventpid -- it's already been waited. 
+
+   Special considerations:
+     The debug signal does not go into the event queue, 
+     does not get forwarded to the thread etc. */
+
+static void
+wait_all_threads (struct child_process *process)
+{
+  struct gdbserv_thread *thread;
+  union  wait w;
+  int    ret, stopsig;
+
+  for (thread = first_thread_in_list ();
+       thread;
+       thread = next_thread_in_list (thread))
+    {
+      /* Special handling for the thread that has already been waited. */
+      if (thread->ti.ti_lid == process->pid)
+       {
+         /* HACK mark him waited. */
+         thread->waited = 1;
+         continue;
+       }
+
+      while ((thread->stopped || thread->attached) &&
+            !thread->waited)
+       {
+         errno = 0;
+         ret = waitpid (thread->ti.ti_lid, (int *) &w, 
+                        thread->ti.ti_lid == proc_handle.pid ? 0 : __WCLONE);
+         if (ret == -1)
+           {
+             if (errno == ECHILD)
+               fprintf (stderr, "<wait_all_threads: %d has disappeared>\n", 
+                       thread->ti.ti_lid);
+             else
+               fprintf (stderr, "<wait_all_threads: waitpid %d failed, '%s'>\n", 
+                       thread->ti.ti_lid, strerror (errno));
+             break;
+           }
+         if (WIFEXITED (w))
+           {
+             add_pending_event (thread, w);
+             fprintf (stderr, "<wait_all_threads: %d has exited>\n", 
+                     thread->ti.ti_lid);
+             break;
+           }
+         if (WIFSIGNALED (w))
+           {
+             add_pending_event (thread, w);
+             fprintf (stderr, "<wait_all_threads: %d died with signal %d>\n", 
+                     thread->ti.ti_lid, WTERMSIG (w));
+             break;
+           }
+         stopsig = WSTOPSIG (w);
+         switch (stopsig) {
+         case SIGSTOP:
+           /* This is the one we're looking for.
+              Mark the thread as 'waited' and move on to the next thread. */
+#if 0 /* too noisy! */
+           if (thread_db_noisy)
+             fprintf (stderr, "<waitpid (%d, SIGSTOP)>\n", thread->ti.ti_lid);
+#endif
+           thread->waited = 1;
+           break;
+         default:
+           if (stopsig == debug_signal)
+             {
+               /* This signal does not need to be forwarded. */
+               if (thread_db_noisy)
+                 fprintf (stderr, "<wait_all_threads: ignoring SIGDEBUG for %d>\n",
+                         thread->ti.ti_lid);
+             }
+           else
+             {
+               if (thread_db_noisy)
+                 fprintf (stderr, "<wait_all_threads: stash sig %d for %d at 0x%08x>\n",
+                          stopsig, thread->ti.ti_lid,
+                         (unsigned long) debug_get_pc (process->serv,
+                                                       thread->ti.ti_lid));
+               add_pending_event (thread, w);
+             }
+         }
+
+         if (!thread->waited)  /* Signal was something other than STOP. */
+           {
+             /* Continue the thread so it can stop on the next signal. */
+             continue_lwp (thread->ti.ti_lid, 0);
+           }
+       }
+    }
+  select_pending_event (process);
+  send_pending_signals (process);
+}
+
+/* Function: continue_thread
+   Send continue to a struct gdbserv_thread. */
+
+static void
+continue_thread (struct gdbserv_thread *thread, int signal)
+{
+  thread_db_flush_regset_caches();
+
+  /* Continue thread only if (a) it was just attached, or 
+     (b) we stopped it and waited for it. */
+  if (thread->ti.ti_lid != 0)
+    if (thread->attached || (thread->stopped && thread->waited))
+      {
+       continue_lwp (thread->ti.ti_lid, signal);
+       thread->stopped = thread->attached = thread->waited = 0;
+      }
+  thread_db_invalidate_caches ();
+}
+
+/* Function: continue_all_threads 
+   Send continue to all stopped or attached threads
+   except the event thread (which will be continued separately). */
+
+static void
+continue_all_threads (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  struct gdbserv_thread *thread;
+  int signal;
+
+  for (thread = first_thread_in_list ();
+       thread;
+       thread = next_thread_in_list (thread))
+    {
+      /* Send any newly attached thread the restart signal. */
+      if (thread->attached)
+       continue_thread (thread, restart_signal);
+      else
+       continue_thread (thread, 0);
+    }
+}
+
+/* Function: continue_program
+   Make sure every thread is running, starting with the event thread. */
+
+static void
+thread_db_continue_program (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  /* Synchronize the regset caches.  */
+  thread_db_flush_regset_caches();
+
+  /* First resume the event thread. */
+  if (process->event_thread)
+    continue_thread (process->event_thread, process->signal_to_send);
+  else
+    continue_lwp (process->pid, process->signal_to_send);
+
+  process->stop_signal = process->stop_status = 
+    process->signal_to_send = 0;
+
+  /* Then resume everyone else. */
+  continue_all_threads (serv);
+  process->running = 1;
+  thread_db_invalidate_caches ();
+}
+
+/* Function: singlestep_thread
+   Send SINGLESTEP to a struct gdbserv_thread. */
+
+static void
+singlestep_thread (struct gdbserv_thread *thread, int signal)
+{
+  singlestep_lwp (thread->ti.ti_lid, signal);
+  thread->stopped = thread->attached = thread->waited = 0;
+  thread->stepping = 1;
+}
+
+/* Function: singlestep_program
+   Make sure every thread is runnable, while the event thread gets to 
+   do a singlestep. */
+
+static void
+thread_db_singlestep_program (struct gdbserv *serv)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+
+  /* Synchronize the regset caches.  */
+  thread_db_flush_regset_caches();
+
+  /* First singlestep the event thread. */
+  if (process->event_thread)
+    singlestep_thread (process->event_thread, process->signal_to_send);
+  else
+    singlestep_lwp (process->pid, process->signal_to_send);
+
+  process->stop_status = process->stop_signal =
+    process->signal_to_send = 0;
+
+  /* Then resume everyone else. */
+  continue_all_threads (serv);         /* All but the event thread. */
+  process->running = 1;
+  thread_db_invalidate_caches ();
+}
+
+/* Function: thread_db_continue_thread
+   Let a single thread continue, while everyone else waits. */
+
+static void
+thread_db_continue_thread (struct gdbserv *serv,
+                          struct gdbserv_thread *thread,
+                          const struct gdbserv_reg *signum)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  unsigned long sig;
+
+  /* Synchronize the regset caches.  */
+  thread_db_flush_regset_caches();
+
+  /* Handle the signal value. */
+  if (parentvec.process_signal && signum)
+    {
+      gdbserv_reg_to_ulong (serv, signum, &sig);
+      parentvec.process_signal (serv, (int) sig);
+    }
+
+  /* A null thread argument is to be taken as a continue for all. */
+  if (thread == NULL)
+    thread_db_continue_program (serv);
+  else
+    {
+      process->pid = thread->ti.ti_lid;                /* thread to be continued */
+      continue_thread (thread, process->signal_to_send);
+      process->stop_status = process->stop_signal =
+       process->signal_to_send = 0;
+      process->running = 1;
+    }
+  thread_db_invalidate_caches ();
+}
+
+/* Function: singlestep_thread
+   Let a single thread step, while everyone else waits. */
+
+static void
+thread_db_singlestep_thread (struct gdbserv *serv,
+                            struct gdbserv_thread *thread,
+                            const struct gdbserv_reg *signum)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  unsigned long sig;
+
+  /* Synchronize the regset caches.  */
+  thread_db_flush_regset_caches();
+
+  /* Handle the signal value. */
+  if (parentvec.process_signal && signum)
+    {
+      gdbserv_reg_to_ulong (serv, signum, &sig);
+      parentvec.process_signal (serv, (int) sig);
+    }
+
+  /* A null thread argument is to be taken as a singlestep for all. */
+  if (thread == NULL)
+    thread_db_singlestep_program (serv);
+  else
+    {
+      singlestep_thread (thread, process->signal_to_send);
+      process->stop_status = process->stop_signal =
+       process->signal_to_send = 0;
+      process->running = 1;
+    }
+  thread_db_invalidate_caches ();
+}
+
+/* Function: exit_program
+   Called by main loop when child exits. */
+
+static void
+thread_db_exit_program (struct gdbserv *serv)
+{
+  /* FIXME: stop and kill all threads. */
+
+  /* Shut down the thread_db library interface. */
+  td_ta_delete_p (thread_agent);
+  thread_agent = NULL;
+  currentvec = NULL;
+  /* Discard all cached symbol lookups. */
+  free_symbol_list ();
+  /* Discard all cached threads. */
+  free_thread_list ();
+  /* Call underlying exit_program method. */
+  parentvec.exit_program (serv);
+}
+
+/* Function: check_child_state
+
+   This function checks for signal events in the running child processes.
+   It does not block if there is no event in any child, but if there is
+   an event, it selectively calls other functions that will, if appropriate,
+   make sure that all the other children are stopped as well. 
+
+   This is a polling (non-blocking) function, and may be called when 
+   the child is already stopped. */
+
+static int
+thread_db_check_child_state (struct child_process *process)
+{
+  struct gdbserv *serv = process->serv;
+  int eventpid;
+  union wait w;
+
+  /* The "process" is likely to be the parent thread.
+     We will have to manage a list of threads/pids. */
+
+  /* Since this is a polling call, and threads don't all stop at once, 
+     it is possible for a subsequent call to intercept a new wait event
+     before we've resumed from the previous wait event.  Prevent this
+     with a resume flag. */
+
+  if (process->running)
+    {
+      eventpid = waitpid (-1, (int *) &w, WNOHANG);
+      /* If no event on main thread, check clone threads. 
+         It doesn't matter what event we find first, since we now have
+         a fair algorithm for choosing which event to handle next. */
+      if (eventpid <= 0)
+       eventpid = waitpid (-1, (int *) &w, WNOHANG | __WCLONE);
+
+      if (eventpid > 0)        /* found an event */
+       {
+         /* Allow underlying target to use the event process by default,
+            since it is stopped and the others are still running. */
+         process->pid = eventpid;
+
+         handle_waitstatus (process, w);
+
+         /* Look for thread exit. 
+            This has to be done now -- if the eventpid has exited, I can't
+            run update_thread_list because there is no stopped process 
+            thru which I can read memory.  I could find another one to 
+            stop, but it's not really worth it. */
+         if (process->stop_status == 'W')
+           {
+             if (eventpid == proc_handle.pid)
+               return 1;       /* Main thread exited! */
+             else
+               return 0;       /* Just a thread exit, don't tell GDB. */
+           }
+
+         /* FIXME: this debugging output will be removed soon, but 
+            putting it here before the update_thread_list etc. is
+            bad from the point of view of synchronization. */
+         handle_waitstatus (process, w);
+         if (thread_db_noisy)
+           fprintf (stderr, "<check_child_state: %d got '%c' - %d at 0x%08x>\n", 
+                    process->pid, process->stop_status, process->stop_signal,
+                    (unsigned long) debug_get_pc (process->serv, process->pid));
+
+         /* Update the thread list. */
+         update_thread_list ();
+
+         /* For now, call get_thread_signals from here (FIXME:) */
+         get_thread_signals ();
+
+         /* Put this child's event into the pending list. */
+         add_pending_event (thread_list_lookup_by_lid ((lwpid_t) eventpid), 
+                            w);
+
+         stop_all_threads (process);
+         wait_all_threads (process);
+         /* Note: if more than one thread has an event ready to be
+            handled, wait_all_threads will have chosen one at random. */
+
+         if (got_thread_signals && process->stop_status == 'T')
+           {
+             /* Child stopped with a signal.  
+                See if it was one of our special signals. */
+
+             if (process->stop_signal == cancel_signal  ||     /* ignore */
+                 process->stop_signal == restart_signal ||     /* ignore */
+                 process->stop_signal == debug_signal   ||     /* ignore */
+                 process->stop_signal == SIGCHLD)              /* ignore */
+               {
+                 /* Ignore this signal, restart the child. */
+                 if (thread_db_noisy)
+                   fprintf (stderr, "<check_child_state: ignoring signal %d for %d>\n",
+                            process->stop_signal, process->pid);
+                 if (process->stop_signal == debug_signal)
+                   {
+                     /* The debug signal arrives under two circumstances:
+                        1) The main thread raises it once, upon the first call
+                        to pthread_create.  This lets us detect the manager
+                        thread.  The main thread MUST be given the restart
+                        signal when this occurs. 
+                        2) The manager thread raises it each time a new
+                        child thread is created.  The child thread will be
+                        in sigsuspend, and MUST be sent the restart signal.
+                        However, the manager thread, which raised the debug
+                        signal, does not need to be restarted.  
+
+                        Sending the restart signal to the newly attached
+                        child thread (which is not the event thread) is
+                        handled in continue_all_threads.  */
+
+                     if (process->pid == proc_handle.pid)  /* main thread */
+                       process->stop_signal = restart_signal;
+                     else                              /* not main thread */
+                       process->stop_signal = 0;
+                   }
+                 process->signal_to_send = process->stop_signal;
+                 currentvec->continue_program (serv);
+                 return 0;
+               }
+           }
+         if (process->stop_status == 'W')
+           {
+             if (process->pid == proc_handle.pid)
+               return 1;       /* Main thread exited! */
+             else
+               {
+                 currentvec->continue_program (serv);
+                 return 0;     /* Just a thread exit, don't tell GDB. */
+               }
+           }
+
+         process->running = 0;
+
+         /* This is the place to cancel its 'stepping' flag. */
+         if (process && process->event_thread)
+           process->event_thread->stepping = 0;
+
+         /* Pass this event back to GDB. */
+         if (process->debug_backend)
+           fprintf (stderr, "wait returned '%c' (%d) for %d.\n", 
+                    process->stop_status, process->stop_signal, eventpid);
+         return 1;
+       }
+    }
+
+  /* NOTE: this function is called in a polling loop, so it
+     probably (?) should not block.  Return when there's no event. */
+  return 0;
+}
+
+/* Function: fromtarget_thread_break
+   Called from the main loop when one of the child processes stops.
+   Notifies the RDA library and lets it know which thread took the event. */
+
+static void
+thread_db_fromtarget_thread_break (struct child_process *process)
+{
+  int gdb_signal = parentvec.compute_signal (process->serv,
+                                            process->stop_signal);
+
+  gdbserv_fromtarget_thread_break (process->serv, 
+                                  process->event_thread,
+                                  gdb_signal);
+}
+
+/* Function: get_thread_reg
+   Get a register value for a specific thread. */
+
+static int
+thread_db_get_thread_reg (struct gdbserv *serv, 
+                         struct gdbserv_thread *thread, 
+                         int regnum, 
+                         struct gdbserv_reg *reg)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  td_thrhandle_t thread_handle;
+  td_thrinfo_t   ti;
+  FPREGSET_T fpregset;
+  GREGSET_T gregset;
+  td_err_e ret;
+
+  if (thread == NULL)
+    thread = process->event_thread;    /* Default to the event thread. */
+
+  if (thread_agent == NULL ||          /* Thread layer not alive yet? */
+      thread       == NULL)            /* No thread specified? */
+    {
+      /* Fall back on parentvec non-threaded method. */
+      if (parentvec.get_reg)
+       return parentvec.get_reg (serv, regnum, reg);
+      else
+       return -1;      /* give up. */
+    }
+
+  /* Thread_db active, thread_agent valid.
+     The request goes to the thread_db library. 
+     From there it will be dispatched to ps_lgetregs,
+     and from there it will be kicked back to the parent. */
+
+  if (thread->ti.ti_state == TD_THR_ZOMBIE ||
+      thread->ti.ti_state == TD_THR_UNKNOWN)
+    {
+      /* This thread is dead!  Can't get its registers. */
+      return -1;
+    }
+
+  ret = thread_db_map_id2thr (thread_agent, 
+                             thread->ti.ti_tid,
+                             &thread_handle);
+  if (ret == TD_NOTHR)
+    {
+      /* Thread has exited, no registers. */
+      return -1;
+    }
+  else if (ret != TD_OK)
+    {
+      fprintf (stderr, "<<< ERROR get_thread_reg map_id2thr %d >>>\n",
+              thread->ti.ti_tid);
+      return -1;       /* fail */
+    }
+
+  if (is_fp_reg (regnum))
+    {
+      if (thread_db_getfpregs (&thread_handle, &fpregset) != TD_OK)
+       {
+         /* Failure to get the fpregs isn't necessarily an error.
+            Assume that the target just doesn't support fpregs. */
+         return 0;
+       }
+      /* Now extract the register from the fpregset. */
+      if (reg_from_fpregset (serv, reg, regnum, &fpregset) < 0)
+       {
+         fprintf (stderr, "<<< ERROR reg_from_fpregset %d %d>>>\n",
+                  thread->ti.ti_tid, regnum);
+         return -1;
+       }
+    }
+  else if (td_thr_getxregsize_p != NULL
+           && td_thr_getxregs_p != NULL
+          && is_extended_reg (regnum))
+    {
+      int xregsize;
+      void *xregset;
+
+      if (td_thr_getxregsize_p (&thread_handle, &xregsize) != TD_OK)
+       {
+         /* Failure to get the size of the extended regs isn't
+            necessarily an error.  Assume that the target just
+            doesn't support them.  */
+         return 0;
+       }
+
+      if (xregsize <= 0)
+       {
+         /* Another form of not being supported...  */
+         return 0;
+       }
+
+      /* Allocate space for the extended registers.  */
+      xregset = alloca (xregsize);
+      
+      /* Fetch the extended registers.  */
+      if (td_thr_getxregs_p (&thread_handle, xregset) != TD_OK)
+       {
+         /* Failure to get the extended regs isn't necessarily an error.
+            Assume that the target just doesn't support them.  */
+         return 0;
+       }
+
+      /* Now extract the register from the extended regset.  */
+      if (reg_from_xregset (serv, reg, regnum, xregset) < 0)
+       {
+         fprintf (stderr, "<<< ERROR reg_from_xregset %d %d>>>\n",
+                  thread->ti.ti_tid, regnum);
+         return -1;
+       }
+    }
+  else if (is_gp_reg (regnum)) /* GP reg */
+    {
+      if (thread_db_getgregs (&thread_handle, gregset) != TD_OK)
+       {
+         fprintf (stderr, "<<< ERROR get_thread_reg td_thr_getgregs %d >>>\n",
+                  thread->ti.ti_tid);
+         return -1;    /* fail */
+       }
+      /* Now extract the requested register from the gregset. */
+      if (reg_from_gregset (serv, reg, regnum, gregset) < 0)
+       {
+         fprintf (stderr, "<<< ERROR reg_from_gregset %d %d>>>\n", 
+                  thread->ti.ti_tid, regnum);
+         return -1;    /* fail */
+       }
+    }
+  else
+    {
+      /* Register not supported by this target.  This shouldn't be
+         construed as an error though.  */
+      return 0;
+    }
+
+  return 0;            /* success */
+}
+
+/* Function: set_thread_reg
+   Set a register value for a specific thread. */
+
+static int
+thread_db_set_thread_reg (struct gdbserv *serv, 
+                         struct gdbserv_thread *thread, 
+                         int regnum, 
+                         const struct gdbserv_reg *reg)
+{
+  struct child_process *process = gdbserv_target_data (serv);
+  td_thrhandle_t thread_handle;
+  FPREGSET_T fpregset;
+  GREGSET_T gregset;
+  td_err_e ret;
+
+  if (thread == NULL)
+    thread = process->event_thread;    /* Default to the event thread. */
+
+  if (thread_agent == NULL ||          /* Thread layer not alive yet? */
+      thread       == NULL)            /* No thread specified? */
+    {
+      /* Fall back on parentvec non-threaded method. */
+      if (parentvec.set_reg)
+       return parentvec.set_reg (serv, regnum, (struct gdbserv_reg *) reg);
+      else
+       return -1;      /* give up. */
+    }
+
+  /* Thread_db active, thread_agent valid.
+     The request goes to the thread_db library. 
+     From there it will be dispatched to ps_lsetregs,
+     and from there it will be kicked back to the parent. */
+
+  if (thread->ti.ti_state == TD_THR_ZOMBIE ||
+      thread->ti.ti_state == TD_THR_UNKNOWN)
+    {
+      /* This thread is dead!  Can't get its registers. */
+      return -1;
+    }
+
+  ret = thread_db_map_id2thr (thread_agent, 
+                             thread->ti.ti_tid,
+                             &thread_handle);
+  if (ret == TD_NOTHR)
+    {
+      /* Thread has exited, no registers. */
+      return -1;
+    }
+  else if (ret != TD_OK)
+    {
+      fprintf (stderr, "<<< ERROR set_thread_reg map_id2thr %d >>>\n",
+              thread->ti.ti_tid);
+      return -1;       /* fail */
+    }
+
+  if (is_fp_reg (regnum))
+    {
+      /* Get the current fpregset.  */
+      if (thread_db_getfpregs (&thread_handle, &fpregset) != TD_OK)
+       {
+         /* Failing to get the fpregs is not necessarily an error.
+            Assume it simply means that this target doesn't support
+            fpregs. */
+         return 0;
+       }
+      /* Now write the new reg value into the fpregset. */
+      if (reg_to_fpregset (serv, reg, regnum, &fpregset) < 0)
+       {
+         fprintf (stderr, "<<< ERROR reg_to_fpregset %d %d >>>\n",
+                  thread->ti.ti_tid, regnum);
+         return -1;    /* fail */
+       }
+      /* Now write the fpregset back to the child. */
+      if (thread_db_setfpregs (&thread_handle, &fpregset) != TD_OK)
+       {
+         fprintf (stderr, "<<< ERROR set_thread_reg td_thr_setfpregs %d>>>\n",
+                  thread->ti.ti_tid);
+         return -1;    /* fail */
+       }
+    }
+  else if (td_thr_getxregsize_p != NULL
+           && td_thr_getxregs_p != NULL
+           && td_thr_setxregs_p != NULL
+          && is_extended_reg (regnum))
+    {
+      int xregsize;
+      void *xregset;
+
+      if (td_thr_getxregsize_p (&thread_handle, &xregsize) != TD_OK)
+       {
+         /* Failure to get the size of the extended regs isn't
+            necessarily an error.  Assume that the target just
+            doesn't support them.  */
+         return 0;
+       }
+
+      if (xregsize <= 0)
+       {
+         /* Another form of not being supported...  */
+         return 0;
+       }
+
+      /* Allocate space for the extended registers.  */
+      xregset = alloca (xregsize);
+
+      /* Fetch the extended registers.  */
+      if (td_thr_getxregs_p (&thread_handle, xregset) != TD_OK)
+       {
+         /* Failure to get the extended regs isn't necessarily an error.
+            Assume that the target just doesn't support them.  */
+         return 0;
+       }
+      /* Now write the new reg value into the extended regset. */
+      if (reg_to_xregset (serv, reg, regnum, xregset) < 0)
+       {
+         fprintf (stderr, "<<< ERROR reg_to_xregset %d %d >>>\n", 
+                  thread->ti.ti_tid, regnum);
+         return -1;    /* fail */
+       }
+      /* Now write the extended regset back to the child. */
+      if (td_thr_setxregs_p (&thread_handle, gregset) != TD_OK)
+       {
+         fprintf (stderr, "<<< ERROR set_thread_reg td_thr_setxregs %d >>>\n",
+                  thread->ti.ti_tid);
+         return -1;    /* fail */
+       }
+    }
+  else if (is_gp_reg (regnum))
+    {
+      /* First get the current gregset.  */
+      if (thread_db_getgregs (&thread_handle, gregset) != TD_OK)
+       {
+         fprintf (stderr, "<<< ERROR set_thread_reg td_thr_getgregs %d >>>\n",
+                  thread->ti.ti_tid);
+         return -1;    /* fail */
+       }
+      /* Now write the new reg value into the gregset. */
+      if (reg_to_gregset (serv, reg, regnum, gregset) < 0)
+       {
+         fprintf (stderr, "<<< ERROR reg_to_gregset %d %d >>>\n", 
+                  thread->ti.ti_tid, regnum);
+         return -1;    /* fail */
+       }
+      /* Now write the gregset back to the child. */
+      if (thread_db_setgregs (&thread_handle, gregset) != TD_OK)
+       {
+         fprintf (stderr, "<<< ERROR set_thread_reg td_thr_setgregs %d >>>\n",
+                  thread->ti.ti_tid);
+         return -1;    /* fail */
+       }
+    }
+
+  return 0;    /* success */
+}
+
+/* Function: thread_db_attach
+   gdbserv target function called upon attaching to gdb. 
+   Return -1 for failure, zero for success. 
+   Note that this has nothing to do with attaching to a running process
+   (which in fact we don't even know how to do), or a running thread. */
+
+int
+thread_db_attach (struct gdbserv *serv, struct gdbserv_target *target)
+{
+  td_err_e ret;
+  struct child_process *process = target->data;
+  extern struct server_vector gdbserver;
+  paddr_t dummy;
+
+  if ((thread_db_dlopen ()) < 0)
+    return -1;                 /* fail */
+
+  /* Save a copy of the existing target vector before we modify it. */
+  memcpy (&parentvec, target, sizeof (parentvec));
+  /* Save a pointer to the actual target vector. */
+  currentvec = target;
+
+  /* Initialize the library.  */
+  if ((ret = td_init_p ()) != TD_OK)
+    {
+      fprintf (stderr, 
+              "Cannot initialize libthread_db: %s", thread_db_err_str (ret));
+      currentvec = NULL;
+      return -1;               /* fail */
+    }
+
+  /* Initialize threadish target methods. */
+  target->thread_info         = thread_db_thread_info;
+  target->thread_next         = thread_db_thread_next;
+  target->thread_id           = thread_db_thread_id;
+  target->thread_lookup_by_id = thread_db_thread_lookup_by_id;
+  target->process_set_gen     = thread_db_set_gen;
+  target->process_get_gen     = thread_db_get_gen;
+  target->detach              = thread_db_detach;
+
+  /* Take over selected target methods. */
+  target->exit_program        = thread_db_exit_program;
+  target->continue_program    = thread_db_continue_program;
+  target->singlestep_program  = thread_db_singlestep_program;
+
+  target->continue_thread     = thread_db_continue_thread;
+  target->singlestep_thread   = thread_db_singlestep_thread;
+
+  /* Take over get_reg / set_reg methods with threaded versions. */
+  if (target->next_gg_reg != NULL &&
+      target->reg_format  != NULL &&
+      target->output_reg  != NULL &&
+      target->input_reg   != NULL)
+    {
+      target->get_thread_reg      = thread_db_get_thread_reg;
+      target->set_thread_reg      = thread_db_set_thread_reg;
+    }
+  else
+    fprintf (stderr, "< ERROR attach: GDB will not read thread regs. >>>\n");
+
+  /* KLUDGE: Insert some magic symbols into the cached symbol list,
+     to be looked up later.  This is badly wrong -- we should be 
+     obtaining these values thru the thread_db interface.  Their names
+     should not be hard-coded here <sob>. */
+  add_symbol_to_list ("__pthread_sig_restart",   0, UNDEFINED);
+  add_symbol_to_list ("__pthread_sig_cancel",    0, UNDEFINED);
+  add_symbol_to_list ("__pthread_sig_debug",     0, UNDEFINED);
+  add_symbol_to_list ("__pthread_threads_debug", 0, UNDEFINED);
+
+  /* Attempt to open the thread_db interface.  This attempt will 
+     most likely fail (unles the child is statically linked). */
+  thread_db_open (serv, process->pid); /* Don't test return value */
+
+  /* Take over the "wait" vector. FIXME global object */
+  gdbserver.check_child_state = thread_db_check_child_state;
+  /* Take over the "fromtarget_break" vector. FIXME global object */
+  gdbserver.fromtarget_break = thread_db_fromtarget_thread_break;
+  /* FIXME what about terminate and exit? */
+
+  /* Set up the regset caches.  */
+  initialize_regset_caches ();
+  return 0;            /* success */
+}
diff --git a/rda/win32/ChangeLog b/rda/win32/ChangeLog
new file mode 100644 (file)
index 0000000..0824518
--- /dev/null
@@ -0,0 +1,155 @@
+2002-08-21  Kevin Buettner  <kevinb@redhat.com>
+
+       * Makefile.am, configure.in, server.cc, win32-target.cc: Change
+       ``libremote'' references into ``RDA'' references.
+       * Makefile.in, configure: Regenerate.
+
+2002-08-15  Kevin Buettner  <kevinb@redhat.com>
+
+       * child_process.cc, server.cc, server.h, win32-strace.cc,
+       win32-target.cc:  Update copyright notices.
+
+2001-11-14  Corinna Vinschen  <vinschen@redhat.com>
+
+       * configure.in: Check AC_FUNC_ALLOCA.
+       * configure: Regenerate from configure.in.
+       * config.in: Add HAVE_ALLOCA_H stuff.
+       * server.h: Add alloca check as in gdb's defs.h.
+
+2001-11-12  Corinna Vinschen  <vinschen@redhat.com>
+
+       * win32-target.cc (win32_process_set_pc):  Declare 2nd parameter
+       `const' to avoid errors with some compilers.
+
+2001-04-12  Andrew Cagney  <ac131313@redhat.com>
+
+       * server.cc (main): Replace gdbsocket_poll with gdbloop_poll.
+       * win32-target.cc: Update comments.
+       * server.h: Include "gdbloop.h".
+
+2001-03-22  Andrew Cagney  <ac131313@redhat.com>
+
+       * server.cc (main): Pass win32_attach and process to
+       gdbsocket_startup instead of gdbsocket_poll.
+
+2001-03-14  Andrew Cagney  <ac131313@redhat.com>
+
+       * Makefile.am (INCLUDES): Update. Headers moved to ../include.
+       * Makefile.in: Regenerate.
+
+2000-12-06  Corinna Vinschen  <vinschen@cygnus.com>
+
+       * child_process.cc (check_state): new method.
+       (fromtarget_break): Ditto.
+       (fromtarget_exit): Ditto.
+       (fromtarget_terminate): Ditto.
+       * server.cc (main): Change tabbing. Use new child_process methods.
+       * server.h (struct server_vector): Eliminated.
+       * (class child_process): Add new methods `check_state',
+       `fromtarget_break', `fromtarget_exit' and `fromtarget_terminate'.
+       * win32-target.cc (win32_check_child_state): Eliminated. Functionality
+       moved to class child_process.
+       (win32_fromtarget_break): Ditto.
+       (win32_fromtarget_exit): Ditto.
+       (win32_fromtarget_terminate): Ditto.
+
+2000-11-24  Corinna Vinschen  <vinschen@cygnus.com>
+
+       * Makefile.am: Add child_process.cc dependency.
+       * Makefile.in: Regenerated.
+       * configure.in: Add child_process.o dependency.
+       * configure: Regenerated.
+       * child_process.cc: New file. Contains methods of class child_process.
+       * server.cc: Move global `server_quit_p' to class child_process.
+       (main): Use new child_process methods.
+       * server.h: Move gdb specific includes to here. Move define
+       FLAG_TRACE_BIT to here.
+       (enum proc_state): New type.
+       (class child_process): Change access of `stop_status' and `stop_signal'
+       to private. Add private member `server_quit_p'.
+       (child_process::set_running): New method.
+       (child_process::set_break): Ditto.
+       (child_process::set_exit): Ditto.
+       (child_process::set_term): Ditto.
+       (child_process::status): Ditto.
+       (child_process::stop_signal): Ditto.
+       (child_process::term_signal): Ditto.
+       (child_process::exit_code): Ditto.
+       (child_process::quit_server): Ditto.
+       (child_process::handle_exception): Add declaration for new method.
+       (child_process::fetch_regs): Ditto.
+       (child_process::store_regs): Ditto.
+       (child_process::resume_program): Ditto.
+       (child_process::load_dll_event): Ditto.
+       (child_process::create_child): Ditto.
+       * win32-strace.cc: Slight cleanup.
+       (win32_output_debug_string): Use new child_process methods.
+       * win32-target.cc: Slight cleanups. Use new child_process methods
+       throughout.
+       (child_process::debug): Moved to child_process.cc.
+       (win32_fetch_regs): Changed to method child_process::fetch_regs and
+       moved to child_process.cc.
+       (win32_store_regs): Changed to method child_process::store_regs and
+       moved to child_process.cc.
+       (win32_get_process): Change to inline function.
+       (win32_process_set_pc): New function.
+       (win32_resume_program): Changed to method child_process::resume_program
+       and moved to child_process.cc.
+       (win32_process_signal): Changed storage class to `extern "C"'.
+       (win32_create_child): Changed to method child_process::create_child
+       and moved to child_process.cc.
+       (struct sigmap): Moved to child_process.cc.
+       (win32_handle_waitstatus): Changed to method
+       child_process::handle_exception and moved to child_process.cc.
+       (win32_load_dll_event): Changed to method child_process::load_dll_event
+       and moved to child_process.cc.
+
+2000-11-24  Corinna Vinschen  <vinschen@cygnus.com>
+
+       * Makefile.am: Add win32-strace.cc dependency.
+       * Makefile.in: Regenerated.
+       * configure.in: Add win32-strace.o dependency.
+       * configure: Regenerated.
+       * server.h: Add classes `breakpoint' and `bp_array'.
+       Add various new members to class `child_process'.
+       * server.cc (usage): Clean up output.
+       (main): Add handling for some more flags.
+       * win32-strace.cc: New file.
+       * win32-target.cc: Several cleanups. Additional debug output.
+       Move `win32_handle_debug_output' to win32-strace.cc.
+       (child_process::debug): New method.
+       (win32_process_rcmd): Add handling for [no]trace  and [no]debug_child
+       commands.
+       (win32_remove_breakpoint): New function.
+       (win32_set_breakpoint): Ditto.
+       (win32_process_signal): Ditto.
+       (win32_load_dll_event): Ditto.
+       (win32_check_child_state): Return always 1 when signal condition
+       is raised.
+
+2000-11-22  Corinna Vinschen  <vinschen@cygnus.com>
+
+       * Makefile.am: Drop CXX variable.
+       * Makefile.in: Regenerated.
+       * configure.in: Add the `AC_PROG_CXX' macro.
+       * configure: Regenerated.
+       * server.h: Move `debug_backend' to private. Add methods `set_debug'
+       and `debug'.
+       * server.cc (main): Add debug option `-d'. Fix `-p' option.
+       Slight format changes. Use new debug methods.
+       * win32-target.cc: Use new debug methods. Various cleanups.
+       (win32_process_signal): New function.
+
+2000-11-21  Corinna Vinschen  <vinschen@cygnus.com>
+
+       New directory "win32" for Cygwin win32 gdbserver in libremote
+       * server.cc: New file. Entry point and main event loop.
+       * server.h: New file. Shared declarations.
+       * win32-target.cc: New file. Win32 version of libremote stub.
+       * config.in: New file. config.h source file.
+       * configure.in: New file. Autoconf source.
+       * configure: New file. Autoconf generated from configure.in.
+       * Makefile.am: New file. Automake source.
+       * Makefile.in: New file. Automake-generated makefile source.
+       * aclocal.m4: New file. Copied from ../native.
+       Note: this work is incomplete and only partially working.
diff --git a/rda/win32/Makefile.am b/rda/win32/Makefile.am
new file mode 100644 (file)
index 0000000..b1550e3
--- /dev/null
@@ -0,0 +1,17 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign
+
+noinst_PROGRAMS = server
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include
+
+CC = gcc
+CFLAGS = -g
+CXXFLAGS = $(CFLAGS)
+
+
+server_SOURCES = server.cc 
+EXTRA_server_SOURCES = win32-target.cc win32-strace.cc child_process.cc
+server_LDADD = $(TARGET_MODULES) ../lib/librda.a
+server_DEPENDENCIES = $(server_OBJECTS) $(TARGET_MODULES)
diff --git a/rda/win32/Makefile.in b/rda/win32/Makefile.in
new file mode 100644 (file)
index 0000000..ac56f04
--- /dev/null
@@ -0,0 +1,439 @@
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_alias = @build_alias@
+build_triplet = @build@
+host_alias = @host_alias@
+host_triplet = @host@
+target_alias = @target_alias@
+target_triplet = @target@
+AS = @AS@
+CXX = @CXX@
+DLLTOOL = @DLLTOOL@
+EXEEXT = @EXEEXT@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+TARGET_MODULES = @TARGET_MODULES@
+VERSION = @VERSION@
+
+AUTOMAKE_OPTIONS = foreign
+
+noinst_PROGRAMS = server
+
+INCLUDES = -I$(srcdir) -I$(srcdir)/../include
+
+CC = gcc
+CFLAGS = -g
+CXXFLAGS = $(CFLAGS)
+
+server_SOURCES = server.cc 
+EXTRA_server_SOURCES = win32-target.cc win32-strace.cc child_process.cc
+server_LDADD = $(TARGET_MODULES) ../lib/librda.a
+server_DEPENDENCIES = $(server_OBJECTS) $(TARGET_MODULES)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = 
+noinst_PROGRAMS =  server$(EXEEXT)
+PROGRAMS =  $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+server_OBJECTS =  server.o
+server_LDFLAGS = 
+CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON =  ./stamp-h.in ChangeLog Makefile.am Makefile.in aclocal.m4 \
+config.in configure configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES =  .deps/child_process.P .deps/server.P .deps/win32-strace.P \
+.deps/win32-target.P
+SOURCES = $(server_SOURCES) $(EXTRA_server_SOURCES)
+OBJECTS = $(server_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .cc .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status $(BUILT_SOURCES)
+       cd $(top_builddir) \
+         && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in 
+       cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+       $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+       cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+       @if test ! -f $@; then \
+               rm -f stamp-h; \
+               $(MAKE) stamp-h; \
+       else :; fi
+stamp-h: $(srcdir)/config.in $(top_builddir)/config.status
+       cd $(top_builddir) \
+         && CONFIG_FILES= CONFIG_HEADERS=config.h:config.in \
+            $(SHELL) ./config.status
+       @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+       @if test ! -f $@; then \
+               rm -f $(srcdir)/stamp-h.in; \
+               $(MAKE) $(srcdir)/stamp-h.in; \
+       else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) 
+       cd $(top_srcdir) && $(AUTOHEADER)
+       @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+       -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+       -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.s.o:
+       $(COMPILE) -c $<
+
+.S.o:
+       $(COMPILE) -c $<
+
+mostlyclean-compile:
+       -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+       -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+       $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+       -rm -f *.lo
+
+clean-libtool:
+       -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+server$(EXEEXT): $(server_OBJECTS) $(server_DEPENDENCIES)
+       @rm -f server$(EXEEXT)
+       $(CXXLINK) $(server_LDFLAGS) $(server_OBJECTS) $(server_LDADD) $(LIBS)
+.cc.o:
+       $(CXXCOMPILE) -c $<
+.cc.lo:
+       $(LTCXXCOMPILE) -c $<
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       here=`pwd` && cd $(srcdir) \
+         && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS:  $(HEADERS) $(SOURCES) config.in $(TAGS_DEPENDENCIES) $(LISP)
+       tags=; \
+       here=`pwd`; \
+       list='$(SOURCES) $(HEADERS)'; \
+       unique=`for i in $$list; do echo $$i; done | \
+         awk '    { files[$$0] = 1; } \
+              END { for (i in files) print i; }'`; \
+       test -z "$(ETAGS_ARGS)config.in$$unique$(LISP)$$tags" \
+         || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+       -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+       -rm -rf $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+       mkdir $(distdir)/=build
+       mkdir $(distdir)/=inst
+       dc_install_base=`cd $(distdir)/=inst && pwd`; \
+       cd $(distdir)/=build \
+         && ../configure --srcdir=.. --prefix=$$dc_install_base \
+         && $(MAKE) $(AM_MAKEFLAGS) \
+         && $(MAKE) $(AM_MAKEFLAGS) dvi \
+         && $(MAKE) $(AM_MAKEFLAGS) check \
+         && $(MAKE) $(AM_MAKEFLAGS) install \
+         && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+         && $(MAKE) $(AM_MAKEFLAGS) dist
+       -rm -rf $(distdir)
+       @banner="$(distdir).tar.gz is ready for distribution"; \
+       dashes=`echo "$$banner" | sed s/./=/g`; \
+       echo "$$dashes"; \
+       echo "$$banner"; \
+       echo "$$dashes"
+dist: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+dist-all: distdir
+       -chmod -R a+r $(distdir)
+       GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+       -rm -rf $(distdir)
+distdir: $(DISTFILES)
+       -rm -rf $(distdir)
+       mkdir $(distdir)
+       -chmod 777 $(distdir)
+       here=`cd $(top_builddir) && pwd`; \
+       top_distdir=`cd $(distdir) && pwd`; \
+       distdir=`cd $(distdir) && pwd`; \
+       cd $(top_srcdir) \
+         && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
+       @for file in $(DISTFILES); do \
+         d=$(srcdir); \
+         if test -d $$d/$$file; then \
+           cp -pr $$d/$$file $(distdir)/$$file; \
+         else \
+           test -f $(distdir)/$$file \
+           || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+           || cp -p $$d/$$file $(distdir)/$$file || :; \
+         fi; \
+       done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+       -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+       @echo '$(COMPILE) -c $<'; \
+       $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.c
+       @echo '$(LTCOMPILE) -c $<'; \
+       $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+
+%.o: %.cc
+       @echo '$(CXXCOMPILE) -c $<'; \
+       $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-cp .deps/$(*F).pp .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm .deps/$(*F).pp
+
+%.lo: %.cc
+       @echo '$(LTCXXCOMPILE) -c $<'; \
+       $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+       @-sed -e 's/^\([^:]*\)\.o[      ]*:/\1.lo \1.o :/' \
+         < .deps/$(*F).pp > .deps/$(*F).P; \
+       tr ' ' '\012' < .deps/$(*F).pp \
+         | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+           >> .deps/$(*F).P; \
+       rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+all-recursive-am: config.h
+       $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am:
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+       @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am:
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) config.h
+all-redirect: all-am
+install-strip:
+       $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)
+       -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am:  mostlyclean-hdr mostlyclean-noinstPROGRAMS \
+               mostlyclean-compile mostlyclean-libtool \
+               mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am:  clean-hdr clean-noinstPROGRAMS clean-compile clean-libtool \
+               clean-tags clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am:  distclean-hdr distclean-noinstPROGRAMS distclean-compile \
+               distclean-libtool distclean-tags distclean-depend \
+               distclean-generic clean-am
+       -rm -f libtool
+
+distclean: distclean-am
+       -rm -f config.status
+
+maintainer-clean-am:  maintainer-clean-hdr \
+               maintainer-clean-noinstPROGRAMS \
+               maintainer-clean-compile maintainer-clean-libtool \
+               maintainer-clean-tags maintainer-clean-depend \
+               maintainer-clean-generic distclean-am
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+       -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck all-recursive-am install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/rda/win32/aclocal.m4 b/rda/win32/aclocal.m4
new file mode 100644 (file)
index 0000000..bef94ca
--- /dev/null
@@ -0,0 +1,569 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+# Do all the work for Automake.  This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "[$]*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   if test "[$]*" != "X $srcdir/configure conftestfile" \
+      && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "[$]2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+   $1=$2
+   AC_MSG_RESULT(found)
+else
+   $1="$3/missing $2"
+   AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated.  We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+  case " <<$>>CONFIG_HEADERS " in
+  *" <<$>>am_file "*<<)>>
+    echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+    ;;
+  esac
+  am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode is disabled by default
+  AC_ARG_ENABLE(maintainer-mode,
+[  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer],
+      USE_MAINTAINER_MODE=$enableval,
+      USE_MAINTAINER_MODE=no)
+  AC_MSG_RESULT($USE_MAINTAINER_MODE)
+  AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi])
+
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+  [  --disable-libtool-lock  avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<<  --enable-shared[=PKGS]  build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<<  --enable-static[=PKGS]  build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+#   Where DEFAULT is either `yes' or `no'.  If omitted, it defaults to
+#   `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<<  --enable-fast-install[=PKGS]  optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by GCC])
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+changequote(,)dnl
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -B"
+       break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -p"
+       break
+      else
+       ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$lt_target" in
+*-*-beos* | *-*-cygwin*)
+  # These system don't have libm
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, main, LIBM="-lm")
+  ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  case "$enable_ltdl_convenience" in
+  no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+  "") enable_ltdl_convenience=yes
+      ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+  esac
+  LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+  INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments.  Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called.  If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'.  Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+  AC_CHECK_LIB(ltdl, main,
+  [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+  [if test x"$enable_ltdl_install" = xno; then
+     AC_MSG_WARN([libltdl not installed, but installation disabled])
+   else
+     enable_ltdl_install=yes
+   fi
+  ])
+  if test x"$enable_ltdl_install" = x"yes"; then
+    ac_configure_args="$ac_configure_args --enable-ltdl-install"
+    LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+    INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+  else
+    ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+    LIBLTDL="-lltdl"
+    INCLTDL=
+  fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
diff --git a/rda/win32/child_process.cc b/rda/win32/child_process.cc
new file mode 100644 (file)
index 0000000..2b16d8e
--- /dev/null
@@ -0,0 +1,349 @@
+/* child_process.cc
+
+   Copyright 2000, 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 "config.h"
+
+#include <limits.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if !HAVE_WINDOWS_H
+#error The windows.h header is required when compiling for a Win32 target.
+#endif
+#include <windows.h>
+#include <sys/cygwin.h>
+
+#include "server.h"
+
+struct {
+  DWORD exc;
+  const char *exc_txt;
+  DWORD sig;
+} sigmap[] = {
+  EXCEPTION_ACCESS_VIOLATION,     "EXCEPTION_ACCESS_VIOLATION",        SIGSEGV,
+  EXCEPTION_ARRAY_BOUNDS_EXCEEDED, "EXCEPTION_ARRAY_BOUNDS_EXCEEDED",  SIGSEGV,
+  EXCEPTION_BREAKPOINT,                   "EXCEPTION_BREAKPOINT",              SIGTRAP,
+  EXCEPTION_DATATYPE_MISALIGNMENT, "EXCEPTION_DATATYPE_MISALIGNMENT",  SIGBUS,
+  EXCEPTION_FLT_DENORMAL_OPERAND,  "EXCEPTION_FLT_DENORMAL_OPERAND",   SIGFPE,
+  EXCEPTION_FLT_DIVIDE_BY_ZERO,           "EXCEPTION_FLT_DIVIDE_BY_ZERO",      SIGFPE,
+  EXCEPTION_FLT_INEXACT_RESULT,           "EXCEPTION_FLT_INEXACT_RESULT",      SIGFPE,
+  EXCEPTION_FLT_INVALID_OPERATION, "EXCEPTION_FLT_INVALID_OPERATION",  SIGILL,
+  EXCEPTION_FLT_OVERFLOW,         "EXCEPTION_FLT_OVERFLOW",            SIGFPE,
+  EXCEPTION_FLT_STACK_CHECK,      "EXCEPTION_FLT_STACK_CHECK",         SIGFPE,
+  EXCEPTION_FLT_UNDERFLOW,        "EXCEPTION_FLT_UNDERFLOW",           SIGFPE,
+  EXCEPTION_ILLEGAL_INSTRUCTION,   "EXCEPTION_ILLEGAL_INSTRUCTION",    SIGILL,
+  EXCEPTION_IN_PAGE_ERROR,        "EXCEPTION_IN_PAGE_ERROR",           SIGSEGV,
+  EXCEPTION_INT_DIVIDE_BY_ZERO,           "EXCEPTION_INT_DIVIDE_BY_ZERO",      SIGFPE,
+  EXCEPTION_INT_OVERFLOW,         "EXCEPTION_INT_OVERFLOW",            SIGFPE,
+  EXCEPTION_INVALID_DISPOSITION,   "EXCEPTION_INVALID_DISPOSITION",    SIGILL,
+  EXCEPTION_NONCONTINUABLE_EXCEPTION,
+                                  "EXCEPTION_NONCONTINUABLE_EXCEPTION",SIGILL,
+  EXCEPTION_PRIV_INSTRUCTION,     "EXCEPTION_PRIV_INSTRUCTION",        SIGILL,
+  EXCEPTION_SINGLE_STEP,          "EXCEPTION_SINGLE_STEP",             SIGTRAP,
+  EXCEPTION_STACK_OVERFLOW,       "EXCEPTION_STACK_OVERFLOW",          SIGSEGV,
+  DBG_CONTROL_C,                  "DBG_CONTROL_C",                     SIGINT,
+  0,                              "Unknown exception",                 SIGUSR1
+};
+
+/* Debug output method similar to fprintf. */
+void
+child_process::debug (const char *format, ...)
+{
+  if (!debug_backend)
+    return;
+  
+  va_list ap;
+
+  va_start (ap, format);
+  vfprintf (stderr, format, ap);
+  va_end (ap);
+}
+
+void
+child_process::handle_exception (DEBUG_EVENT &ev)
+{
+  DWORD exc_code = ev.u.Exception.ExceptionRecord.ExceptionCode;
+  DWORD exc_flag = ev.u.Exception.ExceptionRecord.ExceptionFlags;
+
+  int i;
+  for (i = 0; sigmap[i].exc && sigmap[i].exc != exc_code; ++i)
+    ;
+
+  debug ("Win32: Got exception 0x%08x = \"%s\", mapped to signal %d\n",
+                 exc_code, sigmap[i].exc_txt, sigmap[i].sig);
+
+  if (exc_flag == EXCEPTION_NONCONTINUABLE)
+    set_term (sigmap[i].sig);
+  else
+    set_break (sigmap[i].sig);
+}
+
+/* fetch registers vector. */
+void
+child_process::fetch_regs ()
+{
+  if (!suspend_cnt)
+    {
+      HANDLE thread_hdl = threads[cur_thread_id];
+      suspend_cnt = SuspendThread (thread_hdl) + 1;
+      context.ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
+      GetThreadContext (thread_hdl, &context);
+    }
+}
+
+void
+child_process::store_regs ()
+{
+  SetThreadContext (threads[cur_thread_id], &context);
+}
+
+BOOL
+child_process::resume_program (BOOL step)
+{
+  fetch_regs ();
+
+  if (step)
+    context.EFlags |= FLAG_TRACE_BIT;
+
+  store_regs ();
+
+  if (ContinueDebugEvent (cur_process_id,
+                         cur_thread_id,
+                         stop_signal () && stop_signal () != SIGTRAP
+                         ? DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE))
+    {
+      int i;
+
+      for (i = 0; i < suspend_cnt; ++i)
+        ResumeThread (threads[cur_thread_id]);
+      suspend_cnt = 0;
+      set_running ();
+      return TRUE;
+    }
+  return FALSE;
+}
+
+void
+child_process::load_dll_event (DEBUG_EVENT &ev)
+{
+  void *ptr;
+  char buf[512];
+  DWORD processed = 0;
+
+  if (!debug ())
+    return;
+
+  if (ev.dwProcessId == process_id
+      && ev.u.LoadDll.lpImageName
+      && ReadProcessMemory (process_hdl, ev.u.LoadDll.lpImageName,
+                            &ptr, sizeof ptr, &processed)
+      && ptr
+      && ReadProcessMemory (process_hdl, ptr, 
+                            buf, sizeof buf, &processed))
+    {
+      buf[511] = '\0';
+      char *name = buf;
+      if (ev.u.LoadDll.fUnicode)
+       {
+         name = (char *) alloca (256);
+         WideCharToMultiByte (CP_ACP, 0, (const WCHAR *) buf, -1,
+                              name, 256, NULL, NULL);
+       }
+      debug ("Win32: Load DLL \"%s\"\n", name);
+    }
+  else
+    debug ("Win32: Load DLL\n");
+}
+
+BOOL
+child_process::create_child ()
+{
+  char real_path[PATH_MAX];
+  char *winenv;
+  char *temp;
+  int envlen;
+  int len, i;
+  STARTUPINFO si;
+  PROCESS_INFORMATION pi;
+  BOOL ret;
+  DWORD flags;
+  char *args;
+
+  memset (&si, 0, sizeof (si));
+  si.cb = sizeof (si);
+
+  cygwin_conv_to_win32_path (executable, real_path);
+
+  flags = DEBUG_ONLY_THIS_PROCESS;
+
+  if (new_group)
+    flags |= CREATE_NEW_PROCESS_GROUP;
+
+  if (new_console)
+    flags |= CREATE_NEW_CONSOLE;
+
+  len = strlen (real_path);
+  for (i = 1; i < argc; ++i)
+    len += strlen (argv[i]) + 1;
+  
+  args = (char *) alloca (len + 2);
+
+  strcpy (args, real_path);
+
+  for (i = 1; i < argc; ++i)
+    {
+      strcat (args, " ");
+      strcat (args, argv[i]);
+    }
+
+  SetConsoleCtrlHandler (NULL, 0);
+  ret = CreateProcess (0,
+                       args,    /* command line */
+                       NULL,    /* Security */
+                       NULL,    /* thread */
+                       TRUE,    /* inherit handles */
+                       flags,   /* start flags */
+                       NULL,
+                       NULL,    /* current directory */
+                       &si,
+                       &pi);
+  if (!ret)
+    return FALSE;
+
+  process_id = pi.dwProcessId;
+
+  return TRUE;
+}
+
+int
+child_process::check_state ()
+{
+  static DEBUG_EVENT ev;
+
+#if 0
+  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);
+#endif
+
+  if (!WaitForDebugEvent (&ev, 1000))
+    return 0;
+
+  /* found an event */
+
+  cur_process_id = ev.dwProcessId;
+  cur_thread_id = ev.dwThreadId;
+
+  fetch_regs ();
+
+  switch (ev.dwDebugEventCode)
+    {
+    case CREATE_PROCESS_DEBUG_EVENT:
+      if (ev.dwProcessId != process_id)
+        {
+          debug ("Win32: Inferior process created\n");
+         set_break (SIGTRAP);
+         return 1;
+       }
+      else
+        debug ("Win32: A child process was created\n");
+      process_hdl = ev.u.CreateProcessInfo.hProcess;
+      threads += ev;
+      break;
+
+    case CREATE_THREAD_DEBUG_EVENT:
+      debug ("Win32: Create Thread\n");
+      if (ev.dwProcessId == process_id)
+       threads += ev;
+      break;
+
+    case LOAD_DLL_DEBUG_EVENT:
+      load_dll_event (ev);
+      break;
+
+    case UNLOAD_DLL_DEBUG_EVENT:
+      debug ("Win32: Unload DLL\n");
+      break;
+
+    case OUTPUT_DEBUG_STRING_EVENT:
+      debug ("Win32: OutputDebugString\n");
+      if (ev.dwProcessId == process_id
+          && win32_output_debug_string (this, ev))
+       return 1;
+      break;
+
+    case EXIT_PROCESS_DEBUG_EVENT:
+      if (ev.dwProcessId == process_id)
+        {
+          debug ("Win32: Inferior exited with retcode = %d\n",
+                          ev.u.ExitProcess.dwExitCode);
+         set_exit (ev.u.ExitProcess.dwExitCode);
+         return 1;
+       }
+      else
+        debug ("Win32: Some child exited with retcode = %d\n",
+                        ev.u.ExitProcess.dwExitCode);
+      break;
+
+    case EXIT_THREAD_DEBUG_EVENT:
+      debug ("Win32: Thread exited with retcode = %d\n",
+              ev.u.ExitThread.dwExitCode);
+      threads -= ev;
+      /* What to return??? */
+      break;
+
+    case EXCEPTION_DEBUG_EVENT:
+      handle_exception (ev);
+      return 1;
+    }
+
+  if (!resume_program (FALSE))
+    {
+      set_term (SIGILL);
+      return 1;
+    }
+  return 0;
+}
+
+void
+child_process::fromtarget_break ()
+{
+  debug ("Win32: from_target break\n");
+  gdbserv_fromtarget_break (serv, stop_signal ());
+}
+
+void
+child_process::fromtarget_exit ()
+{
+  debug ("Win32: from_target exit\n");
+  gdbserv_fromtarget_exit (serv, exit_code ());
+}
+
+void
+child_process::fromtarget_terminate ()
+{
+  debug ("Win32: from_target terminate\n");
+  gdbserv_fromtarget_terminate (serv, term_signal ());
+}
+
diff --git a/rda/win32/config.in b/rda/win32/config.in
new file mode 100644 (file)
index 0000000..2291aec
--- /dev/null
@@ -0,0 +1,32 @@
+/* config.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
+/* Define if system has <alloca.h> */
+#undef HAVE_ALLOCA_H
+
+/* Define if system has <errno.h> */
+#undef HAVE_ERRNO_H
+
+/* Define if system has <signal.h> */
+#undef HAVE_SIGNAL_H
+
+/* Define if system has <string.h> */
+#undef HAVE_STRING_H
+
+/* Define if system has <strings.h> */
+#undef HAVE_STRINGS_H
+
+/* Define if system has <sys/wait.h> */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if system has <windows.h> */
+#undef HAVE_WINDOWS_H
+
+/* Define if target is Win32 */
+#undef WIN32_TARGET
+
diff --git a/rda/win32/configure b/rda/win32/configure
new file mode 100755 (executable)
index 0000000..cac1014
--- /dev/null
@@ -0,0 +1,2569 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --enable-maintainer-mode enable make rules and dependencies not useful
+                          (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+  --enable-shared[=PKGS]  build shared libraries [default=yes]"
+ac_help="$ac_help
+  --enable-static[=PKGS]  build static libraries [default=yes]"
+ac_help="$ac_help
+  --enable-fast-install[=PKGS]  optimize for fast installation [default=yes]"
+ac_help="$ac_help
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+  --disable-libtool-lock  avoid locking (might break parallel builds)"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"     "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=server.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='       '
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+#    configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+#    same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+#    as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:585: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:606: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+  case $nonopt in
+  NONE) target_alias=$host_alias ;;
+  *) target_alias=$nonopt ;;
+  esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:624: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+  case $nonopt in
+  NONE) build_alias=$host_alias ;;
+  *) build_alias=$nonopt ;;
+  esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+  test "$program_prefix$program_suffix$program_transform_name" = \
+    NONENONEs,x,x, &&
+  program_prefix=${target_alias}-
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:658: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS=        }"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+         if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+           # AIX install.  It has an incompatible calling convention.
+           :
+         else
+           ac_cv_path_install="$ac_dir/$ac_prog -c"
+           break 2
+         fi
+       fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:711: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftestfile`
+   fi
+   if test "$*" != "X $srcdir/configure conftestfile" \
+      && test "$*" != "X conftestfile $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { echo "configure: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+   fi
+
+   test "$2" = conftestfile
+   )
+then
+   # Ok.
+   :
+else
+   { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+  program_transform_name=
+else
+  # Double any \ or $.  echo might interpret backslashes.
+  cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+  rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:768: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+       @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=rda
+
+VERSION=0.1
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+  { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:814: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+   ACLOCAL=aclocal
+   echo "$ac_t""found" 1>&6
+else
+   ACLOCAL="$missing_dir/missing aclocal"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:827: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+   AUTOCONF=autoconf
+   echo "$ac_t""found" 1>&6
+else
+   AUTOCONF="$missing_dir/missing autoconf"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:840: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+   AUTOMAKE=automake
+   echo "$ac_t""found" 1>&6
+else
+   AUTOMAKE="$missing_dir/missing automake"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:853: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+   AUTOHEADER=autoheader
+   echo "$ac_t""found" 1>&6
+else
+   AUTOHEADER="$missing_dir/missing autoheader"
+   echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:866: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf.  Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+   MAKEINFO=makeinfo
+   echo "$ac_t""found" 1>&6
+else
+   MAKEINFO="$missing_dir/missing makeinfo"
+   echo "$ac_t""missing" 1>&6
+fi
+
+
+
+
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:884: checking whether to enable maintainer-specific portions of Makefiles" >&5
+    # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+  enableval="$enable_maintainer_mode"
+  USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+  
+
+if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+  MAINT=$MAINTAINER_MODE_TRUE
+  
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+  enable_shared=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_shared=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+  enableval="$enable_static"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+  enable_static=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_static=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+  enableval="$enable_fast_install"
+  p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+  enable_fast_install=no
+  # Look at the argument we got.  We use all the common list separators.
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+  for pkg in $enableval; do
+    if test "X$pkg" = "X$p"; then
+      enable_fast_install=yes
+    fi
+  done
+  IFS="$ac_save_ifs"
+  ;;
+esac
+else
+  enable_fast_install=yes
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:978: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1008: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1038: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+       continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1089: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1121: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1132 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1137: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1163: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1168: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1177: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1196: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+  withval="$with_gnu_ld"
+  test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1239: checking for ld used by GCC" >&5
+  ac_prog=`($CC -print-prog-name=ld) 2>&5`
+  case "$ac_prog" in
+    # Accept absolute paths.
+    [\\/]* | [A-Za-z]:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the path of ld
+      ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+      while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+       ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1263: checking for GNU ld" >&5
+else
+  echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1266: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -z "$LD"; then
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      ac_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some GNU ld's only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+       test "$with_gnu_ld" != no && break
+      else
+       test "$with_gnu_ld" != yes && break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+else
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1301: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+  ac_cv_prog_gnu_ld=yes
+else
+  ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1317: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  ac_cv_path_NM="$NM"
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+  for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+      # Check to see if the nm accepts a BSD-compat flag.
+      # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+      #   nm: unknown option "B" ignored
+      if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -B"
+       break
+      elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+       ac_cv_path_NM="$ac_dir/nm -p"
+       break
+      else
+       ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+       continue # so that we can try to find one that supports BSD flags
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1353: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+  enableval="$enable_libtool_lock"
+  :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 1402 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:1403: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      LD="${LD-ld} -32"
+      ;;
+    *N32*)
+      LD="${LD-ld} -n32"
+      ;;
+    *64-bit*)
+      LD="${LD-ld} -64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1424: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1429 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool.  ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:1538: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1543 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:1554: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_cygwin=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:1571: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1576 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:1583: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_mingw32=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:1602: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+  ac_cv_exeext=.exe
+else
+  rm -f conftest*
+  echo 'int main () { return 0; }' > conftest.$ac_ext
+  ac_cv_exeext=
+  if { (eval echo configure:1612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+    for file in conftest.*; do
+      case $file in
+      *.c | *.o | *.obj) ;;
+      *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+      esac
+    done
+  else
+    { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+  fi
+  rm -f conftest*
+  test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+for ac_prog in $CCC c++ g++ gcc CC cxx cc++ cl
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1644: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CXX="$ac_prog"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CXX="$ac_cv_prog_CXX"
+if test -n "$CXX"; then
+  echo "$ac_t""$CXX" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+test -n "$CXX" && break
+done
+test -n "$CXX" || CXX="gcc"
+
+
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1676: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5
+
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1687 "configure"
+#include "confdefs.h"
+
+int main(){return(0);}
+EOF
+if { (eval echo configure:1692: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cxx_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cxx_cross=no
+  else
+    ac_cv_prog_cxx_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cxx_works=no
+fi
+rm -fr conftest*
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
+if test $ac_cv_prog_cxx_works = no; then
+  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1718: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
+cross_compiling=$ac_cv_prog_cxx_cross
+
+echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
+echo "configure:1723: checking whether we are using GNU C++" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.C <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1732: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gxx=yes
+else
+  ac_cv_prog_gxx=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gxx" 1>&6
+
+if test $ac_cv_prog_gxx = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+
+ac_test_CXXFLAGS="${CXXFLAGS+set}"
+ac_save_CXXFLAGS="$CXXFLAGS"
+CXXFLAGS=
+echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
+echo "configure:1751: checking whether ${CXX-g++} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.cc
+if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
+  ac_cv_prog_cxx_g=yes
+else
+  ac_cv_prog_cxx_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS="$ac_save_CXXFLAGS"
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+
+for ac_declaration in \
+   ''\
+   '#include <stdlib.h>' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat > conftest.$ac_ext <<EOF
+#line 1792 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+$ac_declaration
+int main() {
+exit (42);
+; return 0; }
+EOF
+if { (eval echo configure:1800: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  continue
+fi
+rm -f conftest*
+  cat > conftest.$ac_ext <<EOF
+#line 1810 "configure"
+#include "confdefs.h"
+$ac_declaration
+int main() {
+exit (42);
+; return 0; }
+EOF
+if { (eval echo configure:1817: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  break
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+
+
+echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6
+echo "configure:1835: checking how to run the C++ preprocessor" >&5
+if test -z "$CXXCPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+  CXXCPP="${CXX-g++} -E"
+  cat > conftest.$ac_ext <<EOF
+#line 1848 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1853: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CXXCPP=/lib/cpp
+fi
+rm -f conftest*
+  ac_cv_prog_CXXCPP="$CXXCPP"
+ac_ext=C
+# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cxx_cross
+fi
+fi
+CXXCPP="$ac_cv_prog_CXXCPP"
+echo "$ac_t""$CXXCPP" 1>&6
+
+for ac_hdr in errno.h string.h strings.h windows.h sys/cygwin.h sys/wait.h 
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1881: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1886 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1891: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
+echo "configure:1921: checking for working alloca.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1926 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if { (eval echo configure:1933: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_header_alloca_h=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6
+if test $ac_cv_header_alloca_h = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&6
+echo "configure:1954: checking for alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1959 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  if HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int main() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if { (eval echo configure:1987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  ac_cv_func_alloca_works=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_func_alloca_works=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6
+if test $ac_cv_func_alloca_works = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca_works = no; then
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+  # that cause trouble.  Some versions do not even contain alloca or
+  # contain a buggy version.  If you still want to use their alloca,
+  # use ar to extract alloca.o from them instead of compiling alloca.c.
+  ALLOCA=alloca.${ac_objext}
+  cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
+echo "configure:2019: checking whether alloca needs Cray hooks" >&5
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2024 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "webecray" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_os_cray=yes
+else
+  rm -rf conftest*
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_os_cray" 1>&6
+if test $ac_cv_os_cray = yes; then
+for ac_func in _getb67 GETB67 getb67; do
+  echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2049: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2054 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2080: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  cat >> confdefs.h <<EOF
+#define CRAY_STACKSEG_END $ac_func
+EOF
+
+  break
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+done
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
+echo "configure:2107: checking stack direction for C alloca" >&5
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_c_stack_direction=0
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2115 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+  exit (find_stack_direction() < 0);
+}
+EOF
+if { (eval echo configure:2134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_c_stack_direction=1
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_c_stack_direction=-1
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+
+case "$target" in
+  *cygwin*) TARGET_MODULES="win32-target.o win32-strace.o child_process.o" ;;
+esac
+
+
+case "$target" in
+  *cygwin*)
+        cat >> confdefs.h <<\EOF
+#define WIN32_TARGET 1
+EOF
+
+    ;;
+esac
+
+if test -f /usr/include/foo.h; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_AC_DEFINE 1
+EOF
+
+fi
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[        ]*VPATH[        ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@RANLIB@%$RANLIB%g
+s%@CC@%$CC%g
+s%@LN_S@%$LN_S%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@EXEEXT@%$EXEEXT%g
+s%@CXX@%$CXX%g
+s%@CXXCPP@%$CXXCPP%g
+s%@ALLOCA@%$ALLOCA%g
+s%@TARGET_MODULES@%$TARGET_MODULES%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([  ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='\([     ][      ]*\)[^  ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_uB='\([     ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="config.h:config.in"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[   ]*#[    ]*undef[        ][      ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
+
diff --git a/rda/win32/configure.in b/rda/win32/configure.in
new file mode 100644 (file)
index 0000000..22f2eea
--- /dev/null
@@ -0,0 +1,38 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(server.h)
+AC_CANONICAL_SYSTEM
+AM_INIT_AUTOMAKE(rda,0.1)
+AM_CONFIG_HEADER(config.h:config.in)
+
+dnl automake support
+AM_MAINTAINER_MODE
+AM_PROG_LIBTOOL
+AC_EXEEXT
+AC_LANG_CPLUSPLUS
+AC_PROG_CXX
+
+dnl headers
+AC_CHECK_HEADERS(errno.h string.h strings.h windows.h sys/cygwin.h sys/wait.h )
+
+AC_FUNC_ALLOCA
+
+case "$target" in
+  *cygwin*) TARGET_MODULES="win32-target.o win32-strace.o child_process.o" ;;
+esac
+AC_SUBST(TARGET_MODULES)
+
+case "$target" in
+  *cygwin*)
+    dnl FIXME: differentiate between flavors of Solaris!
+    AC_DEFINE(WIN32_TARGET)
+    ;;
+esac
+
+if test -f /usr/include/foo.h; then
+  AC_DEFINE(HAVE_AC_DEFINE, 1, [define if have AC_DEFINE])
+fi
+
+dnl Outputs
+AC_OUTPUT(Makefile)
+
+
diff --git a/rda/win32/server.cc b/rda/win32/server.cc
new file mode 100644 (file)
index 0000000..b812984
--- /dev/null
@@ -0,0 +1,144 @@
+/* server.cc
+
+   Copyright 2000, 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 "config.h"
+
+#include <stdio.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#if !HAVE_WINDOWS_H
+#error The windows.h header is required when compiling for a Win32 target.
+#endif
+#include <windows.h>
+
+#include "server.h"
+
+int usage (const char *name)
+{
+  fprintf (stderr, "Usage: %s [OPTIONS]... program [args]...\n", name);
+  fprintf (stderr, "Options:\n");
+  fprintf (stderr, "  -c            create new console for child process.\n");
+  fprintf (stderr, "  -D            debug RDA.\n");
+  fprintf (stderr, "  -d            allow debug output from child process.\n");
+  fprintf (stderr, "  -g            start child in new process group.\n");
+  fprintf (stderr, "  -p portno     listen on port `portno' [def. 2345].\n");
+  fprintf (stderr, "  -t            allow trace output as by `strace(1)'.\n");
+  fprintf (stderr, "  -m hex_mask   trace mask when `-t' is set [def. 1].\n");
+  return 1;
+}
+
+int
+main (int argc, char **argv)
+{
+  int portno = 2345;
+  int c;
+
+  child_process *process = new child_process;
+
+  if (getenv ("GDBSERVER_DEBUG_BACKEND") != NULL)
+    process->set_debug ();
+
+  // Process options
+  while ((c = getopt (argc, argv, "cdDgm:p:t")) != EOF)
+    switch (c)
+      {
+      case 'c':
+        process->new_console = TRUE;
+       break;
+
+      case 'd':
+        process->set_debug_process ();
+       break;
+
+      case 'D':
+        process->set_debug ();
+       break;
+
+      case 'g':
+        process->new_group = TRUE;
+       break;
+
+      case 'p':
+        portno = atoi (optarg);
+       if (portno < 0 || portno > 65535)
+         {
+           fprintf (stderr, "%s: Illegal portno.\n", argv[0]);
+           return usage (argv[0]);
+          }
+        break;
+
+      case 't':
+        process->set_trace ();
+       break;
+
+      case 'm':
+        process->set_trace (strtoul (optarg, NULL, 16));
+       break;
+
+      default:
+        return usage (argv[0]);
+      }
+
+  if (optind < argc)
+    {
+      process->argc       = argc - optind;
+      process->argv       = &argv[optind];
+      process->executable =  argv[optind];
+    }
+  else
+    {
+      fprintf (stderr, "%s: No target process specified.\n", argv[0]);
+      return usage (argv[0]);
+    }
+
+  gdbsocket_startup (portno, win32_attach, process);
+  printf ("Started listening socket on port %d.\n", portno);
+
+  /* Poll for socket traffic. */
+  while (! process->quit_server ())
+    {
+      gdbloop_poll (0 /* second */);
+      if (process->check_state ())
+       {
+         switch (process->status ())
+           {
+           case Break:
+             process->fromtarget_break ();
+             break;
+           case Terminate:
+             process->fromtarget_terminate ();
+             break;
+           case Exit:
+             process->fromtarget_exit ();
+             break;
+           }
+       }
+    }
+  gdbsocket_shutdown ();
+  printf ("Shut down sockets.\n");
+
+  return 0;
+}
diff --git a/rda/win32/server.h b/rda/win32/server.h
new file mode 100644 (file)
index 0000000..a3ef8e7
--- /dev/null
@@ -0,0 +1,352 @@
+/* server.h
+
+   Copyright 2000, 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.  */
+
+extern "C" {
+#include "gdbserv.h" 
+#include "gdbserv-target.h" 
+#include "gdbserv-utils.h"
+#include "gdbsocket.h"
+#include "gdbloop.h"
+};
+
+/* Various possibilities for alloca.  */
+#ifndef alloca
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* Not GNU C */
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#else
+#ifdef _AIX
+#pragma alloca
+#else
+
+/* We need to be careful not to declare this in a way which conflicts with
+   bison.  Bison never declares it as char *, but under various circumstances
+   (like __hpux) we need to use void *.  */
+extern void *alloca ();
+#endif /* Not _AIX */
+#endif /* Not HAVE_ALLOCA_H */
+#endif /* Not GNU C */
+#endif /* alloca not defined */
+
+/* Sequence of bytes for breakpoint instruction.  */
+#define SIZEOF_BP  1
+#define BREAKPOINT {0xcc}
+
+#define FLAG_TRACE_BIT 0x100
+
+enum proc_state {
+  Running,
+  Break,
+  Exit,
+  Terminate
+};
+
+class breakpoint {
+  BOOL  used;
+  DWORD bp_address;
+  char  bp_instruction[SIZEOF_BP];
+
+public:
+  breakpoint () : used (FALSE), bp_address(0)
+    {
+      memset (bp_instruction, 0, SIZEOF_BP);
+    }
+  breakpoint (DWORD naddress, char *nbp_inst)
+  : used (TRUE), bp_address(naddress)
+    {
+      memcpy (bp_instruction, nbp_inst, SIZEOF_BP);
+    }
+  virtual ~breakpoint () {}
+
+  BOOL in_use () const { return used; }
+  DWORD address () const { return used ? bp_address : 0L; }
+  const char *instruction () const { return used ? bp_instruction : NULL; }
+  operator DWORD() const { return used ? bp_address : 0L; }
+
+  void set_in_use (BOOL nin_use) { used = nin_use; }
+};
+
+class bp_array {
+  breakpoint  *bp;
+  int          max_cnt;
+  int          cur_cnt;
+
+public:
+  bp_array () : bp (NULL), max_cnt (0), cur_cnt (0) {}
+  virtual ~bp_array () {}
+
+  int add (breakpoint &new_bp)
+    {
+      for (int i = 0; i < cur_cnt; ++i)
+       if (new_bp.address () == bp[i].address ())
+         return i;
+      if (cur_cnt == max_cnt)
+       {
+         breakpoint *tmp = (breakpoint *)
+                       realloc (bp, (max_cnt += 5) * sizeof (breakpoint));
+          if (!tmp)
+           return -1;
+         bp = tmp;
+        }
+      bp[cur_cnt] = new_bp;
+      return cur_cnt++;
+    }
+  int add (DWORD address, char *instruction)
+    {
+      breakpoint new_bp (address, instruction);
+      return add (new_bp);
+    }
+  BOOL remove (DWORD address)
+    {
+      for (int i = 0; i < cur_cnt; ++i)
+        if (bp[i].address () == address && bp[i].in_use ())
+         {
+           bp[i].set_in_use (FALSE);
+           return TRUE;
+         }
+      return FALSE;
+    }
+  BOOL remove (int bp_id)
+    {
+      if (bp_id >= cur_cnt || !bp[bp_id].in_use ())
+        return FALSE;
+      bp[bp_id].set_in_use (FALSE);
+      return TRUE;
+    }
+  const char *instruction (DWORD address) const
+    {
+      for (int i = 0; i < cur_cnt; ++i)
+        if (bp[i].address () == address)
+         return bp[i].instruction ();
+      return NULL;
+    }
+
+  void operator +=(breakpoint &new_bp) { add (new_bp); }
+  void operator -=(DWORD address) { remove (address); }
+  const char *operator [](DWORD address) const { return instruction (address); }
+};
+
+class thread_slot {
+  BOOL                    used;
+  DWORD                           id;
+  CREATE_THREAD_DEBUG_INFO info;
+
+public:
+  thread_slot () : used (FALSE), id (0) {}
+  thread_slot (DEBUG_EVENT &ev)
+    {
+      used = TRUE;
+      id = ev.dwThreadId;
+      switch (ev.dwDebugEventCode)
+        {
+       case CREATE_THREAD_DEBUG_EVENT:
+         info = ev.u.CreateThread;
+         break;
+       case CREATE_PROCESS_DEBUG_EVENT:
+         info.hThread = ev.u.CreateProcessInfo.hThread;
+         info.lpThreadLocalBase = ev.u.CreateProcessInfo.lpThreadLocalBase;
+         info.lpStartAddress = ev.u.CreateProcessInfo.lpStartAddress;
+         break;
+       default:
+         used = 0;
+         break;
+       }
+    }
+  virtual ~thread_slot () {}
+
+  BOOL in_use () { return used; }
+  DWORD get_id () { return id; }
+  HANDLE get_hdl () { return info.hThread; }
+
+  void set_in_use (BOOL nin_use) { used = nin_use; }
+};
+
+class thread_array {
+  thread_slot *thread;
+  int          max_cnt;
+  int          cur_cnt;
+
+public:
+  thread_array () : thread (NULL), max_cnt (0), cur_cnt (0) {}
+  virtual ~thread_array () {}
+
+  BOOL add (thread_slot &new_slot)
+    {
+      if (cur_cnt == max_cnt)
+       {
+         thread_slot *tmp = (thread_slot *)
+                       realloc (thread, (max_cnt += 5) * sizeof (thread_slot));
+          if (!tmp)
+           return FALSE;
+         thread = tmp;
+        }
+      thread[cur_cnt++] = new_slot;
+      return TRUE;
+    }
+  BOOL add (DEBUG_EVENT &ev)
+    {
+      thread_slot new_slot (ev);
+      return add (new_slot);
+    }
+  BOOL remove (DWORD thread_id)
+    {
+      for (int i = 0; i < cur_cnt; ++i)
+        if (thread[i].get_id () == thread_id)
+         {
+           memcpy (thread + i, thread + i + 1,
+                   (cur_cnt - i - 1) * sizeof (thread_slot));
+           --cur_cnt;
+           return TRUE;
+         }
+      return FALSE;
+    }
+  BOOL remove (DEBUG_EVENT &ev)
+    {
+      if (ev.dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT)
+        return remove (ev.dwThreadId);
+      return FALSE;
+    }
+  HANDLE get_hdl (DWORD thread_id)
+    {
+      for (int i = 0; i < cur_cnt; ++i)
+        if (thread[i].get_id () == thread_id)
+         return thread[i].get_hdl ();
+      return INVALID_HANDLE_VALUE;
+    }
+  DWORD get_id (HANDLE thread_hdl)
+    {
+      for (int i = 0; i < cur_cnt; ++i)
+        if (thread[i].get_hdl () == thread_hdl)
+         return thread[i].get_id ();
+      return 0L;
+    }
+
+  void operator +=(thread_slot &new_slot) { add (new_slot); }
+  void operator +=(DEBUG_EVENT &ev) { add (ev); }
+  void operator -=(DWORD thread_id) { remove (thread_id); }
+  void operator -=(DEBUG_EVENT &ev) { remove (ev); }
+  HANDLE operator [](DWORD thread_id) { get_hdl (thread_id); }
+  DWORD operator [](HANDLE thread_hdl) { get_id (thread_hdl); }
+};
+
+class child_process {
+  BOOL            debug_backend;
+  BOOL            debug_child;
+  DWORD           trace_child;
+  proc_state      stop_status;
+  int             stop_sig;
+  BOOL            server_quit_p;
+
+public:
+  struct gdbserv *serv;
+  char           *executable;
+  int             argc;
+  char          **argv;
+  BOOL            new_group;
+  BOOL            new_console;
+  DWORD           process_id;
+  HANDLE         process_hdl;
+  DWORD           cur_process_id;
+  DWORD           cur_thread_id;
+  thread_array    threads;
+  bp_array       breakpoints;
+  CONTEXT         context;
+  int             suspend_cnt;
+  long            signal_to_send;
+
+  int             saw_stars;
+  char            nfields;
+  long long       start_time;
+  DWORD           last_usecs;
+
+  child_process () 
+  : serv (NULL),
+    executable (NULL),
+    argc (0),
+    argv (NULL),
+    new_group (FALSE),
+    new_console (FALSE),
+    process_id (0),
+    cur_process_id (0),
+    cur_thread_id (0),
+    suspend_cnt (0),
+    signal_to_send (0),
+    debug_backend (FALSE),
+    debug_child (FALSE),
+    trace_child (0),
+    stop_status (Running),
+    stop_sig (0),
+    server_quit_p (FALSE),
+    saw_stars (0),
+    nfields (0),
+    start_time (0),
+    last_usecs (0)
+    {
+      memset (&context, 0, sizeof context);
+    }
+
+  void set_debug (BOOL ndebug = TRUE) { debug_backend = ndebug ? TRUE : FALSE; }
+  BOOL debug () const { return debug_backend; }
+  void debug (const char *format, ...);
+
+  void set_debug_process (BOOL ndebug = TRUE)
+                                     { debug_child = ndebug ? TRUE : FALSE; }
+  int debug_process () const { return debug_child; }
+
+  void set_trace (DWORD ntrace = 1) { trace_child = ntrace; }
+  DWORD trace () const { return trace_child; }
+
+  void set_running ()           { stop_status = Running; stop_sig = 0; }
+  void set_break (int nsignal)  { stop_status = Break; stop_sig = nsignal; }
+  void set_exit (int nexitcode) { stop_status = Exit; stop_sig = nexitcode; }
+  void set_term (int nsignal)   { stop_status = Terminate; stop_sig = nsignal;}
+
+  proc_state status () const { return stop_status; }
+  int stop_signal () const { return stop_sig; }
+  int term_signal () const { return stop_sig; }
+  int exit_code () const { return stop_sig; }
+
+  void quit_server (BOOL quit) { server_quit_p = quit ? TRUE : FALSE; }
+  BOOL quit_server () const { return server_quit_p; }
+
+  void handle_exception (DEBUG_EVENT &ev);
+  void fetch_regs ();
+  void store_regs ();
+  BOOL resume_program (BOOL step);
+  void load_dll_event (DEBUG_EVENT &ev);
+  BOOL create_child ();
+
+  int check_state ();
+  void fromtarget_break ();
+  void fromtarget_exit ();
+  void fromtarget_terminate ();
+};
+
+/* win32-strace.cc */
+extern int win32_output_debug_string (child_process *, DEBUG_EVENT &);
+
+/* win32-target.cc */
+extern "C" struct gdbserv_target *win32_attach (struct gdbserv *, void *);
diff --git a/rda/win32/stamp-h.in b/rda/win32/stamp-h.in
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/rda/win32/win32-strace.cc b/rda/win32/win32-strace.cc
new file mode 100644 (file)
index 0000000..4151b9e
--- /dev/null
@@ -0,0 +1,273 @@
+/* win32-strace.cc
+
+   Copyright 2000, 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 "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/strace.h>
+
+#if !HAVE_WINDOWS_H
+#error The windows.h header is required when compiling for a Win32 target.
+#endif
+#include <windows.h>
+#include <sys/cygwin.h>
+
+#include "server.h"
+
+static int
+output_winerror (FILE *ofile, char *s)
+{
+  char *winerr = strstr (s, "Win32 error ");
+  if (!winerr)
+    return 0;
+
+  DWORD errnum = atoi (winerr + sizeof ("Win32 error ") - 1);
+  if (!errnum)
+    return 0;
+
+  /*
+   * NOTE: Currently there is no policy for how long the
+   * the buffers are, and looks like 256 is a smallest one
+   * (dlfcn.cc). Other than error 1395 (length 213) and
+   * error 1015 (length 249), the rest are all under 188
+   * characters, and so I'll use 189 as the buffer length.
+   * For those longer error messages, FormatMessage will
+   * return FALSE, and we'll get the old behaviour such as
+   * ``Win32 error 1395'' etc.
+   */
+  char buf[4096];
+  if (!FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
+                     | FORMAT_MESSAGE_IGNORE_INSERTS,
+                     NULL,
+                     errnum,
+                     MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
+                     (LPTSTR) buf, sizeof (buf), NULL))
+    return 0;
+
+  /* Get rid the trailing CR/NL pair. */
+  char *p = strchr (buf, '\0');
+  p[-2] = '\n';
+  p[-1] = '\0';
+
+  *winerr = '\0';
+  fputs (s, ofile);
+  fputs (buf, ofile);
+  return 1;
+}
+
+static SYSTEMTIME *
+syst (long long t)
+{
+  FILETIME n;
+  static SYSTEMTIME st;
+  long long now = t + ((long long) 1/*usecs*/ * 10);
+  n.dwHighDateTime = now >> 32;
+  n.dwLowDateTime = now & 0xffffffff;
+  FileTimeToSystemTime (&n, &st);
+  return &st;
+}
+
+#define CYGWIN_SIGNAL_STRING "cygwin: signal"
+#define INTROLEN (3 + 8)
+
+int
+win32_output_debug_string (child_process *process, DEBUG_EVENT &ev)
+{
+  /* This includes the terminating null character already. */
+  DWORD size = ev.u.DebugString.nDebugStringLength;
+  BOOL unicode = ev.u.DebugString.fUnicode;
+
+  char *s = (char *) alloca (unicode ? 2 * size : size);
+
+  if (!ReadProcessMemory (process->process_hdl,
+                         ev.u.DebugString.lpDebugStringData,
+                         s, unicode ? 2 * size : size, NULL))
+    {
+      process->debug ("\nReadProcessMemory failed with error %d\n",
+                      GetLastError ());
+      return 0;
+    }
+  if (!strncmp (s, CYGWIN_SIGNAL_STRING, sizeof CYGWIN_SIGNAL_STRING - 1))
+    {
+      /* Cygwin raised a signal. */
+      process->set_break (strtol (s + sizeof CYGWIN_SIGNAL_STRING - 1, NULL,0));
+
+      process->debug ("Win32: Cygwin raised a signal %d\n",
+                     process->stop_signal ());
+
+      return process->stop_signal ();
+    }
+
+  char *str = s;
+  if (unicode)
+    {
+      str = (char *) alloca (size);
+      WideCharToMultiByte (CP_ACP, 0, (const WCHAR *) s, -1,
+                          str, size, NULL, NULL);
+    }
+
+  if (strncmp (s, "cYg", 3) && process->debug_process ())
+    {
+      fprintf (stderr, "%s\n", s);
+      return 0;
+    }
+
+  if (!process->trace ())
+    return 0;
+
+  int len = (int) strtoul (s + 3, NULL, 16);
+  if (!len)
+    return 0;
+
+  int special;
+  if (len > 0)
+    special = 0;
+  else
+    {
+      special = len;
+      if (special == _STRACE_INTERFACE_ACTIVATE_ADDR)
+        len = 17;
+    }
+  char *buf = s + INTROLEN;
+  buf[len] = '\0';
+
+  s = strtok (buf, " ");
+
+  unsigned n = strtoul (s, NULL, 16);
+
+  s = strchr (s, '\0') + 1;
+
+  if (special == _STRACE_INTERFACE_ACTIVATE_ADDR)
+    {
+      DWORD nbytes;
+      DWORD new_flag = 1;
+      if (!WriteProcessMemory (process->process_hdl, (LPVOID) n, &new_flag,
+                               sizeof (new_flag), &nbytes))
+        process->debug ("Win32: couldn't write strace flag to child, "
+                      "windows error %d", GetLastError ());
+      return 0;
+    }
+
+  char *origs = s;
+
+  if (process->trace () & n)
+    /* got it */ ;
+  else if (!(process->trace () & _STRACE_ALL) || (n & _STRACE_NOTALL))
+    return 0;                  /* This should not be included in "all" output */
+
+  DWORD dusecs, usecs;
+  char *ptusec, *ptrest;
+
+  dusecs = strtoul (s, &ptusec, 10);
+  char *q = ptusec;
+  while (*q == ' ')
+    q++;
+  if (*q != '[')
+    {
+      usecs = strtoul (q, &ptrest, 10);
+      while (*ptrest == ' ')
+       ptrest++;
+    }
+  else
+    {
+      ptrest = q;
+      ptusec = s;
+      usecs = dusecs;
+    }
+
+  if (process->saw_stars == 0)
+    {
+      FILETIME st;
+      char *news;
+
+      GetSystemTimeAsFileTime (&st);
+      FileTimeToLocalFileTime (&st, &st);
+      process->start_time = st.dwHighDateTime;
+      process->start_time <<= 32;
+      process->start_time |= st.dwLowDateTime;
+      if (*(news = ptrest) != '[')
+       process->saw_stars = 2;
+      else
+       {
+         process->saw_stars++;
+         while ((news = strchr (news, ' ')) != NULL && *++news != '*')
+           process->nfields++;
+         if (news == NULL)
+           process->saw_stars++;
+         else
+           {
+             s = news;
+             process->nfields++;
+           }
+       }
+    }
+  else if (process->saw_stars < 2)
+    {
+      int i;
+      char *news;
+      if (*(news = ptrest) != '[')
+       process->saw_stars = 2;
+      else
+       {
+         for (i = 0; i < process->nfields; i++)
+           if ((news = strchr (news, ' ')) == NULL)
+             break;            // Should never happen
+           else
+             news++;
+
+         if (news == NULL)
+           process->saw_stars = 2;
+         else
+           {
+             s = news;
+             if (*s == '*')
+               {
+                 SYSTEMTIME *st = syst (process->start_time);
+                 fprintf (stderr,
+                          "Date/Time:    %d-%02d-%02d %02d:%02d:%02d\n",
+                          st->wYear, st->wMonth, st->wDay, st->wHour,
+                          st->wMinute, st->wSecond);
+                 process->saw_stars++;
+               }
+           }
+       }
+    }
+
+  long long d = usecs - process->last_usecs;
+  char intbuf[40];
+
+  s = ptusec;
+  sprintf (intbuf, "%5d ", (int) d);
+  len = strlen (intbuf);
+
+  memcpy ((s -= len), intbuf, len);
+
+  process->last_usecs = usecs;
+  if (!output_winerror (stderr, s))
+    fputs (s, stderr);
+
+  return 0;
+}
diff --git a/rda/win32/win32-target.cc b/rda/win32/win32-target.cc
new file mode 100644 (file)
index 0000000..048a928
--- /dev/null
@@ -0,0 +1,517 @@
+/* win32-target.cc
+
+   Copyright 2000, 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 "config.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* This is a win32 Cygwin gdbserv target that uses the RDA library to
+   implement a remote gdbserver on a Win32 host.  It controls the
+   process to be debugged on the Win32 host, allowing GDB to pull the
+   strings from any host on the network (or on a serial port).  */
+
+#if !HAVE_WINDOWS_H
+#error The windows.h header is required when compiling for a Win32 target.
+#endif
+#include <windows.h>
+#include <sys/cygwin.h>
+
+#include "server.h"
+
+/* This vector maps GDB's idea of a register's number into an address
+   in the win32 exception context vector.
+
+   It also contains the bit mask needed to load the register in question.
+
+   One day we could read a reg, we could inspect the context we
+   already have loaded, if it doesn't have the bit set that we need,
+   we read that set of registers in using GetThreadContext.  If the
+   context already contains what we need, we just unpack it. Then to
+   write a register, first we have to ensure that the context contains
+   the other regs of the group, and then we copy the info in and set
+   out bit. */
+#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
+static const int mappings[] =
+{
+  context_offset (Eax),
+  context_offset (Ecx),
+  context_offset (Edx),
+  context_offset (Ebx),
+  context_offset (Esp),
+  context_offset (Ebp),
+  context_offset (Esi),
+  context_offset (Edi),
+  context_offset (Eip),
+  context_offset (EFlags),
+  context_offset (SegCs),
+  context_offset (SegSs),
+  context_offset (SegDs),
+  context_offset (SegEs),
+  context_offset (SegFs),
+  context_offset (SegGs),
+  context_offset (FloatSave.RegisterArea[0 * 10]),
+  context_offset (FloatSave.RegisterArea[1 * 10]),
+  context_offset (FloatSave.RegisterArea[2 * 10]),
+  context_offset (FloatSave.RegisterArea[3 * 10]),
+  context_offset (FloatSave.RegisterArea[4 * 10]),
+  context_offset (FloatSave.RegisterArea[5 * 10]),
+  context_offset (FloatSave.RegisterArea[6 * 10]),
+  context_offset (FloatSave.RegisterArea[7 * 10]),
+  context_offset (FloatSave.ControlWord),
+  context_offset (FloatSave.StatusWord),
+  context_offset (FloatSave.TagWord),
+  context_offset (FloatSave.ErrorSelector),
+  context_offset (FloatSave.ErrorOffset),
+  context_offset (FloatSave.DataSelector),
+  context_offset (FloatSave.DataOffset),
+  context_offset (FloatSave.ErrorSelector)
+};
+#undef context_offset
+
+#define REG_SIZE     4
+#define FP_REG_SIZE 10
+
+#define FP_REG_0    16
+#define FP_REG_7    23
+
+#define SIZEOF_REGMAP  32
+
+#define IS_REG(x)    ((x) >= 0 && (x) <= SIZEOF_REGMAP)
+#define IS_FP_REG(x) ((x) >= FP_REG_0 && (x) <= FP_REG_7)
+
+/* Track sole connection to a remote gdb client. */
+/* FIXME: needed? */
+static struct gdbserv *win32_connect_lock = NULL;
+
+/* Retrieves the Cygwin PID which is attached to the windows PID. */
+static pid_t
+win32_get_cygwin_pid (DWORD winpid)
+{
+  external_pinfo *p;
+  cygwin_getinfo_types query = CW_GETPINFO;
+
+  cygwin_internal (CW_LOCK_PINFO, 1000);
+  for (int pid = 0;
+       (p = (external_pinfo *) cygwin_internal (query, pid | CW_NEXTPID));
+       pid = p->pid)
+    if (p->dwProcessId == winpid)
+      break;
+  cygwin_internal (CW_UNLOCK_PINFO);
+
+  return p ? p->pid : 0;
+}
+
+inline child_process *
+win32_get_process (struct gdbserv *serv)
+{
+  return (child_process *) gdbserv_target_data (serv);
+}
+
+extern "C" int
+win32_process_get_reg (struct gdbserv *serv, int regno)
+{
+  child_process *process = win32_get_process (serv);
+
+  process->fetch_regs ();
+  if (!IS_REG (regno))
+    { /* Illegal register number, return 0. */
+      DWORD regval = 0;
+      gdbserv_output_bytes (serv, (const char *) &regval, sizeof regval);
+    }
+  else
+    gdbserv_output_bytes (serv,
+                         (char *) &process->context + mappings[regno],
+                         IS_FP_REG (regno) ? FP_REG_SIZE : REG_SIZE);
+  return 0;
+}
+
+extern "C" void
+win32_process_get_regs (struct gdbserv *serv)
+{
+  int regno;
+
+  for (regno = 0; regno < SIZEOF_REGMAP; regno++)
+    win32_process_get_reg (serv, regno);
+}
+
+extern "C" int
+win32_process_set_reg (struct gdbserv *serv, int regno)
+{
+  child_process *process = win32_get_process (serv);
+
+  process->fetch_regs ();
+  if (IS_REG (regno))
+    gdbserv_input_bytes (serv,
+                        (char *) &process->context + mappings[regno],
+                        IS_FP_REG (regno) ? FP_REG_SIZE : REG_SIZE);
+  return 0;
+}
+
+extern "C" int
+win32_process_set_regs (struct gdbserv *serv)
+{
+  int regno;
+
+  for (regno = 0; regno < SIZEOF_REGMAP; regno++)
+    win32_process_set_reg (serv, regno);
+  return 0;
+}
+
+extern "C" void
+win32_process_set_pc (struct gdbserv *serv, const struct gdbserv_reg *addr)
+{
+  child_process *process = win32_get_process (serv);
+
+  process->fetch_regs ();
+  gdbserv_reg_to_ulong (serv, addr, &process->context.Eip);
+}
+
+static long
+win32_xfer_mem (struct gdbserv *serv, 
+                struct gdbserv_reg *addr, 
+                void *data, 
+                long len, 
+                int read)
+{
+  child_process *process = win32_get_process (serv);
+  DWORD tgtaddr;
+  DWORD processed = 0;
+
+  /* Get request address.  */
+  gdbserv_reg_to_ulong (serv, addr, &tgtaddr);
+
+  if (read)
+    {
+      ReadProcessMemory (process->process_hdl, (LPCVOID) tgtaddr,
+                        data, len, &processed);
+    }
+  else /* write */
+    {
+      WriteProcessMemory (process->process_hdl, (LPVOID) tgtaddr,
+                         data, len, &processed);
+      FlushInstructionCache (process->process_hdl, (LPCVOID) tgtaddr, len);
+    }
+
+  return processed;
+}
+
+extern "C" long
+win32_set_mem (struct gdbserv *serv, 
+               struct gdbserv_reg *addr, 
+               void *data, 
+               long len)
+{
+  return win32_xfer_mem (serv, addr, data, len, 0);
+}
+
+extern "C" long
+win32_get_mem (struct gdbserv *serv, 
+               struct gdbserv_reg *addr, 
+               void *data, 
+               long len)
+{
+  return win32_xfer_mem (serv, addr, data, len, 1);
+}
+
+extern "C" void
+win32_flush_i_cache (struct gdbserv *serv)
+{
+  child_process *process = win32_get_process (serv);
+
+  FlushInstructionCache (process->process_hdl, NULL, 0L);
+}
+
+/* exit program vector 
+ */
+extern "C" void
+win32_exit_program (struct gdbserv *serv)
+{ 
+  child_process *process = win32_get_process (serv);
+
+  process->debug ("Win32: KILL %d\n", process->process_id);
+
+  pid_t pid = win32_get_cygwin_pid (process->process_id);
+
+  if (pid)
+    kill (pid, SIGKILL);
+  else
+    TerminateThread (process->process_hdl, SIGKILL);
+
+  gdbserv_fromtarget_exit (serv, GDBSERV_SIGQUIT);
+}
+
+/* break program vector
+ */
+extern "C" void
+win32_break_program (struct gdbserv *serv)
+{
+  child_process *process = win32_get_process (serv);
+
+  process->debug ("Win32: Send SIGINT to child %d\n", process->process_id);
+
+  pid_t pid = win32_get_cygwin_pid (process->process_id);
+
+  if (pid)
+    kill (pid, SIGINT);
+  else
+    TerminateThread (process->process_hdl, SIGINT);
+}
+
+extern "C" void
+win32_singlestep_program (struct gdbserv *serv)
+{
+  child_process *process = win32_get_process (serv);
+
+  process->resume_program (TRUE);
+}
+
+extern "C" void
+win32_continue_program (struct gdbserv *serv)
+{
+  child_process *process = win32_get_process (serv);
+
+  process->resume_program (FALSE);
+}
+
+/* Process Rcmd vector
+ * (apparently a target-specific remote command).
+ */
+
+extern "C" void
+win32_process_rcmd (struct gdbserv *serv, const char *cmd, int cmdsize)
+{
+  child_process *process = win32_get_process (serv);
+
+  if (!strcmp (cmd, "debug"))
+    process->set_debug (TRUE);
+  else if (!strcmp (cmd, "nodebug"))
+    process->set_debug (FALSE);
+  else if (!strcmp (cmd, "debug_child"))
+    process->set_debug_process (TRUE);
+  else if (!strcmp (cmd, "nodebug_child"))
+    process->set_debug_process (FALSE);
+  else if (!strcmp (cmd, "trace"))
+    process->set_trace (FALSE);
+  else if (!strcmp (cmd, "notrace"))
+    process->set_trace (FALSE);
+}
+
+/* Set continue-signal vector 
+ */
+
+extern "C" int
+win32_process_signal (struct gdbserv *serv, int sig)
+{
+  /* This is disfunctional on Win32. */
+  return 0;
+}
+
+extern "C" unsigned long
+win32_get_trap_number (struct gdbserv *serv)
+{
+  child_process *process = win32_get_process (serv);
+
+  return process->stop_signal ();
+}
+
+/* compute signal vector
+ * No translation necessary -- using unix native signals.
+ */
+extern "C" unsigned long
+win32_compute_signal (struct gdbserv *serv, unsigned long tgtsig)
+{
+  return tgtsig;
+}
+
+/* Reset a breakpoint. */
+
+extern "C" enum gdbserv_target_rc
+win32_remove_breakpoint (struct gdbserv *serv,
+                        enum gdbserv_target_bp type,
+                         struct gdbserv_reg *addr,
+                        struct gdbserv_reg *len)
+{
+  child_process *process = win32_get_process (serv);
+  enum gdbserv_target_rc tgt_rc = GDBSERV_TARGET_RC_OK;
+  DWORD pc;
+  const char *old_instruction;
+
+  process->debug ("Win32: remove breakpoint\n");
+  switch (type)
+    {
+    case GDBSERV_TARGET_BP_SOFTWARE:
+      gdbserv_reg_to_ulong (serv, addr, &pc);
+      if (old_instruction = process->breakpoints[pc])
+        {
+         win32_set_mem (serv, addr, (void *) old_instruction, SIZEOF_BP);
+         process->breakpoints.remove (pc);
+       }
+      break;
+
+    case GDBSERV_TARGET_BP_HARDWARE:
+    case GDBSERV_TARGET_BP_WRITE:
+    case GDBSERV_TARGET_BP_READ:
+    case GDBSERV_TARGET_BP_ACCESS:
+    default:
+      tgt_rc = GDBSERV_TARGET_RC_UNKNOWN;
+      break;
+    }
+  return tgt_rc;
+}
+
+/* Set a breakpoint. */
+
+extern "C" enum gdbserv_target_rc
+win32_set_breakpoint (struct gdbserv *serv,
+                     enum gdbserv_target_bp type,
+                      struct gdbserv_reg *addr,
+                     struct gdbserv_reg *len)
+{
+  child_process *process = win32_get_process (serv);
+  enum gdbserv_target_rc tgt_rc = GDBSERV_TARGET_RC_OK;
+  DWORD pc;
+  char buf[SIZEOF_BP];
+  char bp[SIZEOF_BP] = BREAKPOINT;
+
+  process->debug ("Win32: set breakpoint\n");
+  switch (type)
+    {
+    case GDBSERV_TARGET_BP_SOFTWARE:
+      gdbserv_reg_to_ulong (serv, addr, &pc);
+      win32_get_mem (serv, addr, buf, SIZEOF_BP);
+      process->breakpoints.add (pc, buf);
+      win32_set_mem (serv, addr, bp, SIZEOF_BP);
+      break;
+
+    case GDBSERV_TARGET_BP_HARDWARE:
+    case GDBSERV_TARGET_BP_WRITE:
+    case GDBSERV_TARGET_BP_READ:
+    case GDBSERV_TARGET_BP_ACCESS:
+    default:
+      tgt_rc = GDBSERV_TARGET_RC_UNKNOWN;
+      break;
+    }
+  return tgt_rc;
+}
+
+/* Detach vector -- shut down this target connection.
+ */
+extern "C" void
+win32_detach (struct gdbserv *serv, struct gdbserv_target *target)
+{
+  assert (win32_connect_lock == serv);
+
+  child_process *process = win32_get_process (serv);
+
+  process->debug ("Win32: Detached.\n");
+  win32_connect_lock = NULL;
+
+  /* Quit out of main loop. This kills the target process on Win32 as well.  */
+  process->quit_server (TRUE);
+}
+
+/* This function is called from gdbloop_poll when a new incoming
+   connection is attempted.  It may return NULL if the new connection
+   is to be refused, or a gdbserv_target vector if the connection is
+   accepted.  */
+
+extern "C" struct gdbserv_target *
+win32_attach (struct gdbserv *serv, void *data)
+{
+  struct gdbserv_target *win32_target;
+  child_process *process = (child_process *) data;
+
+  /* Enable server tracing. */
+  /*  gdbserv_state_trace = stderr;*/
+
+  if (win32_connect_lock != NULL)
+    {
+      process->debug ("Win32: rejected duplicate connection.\n");
+      return NULL;
+    }
+
+  process->debug ("Win32: accepted gdb connection.\n");
+  win32_connect_lock = serv;
+
+  if (!process->create_child ())
+    {
+      process->debug ("Win32: Creating target process failed.\n");
+      win32_connect_lock = NULL;
+      return NULL;
+    }
+
+  win32_target = (struct gdbserv_target *)
+                       malloc (sizeof (struct gdbserv_target));
+  memset (win32_target, 0, sizeof (*win32_target));
+
+  /* Callback structure for function pointers that handle processed
+     control packets.  See gdbserv-target.h for docs on the individual
+     functions. */
+
+  win32_target->process_get_gen       = NULL;
+  win32_target->process_set_gen       = NULL;
+  win32_target->process_rcmd          = win32_process_rcmd;
+  win32_target->process_set_args      = NULL;
+  win32_target->process_set_reg       = win32_process_set_reg;
+  win32_target->process_get_reg       = win32_process_get_reg;
+  win32_target->process_set_regs      = win32_process_set_regs;
+  win32_target->process_get_regs      = win32_process_get_regs;
+  win32_target->input_reg             = NULL;
+  win32_target->output_reg            = NULL;
+  win32_target->gg_reg_nr             = NULL;
+  win32_target->expedited_reg_nr      = NULL;
+  win32_target->sizeof_reg            = NULL;
+  win32_target->set_reg               = NULL;
+  win32_target->get_reg               = NULL;
+  win32_target->get_mem               = win32_get_mem;
+  win32_target->set_mem               = win32_set_mem;
+  win32_target->process_set_pc        = win32_process_set_pc;
+  win32_target->flush_i_cache         = win32_flush_i_cache;
+  win32_target->process_signal        = win32_process_signal;
+  win32_target->compute_signal        = win32_compute_signal;
+  win32_target->get_trap_number       = win32_get_trap_number;
+  win32_target->exit_program          = win32_exit_program;
+  win32_target->break_program         = win32_break_program;
+  win32_target->reset_program         = NULL;
+  win32_target->restart_program       = NULL;
+  win32_target->singlestep_program    = win32_singlestep_program;
+  win32_target->cyclestep_program     = NULL;
+  win32_target->sigkill_program       = NULL;
+  win32_target->continue_program      = win32_continue_program;
+  win32_target->remove_breakpoint     = win32_remove_breakpoint;
+  win32_target->set_breakpoint        = win32_set_breakpoint;
+  win32_target->process_target_packet = NULL;
+  win32_target->detach                = win32_detach;
+
+  win32_target->data = data;
+  process->serv = serv;
+  return win32_target;
+}