This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 07/18] remote-wtxapi: The WTX API abstraction layer.


This provides an API torwards for the WTX protocol which is stable
across versions of WTX. The implementation is a thin binding over
the wtx API provided by WindRiver.

gdb/ChangeLog:

        * remote-wtxapi.h, remote-wtxapi.c: New files.
---
 gdb/remote-wtxapi.c | 3027 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/remote-wtxapi.h | 1221 +++++++++++++++++++++
 2 files changed, 4248 insertions(+), 0 deletions(-)
 create mode 100644 gdb/remote-wtxapi.c
 create mode 100644 gdb/remote-wtxapi.h

diff --git a/gdb/remote-wtxapi.c b/gdb/remote-wtxapi.c
new file mode 100644
index 0000000..54e6e4f
--- /dev/null
+++ b/gdb/remote-wtxapi.c
@@ -0,0 +1,3027 @@
+/* Thin binding for the WTX protocol, for GDB.
+
+   Copyright 2004, 2010, 2011 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "gdb_string.h"
+#include "remote-wtxapi.h"
+#include "gdb_assert.h"
+#include "remote-wtx-utils.h"
+#include "remote-wtx-opt.h"
+
+/* This layer is only implemented and tested on WTX 2.0, 3.0 and 4.0.  */
+
+#if WTX_PROT_VERSION != 2 && WTX_PROT_VERSION != 3 && WTX_PROT_VERSION != 4
+#error
+#endif
+
+/* In WTX 4.0, the context-related functions take a WTX_CONTEXT * as
+   parameter; In previous versions, it was a WTX_CONTEXT_ID_T and a
+   WTX_CONTEXT_TYPE.  The following macros are a klugde to fix that.
+   FIXME: The good method is probably to change the specs of the
+   corresponding functions in remote-wtxapi.  */
+static void initialize_context (WTX_CONTEXT * context,
+                                WTX_CONTEXT_TYPE context_type,
+                                WTX_CONTEXT_ID_T context_id);
+
+#if WTX_PROT_VERSION > 3
+#define MARSHALL_WTX_CONTEXT_PARAM(context) &context
+#else
+#define MARSHALL_WTX_CONTEXT_PARAM(context) \
+  context.contextType, context.contextId
+#endif
+
+#if WTX_PROT_VERSION != 2
+typedef WTX_EVTPT_LIST wtx_evtpt_list;
+#else
+typedef WTX_EVTPT_LIST_2 wtx_evtpt_list;
+#endif
+
+#if WTX_PROT_VERSION != 2
+typedef WTX_MODULE_INFO wtx_module_info;
+#else
+typedef WTX_LD_M_FILE_DESC wtx_module_info;
+#endif
+
+static STATUS (*wtx_initialize) ();
+static STATUS (*wtx_terminate) ();
+static WTX_DESC_Q *(*wtx_info_q) ();
+static STATUS (*wtx_tool_attach) ();
+static int (*wtx_tool_connected) ();
+static STATUS (*wtx_tool_detach) ();
+static STATUS (*wtx_err_clear) ();
+static WTX_ERROR_T (*wtx_err_get) ();
+static WTX_HANDLER_T (*wtx_err_handler_add) ();
+static STATUS (*wtx_err_handler_remove) ();
+static char * (*wtx_err_msg_get) ();
+static WTX_AGENT_MODE_TYPE (*wtx_agent_mode_get) ();
+static STATUS (*wtx_agent_mode_set) ();
+static evtpt_id_t (*wtx_breakpoint_add) ();
+static evtpt_id_t (*wtx_eventpoint_add) ();
+static STATUS (*wtx_eventpoint_delete) ();
+static WTX_EVENT_DESC * (*wtx_event_get) ();
+static WTX_CONTEXT_STATUS (*wtx_context_status_get) ();
+static STATUS (*wtx_context_cont) ();
+static WTX_CONTEXT_ID_T (*wtx_context_create) ();
+static STATUS (*wtx_context_resume) ();
+static evtpt_id_t (*wtx_context_exit_notify_add) ();
+static STATUS (*wtx_context_kill) ();
+static STATUS (*wtx_context_step) ();
+static STATUS (*wtx_context_suspend) ();
+static STATUS (*wtx_context_stop) ();
+static wtx_evtpt_list * (*wtx_eventpoint_list_get) ();
+static STATUS (*wtx_result_free) ();
+static WTX_GOPHER_TAPE * (*wtx_gopher_eval) ();
+static WTX_MEM_INFO * (*wtx_mem_info_get) ();
+static wtxapi_tgt_addr_t (*wtx_mem_alloc) ();
+static int (*wtx_mem_checksum) ();
+static STATUS (*wtx_mem_move) ();
+static STATUS (*wtx_mem_free) ();
+static int (*wtx_mem_read) ();
+static int (*wtx_mem_width_read) ();
+static int (*wtx_mem_write) ();
+static int (*wtx_mem_width_write) ();
+static int (*wtx_mem_set) ();
+static STATUS (*wtx_mem_add_to_pool) ();
+static wtxapi_tgt_addr_t (*wtx_mem_realloc) ();
+static wtxapi_tgt_addr_t (*wtx_mem_align) ();
+static STATUS (*wtx_mem_scan) ();
+static STATUS (*wtx_obj_module_checksum) ();
+static module_id_t (*wtx_obj_module_find_id) ();
+static char * (*wtx_obj_module_find_name) ();
+static WTX_MODULE_INFO * (*wtx_obj_module_info_get) ();
+static wtx_module_info * (*wtx_obj_module_load) ();
+static STATUS (*wtx_obj_module_unload) ();
+static STATUS (*wtx_obj_module_by_name_unload) ();
+static STATUS (*wtx_register_for_event) ();
+static STATUS (*wtx_regs_get) ();
+static STATUS (*wtx_regs_set) ();
+static wtxapi_tgt_addr_t (*wtx_str_to_tgt_addr) ();
+static WTX_CONTEXT_ID_T (*wtx_str_to_context_id) ();
+static WTX_CONTEXT_TYPE (*wtx_str_to_context_type) ();
+static int (*wtx_str_to_int32) ();
+static WTX_EVENT_TYPE (*wtx_str_to_event_type) ();
+static STATUS (*wtx_sym_add) ();
+static WTX_SYMBOL * (*wtx_sym_find) ();
+static WTX_SYM_LIST * (*wtx_sym_list_get) ();
+static WTX_SYM_LIST * (*wtx_sym_list_by_module_id_get) ();
+static WTX_SYM_LIST * (*wtx_sym_list_by_module_name_get) ();
+static STATUS (*wtx_sym_remove) ();
+static WTX_SYM_TBL_INFO * (*wtx_sym_tbl_info_get) ();
+static STATUS (*wtx_target_reset) ();
+static char * (*wtx_ts_name_get) ();
+static int (*wtx_target_cpu_type_get) ();
+static int (*wtx_target_has_fpp_get) ();
+static WTX_ENDIAN_T (*wtx_target_endian_get) ();
+static char * (*wtx_target_bootline_get) ();
+static char * (*wtx_tool_name_get) ();
+static char * (*wtx_ts_version_get) ();
+static STATUS (*wtx_unregister_for_event) ();
+static STATUS (*wtx_direct_call) ();
+static WTX_TS_INFO * (*wtx_ts_info_get) ();
+static STATUS (*wtx_target_attach) ();
+static STATUS (*wtx_probe) ();
+static STATUS (*wtx_timeout_set) ();
+static STATUS (*wtx_timeout_get) ();
+
+#if WTX_PROT_VERSION != 2
+static WTX_MODULE_LIST * (*wtx_obj_module_list_get) ();
+static pd_id_t (*wtx_pd_create) ();
+static pd_id_t (*wtx_pd_kernel_get) ();
+static pd_id_t (*wtx_pd_current_get) ();
+static STATUS (*wtx_pd_current_set) ();
+static WTX_PD_DESC_Q * (*wtx_pd_info_q_get) ();
+#else
+static WTX_MODULE_LIST * (*wtx_obj_module_list) ();
+#endif
+
+/* Conversion from an to a BOOL32.  */
+
+#define TO_BOOL(b) (b ? TRUE : FALSE)
+
+#ifndef WTX_PD_CURRENT
+const wtxapi_tgt_addr_t WTX_PD_CURRENT;
+#endif
+
+#ifndef WTX_PD_ALL
+const wtxapi_tgt_addr_t WTX_PD_ALL = -1;
+#endif
+
+#ifndef WTX_MOD_FIND_IN_ALL_PD
+const wtxapi_tgt_addr_t WTX_MOD_FIND_IN_ALL_PD = -1;
+#endif
+
+#ifndef WTX_SYM_FIND_IN_ALL_PD
+const int WTX_SYM_FIND_IN_ALL_PD = -1;
+#endif
+
+#if WTX_PROT_VERSION == 2
+const WTX_CONTEXT_TYPE WTX_CONTEXT_PD = WTX_CONTEXT_ANY_TASK;
+const int WTX_ERR_PD_INVALID_PD = WTX_ERROR;
+#endif
+
+#if WTX_PROT_VERSION > 3
+const WTX_ACTION_TYPE WTX_ACTION_STOP_ALL = WTX_ACTION_ALL_STOP;
+#endif
+
+const int wtxapi_symbol_copy_none = 0;
+const int wtxapi_symbol_copy_name = 1 << 0;
+const int wtxapi_symbol_copy_module_name = 1 << 1;
+
+const pd_id_t invalid_pd_id = WTX_ERROR;
+const evtpt_id_t invalid_module_id = WTX_ERROR;
+const evtpt_id_t invalid_evtpt_id = WTX_ERROR;
+const WTX_CONTEXT_ID_T invalid_context_id = WTX_ERROR;
+const WTX_AGENT_MODE_TYPE invalid_agent_mode = WTX_ERROR;
+const WTX_CONTEXT_STATUS invalid_context_status = WTX_ERROR;
+
+/* Only one PD is allowed in WTX 2.0; NULL_PD is the value of this PD
+   ID.  */
+
+const pd_id_t NULL_PD = 0;
+
+/* Symbol list: complete declaration.  Based on WTX_SYMBOL and
+   WTX_SYMBOL_LIST.  */
+
+struct wtxapi_symbol_list
+{
+  /* First element of the list.  */
+  WTX_SYMBOL *first;
+
+  /* Current element (when going through the list with the iterator).  */
+  WTX_SYMBOL *current;
+
+  /* Pointer to the result of the WTX operation used to get the symbol
+     list.  It is used at deallocation time.  */
+  void *wtx_result_to_cleanup;
+};
+
+/* Current WTX handle.  */
+
+static HWTX current_wtx_handle = 0;
+
+/* Allocate a new wtxapi_symbol_list and initialize it with
+   WTX_SYM.  WTX_SYM should not be deallocated directly by the caller,
+   it will be deallocated by free_wtxapi_symbol_list.  */
+
+static struct wtxapi_symbol_list
+  *new_wtxapi_symbol_list (WTX_SYM_LIST *wtx_sym);
+
+
+static struct wtxapi_symbol_list
+  *new_wtxapi_symbol_list_from_symbol (WTX_SYMBOL *wtx_sym);
+
+
+/* Allocate a new wtxapi_module_info, and initialize it with
+   WTX_MINFO.  The caller can deallocate WTX_MINFO, as it is fully
+   copied.  It does not initialize wtx_minfo->undef_list; it should
+   be handled separatly if needed.  */
+
+static struct wtxapi_module_info
+  *new_wtxapi_module_info (WTX_MODULE_INFO * wtx_minfo);
+
+static void
+initialize_context (WTX_CONTEXT *context,
+                    WTX_CONTEXT_TYPE context_type,
+                    WTX_CONTEXT_ID_T context_id)
+{
+  context->contextType = context_type;
+  context->contextId = context_id;
+#if WTX_PROT_VERSION > 3
+  context->contextSubId = 0;
+#endif
+}
+
+/* Build and initialize a WTX client handle.  This handle can then be
+   used to connect to a target server.  */
+
+int
+wtxapi_initialize ()
+{
+  return wtx_initialize (&current_wtx_handle) != WTX_ERROR;
+}
+
+/* Return the current WTX handle.  */
+
+HWTX
+wtxapi_get_current_wtx_handle ()
+{
+  return current_wtx_handle;
+}
+
+/* Terminate use of WTX client handle.  */
+
+int
+wtxapi_terminate ()
+{
+  return wtx_terminate (current_wtx_handle) != WTX_ERROR;
+}
+
+/* Return list of registred services.  NAME_PAT is the reg expression
+   to match svc name.  TYPE_PAT is the reg expression to match svc
+   type.  KEY_PAT is the reg expression to match svc key.  */
+
+WTX_DESC_Q *
+wtxapi_info_q (const char *name_pat, const char *type_pat,
+               const char *key_pat)
+{
+  return wtx_info_q (current_wtx_handle, name_pat, type_pat, key_pat);
+}
+
+/* Connect client to the target server.  */
+
+int
+wtxapi_tool_attach (const char *target_name, const char *tool_name)
+{
+  return wtx_tool_attach (current_wtx_handle, target_name,
+                          tool_name) != WTX_ERROR;
+}
+
+/* Check tool connection to the server.  */
+
+int
+wtxapi_tool_connected ()
+{
+  return wtx_tool_connected (current_wtx_handle) == TRUE;
+}
+
+/* Detach from the target server.  */
+
+int
+wtxapi_tool_detach ()
+{
+  return wtx_tool_detach (current_wtx_handle) != WTX_ERROR;
+}
+
+/* Clear any error for the tool.  */
+
+int
+wtxapi_err_clear ()
+{
+  return wtx_err_clear (current_wtx_handle) != WTX_ERROR;
+}
+
+/* Return the last error for a handle.  */
+
+WTX_ERROR_T
+wtxapi_err_get ()
+{
+  return wtx_err_get (current_wtx_handle);
+}
+
+/* Add an error handler.  */
+
+WTX_HANDLER_T
+wtxapi_err_handler_add (WTX_HANDLER_FUNC p_func, void *p_client_data)
+{
+  return wtx_err_handler_add (current_wtx_handle, p_func, p_client_data);
+}
+
+/* Remove error handler for WTX handle.  */
+
+int
+wtxapi_err_handler_remove (WTX_HANDLER_T p_handler)
+{
+  return wtx_err_handler_remove (current_wtx_handle, p_handler) != WTX_ERROR;
+}
+
+/* Fetch last WTX API error string.  */
+
+const char *
+wtxapi_err_msg_get ()
+{
+  if (current_wtx_handle == 0)
+    return "Invalid WTX handle";
+  else
+    return wtx_err_msg_get (current_wtx_handle);
+}
+
+/* Get agent mode.  */
+
+WTX_AGENT_MODE_TYPE
+wtxapi_agent_mode_get ()
+{
+  return wtx_agent_mode_get (current_wtx_handle);
+}
+
+/* Set the mode of the target agent.  */
+
+int
+wtxapi_agent_mode_set (WTX_AGENT_MODE_TYPE agent_mode)
+{
+  return wtx_agent_mode_set (current_wtx_handle, agent_mode) != WTX_ERROR;
+}
+
+/* Create a new breakpoint.  */
+
+evtpt_id_t
+wtxapi_breakpoint_add (WTX_CONTEXT_TYPE context_type,
+                       WTX_CONTEXT_ID_T context_id, wtxapi_tgt_addr_t tgt_addr)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+  return wtx_breakpoint_add (current_wtx_handle,
+                             MARSHALL_WTX_CONTEXT_PARAM (context), tgt_addr);
+}
+
+/* Create a new event point.  */
+
+evtpt_id_t
+wtxapi_eventpoint_add (struct wtxapi_evtpt *p_evtpt)
+{
+#if WTX_PROT_VERSION != 2
+  WTX_EVTPT wtx_evtpt;
+#else
+  WTX_EVTPT_2 wtx_evtpt;
+#endif
+  memset (&wtx_evtpt, 0, sizeof (wtx_evtpt));
+  wtx_evtpt.event.eventType = p_evtpt->event.event_type;
+  wtx_evtpt.event.numArgs = p_evtpt->event.num_args;
+  wtx_evtpt.event.args = p_evtpt->event.args;
+  wtx_evtpt.context.contextType = p_evtpt->context.context_type;
+
+  /* In WTX 4.1, WTX_CONTEXT_ANY_TASK does not work if the context ID
+     is not null; in the previous versions, it is simply ignored; so
+     unconditionally set the context ID to zero in the "any task"
+     case.  */
+  if (p_evtpt->context.context_type == WTX_CONTEXT_ANY_TASK)
+    wtx_evtpt.context.contextId = 0;
+  else
+    wtx_evtpt.context.contextId = p_evtpt->context.context_id;
+
+  wtx_evtpt.action.actionType = p_evtpt->action.action_type;
+  wtx_evtpt.action.actionArg = p_evtpt->action.action_arg;
+  wtx_evtpt.action.callRtn = p_evtpt->action.call_rtn;
+  wtx_evtpt.action.callArg = p_evtpt->action.call_arg;
+  return wtx_eventpoint_add (current_wtx_handle, &wtx_evtpt);
+}
+
+/* Delete eventpoint from the target.  */
+
+int
+wtxapi_eventpoint_delete (evtpt_id_t evtpt_id)
+{
+  return wtx_eventpoint_delete (current_wtx_handle, evtpt_id) != WTX_ERROR;
+}
+
+/* Parse a CTX_EXIT event string, and return the associated EVENT.  */
+
+static void
+wtxapi_parse_ctx_exit_event  (char *event_str,
+                              struct wtxapi_ctx_exit_event *event)
+{
+  char *context_id_str = NULL;
+  char *context_type_str = NULL;
+  char *exit_code_str = NULL;
+
+  if (WTX_PROT_VERSION > 3)
+    {
+      /* Format: "Context_Type Context_ID xxx Exit_Code..."
+         (where "xxx" is a field that we can ignore).  */
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = get_space_delimited_token (event_str, &context_id_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &exit_code_str);
+    }
+  else
+    {
+      /* Format: "Context_Type Context_ID Exit_Code".  */
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = get_space_delimited_token (event_str, &context_id_str);
+      event_str = get_space_delimited_token (event_str, &exit_code_str);
+    }
+
+  event->context_id = wtxapi_str_to_context_id (context_id_str);
+  event->context_type = wtxapi_str_to_context_type (context_type_str);
+  event->exit_code = wtxapi_str_to_int32 (exit_code_str);
+
+  wtx_opt_events_debug (1, "CTX_EXIT: "
+                          "context_id = \"%s\" 0x%lx, "
+                          "context_type = \"%s\" %d, "
+                          "exit_code = \"%s\" %d",
+                        context_id_str, event->context_id,
+                        context_type_str, event->context_type,
+                        exit_code_str, event->exit_code);
+  xfree (context_id_str);
+  xfree (context_type_str);
+  xfree (exit_code_str);
+
+}
+
+/* Parse a DATA_ACCESS event string, and return the associated EVENT.  */
+
+static void
+wtxapi_parse_data_access_event (char *event_str,
+                                struct wtxapi_data_access_event *event)
+{
+  char *task_id_str = NULL;
+  char *context_id_str = NULL;
+  char *context_type_str = NULL;
+  char *data_addr_str = NULL;
+
+  /* The formatting of the DATA_ACCESS event depends on the WTX
+     protocol version.  Extract each of the appropriate field
+     and discard the others.  */
+
+  if (WTX_PROT_VERSION == 2)
+    {
+      /* Format: "Task_ID/Context_ID Context_Type xxx xxx xxx Data_Addr..."
+         (where "xxx" is a field that we can ignore, and the Task_ID and
+         Context_ID are identical).  */
+      event_str = get_space_delimited_token (event_str, &task_id_str);
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &data_addr_str);
+      context_id_str = xstrdup (task_id_str);
+    }
+  else if (WTX_PROT_VERSION == 3)
+    {
+      /* Format: "Context_ID Context_Type xxx xxx xxx Data_Addr Task_ID ..."
+         (where "xxx" is a field that we can ignore).  */
+      event_str = get_space_delimited_token (event_str, &context_id_str);
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &data_addr_str);
+      event_str = get_space_delimited_token (event_str, &task_id_str);
+    }
+  else
+    {
+      /* Format: "xxx Context_Type Context_ID xxx xxx Task_ID xxx
+                 xxx xxx xxx Data_Addr"
+         (where "xxx" is a field that we can ignore).  */
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = get_space_delimited_token (event_str, &context_id_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &task_id_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &data_addr_str);
+    }
+
+  event->task_id = wtxapi_str_to_context_id (task_id_str);
+  event->context_id = wtxapi_str_to_context_id (context_id_str);
+  event->context_type = wtxapi_str_to_context_type (context_type_str);
+  event->data_addr = wtxapi_str_to_tgt_addr (data_addr_str);
+
+  wtx_opt_events_debug (1, "DATA_ACCESS: "
+                          "task_id = \"%s\" 0x%lx, "
+                          "context_id = \"%s\" 0x%lx, "
+                          "context_type = \"%s\" %d, "
+                          "data_addr = \"%s\" 0x%s",
+                        task_id_str, event->task_id,
+                        context_id_str, event->context_id,
+                        context_type_str, event->context_type,
+                        data_addr_str,
+                        paddress (target_gdbarch, event->data_addr));
+  xfree (task_id_str);
+  xfree (context_id_str);
+  xfree (context_type_str);
+  xfree (data_addr_str);
+}
+
+/* Parse an EXCEPTION event string, and return the associated EVENT.  */
+
+static void
+wtxapi_parse_exception_event (char *event_str,
+                              struct wtxapi_exception_event *event)
+{
+  char *context_id_str = NULL;
+  char *context_type_str = NULL;
+  char *exception_value_str = NULL;
+
+  /* The formatting of the EXCEPTION event depends on the WTX
+     protocol version.  Extract each of the appropriate field
+     and discard the others.  */
+
+  if (WTX_PROT_VERSION < 4)
+    {
+      /* Format: "Context_Type Context_ID ...".  */
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = get_space_delimited_token (event_str, &context_id_str);
+      event_str = get_space_delimited_token (event_str, &exception_value_str);
+    }
+  else
+    {
+      /* Format: "xxx xxx xxx xxx Context_Type Context_ID xxx Data_Addr ..."
+         (where "xxx" are fields we can ignore).  */
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = get_space_delimited_token (event_str, &context_id_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &exception_value_str);
+    }
+
+  event->context_id = wtxapi_str_to_context_id (context_id_str);
+  event->context_type = wtxapi_str_to_context_type (context_type_str);
+  event->exception_value = wtxapi_str_to_tgt_addr (exception_value_str);
+  
+  wtx_opt_events_debug (1, "EXCEPTION: "
+                          "context_id = \"%s\" 0x%lx, "
+                          "context_type = \"%s\" %d, "
+                          "exception_value = \"%s\" %s",
+                        context_id_str, event->context_id,
+                        context_type_str, event->context_type,
+                        exception_value_str,
+                        hex_string (event->exception_value));
+  xfree (context_id_str);
+  xfree (context_type_str);
+}
+
+/* Parse an OBJ_LOADED event string, and return the associated EVENT.  */
+
+static void
+wtxapi_parse_obj_loaded_event (char *event_str,
+                               struct wtxapi_obj_loaded_event *event)
+{
+  char *module_id_str = NULL;
+
+  /* Format: "Module_Id Module_Name [...]", but we only need
+     the module ID.  */
+  event_str = get_space_delimited_token (event_str, &module_id_str);
+  event->module_id = wtxapi_str_to_int32 (module_id_str);
+
+  wtx_opt_events_debug (1, "OBJ_LOADED: module_id_str = \"%s\" 0x%x",
+                        module_id_str, event->module_id);
+
+  xfree (module_id_str);
+}
+
+/* Parse an OBJ_UNLOADED event string, and return the associated EVENT.  */
+
+static void
+wtxapi_parse_obj_unloaded_event (char *event_str,
+                                 struct wtxapi_obj_unloaded_event *event)
+{
+  /* Format: "Module_Id Module_Name [...]", but we only need
+     the module filename.  */
+  event_str = skip_space_delimited_token (event_str);
+  event_str = get_space_delimited_token (event_str, &event->module_filename);
+
+  wtx_opt_events_debug (1, "OBJ_LOADED: module_filename = \"%s\"",
+                        event->module_filename);
+}
+
+/* Parse a TEXT_ACCESS event string, and return the associated EVENT.  */
+
+static void
+wtxapi_parse_text_access_event (char *event_str,
+                                struct wtxapi_text_access_event *event)
+{
+  char *task_id_str = NULL;
+  char *context_id_str = NULL;
+  char *context_type_str = NULL;
+  char *text_addr_str = NULL;
+
+  /* The formatting of the TEXT_ACCESS event depends on the WTX
+     protocol version.  Extract each of the appropriate field
+     and discard the others.  */
+
+  if (WTX_PROT_VERSION == 2)
+    {
+      /* Format: "Task_ID/Context_ID Context_Type Text_Addr ..."
+         (the Task_ID and Context_ID are equal).  */
+      event_str = get_space_delimited_token (event_str, &task_id_str);
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = get_space_delimited_token (event_str, &text_addr_str);
+      context_id_str = xstrdup (task_id_str);
+    }
+  else if (WTX_PROT_VERSION == 3)
+    {
+      /* Format: "Context_ID Context_Type Text_Addr xxx xxx Task_ID ..."
+         (where "xxx" is a field that we can ignore).  */
+      event_str = get_space_delimited_token (event_str, &context_id_str);
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = get_space_delimited_token (event_str, &text_addr_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &task_id_str);
+    }
+  else
+    {
+      /* Format: "xxx Context_Type Context_ID xxx xxx Task_ID xxx Text_Addr..."
+         (where "xxx" is a field that we can ignore).  */
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &context_type_str);
+      event_str = get_space_delimited_token (event_str, &context_id_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &task_id_str);
+      event_str = skip_space_delimited_token (event_str);
+      event_str = get_space_delimited_token (event_str, &text_addr_str);
+    }
+
+  /* With WTX version 3 and later and when in system mode, the task ID
+     in the event string is apparently not the ID we are looking for.
+     Get the current task ID differently.  */
+  /* brobecker/2007-08-31: Not sure what the wrong task ID could be.
+     So, for now, do nothing special; enhance later if we find some
+     evidence that it is necessary.  */
+
+  event->task_id = wtxapi_str_to_context_id (task_id_str);
+  event->context_id = wtxapi_str_to_context_id (context_id_str);
+  event->context_type = wtxapi_str_to_context_type (context_type_str);
+  event->text_addr = wtxapi_str_to_tgt_addr (text_addr_str);
+
+  wtx_opt_events_debug (1, "TEXT_ACCESS: "
+                          "task_id = \"%s\" 0x%lx, "
+                          "context_id = \"%s\" 0x%lx, "
+                          "context_type = \"%s\" %d, "
+                          "text_addr = \"%s\" 0x%s",
+                        task_id_str, event->task_id,
+                        context_id_str, event->context_id,
+                        context_type_str, event->context_type,
+                        text_addr_str,
+                        paddress (target_gdbarch, event->text_addr));
+
+  xfree (task_id_str);
+  xfree (context_id_str);
+  xfree (context_type_str);
+  xfree (text_addr_str);
+}
+
+/* Parse a VIO_WRITE event string, the given DATA and its associated
+   DATA_LEN, and return the corresponding EVENT.  */
+
+static void
+wtxapi_parse_vio_write_event (char *event_str, char *data, int data_len,
+                              struct wtxapi_vio_write_event *event)
+{
+  char *channel_id_str = NULL;
+
+  /* Format: "Channel_Id".  The rest of the information is
+     inside the additional_data.  */
+  event_str = get_space_delimited_token (event_str, &channel_id_str);
+
+  event->channel_id = atoi (event_str);
+
+  event->data = xmalloc ((data_len + 1) * sizeof (char));
+  strncpy (event->data, data, data_len);
+  event->data[data_len] = '\0';
+
+  wtx_opt_events_debug (1, "VIO_WRITE: "
+                          "channel_id = \"%s\" %d, "
+                          "data = \"%s\"",
+                        channel_id_str, event->channel_id,
+                        event->data);
+
+  xfree (channel_id_str);
+}
+
+
+/* Get the next event from the event queue if one is available.
+   Return NULL otherwise.
+   
+   The new event must be deallocated after use.  */
+
+struct wtxapi_event_desc *
+wtxapi_event_get (void)
+{
+  WTX_EVENT_DESC *event_desc = wtx_event_get (current_wtx_handle);
+  char *event_str;
+  char *token = NULL;
+  struct wtxapi_event_desc *result;
+
+  if (event_desc == NULL)
+    return NULL;
+  if (event_desc->event == NULL)
+    {
+      /* That's kind of dumb, but it actually happens.  */
+      wtx_result_free (current_wtx_handle, event_desc);
+      return NULL;
+    }
+
+  wtx_opt_events_debug (2, "wtxapi_event_get: \"%s\"", event_desc->event);
+
+  result = xmalloc (sizeof (struct wtxapi_event_desc));
+
+  /* Get the event type from the first token in the event string.  */
+  event_str = event_desc->event;
+  event_str = get_space_delimited_token (event_str, &token);
+  result->event_type = wtxapi_str_to_event_type (token);
+  xfree (token);
+
+  switch (result->event_type)
+    {
+      case WTX_EVENT_CTX_EXIT:
+        wtxapi_parse_ctx_exit_event (event_str, &result->desc.ctx_exit);
+        break;
+
+      case WTX_EVENT_DATA_ACCESS:
+        wtxapi_parse_data_access_event (event_str, &result->desc.data_access);
+        break;
+
+      case WTX_EVENT_EXCEPTION:
+        wtxapi_parse_exception_event (event_str, &result->desc.exception);
+        break;
+
+      case WTX_EVENT_OBJ_LOADED:
+        wtxapi_parse_obj_loaded_event (event_str, &result->desc.obj_loaded);
+        break;
+
+      case WTX_EVENT_OBJ_UNLOADED:
+        wtxapi_parse_obj_unloaded_event (event_str,
+                                         &result->desc.obj_unloaded);
+        break;
+
+      case WTX_EVENT_TEXT_ACCESS:
+        wtxapi_parse_text_access_event (event_str, &result->desc.text_access);
+        break;
+
+      case WTX_EVENT_VIO_WRITE:
+        wtxapi_parse_vio_write_event (event_str,
+                                      event_desc->addlData,
+                                      event_desc->addlDataLen,
+                                      &result->desc.vio_write);
+        break;
+
+      case WTX_EVENT_EVTPT_ADDED:
+      case WTX_EVENT_EVTPT_DELETED:
+        /* We do not handle eventpoints added/removed by other tools.
+           So ignore these events by falling back to the "default" case.  */
+      default:
+        /* Ignore this event.  */
+        xfree (result);
+        result = NULL;
+        break;
+    }
+
+  wtx_result_free (current_wtx_handle, event_desc);
+  return result;
+}
+
+WTX_CONTEXT_STATUS
+wtxapi_context_status_get (WTX_CONTEXT_TYPE context_type,
+                           WTX_CONTEXT_ID_T context_id)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+  return wtx_context_status_get (current_wtx_handle,
+                                 MARSHALL_WTX_CONTEXT_PARAM (context));
+}
+
+
+/* Continue execution of target context.  */
+
+int
+wtxapi_context_cont (WTX_CONTEXT_TYPE context_type,
+                     WTX_CONTEXT_ID_T context_id)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+  return wtx_context_cont (current_wtx_handle,
+                           MARSHALL_WTX_CONTEXT_PARAM (context)) != WTX_ERROR;
+}
+
+/* Create a context on target.  */
+
+WTX_CONTEXT_ID_T
+wtxapi_context_create (struct wtxapi_context_desc *p_context_desc)
+{
+  int ix;
+  WTX_CONTEXT_DESC context_desc;
+  memset (&context_desc, 0, sizeof (context_desc));
+#if WTX_PROT_VERSION != 2
+  context_desc.wtxContextType = p_context_desc->context_type;
+
+  if (p_context_desc->context_type == WTX_CONTEXT_PD)
+    {
+      context_desc.wtxContextDef.wtxPdContextDef.name =
+        p_context_desc->wtx_context_def.pd_context.name;
+      context_desc.wtxContextDef.wtxPdContextDef.options =
+        p_context_desc->wtx_context_def.pd_context.options;
+      context_desc.wtxContextDef.wtxPdContextDef.heapSize =
+        p_context_desc->wtx_context_def.pd_context.heap_size;
+      context_desc.wtxContextDef.wtxPdContextDef.lowPriority =
+        p_context_desc->wtx_context_def.pd_context.low_priority;
+      context_desc.wtxContextDef.wtxPdContextDef.highPriority =
+        p_context_desc->wtx_context_def.pd_context.high_priority;
+      context_desc.wtxContextDef.wtxPdContextDef.pagePoolList =
+        p_context_desc->wtx_context_def.pd_context.page_pool_list;
+      context_desc.wtxContextDef.wtxPdContextDef.destroyRtn =
+        p_context_desc->wtx_context_def.pd_context.destroy_rtn;
+      context_desc.wtxContextDef.wtxPdContextDef.linkPath =
+        p_context_desc->wtx_context_def.pd_context.link_path;
+      context_desc.wtxContextDef.wtxPdContextDef.redirIn =
+        p_context_desc->wtx_context_def.pd_context.redir_in;
+      context_desc.wtxContextDef.wtxPdContextDef.redirOut =
+        p_context_desc->wtx_context_def.pd_context.redir_out;
+      context_desc.wtxContextDef.wtxPdContextDef.redirErr =
+        p_context_desc->wtx_context_def.pd_context.redir_err;
+      context_desc.wtxContextDef.wtxPdContextDef.argc =
+        p_context_desc->wtx_context_def.pd_context.argc;
+      context_desc.wtxContextDef.wtxPdContextDef.argv =
+        p_context_desc->wtx_context_def.pd_context.argv;
+    }
+  else
+    {
+      context_desc.wtxContextDef.wtxTaskContextDef.pdId =
+        p_context_desc->wtx_context_def.task_context.pd_id;
+      context_desc.wtxContextDef.wtxTaskContextDef.returnType =
+        p_context_desc->wtx_context_def.task_context.return_type;
+      context_desc.wtxContextDef.wtxTaskContextDef.name =
+        p_context_desc->wtx_context_def.task_context.name;
+      context_desc.wtxContextDef.wtxTaskContextDef.priority =
+        p_context_desc->wtx_context_def.task_context.priority;
+      context_desc.wtxContextDef.wtxTaskContextDef.options =
+        p_context_desc->wtx_context_def.task_context.options;
+      context_desc.wtxContextDef.wtxTaskContextDef.stackBase =
+        p_context_desc->wtx_context_def.task_context.stack_base;
+      context_desc.wtxContextDef.wtxTaskContextDef.stackSize =
+        p_context_desc->wtx_context_def.task_context.stack_size;
+      context_desc.wtxContextDef.wtxTaskContextDef.entry =
+        p_context_desc->wtx_context_def.task_context.entry;
+      context_desc.wtxContextDef.wtxTaskContextDef.redirIn =
+        p_context_desc->wtx_context_def.task_context.redir_in;
+      context_desc.wtxContextDef.wtxTaskContextDef.redirOut =
+        p_context_desc->wtx_context_def.task_context.redir_out;
+      context_desc.wtxContextDef.wtxTaskContextDef.redirErr =
+        p_context_desc->wtx_context_def.task_context.redir_err;
+      context_desc.wtxContextDef.wtxTaskContextDef.argc =
+        p_context_desc->wtx_context_def.task_context.argc;
+      context_desc.wtxContextDef.wtxTaskContextDef.argv =
+        p_context_desc->wtx_context_def.task_context.argv;
+    }
+
+#else
+
+  /* In WTX 2.0, we cannot create a new PD.  */
+
+  if (p_context_desc->context_type == WTX_CONTEXT_PD)
+    return invalid_context_id;
+
+  context_desc.contextType = p_context_desc->context_type;
+  context_desc.returnType =
+    p_context_desc->wtx_context_def.task_context.return_type;
+  context_desc.name = p_context_desc->wtx_context_def.task_context.name;
+  context_desc.priority =
+    p_context_desc->wtx_context_def.task_context.priority;
+  context_desc.options = p_context_desc->wtx_context_def.task_context.options;
+  context_desc.stackBase =
+    p_context_desc->wtx_context_def.task_context.stack_base;
+  context_desc.stackSize =
+    p_context_desc->wtx_context_def.task_context.stack_size;
+  context_desc.entry = p_context_desc->wtx_context_def.task_context.entry;
+  context_desc.redirIn = p_context_desc->wtx_context_def.task_context.redir_in;
+  context_desc.redirOut =
+    p_context_desc->wtx_context_def.task_context.redir_out;
+  for (ix = 0; ix < WTX_MAX_ARG_CNT; ix++)
+    if (ix < p_context_desc->wtx_context_def.task_context.argc)
+      context_desc.args[ix] =
+        p_context_desc->wtx_context_def.task_context.argv[ix];
+    else
+      context_desc.args[ix] = NULL_PD;
+#endif
+  return wtx_context_create (current_wtx_handle, &context_desc);
+}
+
+/* Resume execution of a target context.  */
+
+int
+wtxapi_context_resume (WTX_CONTEXT_TYPE context_type,
+                       WTX_CONTEXT_ID_T context_id)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+  return wtx_context_resume (current_wtx_handle,
+                             MARSHALL_WTX_CONTEXT_PARAM (context))
+    != WTX_ERROR;
+}
+
+/* Add exit evpt notification.  */
+
+evtpt_id_t
+wtxapi_context_exit_notify_add (WTX_CONTEXT_TYPE context_type,
+                                WTX_CONTEXT_ID_T context_id)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+  return wtx_context_exit_notify_add (current_wtx_handle,
+                                      MARSHALL_WTX_CONTEXT_PARAM (context));
+}
+
+/* Kill a target context.  */
+
+int
+wtxapi_context_kill (WTX_CONTEXT_TYPE context_type,
+                     WTX_CONTEXT_ID_T context_id)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+#if WTX_PROT_VERSION != 2
+  return wtx_context_kill (current_wtx_handle,
+                           MARSHALL_WTX_CONTEXT_PARAM (context),
+                           WTX_PD_DELETE_OPTION_NONE) != WTX_ERROR;
+#else
+  return wtx_context_kill (current_wtx_handle,
+                           MARSHALL_WTX_CONTEXT_PARAM (context)) != WTX_ERROR;
+#endif
+}
+
+/* Single step exec of target context.  */
+
+int
+wtxapi_context_step (WTX_CONTEXT_TYPE context_type,
+                     WTX_CONTEXT_ID_T context_id, wtxapi_tgt_addr_t step_start,
+                     wtxapi_tgt_addr_t step_end)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+  return wtx_context_step (current_wtx_handle,
+                           MARSHALL_WTX_CONTEXT_PARAM (context),
+                           step_start, step_end) != WTX_ERROR;
+}
+
+/* Suspend a target context.  */
+
+int
+wtxapi_context_suspend (WTX_CONTEXT_TYPE context_type,
+                        WTX_CONTEXT_ID_T context_id)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+  return wtx_context_suspend (current_wtx_handle,
+                              MARSHALL_WTX_CONTEXT_PARAM (context))
+    != WTX_ERROR;
+}
+
+int
+wtxapi_context_stop (WTX_CONTEXT_TYPE context_type,
+                     WTX_CONTEXT_ID_T context_id)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+
+#if WTX_PROT_VERSION != 2
+  return wtx_context_stop (current_wtx_handle,
+                           MARSHALL_WTX_CONTEXT_PARAM (context)) != WTX_ERROR;
+#else
+  /* FIXME : wtxContextStop does not exist on WTX 2.0.  For now, use
+     wtxContextSuspend as a workaround.  */
+
+  return wtx_context_suspend (current_wtx_handle,
+                              MARSHALL_WTX_CONTEXT_PARAM (context))
+    != WTX_ERROR;
+#endif
+}
+
+/* List event points on TS.  */
+
+struct wtxapi_evtpt_list *
+wtxapi_eventpoint_list_get ()
+{
+  int ix;
+  struct wtxapi_evtpt_list *evtpt_list;
+  wtx_evtpt_list *wtx_list;
+  wtx_list = wtx_eventpoint_list_get (current_wtx_handle);
+
+  if (!wtx_list)
+    return NULL;
+
+  evtpt_list = (struct wtxapi_evtpt_list *)
+    xmalloc (sizeof (struct wtxapi_evtpt_list));
+  evtpt_list->n_evtpt = wtx_list->nEvtpt;
+  evtpt_list->p_evtpt_info = (struct wtxapi_evtpt_info *)
+    xmalloc (sizeof (struct wtxapi_evtpt_info) * wtx_list->nEvtpt);
+  for (ix = 0; ix < wtx_list->nEvtpt; ix++)
+    {
+      evtpt_list->p_evtpt_info[ix].wtx_evtpt.event.event_type =
+        wtx_list->pEvtptInfo[ix].wtxEvtpt.event.eventType;
+      evtpt_list->p_evtpt_info[ix].wtx_evtpt.event.num_args =
+        wtx_list->pEvtptInfo[ix].wtxEvtpt.event.numArgs;
+      evtpt_list->p_evtpt_info[ix].wtx_evtpt.event.args = (wtxapi_tgt_arg_t *)
+        xmalloc (wtx_list->pEvtptInfo[ix].wtxEvtpt.event.numArgs *
+                 sizeof (wtxapi_tgt_arg_t));
+      memcpy (evtpt_list->p_evtpt_info[ix].wtx_evtpt.event.args,
+              wtx_list->pEvtptInfo[ix].wtxEvtpt.event.args,
+              wtx_list->pEvtptInfo[ix].wtxEvtpt.event.numArgs *
+              sizeof (wtxapi_tgt_arg_t));
+      evtpt_list->p_evtpt_info[ix].wtx_evtpt.context.context_type =
+        wtx_list->pEvtptInfo[ix].wtxEvtpt.context.contextType;
+      evtpt_list->p_evtpt_info[ix].wtx_evtpt.context.context_id =
+        wtx_list->pEvtptInfo[ix].wtxEvtpt.context.contextId;
+      evtpt_list->p_evtpt_info[ix].wtx_evtpt.action.action_type =
+        wtx_list->pEvtptInfo[ix].wtxEvtpt.action.actionType;
+      evtpt_list->p_evtpt_info[ix].wtx_evtpt.action.action_arg =
+        wtx_list->pEvtptInfo[ix].wtxEvtpt.action.actionArg;
+      evtpt_list->p_evtpt_info[ix].wtx_evtpt.action.call_rtn =
+        wtx_list->pEvtptInfo[ix].wtxEvtpt.action.callRtn;
+      evtpt_list->p_evtpt_info[ix].wtx_evtpt.action.call_arg =
+        wtx_list->pEvtptInfo[ix].wtxEvtpt.action.callArg;
+      evtpt_list->p_evtpt_info[ix].tool_id = wtx_list->pEvtptInfo[ix].toolId;
+      evtpt_list->p_evtpt_info[ix].evtpt_num =
+        wtx_list->pEvtptInfo[ix].evtptNum;
+    }
+
+  wtx_result_free (current_wtx_handle, wtx_list);
+  return evtpt_list;
+}
+
+/* Free mem allocated by WTX API call.  */
+
+int
+wtxapi_result_free (void *p_result)
+{
+  return wtx_result_free (current_wtx_handle, p_result) != WTX_ERROR;
+}
+
+/* Evaluate Gopher string on target.  */
+
+WTX_GOPHER_TAPE *
+wtxapi_gopher_eval (pd_id_t pd_id, const char *input_string)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_gopher_eval (current_wtx_handle, pd_id, input_string);
+#else
+  return wtx_gopher_eval (current_wtx_handle, input_string);
+#endif
+}
+
+/* Get info about memory pool.  */
+
+WTX_MEM_INFO *
+wtxapi_mem_info_get (pd_id_t pd_id)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_info_get (current_wtx_handle, pd_id);
+#else
+  return wtx_mem_info_get (current_wtx_handle);
+#endif
+}
+
+/* Alloc blocks in memory pool.  */
+
+wtxapi_tgt_addr_t
+wtxapi_mem_alloc (pd_id_t pd_id, int num_bytes)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_alloc (current_wtx_handle, pd_id, num_bytes);
+#else
+  return wtx_mem_alloc (current_wtx_handle, num_bytes);
+#endif
+}
+
+/* Perform checksum on target memory.  */
+
+int
+wtxapi_mem_checksum (pd_id_t pd_id, wtxapi_tgt_addr_t start_addr,
+                     int num_bytes)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_checksum (current_wtx_handle, pd_id, start_addr, num_bytes);
+#else
+  return wtx_mem_checksum (current_wtx_handle, start_addr, num_bytes);
+#endif
+}
+
+/* Move a block of target memory.  */
+
+int
+wtxapi_mem_move (pd_id_t src_pd_id, wtxapi_tgt_addr_t src_addr,
+                 pd_id_t dst_pd_id, wtxapi_tgt_addr_t dest_addr, int num_bytes)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_move (current_wtx_handle, src_pd_id, src_addr, dst_pd_id,
+                       dest_addr, num_bytes) != WTX_ERROR;
+#else
+  return wtx_mem_move (current_wtx_handle, src_addr, dest_addr,
+                       num_bytes) != WTX_ERROR;
+#endif
+}
+
+/* Free a block of target memory.  */
+
+int
+wtxapi_mem_free (pd_id_t pd_id, wtxapi_tgt_addr_t address)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_free (current_wtx_handle, pd_id, address) != WTX_ERROR;
+#else
+  return wtx_mem_free (current_wtx_handle, address) != WTX_ERROR;
+#endif
+}
+
+/* Read memory from the target.  */
+
+int
+wtxapi_mem_read (pd_id_t pd_id, wtxapi_tgt_addr_t from_addr,
+                 void *to_addr, int num_bytes)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_read (current_wtx_handle, pd_id, from_addr, to_addr,
+                       num_bytes, 0);
+#else
+  return wtx_mem_read (current_wtx_handle, from_addr, to_addr, num_bytes);
+#endif
+}
+
+/* Read memory on WIDTH bytes.  */
+
+int
+wtxapi_mem_width_read (pd_id_t pd_id, wtxapi_tgt_addr_t from_addr,
+                       void *to_addr, int num_bytes, int width)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_width_read (current_wtx_handle, pd_id, from_addr, to_addr,
+                             num_bytes, width, 0);
+#else
+  return wtx_mem_width_read (current_wtx_handle, from_addr, to_addr, num_bytes,
+                             width);
+#endif
+}
+
+/* Write memory on the target.  */
+
+int
+wtxapi_mem_write (pd_id_t pd_id, void *from_addr,
+                  wtxapi_tgt_addr_t to_addr, int num_bytes)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_write (current_wtx_handle, pd_id, from_addr, to_addr,
+                        num_bytes, 0);
+#else
+  return wtx_mem_write (current_wtx_handle, from_addr, to_addr, num_bytes);
+#endif
+}
+
+/* Write memory on the target on WIDTH bytes large.  */
+
+int
+wtxapi_mem_width_write (pd_id_t pd_id, void *from_addr,
+                        wtxapi_tgt_addr_t to_addr, int num_bytes, int width)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_width_write (current_wtx_handle, pd_id, from_addr, to_addr,
+                              num_bytes, width, 0);
+#else
+  return wtx_mem_width_write (current_wtx_handle, from_addr, to_addr,
+                              num_bytes, width);
+#endif
+}
+
+/* Set target memory to given value.  */
+
+int
+wtxapi_mem_set (pd_id_t pd_id, wtxapi_tgt_addr_t addr, int num_bytes, int val)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_set (current_wtx_handle, pd_id, addr, num_bytes, val);
+#else
+  return wtx_mem_set (current_wtx_handle, addr, num_bytes, val);
+#endif
+}
+
+/* Add memory to the agent pool.  */
+
+int
+wtxapi_mem_add_to_pool (pd_id_t pd_id, wtxapi_tgt_addr_t address, int size)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_add_to_pool (current_wtx_handle, pd_id, address,
+                              size) != WTX_ERROR;
+#else
+  return wtx_mem_add_to_pool (current_wtx_handle, address, size) != WTX_ERROR;
+#endif
+}
+
+/* Reallocate a block of target mem.  */
+
+wtxapi_tgt_addr_t
+wtxapi_mem_realloc (pd_id_t pd_id, wtxapi_tgt_addr_t address, int num_bytes)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_realloc (current_wtx_handle, pd_id, address, num_bytes);
+#else
+  return wtx_mem_realloc (current_wtx_handle, address, num_bytes);
+#endif
+}
+
+/* Allocate aligned target memory.  */
+
+wtxapi_tgt_addr_t
+wtxapi_mem_align (pd_id_t pd_id, wtxapi_tgt_addr_t alignment, int num_bytes)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_align (current_wtx_handle, pd_id, alignment, num_bytes);
+#else
+  return wtx_mem_align (current_wtx_handle, alignment, num_bytes);
+#endif
+}
+
+/* Scan target memory for pattern.  */
+
+int
+wtxapi_mem_scan (pd_id_t pd_id, int match, wtxapi_tgt_addr_t start_addr,
+                 wtxapi_tgt_addr_t end_addr, int num_bytes, void *pattern,
+                 wtxapi_tgt_addr_t * p_result)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_mem_scan (current_wtx_handle, pd_id, TO_BOOL (match), start_addr,
+                       end_addr, num_bytes, pattern, p_result) != WTX_ERROR;
+#else
+  return wtx_mem_scan (current_wtx_handle, TO_BOOL (match), start_addr,
+                       end_addr, num_bytes, pattern, p_result) != WTX_ERROR;
+#endif
+}
+
+/* Checks validity of target memory.  */
+
+int
+wtxapi_obj_module_checksum (pd_id_t pd_id, module_id_t module_id,
+                            char *module_name)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_obj_module_checksum (current_wtx_handle, pd_id, module_id,
+                                  module_name) != WTX_ERROR;
+#else
+  return wtx_obj_module_checksum (current_wtx_handle, module_id,
+                                  module_name) != WTX_ERROR;
+#endif
+}
+
+/* Find obj module ID from name.  */
+
+module_id_t
+wtxapi_obj_module_find_id (pd_id_t pd_id, const char *module_name)
+{
+  module_id_t module_id;
+#if WTX_PROT_VERSION != 2
+  module_id = wtx_obj_module_find_id (current_wtx_handle, pd_id, module_name);
+#else
+  module_id = wtx_obj_module_find_id (current_wtx_handle, module_name);
+#endif
+  return module_id;
+}
+
+module_id_t
+wtxapi_obj_module_in_system_find_id (const char *module_name)
+{
+#if WTX_PROT_VERSION != 2
+  const pd_id_t current_pd = wtxapi_pd_current_get (current_wtx_handle);
+  module_id_t module_id;
+
+  module_id = wtx_obj_module_find_id (current_wtx_handle, current_pd, module_name);
+  if (module_id != WTX_ERROR)
+    return module_id;
+
+  return wtx_obj_module_find_id (current_wtx_handle, WTX_PD_ALL, module_name);
+#else
+  return wtx_obj_module_find_id (current_wtx_handle, module_name);
+#endif
+}
+
+/* Find module name given its ID.  */
+
+const char *
+wtxapi_obj_module_find_name (pd_id_t pd_id, module_id_t module_id)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_obj_module_find_name (current_wtx_handle, pd_id, module_id);
+#else
+  return wtx_obj_module_find_name (current_wtx_handle, module_id);
+#endif
+}
+
+/* Allocate a new wtxapi_module_info.  */
+
+static struct wtxapi_module_info *
+new_wtxapi_module_info (WTX_MODULE_INFO *wtx_minfo)
+{
+  int i;
+  struct wtxapi_module_info *module_info;
+
+  if (!wtx_minfo)
+    return NULL;
+
+  module_info = (struct wtxapi_module_info *)
+    xzalloc (sizeof (struct wtxapi_module_info));
+#if WTX_PROT_VERSION != 2
+  module_info->pd_id = wtx_minfo->pdId;
+  module_info->section_addrs = alloc_section_addr_info (wtx_minfo->nSections);
+  for (i = 0; i < wtx_minfo->nSections; i++)
+    {
+      struct other_sections *other = module_info->section_addrs->other + i;
+
+      other->name = xstrdup (wtx_minfo->section[i].name);
+      other->addr = wtx_minfo->section[i].baseAddr;
+      /* brobecker/2007-05-14:  The sectindex should really be set to
+         the same index as the BFD section index.  But accessing the BFD
+         data at this point is not easy, so I am making a bet instead
+         that the BFD index is the same as the WTX section index.  If
+         this assertion turns out to be false, then we'll have to add
+         some fixup code in remote-wtx.c that recomputes all section
+         indexes from BFD.  */
+      other->sectindex = i;
+    }
+  module_info->segments = NULL;
+#else
+  /* On Tornado 2, the system does not give us access to the section
+     addresses, but 3 segment base addresses instead, from which we
+     need to compute the actual section addresses.  Ideally, it would
+     have been nice to compute these addresses at this point, to make
+     the behavior of this function independent of the Tornado version,
+     but the implementation is too awkward (one of the problems we
+     are facing is trying to locate the object file on the host file
+     system, which is something we already do, but sometime later in
+     another part of the code, and using the result from this function).
+     So we just return the segment addresses for now, and let the client
+     deal with the conversion at a more appropriate moment.  */
+  gdb_assert (wtx_minfo->nSegments == 3);
+
+  module_info->pd_id = NULL_PD;
+  module_info->section_addrs = NULL;
+  module_info->segments =
+    (struct segment_addresses *) xmalloc (sizeof (struct segment_addresses));
+  module_info->segments->text_addr = wtx_minfo->segment[0].addr;
+  module_info->segments->data_addr = wtx_minfo->segment[1].addr;
+  module_info->segments->bss_addr = wtx_minfo->segment[2].addr;
+#endif
+  module_info->module_id = wtx_minfo->moduleId;
+  if (wtx_minfo->moduleName)
+    module_info->module_name = xstrdup (wtx_minfo->moduleName);
+  module_info->load_flag = wtx_minfo->loadFlag;
+  module_info->undef_list = NULL;
+  return module_info;
+}
+
+/* Give info on obj module.  */
+
+struct wtxapi_module_info *
+wtxapi_obj_module_info_get (pd_id_t pd_id, module_id_t module_id)
+{
+  struct wtxapi_module_info *module_info;
+  WTX_MODULE_INFO *wtx_minfo;
+#if WTX_PROT_VERSION != 2
+  wtx_minfo = wtx_obj_module_info_get (current_wtx_handle, pd_id, module_id);
+#else
+  wtx_minfo = wtx_obj_module_info_get (current_wtx_handle, module_id);
+#endif
+  if (!wtx_minfo)
+    return NULL;
+
+  module_info = new_wtxapi_module_info (wtx_minfo);
+  wtx_result_free (current_wtx_handle, wtx_minfo);
+  return module_info;
+}
+
+/* List loaded obj modules.  */
+
+struct wtxapi_module_list *
+wtxapi_obj_module_list_get (pd_id_t pd_id)
+{
+  WTX_MODULE_LIST *wtx_mlist;
+  struct wtxapi_module_list *list;
+  int ix = 0;
+#if WTX_PROT_VERSION != 2
+  WTX_MOD_FIND_CRITERIA criteria;
+  WTX_MODULE *current;
+
+  memset (&criteria, 0, sizeof (criteria));
+  criteria.options = WTX_MOD_FIND_ALL;
+  criteria.pdId = pd_id;
+  criteria.moduleId = 0;
+  criteria.moduleName = NULL;
+  criteria.ref = 0;
+
+  wtx_mlist = wtx_obj_module_list_get (current_wtx_handle, &criteria);
+
+  if (!wtx_mlist)
+    return NULL;
+
+  list = (struct wtxapi_module_list *)
+    xmalloc (sizeof (struct wtxapi_module_list));
+
+  /* Note: as the module list is expected to have, say, less than 10
+     elements, the full copy should not take much time.  */
+
+  list->num_obj_mod = 0;
+  for (current = wtx_mlist->pModule; current; current = current->next)
+    list->num_obj_mod++;
+
+  list->mod_id_array = (int *) xmalloc (list->num_obj_mod * sizeof (int));
+  list->pd_id_array = (pd_id_t *)
+    xmalloc (list->num_obj_mod * sizeof (pd_id_t));
+  for (current = wtx_mlist->pModule; current; current = current->next)
+    {
+      list->mod_id_array[ix] = current->moduleId;
+      list->pd_id_array[ix] = current->pdId;
+      ix++;
+    }
+
+#else
+  wtx_mlist = wtx_obj_module_list (current_wtx_handle);
+
+  if (!wtx_mlist)
+    return NULL;
+
+  list = (struct wtxapi_module_list *)
+    xmalloc (sizeof (struct wtxapi_module_list));
+  list->num_obj_mod = wtx_mlist->numObjMod;
+  list->mod_id_array = (int *) xmalloc (list->num_obj_mod * sizeof (int));
+  list->pd_id_array = (pd_id_t *)
+    xmalloc (list->num_obj_mod * sizeof (pd_id_t));
+  for (ix = 0; ix < list->num_obj_mod; ix++)
+    list->mod_id_array[ix] = wtx_mlist->modIdList[ix];
+  memset (list->pd_id_array, 0, list->num_obj_mod * sizeof (pd_id_t));
+#endif
+  wtx_result_free (current_wtx_handle, wtx_mlist);
+  return list;
+}
+
+/* Load a new object module.  */
+
+struct wtxapi_module_info *
+wtxapi_obj_module_load (pd_id_t pd_id, char *filename, int load_flags)
+{
+  struct wtxapi_module_info *minfo;
+  wtx_module_info * wtx_minfo;
+
+#if WTX_PROT_VERSION != 2
+  WTX_MODULE_FILE_DESC wtx_fdesc;
+
+  memset (&wtx_fdesc, 0, sizeof (wtx_fdesc));
+  wtx_fdesc.filename = filename;
+  wtx_fdesc.loadFlag = load_flags;
+
+  wtx_minfo = wtx_obj_module_load (current_wtx_handle, pd_id, &wtx_fdesc,
+                                   WTX_LOAD_FROM_TOOL);
+
+  if (!wtx_minfo)
+    return NULL;
+
+  minfo = new_wtxapi_module_info (wtx_minfo);
+  minfo->undef_list =
+    new_wtxapi_symbol_list_from_symbol (wtx_minfo->undefSymList.pSymbol);
+  if (minfo->undef_list)
+    minfo->undef_list->wtx_result_to_cleanup = (void *) wtx_minfo;
+#else
+  WTX_LD_M_FILE_DESC wtx_fdesc;
+
+  memset (&wtx_fdesc, 0, sizeof (wtx_fdesc));
+  wtx_fdesc.filename = filename;
+  wtx_fdesc.loadFlag = load_flags;
+
+  wtx_minfo = wtx_obj_module_load (current_wtx_handle, &wtx_fdesc);
+
+  if (!wtx_minfo)
+    return NULL;
+  minfo = wtxapi_obj_module_info_get (wtxapi_pd_current_get (),
+                                      wtx_minfo->moduleId);
+  if (minfo->undef_list)
+    minfo->undef_list->wtx_result_to_cleanup = (void *) wtx_minfo;
+#endif
+  return minfo;
+}
+
+/* The same as wtxapi_obj_module_load except that it temporary changes
+   the WTX timeout value to the given TIMEOUT.  
+   
+   Basically, this function changes the WTX timeout to TIMEOUT,
+   calls wtxapi_obj_module_load, and then restores the old timeout.  */
+
+struct wtxapi_module_info *
+wtxapi_module_load (pd_id_t pd_id, char *filename, int load_flag, int timeout)
+{
+  int saved_timeout;
+  struct wtxapi_module_info *module_info;
+
+  wtxapi_timeout_get (&saved_timeout);
+  wtxapi_timeout_set (timeout);
+  module_info = wtxapi_obj_module_load (pd_id, filename, load_flag);
+  wtxapi_timeout_set (saved_timeout);
+
+  return module_info;
+}
+
+/* Unload an obj module from target.  */
+
+int
+wtxapi_obj_module_unload (pd_id_t pd_id, module_id_t mod_id)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_obj_module_unload (current_wtx_handle, pd_id, 0,
+                                mod_id) != WTX_ERROR;
+#else
+  return wtx_obj_module_unload (current_wtx_handle, mod_id) != WTX_ERROR;
+#endif
+}
+
+/* Unload an obj. module from target.  */
+
+int
+wtxapi_obj_module_by_name_unload (pd_id_t pd_id, char *name)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_obj_module_by_name_unload (current_wtx_handle, pd_id, 0,
+                                        name) != WTX_ERROR;
+#else
+  return wtx_obj_module_by_name_unload (current_wtx_handle, name) != WTX_ERROR;
+#endif
+}
+
+/* Send events matching expression.  */
+
+int
+wtxapi_register_for_event (const char *reg_exp)
+{
+  return wtx_register_for_event (current_wtx_handle, reg_exp) != WTX_ERROR;
+}
+
+/* Read register data from the target.  */
+
+int
+wtxapi_regs_get (WTX_CONTEXT_TYPE context_type,
+                 WTX_CONTEXT_ID_T context_id, WTX_REG_SET_TYPE reg_set,
+                 int first_byte, int num_bytes, void *reg_memory)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+  return wtx_regs_get (current_wtx_handle,
+                       MARSHALL_WTX_CONTEXT_PARAM (context), reg_set,
+                       first_byte, num_bytes, reg_memory) != WTX_ERROR;
+}
+
+/* Write to registers on the target.  */
+
+int
+wtxapi_regs_set (WTX_CONTEXT_TYPE context_type, WTX_CONTEXT_ID_T context_id,
+                 WTX_REG_SET_TYPE reg_set, int first_byte, int num_bytes,
+                 void *reg_memory)
+{
+  WTX_CONTEXT context;
+  initialize_context (&context, context_type, context_id);
+  return wtx_regs_set (current_wtx_handle,
+                       MARSHALL_WTX_CONTEXT_PARAM (context), reg_set,
+                       first_byte, num_bytes, reg_memory) != WTX_ERROR;
+}
+
+/* Convert str to a wtxapi_tgt_addr_t.  */
+
+wtxapi_tgt_addr_t
+wtxapi_str_to_tgt_addr (const char *str)
+{
+  return wtx_str_to_tgt_addr (current_wtx_handle, str);
+}
+
+/* Convert str to context ID.  */
+
+WTX_CONTEXT_ID_T
+wtxapi_str_to_context_id (const char *str)
+{
+  return wtx_str_to_context_id (current_wtx_handle, str);
+}
+
+/* Convert str ton context type.  */
+
+WTX_CONTEXT_TYPE
+wtxapi_str_to_context_type (const char *str)
+{
+  return wtx_str_to_context_type (current_wtx_handle, str);
+}
+
+/* Convert str to an int.  */
+
+int
+wtxapi_str_to_int32 (const char *str)
+{
+  return wtx_str_to_int32 (current_wtx_handle, str);
+}
+
+/* Convert string to event type.  */
+
+WTX_EVENT_TYPE
+wtxapi_str_to_event_type (const char *str)
+{
+  return wtx_str_to_event_type (current_wtx_handle, str);
+}
+
+/* Add symbol with given params.  */
+
+int
+wtxapi_sym_add (pd_id_t pd_id, const char *sym_name,
+                wtxapi_tgt_addr_t sym_value, int sym_type)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_sym_add (current_wtx_handle, pd_id, sym_name, sym_value,
+                      sym_type) != WTX_ERROR;
+#else
+  return wtx_sym_add (current_wtx_handle, sym_name, sym_value,
+                      (UINT8) sym_type) != WTX_ERROR;
+#endif
+}
+
+static struct wtxapi_symbol_list *
+new_wtxapi_symbol_list (WTX_SYM_LIST *wtx_sym)
+{
+  struct wtxapi_symbol_list *sym_list;
+
+  if (!wtx_sym)
+    return NULL;
+
+  sym_list = (struct wtxapi_symbol_list *)
+    xmalloc (sizeof (struct wtxapi_symbol_list));
+  sym_list->wtx_result_to_cleanup = (void *) wtx_sym;
+  sym_list->first = wtx_sym->pSymbol;
+  sym_list->current = sym_list->first;
+  return sym_list;
+}
+
+static struct wtxapi_symbol_list *
+new_wtxapi_symbol_list_from_symbol (WTX_SYMBOL *wtx_sym)
+{
+  struct wtxapi_symbol_list *sym_list;
+
+  if (!wtx_sym)
+    return NULL;
+
+  sym_list = (struct wtxapi_symbol_list *)
+    xmalloc (sizeof (struct wtxapi_symbol_list));
+  sym_list->wtx_result_to_cleanup = (void *) wtx_sym;
+  sym_list->first = wtx_sym;
+  sym_list->current = wtx_sym;
+  return sym_list;
+}
+
+/* Find info on symbol.  Based on wtxSymFind WTX 2.0, with two differences:
+   _ one additional parameter: the protection domain ID (PD_ID);
+   _ no filter on the type.  */
+
+struct wtxapi_symbol_list *
+wtxapi_sym_find (pd_id_t pd_id, char *sym_name,
+                 wtxapi_tgt_addr_t sym_value, int exact_name)
+{
+#if WTX_PROT_VERSION != 2
+  WTX_SYM_FIND_CRITERIA criteria;
+  memset (&criteria, 0, sizeof (criteria));
+  criteria.pdId = pd_id;
+  criteria.type = 0;
+  criteria.nSymbols = 1;
+  criteria.ref = 0;
+  criteria.moduleId = 0;
+  criteria.moduleName = NULL;
+
+  if (sym_name)
+    {
+      criteria.findName = sym_name;
+      criteria.findValue = 0;
+      criteria.options |= WTX_SYM_FIND_BY_NAME;
+
+      if (exact_name)
+        criteria.options |= WTX_SYM_FIND_BY_EXACT_NAME;
+    }
+  else
+    {
+      criteria.findName = NULL;
+      criteria.findValue = sym_value;
+      criteria.options |= WTX_SYM_FIND_BY_VALUE;
+
+      if (exact_name)
+        criteria.options |= WTX_SYM_FIND_BY_EXACT_VALUE;
+    }
+
+  return new_wtxapi_symbol_list_from_symbol (wtx_sym_find (current_wtx_handle,
+                                                           &criteria));
+#else
+  return new_wtxapi_symbol_list_from_symbol (wtx_sym_find (current_wtx_handle,
+                                                           sym_name,
+                                                           sym_value,
+                                                           exact_name, 0, 0));
+#endif
+}
+
+/* Get list of symbols.  Based on wtxSymListGet WTX 2.0, with three differences:
+   - one additional parameter: the protection domain ID (PD_ID);
+   - no filter on the unknown symbols;
+   - no filter on the module name/id.  */
+
+struct wtxapi_symbol_list *
+wtxapi_sym_list_get (pd_id_t pd_id, char *substring, wtxapi_tgt_addr_t value)
+{
+  struct wtxapi_symbol_list *sym_list;
+  WTX_SYM_LIST *wtx_sym_list;
+#if WTX_PROT_VERSION != 2
+  WTX_SYM_FIND_CRITERIA criteria;
+  memset (&criteria, 0, sizeof (criteria));
+  criteria.pdId = pd_id;
+  criteria.type = 0;
+  criteria.nSymbols = 0;
+  criteria.ref = 0;
+  criteria.moduleId = 0;
+  criteria.moduleName = NULL;
+
+  if (substring)
+    {
+      criteria.findName = substring;
+      criteria.findValue = 0;
+      criteria.options |= WTX_SYM_FIND_BY_NAME;
+    }
+  else
+    {
+      criteria.findName = NULL;
+      criteria.findValue = value;
+      criteria.options |= WTX_SYM_FIND_BY_VALUE;
+    }
+
+  wtx_sym_list = wtx_sym_list_get (current_wtx_handle, &criteria);
+#else
+  wtx_sym_list =
+    wtx_sym_list_get (current_wtx_handle, substring, NULL, value, FALSE);
+#endif
+  sym_list = new_wtxapi_symbol_list (wtx_sym_list);
+  return sym_list;
+}
+
+/* Get list of symbols.  */
+
+struct wtxapi_symbol_list *
+wtxapi_sym_list_by_module_id_get (pd_id_t pd_id, const char *string,
+                                  module_id_t module_id,
+                                  wtxapi_tgt_addr_t value,
+                                  int list_unknown)
+{
+#if WTX_PROT_VERSION != 2
+  return new_wtxapi_symbol_list
+    (wtx_sym_list_by_module_id_get (current_wtx_handle, pd_id, string,
+                                    module_id, value, TO_BOOL (list_unknown)));
+#else
+  return new_wtxapi_symbol_list
+    (wtx_sym_list_by_module_id_get (current_wtx_handle, string, module_id,
+                                    value, TO_BOOL (list_unknown)));
+#endif
+}
+
+/* Get list of symbols.  */
+
+struct wtxapi_symbol_list *
+wtxapi_sym_list_by_module_name_get (pd_id_t pd_id, const char *string,
+                                    const char *module_name,
+                                    wtxapi_tgt_addr_t value,
+                                    int list_unknown)
+{
+#if WTX_PROT_VERSION != 2
+  return new_wtxapi_symbol_list
+    (wtx_sym_list_by_module_name_get (current_wtx_handle, pd_id, string,
+                                      module_name, value,
+                                      TO_BOOL (list_unknown)));
+#else
+  return new_wtxapi_symbol_list
+    (wtx_sym_list_by_module_name_get (current_wtx_handle, string,
+                                      module_name, value,
+                                      TO_BOOL (list_unknown)));
+#endif
+}
+
+/* Remove a symbol from sym table.  */
+
+int
+wtxapi_sym_remove (pd_id_t pd_id, const char *sym_name, int sym_type)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_sym_remove (current_wtx_handle, pd_id, sym_name,
+                         sym_type) != WTX_ERROR;
+#else
+  return wtx_sym_remove (current_wtx_handle, sym_name, sym_type) != WTX_ERROR;
+#endif
+}
+
+/* Return sym table info.  */
+
+struct wtxapi_sym_tbl_info *
+wtxapi_sym_tbl_info_get (pd_id_t pd_id)
+{
+  WTX_SYM_TBL_INFO *wtx_tbl_info;
+  struct wtxapi_sym_tbl_info *tbl_info;
+  pd_id_t current_pd_id;
+#if WTX_PROT_VERSION != 2
+  wtx_tbl_info = wtx_sym_tbl_info_get (current_wtx_handle, pd_id);
+  current_pd_id = wtx_tbl_info->pdId;
+#else
+  wtx_tbl_info = wtx_sym_tbl_info_get (current_wtx_handle);
+  current_pd_id = NULL_PD;
+#endif
+
+  if (!wtx_tbl_info)
+    return NULL;
+
+  tbl_info = (struct wtxapi_sym_tbl_info *)
+    xmalloc (sizeof (struct wtxapi_sym_tbl_info));
+  tbl_info->pd_id = current_pd_id;
+  tbl_info->sym_num = wtx_tbl_info->symNum;
+  tbl_info->same_name_ok = (wtx_tbl_info->sameNameOk == TRUE);
+  wtx_result_free (current_wtx_handle, wtx_tbl_info);
+  return tbl_info;
+}
+
+/* Reset the target.  */
+
+int
+wtxapi_target_reset ()
+{
+  return wtx_target_reset (current_wtx_handle) != WTX_ERROR;
+}
+
+/* Get target server name.  */
+
+const char *
+wtxapi_ts_name_get ()
+{
+  return wtx_ts_name_get (current_wtx_handle);
+}
+
+/* Get the target CPU type code.  */
+
+int
+wtxapi_target_cpu_type_get ()
+{
+  return wtx_target_cpu_type_get (current_wtx_handle);
+}
+
+/* Check for floating point processor.  */
+
+int
+wtxapi_target_has_fpp_get ()
+{
+  return wtx_target_has_fpp_get (current_wtx_handle);
+}
+
+/* Get edianness of target.  */
+
+WTX_ENDIAN_T
+wtxapi_target_endian_get ()
+{
+  return wtx_target_endian_get (current_wtx_handle);
+}
+
+/* Get target boot line info (or NULL on error).
+ 
+   The string returned is a pointer to temporary memory, and should
+   be duplicated if it is to be stored.  */
+
+const char *
+wtxapi_target_bootline_get ()
+{
+  return wtx_target_bootline_get (current_wtx_handle);
+}
+
+/* Return name of current tool.  */
+
+const char *
+wtxapi_tool_name_get ()
+{
+  return wtx_tool_name_get (current_wtx_handle);
+}
+
+/* Return the Tornado version.  */
+
+const char *
+wtxapi_ts_version_get ()
+{
+  return wtx_ts_version_get (current_wtx_handle);
+}
+
+/* Return the version of WTX.  */
+int
+wtxapi_version_get ()
+{
+  return WTX_PROT_VERSION;
+}
+
+/* Unregister for some events.  */
+
+int
+wtxapi_unregister_for_event (char *reg_exp)
+{
+  return wtx_unregister_for_event (current_wtx_handle, reg_exp) != WTX_ERROR;
+}
+
+/* Call func on target within agent.  */
+
+int
+wtxapi_direct_call (wtxapi_tgt_addr_t entry, void *p_ret_val,
+                    wtxapi_tgt_arg_t arg0, wtxapi_tgt_arg_t arg1,
+                    wtxapi_tgt_arg_t arg2, wtxapi_tgt_arg_t arg3,
+                    wtxapi_tgt_arg_t arg4, wtxapi_tgt_arg_t arg5,
+                    wtxapi_tgt_arg_t arg6, wtxapi_tgt_arg_t arg7,
+                    wtxapi_tgt_arg_t arg8, wtxapi_tgt_arg_t arg9)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_direct_call (current_wtx_handle, entry, p_ret_val, 10, arg0, arg1,
+                          arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+                          arg9) != WTX_ERROR;
+#else
+  return wtx_direct_call (current_wtx_handle, entry, p_ret_val, arg0, arg1,
+                          arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+                          arg9) != WTX_ERROR;
+#endif
+}
+
+/* Get info about target and server.  */
+
+struct wtxapi_ts_info *
+wtxapi_ts_info_get ()
+{
+  static const char vxworks_prefix[] = "VxWorks";
+  WTX_TS_INFO *wtx_tsinfo = wtx_ts_info_get (current_wtx_handle);
+  struct wtxapi_ts_info *ts_info;
+  char *version;
+  if (!wtx_tsinfo)
+    return NULL;
+
+  ts_info = (struct wtxapi_ts_info *)
+    xmalloc (sizeof (struct wtxapi_ts_info));
+  memset (ts_info, 0, sizeof (struct wtxapi_ts_info));
+  ts_info->tgt_link_desc = wtx_tsinfo->tgtLinkDesc;
+
+#if WTX_PROT_VERSION != 2
+  if (wtx_tsinfo->tgtInfo.rtInfo.rtName)
+    ts_info->tgt_info.rt_info.rt_name =
+      xstrdup (wtx_tsinfo->tgtInfo.rtInfo.rtName);
+  if (wtx_tsinfo->tgtInfo.rtInfo.rtVersion)
+    ts_info->tgt_info.rt_info.rt_version =
+      xstrdup (wtx_tsinfo->tgtInfo.rtInfo.rtVersion);
+#else
+  /* On VxWorks 5, the runtime name is not included into the rt info;
+     instead, the version information is prefixed by "vxWorks".
+     Strip it the prefix, move it to rt_name.  */
+  version = wtx_tsinfo->tgtInfo.rtInfo.rtVersion;
+  if (version)
+    {
+      if (strncmp (vxworks_prefix, version, strlen (vxworks_prefix)) == 0)
+        version += strlen (vxworks_prefix);
+      ts_info->tgt_info.rt_info.rt_version = xstrdup (version);
+    }
+  ts_info->tgt_info.rt_info.rt_name = xstrdup (vxworks_prefix);
+#endif
+  ts_info->tgt_info.rt_info.cpu_type =
+    wtx_tsinfo->tgtInfo.rtInfo.cpuType;
+
+#if WTX_PROT_VERSION > 3
+  if (wtx_tsinfo->tgtInfo.rtInfo.cpuVariant)
+    ts_info->tgt_info.rt_info.cpu_variant =
+      xstrdup (wtx_tsinfo->tgtInfo.rtInfo.cpuVariant);
+#endif
+
+  ts_info->tgt_info.rt_info.has_write_protect =
+    wtx_tsinfo->tgtInfo.rtInfo.hasWriteProtect;
+  ts_info->tgt_info.rt_info.page_size =
+    wtx_tsinfo->tgtInfo.rtInfo.pageSize;
+  ts_info->tgt_info.rt_info.endian =
+    wtx_tsinfo->tgtInfo.rtInfo.endian;
+  if (wtx_tsinfo->tgtInfo.rtInfo.bspName)
+    ts_info->tgt_info.rt_info.bsp_name =
+      xstrdup (wtx_tsinfo->tgtInfo.rtInfo.bspName);
+  if (wtx_tsinfo->tgtInfo.rtInfo.bootline)
+    ts_info->tgt_info.rt_info.boot_line =
+      xstrdup (wtx_tsinfo->tgtInfo.rtInfo.bootline);
+  ts_info->tgt_info.rt_info.mem_base =
+    wtx_tsinfo->tgtInfo.rtInfo.memBase;
+  ts_info->tgt_info.rt_info.mem_size =
+    wtx_tsinfo->tgtInfo.rtInfo.memSize;
+  ts_info->tgt_info.rt_info.num_regions =
+    wtx_tsinfo->tgtInfo.rtInfo.numRegions;
+  ts_info->tgt_info.rt_info.host_pool_base =
+    wtx_tsinfo->tgtInfo.rtInfo.hostPoolBase;
+  ts_info->tgt_info.rt_info.host_pool_size =
+    wtx_tsinfo->tgtInfo.rtInfo.hostPoolSize;
+  ts_info->tgt_info.agent_info.agent_version =
+    wtx_tsinfo->tgtInfo.agentInfo.agentVersion;
+  ts_info->tgt_info.agent_info.mtu =
+    wtx_tsinfo->tgtInfo.agentInfo.mtu;
+  ts_info->tgt_info.agent_info.mode =
+    wtx_tsinfo->tgtInfo.agentInfo.mode;
+
+  if (wtx_tsinfo->version)
+    ts_info->version = xstrdup (wtx_tsinfo->version);
+  if (wtx_tsinfo->userName)
+    ts_info->user_name = xstrdup (wtx_tsinfo->userName);
+  if (wtx_tsinfo->lockMsg)
+    ts_info->lock_msg = xstrdup (wtx_tsinfo->lockMsg);
+#if WTX_PROT_VERSION != 2
+  ts_info->pd_initialized = (wtx_tsinfo->pdInitialized == TRUE);
+#else
+  ts_info->pd_initialized = 1;
+#endif
+  return ts_info;
+}
+
+/* Reattach to the target.  */
+
+int
+wtxapi_target_attach ()
+{
+  return wtx_target_attach (current_wtx_handle) != WTX_ERROR;
+}
+
+/* Probe to see if registry is running.  */
+
+int
+wtxapi_probe ()
+{
+  return wtx_probe (current_wtx_handle) != WTX_ERROR;
+}
+
+/* Set WTX timeout.  */
+
+int
+wtxapi_timeout_set (int msec)
+{
+  return wtx_timeout_set (current_wtx_handle, msec) != WTX_ERROR;
+}
+
+/* Get the current timeout.  */
+
+int
+wtxapi_timeout_get (int *p_msec)
+{
+  UINT32 wtx_timeout;
+  int result = wtx_timeout_get (current_wtx_handle, &wtx_timeout) != WTX_ERROR;
+  *p_msec = wtx_timeout;
+  return result;
+}
+
+/* Create a new protection domain.  */
+
+pd_id_t
+wtxapi_pd_create (const char *name, int options, int heap_size,
+                  int low_priority, int high_priority,
+                  wtxapi_tgt_addr_t page_pool_list, const char *link_path)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_pd_create (current_wtx_handle, name, options, heap_size,
+                        low_priority, high_priority, page_pool_list,
+                        link_path);
+#else
+  return NULL_PD;
+#endif
+}
+
+/* Get kernel Protection Domain ID.  */
+
+pd_id_t
+wtxapi_pd_kernel_get ()
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_pd_kernel_get (current_wtx_handle);
+#else
+  return NULL_PD;
+#endif
+}
+
+/* Get the current Protection Domain.  */
+
+pd_id_t
+wtxapi_pd_current_get ()
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_pd_current_get (current_wtx_handle);
+#else
+  return NULL_PD;
+#endif
+}
+
+/* Set the current Protection Domain.  Return non-zero if the operation
+   was successful.  Otherwise, sets the WTX error (to be retrieved using
+   wtx_err_get).  */
+
+int
+wtxapi_pd_current_set (pd_id_t pd_id)
+{
+#if WTX_PROT_VERSION != 2
+  return wtx_pd_current_set (current_wtx_handle, pd_id) != WTX_ERROR;
+#else
+  return pd_id == NULL_PD;
+#endif
+}
+
+/* Get the list of allocated PDs.  */
+
+/* NOTE: it performs a full copy of the PD description list.  It should
+   not be a problem, we should not expect to many PDs.  If there are
+   some speed issues, the solution would be to have the same kind of
+   model we use for wtxapi_symbol_list.  To be investigated.  */
+
+struct wtxapi_pd_desc_q *
+wtxapi_pd_info_q_get ()
+{
+  struct wtxapi_pd_desc_q *pd_desc_list;
+#if WTX_PROT_VERSION != 2
+  WTX_PD_DESC_Q *wtx_pd_desc_q = wtx_pd_info_q_get (current_wtx_handle);
+  WTX_PD_DESC_Q *current_wtx_desc = wtx_pd_desc_q;
+  struct wtxapi_pd_desc_q *current_desc;
+  int ix;
+
+  if (wtx_pd_desc_q == NULL)
+    return NULL;
+
+  pd_desc_list = (struct wtxapi_pd_desc_q *)
+    xmalloc (sizeof (struct wtxapi_pd_desc_q));
+  current_desc = pd_desc_list;
+
+  for (current_wtx_desc = wtx_pd_desc_q;
+       current_wtx_desc != NULL;
+       current_wtx_desc = current_wtx_desc->pNext)
+    {
+      current_desc->pd_desc.pd_id = current_wtx_desc->wtxPdDesc.pdId;
+      if (current_wtx_desc->wtxPdDesc.pdName)
+        current_desc->pd_desc.pd_name =
+          xstrdup (current_wtx_desc->wtxPdDesc.pdName);
+      current_desc->pd_desc.pd_flags = current_wtx_desc->wtxPdDesc.pdFlags;
+      if (current_wtx_desc->wtxPdDesc.pdLinkPathStr)
+        current_desc->pd_desc.pd_link_path_str =
+          xstrdup (current_wtx_desc->wtxPdDesc.pdLinkPathStr);
+      current_desc->pd_desc.pd_link_path_count =
+        current_wtx_desc->wtxPdDesc.pdLinkPathCount;
+      if (current_wtx_desc->wtxPdDesc.pdLinkPathCount)
+        {
+          current_desc->pd_desc.pd_link_path = (pd_id_t *)
+            xmalloc (current_wtx_desc->wtxPdDesc.pdLinkPathCount
+                     * sizeof (pd_id_t));
+          for (ix = 0; ix < current_wtx_desc->wtxPdDesc.pdLinkPathCount; ix++)
+            current_desc->pd_desc.pd_link_path[ix]
+              = current_wtx_desc->wtxPdDesc.pdLinkPath[ix];
+
+        }
+      else
+        {
+          current_desc->pd_desc.pd_link_path = NULL;
+        }
+      if (current_wtx_desc->wtxPdDesc.pdAttachToCount)
+        {
+          current_desc->pd_desc.pd_attach_to_count =
+            current_wtx_desc->wtxPdDesc.pdAttachToCount;
+          current_desc->pd_desc.pd_attach_to = (pd_id_t *)
+            xmalloc (current_wtx_desc->wtxPdDesc.pdAttachToCount
+                     * sizeof (pd_id_t));
+          for (ix = 0; ix < current_wtx_desc->wtxPdDesc.pdAttachToCount; ix++)
+            current_desc->pd_desc.pd_attach_to[ix]
+              = current_wtx_desc->wtxPdDesc.pdAttachTo[ix];
+        }
+      else
+        {
+          current_desc->pd_desc.pd_attach_to = NULL;
+        }
+
+      if (current_wtx_desc->pNext != NULL)
+        {
+          current_desc->next = (struct wtxapi_pd_desc_q *)
+            xmalloc (sizeof (struct wtxapi_pd_desc_q));
+          current_desc = current_desc->next;
+        }
+      else
+        current_desc->next = NULL;
+    }
+  wtx_result_free (current_wtx_handle, wtx_pd_desc_q);
+#else
+  pd_desc_list = (struct wtxapi_pd_desc_q *)
+    xmalloc (sizeof (struct wtxapi_pd_desc_q));
+  memset (&pd_desc_list, 0, sizeof (pd_desc_list));
+  pd_desc_list->pd_desc.pd_name = xstrdup ("kernel");
+  pd_desc_list->pd_desc.pd_link_path_str = xstrdup ("<none>");
+#endif
+  return pd_desc_list;
+}
+
+/* Return non-zero if the given module has been fully linked,
+   or, in other words, relocation has already been performed.  */
+
+int
+wtxapi_load_fully_linked (const struct wtxapi_module_info *module_info)
+{
+  /* The WTX_LOAD_FULLY_LINKED macro has been introduced *after* Vxworks 5.x.  
+     For Vxworks 5.x targets, we simply define it ourselves.  */
+#ifndef WTX_LOAD_FULLY_LINKED
+#define WTX_LOAD_FULLY_LINKED 0x20
+#endif
+
+  return module_info->load_flag & WTX_LOAD_FULLY_LINKED;
+}
+
+/* Test target server availability.  */
+
+int
+wtxapi_target_server_available_p ()
+{
+  WTX_TS_INFO *ts_info = wtx_ts_info_get (current_wtx_handle);
+  return ts_info != NULL;
+}
+
+
+/* Symbol list handling.  */
+
+struct wtxapi_symbol *
+get_current_wtxapi_symbol (struct wtxapi_symbol_list *list)
+{
+  struct wtxapi_symbol *sym;
+  if (!list || !list->current)
+    return NULL;
+
+  sym = (struct wtxapi_symbol *) xmalloc (sizeof (struct wtxapi_symbol));
+  copy_current_wtxapi_symbol (list, sym, wtxapi_symbol_copy_full);
+  return sym;
+}
+
+void
+copy_current_wtxapi_symbol (struct wtxapi_symbol_list *list,
+                            struct wtxapi_symbol *to, int options)
+{
+  if (!to || !list || !list->current)
+    return;
+
+  to->status = list->current->status;
+#if WTX_PROT_VERSION != 2
+  to->pd_id = list->current->pdId;
+#else
+  to->pd_id = NULL_PD;
+#endif
+  if (options != wtxapi_symbol_copy_dont_copy_name
+      && options != wtxapi_symbol_copy_dont_copy_strings
+      && list->current->name)
+    to->name = xstrdup (list->current->name);
+  else
+    to->name = NULL;
+
+  if (options != wtxapi_symbol_copy_dont_copy_module_name
+      && options != wtxapi_symbol_copy_dont_copy_strings
+      && list->current->moduleName)
+    to->module_name = xstrdup (list->current->moduleName);
+  else
+    to->module_name = NULL;
+
+  to->exact_name = (list->current->exactName == TRUE);
+  to->value = list->current->value;
+  to->type = list->current->type;
+  to->type_mask = list->current->typeMask;
+}
+
+char *
+current_wtxapi_symbol_name (struct wtxapi_symbol_list *list)
+{
+  return xstrdup (list->current->name);
+}
+
+int
+go_to_first_element_in_wtxapi_sym_list (struct wtxapi_symbol_list *list)
+{
+  if (!list || !list->first)
+    return 0;
+
+  list->current = list->first;
+  return 1;
+}
+
+int
+go_to_next_element_in_wtxapi_sym_list (struct wtxapi_symbol_list *list)
+{
+  if (!list->current || !list->current->next)
+    return 0;
+
+  list->current = list->current->next;
+  return 1;
+}
+
+/* Deallocation functions.  */
+
+void
+free_wtxapi_evtpt_list (struct wtxapi_evtpt_list *to_free)
+{
+  int ix;
+  for (ix = 0; ix < to_free->n_evtpt; ix++)
+    {
+      xfree (to_free->p_evtpt_info[ix].wtx_evtpt.event.args);
+    }
+  xfree (to_free->p_evtpt_info);
+  xfree (to_free);
+}
+
+void
+free_wtxapi_module_list (struct wtxapi_module_list *to_free)
+{
+  xfree (to_free->mod_id_array);
+  xfree (to_free->pd_id_array);
+  xfree (to_free);
+}
+
+void
+free_wtxapi_pd_desc_q (struct wtxapi_pd_desc_q *to_free)
+{
+  struct wtxapi_pd_desc_q *current;
+  struct wtxapi_pd_desc_q *element_to_deallocate = NULL;
+
+  for (current = to_free; current != NULL; current = current->next)
+    {
+      if (element_to_deallocate)
+        xfree (element_to_deallocate);
+      if (current->pd_desc.pd_name)
+        xfree (current->pd_desc.pd_name);
+      if (current->pd_desc.pd_link_path_str)
+        xfree (current->pd_desc.pd_link_path_str);
+      if (current->pd_desc.pd_link_path)
+        xfree (current->pd_desc.pd_link_path);
+      if (current->pd_desc.pd_attach_to)
+        xfree (current->pd_desc.pd_attach_to);
+      element_to_deallocate = current;
+    }
+}
+
+void
+free_wtxapi_symbol (struct wtxapi_symbol *to_free)
+{
+  if (to_free->name)
+    xfree (to_free->name);
+
+  if (to_free->module_name)
+    xfree (to_free->module_name);
+
+  xfree (to_free);
+}
+
+void
+free_wtxapi_symbol_list (struct wtxapi_symbol_list *to_free)
+{
+  if (to_free->wtx_result_to_cleanup != NULL)
+    wtx_result_free (current_wtx_handle, to_free->wtx_result_to_cleanup);
+
+  xfree (to_free);
+}
+
+void
+free_wtxapi_module_info (struct wtxapi_module_info *to_free)
+{
+  xfree (to_free->module_name);
+  if (to_free->section_addrs != NULL)
+    free_section_addr_info (to_free->section_addrs);
+  if (to_free->segments != NULL)
+    xfree (to_free->segments);
+  if (to_free->undef_list)
+    free_wtxapi_symbol_list (to_free->undef_list);
+  xfree (to_free);
+}
+
+void
+free_wtxapi_ts_info (struct wtxapi_ts_info *to_free)
+{
+  if (to_free->tgt_info.rt_info.rt_name)
+    xfree (to_free->tgt_info.rt_info.rt_name);
+
+  if (to_free->tgt_info.rt_info.cpu_variant)
+    xfree (to_free->tgt_info.rt_info.cpu_variant);
+
+  if (to_free->tgt_info.rt_info.rt_version)
+    xfree (to_free->tgt_info.rt_info.rt_version);
+
+  if (to_free->tgt_info.rt_info.bsp_name)
+    xfree (to_free->tgt_info.rt_info.bsp_name);
+
+  if (to_free->tgt_info.rt_info.boot_line)
+    xfree (to_free->tgt_info.rt_info.boot_line);
+
+  if (to_free->version)
+    xfree (to_free->version);
+
+  if (to_free->user_name)
+    xfree (to_free->user_name);
+
+  if (to_free->lock_msg)
+    xfree (to_free->lock_msg);
+
+  xfree (to_free);
+}
+
+void
+free_wtxapi_event_desc (struct wtxapi_event_desc *to_free)
+{
+  switch (to_free->event_type)
+    {
+      case WTX_EVENT_OBJ_UNLOADED:
+        xfree (to_free->desc.obj_unloaded.module_filename);
+        break;
+      case WTX_EVENT_VIO_WRITE:
+        xfree (to_free->desc.vio_write.data);
+        break;
+    }
+
+  xfree (to_free);
+}
+
+
+/* cleanup functions.  */
+
+void
+cleanup_wtxapi_evtpt_list (void *to_free)
+{
+  free_wtxapi_evtpt_list ((struct wtxapi_evtpt_list *) to_free);
+}
+
+void
+cleanup_wtxapi_module_list (void *to_free)
+{
+  free_wtxapi_module_list ((struct wtxapi_module_list *) to_free);
+}
+
+void
+cleanup_wtxapi_pd_desc_q (void *to_free)
+{
+  free_wtxapi_pd_desc_q ((struct wtxapi_pd_desc_q *) to_free);
+}
+
+void
+cleanup_wtxapi_symbol (void *to_free)
+{
+  free_wtxapi_symbol ((struct wtxapi_symbol *) to_free);
+}
+
+void
+cleanup_wtxapi_symbol_list (void *to_free)
+{
+  free_wtxapi_symbol_list ((struct wtxapi_symbol_list *) to_free);
+}
+
+void
+cleanup_wtxapi_module_info (void *to_free)
+{
+  free_wtxapi_module_info ((struct wtxapi_module_info *) to_free);
+}
+
+void
+cleanup_wtxapi_ts_info (void *to_free)
+{
+  free_wtxapi_ts_info ((struct wtxapi_ts_info *) to_free);
+}
+
+void
+cleanup_wtxapi_result_free (void *to_free)
+{
+  wtxapi_result_free (to_free);
+}
+
+
+/* Implements simple symbol lookup.  */
+
+int
+remote_wtxapi_get_symbol_address (char *symbol_name, CORE_ADDR *symbol_addr)
+{
+  struct wtxapi_symbol_list *symbol_list;
+  struct wtxapi_symbol *symbol_info;
+
+  symbol_list = wtxapi_sym_find (wtxapi_pd_current_get (), symbol_name, 0, 1);
+  symbol_info = get_current_wtxapi_symbol (symbol_list);
+
+  if (symbol_info != NULL)
+    {
+      *symbol_addr = symbol_info->value;
+
+      free_wtxapi_symbol (symbol_info);
+      free_wtxapi_symbol_list (symbol_list);
+      return 0;
+    }
+  else
+    {
+      *symbol_addr = 0;
+      return -1;
+    }
+}
+
+/* Return non-zero if BoDA support (Breakpoint on Data Access) is available
+   on the system we're connected to.  This routine assumes that we are
+   connected to the target server.  */
+
+int
+wtxapi_target_has_BoDA (void)
+{
+  /* Will be set to 1 as soon as we've checked whether the system
+     we're running on provides BoDA or not.  This is used to determine
+     whether BoDA_supported_p has been set yet, or not.  */
+  static int BoDA_support_checked_p = 0;
+
+  /* Set to non-zero if BoDA is supported on the system.  Set iff
+     BoDA_support_checked_p is non-zero.
+
+     We're checking the support for BoDA in a lazy fashion, because
+     it's a tiny bit expensive (need to do a symbol lookup), and because
+     we need to be connected to the system before we do so.  We could
+     be doing that check after connecting with the target server, but
+     that would be useless during the sessions when watchpoints are
+     not actually used.  So we wait until we need to have this info
+     before we actually do the check.  */
+  static int BoDA_supported_p = 0;
+
+  if (!BoDA_support_checked_p)
+    {
+      /* BoDA is supported by the target iff the symbol wdbEventClassHwBpVa
+         is defined in the Core OS partition.  Instead of trying to find
+         the PD ID of the Core OS partition, we just seach the symbol
+         in all partitions.  It's unlikely that any other partition
+         would define a symbol using that name, so accept that risk.  */
+      struct wtxapi_symbol_list *symbol_list;
+
+      symbol_list = wtxapi_sym_find (WTX_SYM_FIND_IN_ALL_PD,
+                                     "wdbEventClassHwBpVa", 0, 1);
+
+      if (symbol_list != NULL)
+        {
+          BoDA_supported_p = 1;
+          free_wtxapi_symbol_list (symbol_list);
+        }
+
+      BoDA_support_checked_p = 1;
+    }
+
+  return BoDA_supported_p;
+}
+
+/* Free the memory allocated by the given THREADS list.  */
+
+void
+free_wtxapi_thread_info (struct wtxapi_thread_info *threads)
+{
+  struct wtxapi_thread_info *this = threads;
+  struct wtxapi_thread_info *next;
+
+  while (this != NULL)
+    {
+      next = this->next;
+      xfree (this->name);
+      xfree (this);
+      this = next;
+    }
+}
+
+/* Routines implemented using the support of external modules.  */
+
+static struct wtxapi_support_ops *support_ops = NULL;
+
+/* Setup the current wtx_support_ops vector to OPS.  */
+
+void
+wtxapi_set_support_ops (struct wtxapi_support_ops *ops)
+{
+  support_ops = ops;
+}
+
+/* Call the wtx_connection_established_callback method of
+   the support_ops vector.  */
+
+void
+wtxapi_notify_connection_established (void)
+{
+  /* If the support_ops structure hasn't been set, then simply
+     do nothing.  */
+  if (support_ops == NULL)
+    return;
+  gdb_assert (support_ops->wtx_connection_established_callback != NULL);
+
+  support_ops->wtx_connection_established_callback (current_wtx_handle);
+}
+
+/* Return the list of threads currently running on the target.
+
+   This routine is dependent on the support_ops vector being set,
+   or else NULL will be returned.  */
+
+struct wtxapi_thread_info *
+wtxapi_get_thread_list (void)
+{
+  /* If the support_ops structure has not be set, then return NULL.  */
+  if (support_ops == NULL)
+    return NULL;
+  gdb_assert (support_ops->get_thread_list != NULL);
+
+  return support_ops->get_thread_list ();
+}
+
+/* If TASK_ID is a valid task ID, then save its PD inside TASK_PD,
+   and return non-zero.  In case of failure, return zero, and the value
+   of TASK_PD is undefined.
+   
+   This function is dependent on the support_ops vector being set,
+   or else zero will be returned.  */
+   
+int
+wtxapi_get_task_pd (int task_id, pd_id_t *task_pd)
+{
+  /* If the support_ops structure has not be set, then return 0.  */
+  if (support_ops == NULL)
+    return 0;
+  gdb_assert (support_ops->get_task_pd != NULL);
+
+  return support_ops->get_task_pd (task_id, task_pd);
+}
+
+/* Execute the system_mode_support_p method of the wtxapi_support_ops
+   vector.
+   
+   This function is dependent on the support_ops vector being set,
+   or else zero will be returned.   */
+
+int
+wtxapi_system_mode_support_p (void)
+{
+  if (support_ops == NULL)
+    return 0;
+  gdb_assert (support_ops->system_mode_support_p != NULL);
+
+  return support_ops->system_mode_support_p ();
+}
+
+/* Execute the system_mode_get_current_context_id method of the
+   wtxapi_support_ops vector.
+   
+   This function is dependent on the support_ops vector being set,
+   or else the SYSTEM_CID will be returned.   */
+
+WTX_CONTEXT_ID_T
+wtxapi_system_mode_get_current_context_id (void)
+{
+  /* If the support_ops structure has not be set, then return 0.  */
+  if (support_ops == NULL)
+    return SYSTEM_CID;
+  gdb_assert (support_ops->system_mode_get_current_context_id != NULL);
+
+  return support_ops->system_mode_get_current_context_id ();
+}
+
+/* Return the value of VX_FP_TASK for the current target.  The value of
+   this option depends on the VxWorks version.  */
+
+int
+wtxapi_vx_fp_task ()
+{
+  struct wtxapi_ts_info *ts_info = wtxapi_ts_info_get ();
+  struct cleanup *old_cleanup = make_cleanup (cleanup_wtxapi_ts_info, ts_info);
+  char vx6_pattern[] = "6.";
+  
+  if (strncmp (vx6_pattern, ts_info->tgt_info.rt_info.rt_version,
+               strlen (vx6_pattern)) == 0)
+    return 0x1000000;
+  else
+    return 0x8;
+  do_cleanups (old_cleanup);
+}
+
+/* Ask WTX which variant is the target CPU, and compare it against
+   VARIANT.  If they match, return 1; otherwise, return 0.  */
+
+int
+wtxapi_has_target_variant (const char *variant)
+{
+  int result;
+  struct wtxapi_ts_info *ts_info = wtxapi_ts_info_get ();
+  struct cleanup *old_cleanup = make_cleanup (cleanup_wtxapi_ts_info, ts_info);
+  
+  if (ts_info->tgt_info.rt_info.cpu_variant
+      && strcmp (ts_info->tgt_info.rt_info.cpu_variant, variant) == 0)
+    result = 1;
+  else
+    result = 0;
+
+  do_cleanups (old_cleanup);
+  return result;
+}
+
+static struct cmd_list_element *info_wtx_list = NULL;
+
+/* If connected, return the targer server info; othewise, issue an error.  */
+
+static struct wtxapi_ts_info *
+get_ts_info ()
+{
+  struct wtxapi_ts_info *ts_info;
+
+  if (current_wtx_handle == NULL
+      || !(ts_info = wtxapi_ts_info_get ()))
+    error (_("Not connected to a VxWorks target."));
+
+  return ts_info;
+}
+
+static void
+info_wtx_version_command (char *args, int from_tty)
+{
+  printf_filtered (_("WTX protocol version %d\n"), wtxapi_version_get ());
+}
+
+/* Print the version of VxWorks running on the target.  */
+
+static void
+info_wtx_vxworks_version ()
+{
+  struct wtxapi_ts_info *ts_info = get_ts_info ();
+  struct cleanup *old_cleanup = make_cleanup (cleanup_wtxapi_ts_info, ts_info);
+  char *name;
+  char *version;
+
+  name = ts_info->tgt_info.rt_info.rt_name;
+  version = ts_info->tgt_info.rt_info.rt_version;
+  if (name && version)
+    printf_filtered (_("%s version %s\n"), name, version);
+  do_cleanups (old_cleanup);
+}
+
+static void
+info_wtx_threads_command (char *args, int from_tty)
+{
+  struct wtxapi_thread_info *threads = wtxapi_get_thread_list ();
+  struct wtxapi_thread_info *current_thread = threads;
+
+  if (threads == NULL)
+    {
+      printf_filtered (_("No threads.\n"));
+      return;
+    }
+
+  while (current_thread != NULL)
+    {
+      printf_filtered ("0x%lx\t%s\n", current_thread->id,
+                       current_thread->name);
+      current_thread = current_thread->next;
+    }
+  free_wtxapi_thread_info (threads);
+}
+
+/* Helper function for info_wtx_threads_command.  If INFO is not-null,
+   print it; otherwise, do nothing.  */
+
+static void
+print_info (const char *label, char *info)
+{
+  if (info)
+    printf_filtered ("%s: %s\n", label, info);
+}
+
+/* Print target server information for the current WTX connection.  */
+
+static void
+info_wtx_target_server  (char *args, int from_tty)
+{
+  struct wtxapi_ts_info *ts_info = get_ts_info ();
+  struct cleanup *old_cleanup = make_cleanup (cleanup_wtxapi_ts_info, ts_info);
+
+  printf_filtered (_("\nTarget agent:\n"));
+  print_info (_("version"),
+	      ts_info->tgt_info.agent_info.agent_version);
+  printf_filtered (_("max transfer size in bytes: %d\n"),
+		   ts_info->tgt_info.agent_info.mtu);
+  printf_filtered (_("available agent modes: %d\n"),
+		   ts_info->tgt_info.agent_info.mode);
+
+  printf_filtered (_("\nRuntime:\n"));
+  print_info (_("name"),
+	      ts_info->tgt_info.rt_info.rt_name);
+  print_info (_("version"),
+	      ts_info->tgt_info.rt_info.rt_version);
+  printf_filtered (_("target processor type: %d\n"),
+		   ts_info->tgt_info.rt_info.cpu_type);
+  print_info (_("target cpu variant"),
+	      ts_info->tgt_info.rt_info.cpu_variant);
+  printf_filtered (_("has write protect: %d\n"),
+		   ts_info->tgt_info.rt_info.has_write_protect);
+  printf_filtered (_("page size: %d\n"),
+		   ts_info->tgt_info.rt_info.page_size);
+  printf_filtered (_("endianness: %d\n"),
+		   ts_info->tgt_info.rt_info.endian);
+  print_info (_("BSP"),
+	      ts_info->tgt_info.rt_info.bsp_name);
+  print_info (_("boot file"),
+	      ts_info->tgt_info.rt_info.boot_line);
+  printf_filtered (_("target main memory base address: %#x\n"),
+		   (unsigned int) ts_info->tgt_info.rt_info.mem_base);
+  printf_filtered (_("target memory size: %d\n"),
+		   ts_info->tgt_info.rt_info.mem_size);
+  printf_filtered (_("number of memory regions: %d\n"),
+		   ts_info->tgt_info.rt_info.num_regions);
+  printf_filtered (_("target server memory pool base: %#x\n"),
+		   (unsigned int) ts_info->tgt_info.rt_info.host_pool_base);
+  printf_filtered (_("target server memory pool size: %d\n"),
+		   ts_info->tgt_info.rt_info.host_pool_size);
+  do_cleanups (old_cleanup);  
+}
+
+static void
+info_wtx_command (char *args, int from_tty)
+{
+  /* brobecker/2007-12-17: Ideally, the "info wtx" command should
+     only be a prefix command.  But we have been using it to get
+     the WTX protocol version for the past few years.  So keep this
+     command as an alias of "info wtx version" for now.  Eventually,
+     when all the GDB versions that didn't support "info wtx version"
+     are no longer supported, we can remove this compatibility hack.  */
+  info_wtx_version_command (NULL, from_tty);
+}
+
+/* Load the WTX shared libraries and initialize the pointers to WTX
+   functions.  */
+
+static void
+load_wtx_libraries ()
+{
+  void *wtx_lib = NULL;
+
+  if (WTX_PROT_VERSION == 4)
+    {
+      wtx_lib = load_shared_lib ("wtxapi41");
+
+      if (!wtx_lib)
+	wtx_lib = load_shared_lib ("wtxapi40");
+    }
+  else if (WTX_PROT_VERSION == 3)
+    {
+      wtx_lib = load_shared_lib ("wtxapi30");
+    }
+  else if (WTX_PROT_VERSION == 2)
+    {
+      wtx_lib = load_shared_lib ("wtxapi");
+    }
+
+  if (!wtx_lib)
+    error (_("WTX library not found."));
+
+#define resolve(sym, name) \
+  if (!(sym = get_symbol_from_shared_lib (wtx_lib, name))) \
+      error (_("cannot find symbol `%s' in WTX library"), name);
+
+  resolve (wtx_initialize, "wtxInitialize");
+  resolve (wtx_terminate, "wtxTerminate");
+  resolve (wtx_info_q, "wtxInfoQ");
+  resolve (wtx_tool_attach, "wtxToolAttach");
+  resolve (wtx_tool_connected, "wtxToolConnected");
+  resolve (wtx_tool_detach, "wtxToolDetach");
+  resolve (wtx_err_clear, "wtxErrClear");
+  resolve (wtx_err_get, "wtxErrGet");
+  resolve (wtx_err_handler_add, "wtxErrHandlerAdd");
+  resolve (wtx_err_handler_remove, "wtxErrHandlerRemove");
+  resolve (wtx_err_msg_get, "wtxErrMsgGet");
+  resolve (wtx_agent_mode_get, "wtxAgentModeGet");
+  resolve (wtx_agent_mode_set, "wtxAgentModeSet");
+  resolve (wtx_breakpoint_add, "wtxBreakpointAdd");
+  resolve (wtx_eventpoint_add, "wtxEventpointAdd");
+  resolve (wtx_eventpoint_delete, "wtxEventpointDelete");
+  resolve (wtx_event_get, "wtxEventGet");
+  resolve (wtx_context_status_get, "wtxContextStatusGet");
+  resolve (wtx_context_cont, "wtxContextCont");
+  resolve (wtx_context_create, "wtxContextCreate");
+  resolve (wtx_context_resume, "wtxContextResume");
+  resolve (wtx_context_exit_notify_add, "wtxContextExitNotifyAdd");
+  resolve (wtx_context_kill, "wtxContextKill");
+  resolve (wtx_context_step, "wtxContextStep");
+  resolve (wtx_context_suspend, "wtxContextSuspend");
+  resolve (wtx_eventpoint_list_get, "wtxEventpointListGet");
+  resolve (wtx_result_free, "wtxResultFree");
+  resolve (wtx_gopher_eval, "wtxGopherEval");
+  resolve (wtx_mem_info_get, "wtxMemInfoGet");
+  resolve (wtx_mem_alloc, "wtxMemAlloc");
+  resolve (wtx_mem_checksum, "wtxMemChecksum");
+  resolve (wtx_mem_move, "wtxMemMove");
+  resolve (wtx_mem_free, "wtxMemFree");
+  resolve (wtx_mem_read, "wtxMemRead");
+  resolve (wtx_mem_width_read, "wtxMemWidthRead");
+  resolve (wtx_mem_write, "wtxMemWrite");
+  resolve (wtx_mem_width_write, "wtxMemWidthWrite");
+  resolve (wtx_mem_set, "wtxMemSet");
+  resolve (wtx_mem_add_to_pool, "wtxMemAddToPool");
+  resolve (wtx_mem_realloc, "wtxMemRealloc");
+  resolve (wtx_mem_align, "wtxMemAlign");
+  resolve (wtx_mem_scan, "wtxMemScan");
+  resolve (wtx_obj_module_checksum, "wtxObjModuleChecksum");
+  resolve (wtx_obj_module_find_id, "wtxObjModuleFindId");
+  resolve (wtx_obj_module_find_name, "wtxObjModuleFindName");
+  resolve (wtx_obj_module_info_get, "wtxObjModuleInfoGet");
+  resolve (wtx_obj_module_load, "wtxObjModuleLoad");
+  resolve (wtx_obj_module_unload, "wtxObjModuleUnload");
+  resolve (wtx_obj_module_by_name_unload, "wtxObjModuleByNameUnload");
+  resolve (wtx_register_for_event, "wtxRegisterForEvent");
+  resolve (wtx_regs_get, "wtxRegsGet");
+  resolve (wtx_regs_set, "wtxRegsSet");
+  resolve (wtx_str_to_tgt_addr, "wtxStrToTgtAddr");
+  resolve (wtx_str_to_context_id, "wtxStrToContextId");
+  resolve (wtx_str_to_context_type, "wtxStrToContextType");
+  resolve (wtx_str_to_int32, "wtxStrToInt32");
+  resolve (wtx_str_to_event_type, "wtxStrToEventType");
+  resolve (wtx_sym_add, "wtxSymAdd");
+  resolve (wtx_sym_find, "wtxSymFind");
+  resolve (wtx_sym_list_get, "wtxSymListGet");
+  resolve (wtx_sym_list_by_module_id_get, "wtxSymListByModuleIdGet");
+  resolve (wtx_sym_list_by_module_name_get, "wtxSymListByModuleNameGet");
+  resolve (wtx_sym_remove, "wtxSymRemove");
+  resolve (wtx_sym_tbl_info_get, "wtxSymTblInfoGet");
+  resolve (wtx_target_reset, "wtxTargetReset");
+  resolve (wtx_ts_name_get, "wtxTsNameGet");
+  resolve (wtx_target_cpu_type_get, "wtxTargetCpuTypeGet");
+  resolve (wtx_target_has_fpp_get, "wtxTargetHasFppGet");
+  resolve (wtx_target_endian_get, "wtxTargetEndianGet");
+  resolve (wtx_target_bootline_get, "wtxTargetBootlineGet");
+  resolve (wtx_tool_name_get, "wtxToolNameGet");
+  resolve (wtx_ts_version_get, "wtxTsVersionGet");
+  resolve (wtx_unregister_for_event, "wtxUnregisterForEvent");
+  resolve (wtx_direct_call, "wtxDirectCall");
+  resolve (wtx_ts_info_get, "wtxTsInfoGet");
+  resolve (wtx_target_attach, "wtxTargetAttach");
+  resolve (wtx_probe, "wtxProbe");
+  resolve (wtx_timeout_set, "wtxTimeoutSet");
+  resolve (wtx_timeout_get, "wtxTimeoutGet");
+
+#if WTX_PROT_VERSION != 2
+  resolve (wtx_obj_module_list_get, "wtxObjModuleListGet");
+  resolve (wtx_context_stop, "wtxContextStop");
+  resolve (wtx_pd_create, "wtxPdCreate");
+  resolve (wtx_pd_kernel_get, "wtxPdKernelGet");
+  resolve (wtx_pd_current_get, "wtxPdCurrentGet");
+  resolve (wtx_pd_current_set, "wtxPdCurrentSet");
+  resolve (wtx_pd_info_q_get, "wtxPdInfoQGet");
+#else
+  resolve (wtx_obj_module_list, "wtxObjModuleList");
+#endif
+
+}
+
+void
+_initialize_remote_wtxapi ()
+{
+  load_wtx_libraries ();
+
+  add_prefix_cmd ("wtx", no_class, info_wtx_command,
+                  _("Display version of WTX protocol for which gdb is built."),
+                  &info_wtx_list, "info wtx ", 0, &infolist);
+
+  add_cmd ("threads", class_info, info_wtx_threads_command,
+           _("Display the list of threads running on the target."),
+           &info_wtx_list);
+
+  add_cmd ("version", class_info, info_wtx_version_command,
+           _("Display version of WTX protocol for which gdb is built."),
+           &info_wtx_list);
+
+  add_cmd ("vxworks-version", class_info, info_wtx_vxworks_version,
+           _("Display version of VxWorks for the target."),
+           &info_wtx_list);
+
+  add_cmd ("target-server", class_info, info_wtx_target_server,
+           _("Display target server information for the current connection."),
+           &info_wtx_list);
+}
diff --git a/gdb/remote-wtxapi.h b/gdb/remote-wtxapi.h
new file mode 100644
index 0000000..d719802
--- /dev/null
+++ b/gdb/remote-wtxapi.h
@@ -0,0 +1,1221 @@
+/* Thin binding for the WTX protocol, for GDB.
+
+   Copyright 2004, 2010, 2011 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef REMOTE_WTXAPI_H
+#define REMOTE_WTXAPI_H
+
+/* For wtx.h : GDB is run on the host.  */
+#define HOST
+
+#include "wtx.h"
+#include "symfile.h"
+
+/* When in system-mode, the context ID to use is -1.  */
+
+#define SYSTEM_CID (-1)
+
+#ifndef WTX_PROT_VERSION
+#define WTX_PROT_VERSION 2
+#endif
+
+#if WTX_PROT_VERSION == 4
+typedef WTX_TGT_ADDR_T wtxapi_tgt_addr_t;
+typedef WTX_TGT_ARG_T wtxapi_tgt_arg_t;
+#else
+typedef TGT_ADDR_T wtxapi_tgt_addr_t;
+typedef TGT_ARG_T wtxapi_tgt_arg_t;
+#endif
+
+/* Some macros are not defined in WTX 2.0.  Define them as constant when
+   possible.  */
+
+#ifndef WTX_PD_CURRENT
+extern const wtxapi_tgt_arg_t WTX_PD_CURRENT;
+#endif
+
+#ifndef WTX_PD_ALL
+extern const wtxapi_tgt_addr_t WTX_PD_ALL;
+#endif
+
+#ifndef WTX_MOD_FIND_IN_ALL_PD
+extern const wtxapi_tgt_addr_t WTX_MOD_FIND_IN_ALL_PD;
+#endif
+
+#ifndef WTX_SYM_FIND_IN_ALL_PD
+extern const int WTX_SYM_FIND_IN_ALL_PD;
+#endif
+
+/* On WTX 3.0, some additional values has been added in the enums to
+   deal with the protection domains.  Emulate these value in WTX 2.0.  */
+
+#if WTX_PROT_VERSION == 2
+extern const WTX_CONTEXT_TYPE WTX_CONTEXT_PD;
+extern const int WTX_ERR_PD_INVALID_PD;
+#endif
+
+#ifndef WTX_LOAD_GLOBAL_SYMBOLS
+#define WTX_LOAD_GLOBAL_SYMBOLS 0x4
+#endif
+
+/* On WTX 4.0, some variables have been renamed.  */
+
+#if WTX_PROT_VERSION == 4
+extern const WTX_ACTION_TYPE WTX_ACTION_STOP_ALL;
+#endif
+
+/* The structures defined below are used to resolve differences
+   between version of the WTX protocol.
+
+   Note those differences:
+   - When the WTX structure contains a BOOL32, the WTX API structure uses an
+   int; if it is FALSE in the WTX structure, it is 0 in the WTX API structure;
+   - When the WTX structure contains a UINT32, the WTX API uses an int; the
+   conversion is straightforward.  */
+
+/* Protection domain ID.  */
+
+typedef wtxapi_tgt_addr_t pd_id_t;
+
+/* Module ID.  */
+
+typedef UINT32 module_id_t;
+
+/* Event point id.  */
+
+typedef UINT32 evtpt_id_t;
+
+
+/* Invalid identifiers.  Equivalent to WTX_ERROR.  */
+
+extern const pd_id_t invalid_pd_id;
+extern const evtpt_id_t invalid_module_id;
+extern const evtpt_id_t invalid_evtpt_id;
+extern const WTX_CONTEXT_ID_T invalid_context_id;
+extern const WTX_AGENT_MODE_TYPE invalid_agent_mode;
+extern const WTX_CONTEXT_STATUS invalid_context_status;
+
+/* Event.  Same as WTX_EVENT in WTX 3.0, and WTX_EVENT_2 in WTX 2.0.  */
+
+struct wtxapi_event
+{
+  WTX_EVENT_TYPE event_type;
+  int num_args;
+  wtxapi_tgt_arg_t *args;
+};
+
+/* Action.  Based on WTX_ACTION.  */
+
+struct wtxapi_action
+{
+  /* Action type to perform.  */
+  WTX_ACTION_TYPE action_type;
+  /* Action dependent argument.  */
+  int action_arg;
+  /* Function to ACTION_CALL.  */
+  wtxapi_tgt_addr_t call_rtn;
+  /* Function argument.  */
+  wtxapi_tgt_arg_t call_arg;
+};
+
+/* Context.  Same as WTX_CONTEXT */
+
+struct wtxapi_context
+{
+  WTX_CONTEXT_TYPE context_type;
+  WTX_CONTEXT_ID_T context_id;
+
+  /* WTX 4.0-specific field.  */
+  WTX_CONTEXT_ID_T context_sub_id;
+};
+
+/* Eventpoint desc.  Same as WTX_EVTPT in WTX 3.0, and WTX_EVTPT_2
+   in WTX 2.0.  */
+
+struct wtxapi_evtpt
+{
+  struct wtxapi_event event;
+  struct wtxapi_context context;
+  struct wtxapi_action action;
+};
+
+/* Eventpoint info.  Same as WTX_EVTPT_INFO.  */
+
+struct wtxapi_evtpt_info
+{
+  /* Eventpoint descriptor.  */
+  struct wtxapi_evtpt wtx_evtpt;
+  /* Tool identifier.  */
+  int tool_id;
+  /* Eventpoint identifier.  */
+  evtpt_id_t evtpt_num;
+};
+
+
+/* Eventpoint list message.  Same as WTX_EVTPT_LIST in WTX 3.0,
+   and WTX_EVTPT_LIST_2 in WTX 2.0.  */
+
+struct wtxapi_evtpt_list
+{
+  int n_evtpt;
+  struct wtxapi_evtpt_info *p_evtpt_info;
+};
+
+/* Section descriptor.  Based on WTX_SECTION_DESC (WTX 3.0)
+   and LD_M_SECTION (WTX 2.0).  */
+
+struct wtxapi_section_desc
+{
+  /* Name of the section.  */
+  char *name;
+  /* Section flags.  */
+  int flags;
+  /* Section base address.  */
+  wtxapi_tgt_addr_t base_addr;
+  /* Section length.  */
+  int length;
+};
+
+/* Symbol description.  Based on WTX_SYMBOL.  */
+
+struct wtxapi_symbol
+{
+  /* Returned value for find request.  */
+  int status;
+  /* Protection domain ID.  */
+  pd_id_t pd_id;
+  /* Symbol name.  */
+  char *name;
+  /* 0 iff symbol name prefixed by an underscore.  */
+  int exact_name;
+  /* Symbol value.  */
+  wtxapi_tgt_addr_t value;
+  /* symbol type.  */
+  int type;
+  /* symbol type mask for lookup.  */
+  int type_mask;
+  /* Module name.  */
+  char *module_name;
+};
+
+/* Symbol copy options for copy_current_symbol.  */
+
+extern const int wtxapi_symbol_copy_none;
+extern const int wtxapi_symbol_copy_name;
+extern const int wtxapi_symbol_copy_module_name;
+#define wtxapi_symbol_copy_all (wtxapi_symbol_copy_module_name \
+                                  | wtxapi_symbol_copy_name)
+
+enum wtxapi_symbol_copy_options
+{
+  wtxapi_symbol_copy_full = 1,
+  wtxapi_symbol_copy_dont_copy_name = 2,
+  wtxapi_symbol_copy_dont_copy_module_name = 3,
+  wtxapi_symbol_copy_dont_copy_strings = 4
+};
+
+/* Symbol list.  Based on WTX_SYMBOL and WTX_SYMBOL_LIST.  */
+
+struct wtxapi_symbol_list;
+
+struct segment_addresses
+{
+  CORE_ADDR text_addr;
+  CORE_ADDR data_addr;
+  CORE_ADDR bss_addr;
+};
+
+/* Object module information.  Based on WTX_MODULE_INFO.  */
+
+struct wtxapi_module_info
+{
+  /* Protection domain ID.  */
+  pd_id_t pd_id;
+  /* Module ID.  */
+  module_id_t module_id;
+  /* Module name (with path).  */
+  char *module_name;
+  /* Flags used to load module.  */
+  int load_flag;
+  /* Section description.  */
+  struct section_addr_info *section_addrs;
+  /* On older systems (Tornado 2), the system does not provide
+     the section addresses, but rather 3 segment addresses.
+     The following field stores these segment addresses to allow
+     us later to compute each section address.
+
+     On targets where the system does provide us with the section
+     addresses, this field should be unused.  */
+  struct segment_addresses *segments;
+  /* List of undefined symbols.  Only initialized after a 'load' operation.  */
+  struct wtxapi_symbol_list *undef_list;
+};
+
+/* Module ID list.  Based on WTX_MODULE_LIST (WTX 2.0).  */
+
+struct wtxapi_module_list
+{
+  /* Number of module in list.  */
+  int num_obj_mod;
+  /* Arrays of object module id and pd id.  For one index, you have a
+     couple (module id, pd id).  */
+  module_id_t *mod_id_array;
+  pd_id_t *pd_id_array;
+};
+
+/* task context descriptor.  Same as WTX_TASK_CONTEXT_DEF (WTX 3.0) and
+   equivalent to WTX_CONTEXT_DESC (WTX 2.0).  */
+
+struct wtxapi_task_context_desc
+{
+  /* Context PD ID.  */
+  pd_id_t pd_id;
+  /* Integer or double.  */
+  WTX_RETURN_TYPE return_type;
+  /* Task name.  */
+  char *name;
+  /* Priority.  */
+  int priority;
+  /* Options.  */
+  int options;
+  /* Base of stack.  */
+  wtxapi_tgt_addr_t stack_base;
+  /* Stack size.  */
+  int stack_size;
+  /* Context entry point.  */
+  wtxapi_tgt_addr_t entry;
+  /* Redirection in file or NULL.  */
+  INT32 redir_in;
+  /* Redirection out file or NULL.  */
+  INT32 redir_out;
+  /* Redirection error file or NULL.  */
+  INT32 redir_err;
+  /* Arguments.  */
+  int argc;
+  wtxapi_tgt_arg_t *argv;
+};
+
+/* PD context descriptor.  Same on WTX_PD_CONTEXT_DEF (WTX 3.0) and
+   equivalent to WTX_CONTEXT_DESC (WTX 2.0).  */
+
+struct wtxapi_pd_context_desc
+{
+  /* PD name.  */
+  char *name;
+  /* Options.  */
+  int options;
+  /* Size of the PD's heap.  */
+  int heap_size;
+  /* Lowest task's priority.  */
+  int low_priority;
+  /* Highest task's priority.  */
+  int high_priority;
+  /* Page pool list name to use.  */
+  wtxapi_tgt_addr_t page_pool_list;
+  /* Return address to call on deletion.  */
+  wtxapi_tgt_addr_t destroy_rtn;
+  /* Initial link path for this PD.  */
+  char *link_path;
+  /* Redirection in file or NULL.  */
+  INT32 redir_in;
+  /* Redirection out file or NULL.  */
+  INT32 redir_out;
+  /* Redirection error file or NULL.  */
+  INT32 redir_err;
+  /* Extra argument count (in argv).  */
+  int argc;
+  /* Extra argument array.  */
+  wtxapi_tgt_arg_t *argv;
+};
+
+/* Context descriptor.  Based on WTX_CONTEXT_DESC (WTX 3.0).  Different
+   from WTX_CONTEXT_DESC in WTX 2.0.  */
+
+struct wtxapi_context_desc
+{
+  /* Type of context.  */
+  WTX_CONTEXT_TYPE context_type;
+
+  union _wtx_context_def
+  {
+    /* Task context definition.  */
+    struct wtxapi_task_context_desc task_context;
+    /* PD context definition.  */
+    struct wtxapi_pd_context_desc pd_context;
+  } wtx_context_def;
+};
+
+/* Some macro to access the fields of a wtxapi_context_desc */ 
+ 
+#define TASK_CONTEXT_ARGV(context_desc, i) \
+  (context_desc.wtx_context_def.task_context.argv[i]) 
+#define TASK_CONTEXT_ENTRY(context_desc) \
+  (context_desc.wtx_context_def.task_context.entry) 
+#define TASK_CONTEXT_NAME(context_desc) \
+  (context_desc.wtx_context_def.task_context.name) 
+#define TASK_CONTEXT_CONTEXT_TYPE(context_desc) \
+  (context_desc.context_type) 
+#define TASK_CONTEXT_STACK_SIZE(context_desc) \
+  (context_desc.wtx_context_def.task_context.stack_size) 
+#define TASK_CONTEXT_PRIORITY(context_desc) \
+  (context_desc.wtx_context_def.task_context.priority) 
+#define TASK_CONTEXT_OPTIONS(context_desc) \
+  (context_desc.wtx_context_def.task_context.options) 
+#define TASK_CONTEXT_ARGC(context_desc) \
+  (context_desc.wtx_context_def.task_context.argc) 
+#define TASK_CONTEXT_PDID(context_desc) \
+  (context_desc.wtx_context_def.task_context.pd_id) 
+
+/* PD descriptor.  Same as WTX_PD_DESC (WTX 3.0).  */
+
+struct wtxapi_pd_desc
+{
+  /* Protection domain ID.  */
+  pd_id_t pd_id;
+  /* Protection domain name.  */
+  char *pd_name;
+  /* Protection domain flags.  */
+  int pd_flags;
+  /* Link path string.  */
+  char *pd_link_path_str;
+  /* Nb of PD in linkpath.  */
+  int pd_link_path_count;
+  /* PD ids of the linkpath.  */
+  pd_id_t *pd_link_path;
+  int pd_attach_to_count;
+  pd_id_t *pd_attach_to;
+};
+
+/* PD descriptor list.  Same as WTX_PD_DESC_Q (WTX 3.0).  */
+
+struct wtxapi_pd_desc_q
+{
+  struct wtxapi_pd_desc pd_desc;
+  struct wtxapi_pd_desc_q *next;
+};
+
+/* Symbol table info.  Same as WTX_SYM_TBL_INFO (WTX 3.0).  */
+
+struct wtxapi_sym_tbl_info
+{
+  /* Protection domain ID.  */
+  pd_id_t pd_id;
+  /* Number of symbols.  */
+  int sym_num;
+  /* Name clash policy.  */
+  int same_name_ok;
+};
+
+/* Target agent info.  Based on WTX_AGENT_INFO.  */
+
+struct wtxapi_agent_info
+{
+  /* WDB agent version.  */
+  char *agent_version;
+  /* Max transfer size (bytes).  */
+  int mtu;
+  /* Available agent modes.  */
+  int mode;
+};
+
+/* Target runtime information.  Based on WTX_RT_INFO.  */
+
+struct wtxapi_rt_info
+{
+  /* Runtime name.  */
+  char *rt_name;
+  /* Runtime version.  */
+  char *rt_version;
+  /* Target processor type.  */
+  int cpu_type;
+  /* Target cpu variant.  */
+  char *cpu_variant;
+  /* Text write protect available.  */
+  int has_write_protect;
+  /* Size of a page.  */
+  int page_size;
+  /* Endianness (LITTLE or BIG).  */
+  int endian;
+  /* Board support package name.  */
+  char *bsp_name;
+  /* Boot file name.  */
+  char *boot_line;
+  /* Target main memory base address.  */
+  wtxapi_tgt_addr_t mem_base;
+  /* Target main memory size.  */
+  int mem_size;
+  /* Number of memory regions.  */
+  int num_regions;
+  /* Target server memory pool base.  */
+  int host_pool_base;
+  /* Target server memory pool size.  */
+  int host_pool_size;
+};
+
+/* Target information.  Based on WTX_TGT_INFO.  */
+struct wtxapi_tgt_info
+{
+  struct wtxapi_agent_info agent_info;
+  struct wtxapi_rt_info rt_info;
+};
+
+/* Target server information message.  Based on WTX_TS_INFO.  */
+
+struct wtxapi_ts_info
+{
+  /* Target link descriptor.  */
+  WTX_TGT_LINK_DESC tgt_link_desc;
+  /* Info obtained from Target.  */
+  struct wtxapi_tgt_info tgt_info;
+  /* Target Server version.  */
+  char *version;
+  /* Target server user name.  */
+  char *user_name;
+  /* Lock/authorization message.  */
+  char *lock_msg;
+  /* 0 iff the PDs are not initialized.  */
+  int pd_initialized;
+};
+
+/* The data from a context-exit event.  */
+
+struct wtxapi_ctx_exit_event
+{
+  WTX_CONTEXT_ID_T context_id;
+  WTX_CONTEXT_TYPE context_type;
+  int exit_code;
+};
+
+/* The data from a data-access (watchpoint) event.  */
+
+struct wtxapi_data_access_event
+{
+  WTX_CONTEXT_ID_T task_id;
+  WTX_CONTEXT_ID_T context_id;
+  WTX_CONTEXT_TYPE context_type;
+
+  /* The address being watched that triggered the DATA_ACCESS event.  */
+  CORE_ADDR data_addr;
+};
+
+/* The data from an exception event.  */
+
+struct wtxapi_exception_event
+{
+  WTX_CONTEXT_ID_T context_id;
+  WTX_CONTEXT_TYPE context_type;
+  int exception_value;
+};
+
+/* The data from an obj-loaded event.  */
+
+struct wtxapi_obj_loaded_event
+{
+  module_id_t module_id;
+};
+
+/* The data from an obj-unloaded event.  */
+
+struct wtxapi_obj_unloaded_event
+{
+  char *module_filename;
+};
+
+/* The data from a text-access (breakpoint) event.  */
+
+struct wtxapi_text_access_event
+{
+  WTX_CONTEXT_ID_T task_id;
+  WTX_CONTEXT_ID_T context_id;
+  WTX_CONTEXT_TYPE context_type;
+
+  /* The address of the breakpoint that triggered this event.  */
+  CORE_ADDR text_addr;
+};
+
+/* The data from the vio-write event.  */
+
+struct wtxapi_vio_write_event
+{
+  int channel_id;
+  char *data;  /* The contents printed on the virtual IO channel.  */
+};
+
+/* A structure representing the contents of an event received from
+   the target server.  */
+
+struct wtxapi_event_desc
+{
+  WTX_EVENT_TYPE event_type;
+  
+  union
+  {
+    struct wtxapi_ctx_exit_event ctx_exit;
+    struct wtxapi_data_access_event data_access;
+    struct wtxapi_exception_event exception;
+    struct wtxapi_obj_loaded_event obj_loaded;
+    struct wtxapi_obj_unloaded_event obj_unloaded;
+    struct wtxapi_text_access_event text_access;
+    struct wtxapi_vio_write_event vio_write;
+  } desc;
+};
+
+/* The following function are simple wrappers used to resolve the
+   differences between the WTX versions.  Unless specified in the
+   comments, the WTX lib C documentation applies.  If the return type
+   is a WTX type, it should be deallocated using wtxapi_result_free.
+   If it is a type defined in remote-wtxapi.h, it should be deallocate
+   using one of the deallocation function provided in this file.
+
+   Note those differences:
+
+   - when the return type of the WTX function is a STATUS, the wrapper
+   returns an int; in this case, iff the WTX function returns
+   WTX_ERROR, the wrapper returns 0;
+
+   - when the return type of the WTX function is a BOOL32, the wrapper
+   returns an int; in this case, iff the WTX function returns FALSE,
+   the wrapper returns 0.  */
+
+/* Initialize the global WTX client handle.  Only one WTX connection is
+   allowed.  */
+
+extern int wtxapi_initialize ();
+
+/* Return the WTX handle of the current WTX connection.
+   Valid only after a successful call to wtxapi_initialize.  */
+
+extern HWTX wtxapi_get_current_wtx_handle ();
+
+/* Return list of registred services.  NAME_PAT is the reg expression
+   to match svc name.  TYPE_PAT is the reg expression to match svc
+   type.  KEY_PAT is the reg expression to match svc key.  */
+
+extern WTX_DESC_Q *wtxapi_info_q (const char *name_pat, const char *type_pat,
+                                  const char *key_pat);
+
+/* Terminate the use of the global WTX client handle.  */
+
+extern int wtxapi_terminate ();
+
+/* Connect the client to the target server.  */
+
+extern int wtxapi_tool_attach (const char *target_name,
+                               const char *tool_name);
+
+/* Check tool connection to the server.  */
+
+extern int wtxapi_tool_connected ();
+
+/* Detach from the target server.  */
+
+extern int wtxapi_tool_detach ();
+
+/* Clear any error for the tool.  */
+
+extern int wtxapi_err_clear ();
+
+/* Return the version of WTX.  */
+
+extern int wtxapi_version_get ();
+
+/* Return the last error for a handle.  */
+
+extern WTX_ERROR_T wtxapi_err_get ();
+
+/* Add an error handler.  */
+
+extern WTX_HANDLER_T wtxapi_err_handler_add (WTX_HANDLER_FUNC p_func,
+                                             void *p_client_data);
+
+/* Remove an error handler for WTX handle.  */
+
+extern int wtxapi_err_handler_remove (WTX_HANDLER_T p_handler);
+
+/* Fetch the last WTX API error string.  */
+
+extern const char *wtxapi_err_msg_get ();
+
+/* Get the agent mode.  Return invalid_agent_mode if an error occurs.  */
+
+extern WTX_AGENT_MODE_TYPE wtxapi_agent_mode_get ();
+
+/* Set the mode of the target agent.  */
+
+extern int wtxapi_agent_mode_set (WTX_AGENT_MODE_TYPE agent_mode);
+
+/* Create a new breakpoint.  */
+
+extern evtpt_id_t wtxapi_breakpoint_add (WTX_CONTEXT_TYPE context_type,
+                                         WTX_CONTEXT_ID_T context_id,
+                                         wtxapi_tgt_addr_t tgt_addr);
+
+/* Create a new event point.  */
+
+extern evtpt_id_t wtxapi_eventpoint_add (struct wtxapi_evtpt *p_evtpt);
+
+/* Delete eventpoint from the target.  */
+
+extern int wtxapi_eventpoint_delete (evtpt_id_t evtpt_id);
+
+/* Get the next event in the event queue.  */
+
+extern struct wtxapi_event_desc * wtxapi_event_get (void);
+
+/* Get status of a context.  Return invalid_context_status if the operation
+   fails.  */
+
+extern WTX_CONTEXT_STATUS wtxapi_context_status_get
+  (WTX_CONTEXT_TYPE context_type, WTX_CONTEXT_ID_T context_id);
+
+/* Continue execution of target context.  */
+
+extern int wtxapi_context_cont (WTX_CONTEXT_TYPE context_type,
+                                WTX_CONTEXT_ID_T context_id);
+
+/* Create a context on target.
+   - if P_CONTEXT_DESC is invalid, generates WTX_ERR_API_INVALID_ARG;
+   - if another unidentified error occurs, return invalid_context_id;
+   e.g if the operation is not permitted by the kernel.  */
+
+extern WTX_CONTEXT_ID_T wtxapi_context_create
+  (struct wtxapi_context_desc *p_context_desc);
+
+/* Resume execution of a target context.  */
+
+extern int wtxapi_context_resume (WTX_CONTEXT_TYPE context_type,
+                                  WTX_CONTEXT_ID_T context_id);
+
+/* Add exit evpt notification.  */
+
+extern evtpt_id_t wtxapi_context_exit_notify_add
+  (WTX_CONTEXT_TYPE context_type, WTX_CONTEXT_ID_T context_id);
+
+/* Kill a target context.  */
+
+extern int wtxapi_context_kill (WTX_CONTEXT_TYPE context_type,
+                                WTX_CONTEXT_ID_T context_id);
+
+/* Single step exec of target context.  */
+
+extern int wtxapi_context_step (WTX_CONTEXT_TYPE context_type,
+                                WTX_CONTEXT_ID_T context_id,
+                                wtxapi_tgt_addr_t step_start,
+                                wtxapi_tgt_addr_t step_end);
+
+/* Suspend a target context.  */
+
+extern int wtxapi_context_suspend (WTX_CONTEXT_TYPE context_type,
+                                   WTX_CONTEXT_ID_T context_id);
+
+/* Stop (on WTX 3.0) or suspend (on WTX 2.0) a target context.  */
+
+extern int wtxapi_context_stop (WTX_CONTEXT_TYPE context_type,
+                                WTX_CONTEXT_ID_T context_id);
+
+/* List event points on TS.  */
+
+extern struct wtxapi_evtpt_list *wtxapi_eventpoint_list_get ();
+
+/* Free mem allocated by WTX API call.  */
+
+extern int wtxapi_result_free (void *p_result);
+
+/* Evaluate Gopher string on target.  */
+
+extern WTX_GOPHER_TAPE *wtxapi_gopher_eval (pd_id_t pd_id,
+                                            const char *input_string);
+
+/* Get info about memory pool.  */
+
+extern WTX_MEM_INFO *wtxapi_mem_info_get (pd_id_t pd_id);
+
+/* Alloc blocks in memory pool.  */
+
+extern wtxapi_tgt_addr_t wtxapi_mem_alloc (pd_id_t pd_id, int num_bytes);
+
+/* Perform checksum on target memory.  */
+
+extern int wtxapi_mem_checksum (pd_id_t pd_id, wtxapi_tgt_addr_t start_addr,
+                                int num_bytes);
+
+/* Move a block of target memory.  */
+
+extern int wtxapi_mem_move (pd_id_t src_pd_id, wtxapi_tgt_addr_t src_addr,
+                            pd_id_t dst_pd_id, wtxapi_tgt_addr_t dest_addr,
+                            int num_bytes);
+
+/* Free a block of target memory.  */
+
+extern int wtxapi_mem_free (pd_id_t pd_id, wtxapi_tgt_addr_t address);
+
+/* Read memory from the target.  */
+
+extern int wtxapi_mem_read (pd_id_t pd_id, wtxapi_tgt_addr_t from_addr,
+                            void *to_addr, int num_bytes);
+
+/* Read memory on WIDTH bytes.  */
+
+extern int wtxapi_mem_width_read (pd_id_t pd_id, wtxapi_tgt_addr_t from_addr,
+                                  void *to_addr, int num_bytes, int width);
+
+/* Write memory on the target.  */
+
+extern int wtxapi_mem_write (pd_id_t pd_id, void *from_addr,
+                             wtxapi_tgt_addr_t to_addr, int num_bytes);
+
+/* Write memory on the target, on WIDTH bytes large.  */
+
+extern int wtxapi_mem_width_write (pd_id_t pd_id, void *from_addr,
+                                   wtxapi_tgt_addr_t to_addr, int num_bytes,
+                                   int width);
+
+/* Set target memory to given value.  */
+
+extern int wtxapi_mem_set (pd_id_t pd_id, wtxapi_tgt_addr_t addr,
+                           int num_bytes, int val);
+
+/* Add memory to the agent pool.  */
+
+extern int wtxapi_mem_add_to_pool (pd_id_t pd_id, wtxapi_tgt_addr_t address,
+                                   int size);
+
+/* Reallocate a block of target mem.  */
+
+extern wtxapi_tgt_addr_t wtxapi_mem_realloc (pd_id_t pd_id,
+                                             wtxapi_tgt_addr_t address,
+                                             int num_bytes);
+
+/* Allocate aligned target memory.  */
+
+extern wtxapi_tgt_addr_t wtxapi_mem_align (pd_id_t pd_id,
+                                           wtxapi_tgt_addr_t alignment,
+                                           int num_bytes);
+
+/* Scan target memory for pattern.  */
+
+extern int wtxapi_mem_scan (pd_id_t pd_id, int match,
+                            wtxapi_tgt_addr_t start_addr,
+                            wtxapi_tgt_addr_t end_addr,
+                            int num_bytes, void *pattern,
+                            wtxapi_tgt_addr_t * p_result);
+
+/* Checks validity of target memory.  */
+
+extern int wtxapi_obj_module_checksum (pd_id_t pd_id, module_id_t module_id,
+                                       char *module_name);
+
+/* Find obj module ID from name.  */
+
+extern module_id_t wtxapi_obj_module_find_id (pd_id_t pd_id,
+                                              const char *module_name);
+
+/* Return the ID of the module which basename is equal to MODULE_NAME.
+   Search the current PD first, before extending the search to all PDs.  */
+
+extern module_id_t wtxapi_obj_module_in_system_find_id
+  (const char *module_name);
+
+/* Find module name given its ID.  */
+
+extern const char *wtxapi_obj_module_find_name (pd_id_t pd_id,
+                                                module_id_t module_id);
+
+/* Give info on obj module.  */
+
+extern struct wtxapi_module_info
+  *wtxapi_obj_module_info_get (pd_id_t pd_id, module_id_t module_id);
+
+/* List loaded obj modules (wrapper around wtxObjModuleList (WTX 2.0)
+   or wtxObjModuleListGet (WTX 3.0)).  To search on every PD, pd_id
+   should be set to WTX_MOD_FIND_IN_ALL_PD.  */
+
+extern struct wtxapi_module_list *wtxapi_obj_module_list_get (pd_id_t pd_id);
+
+/* Load a new object module.  */
+
+extern struct wtxapi_module_info
+  *wtxapi_obj_module_load (pd_id_t pd_id, char *filename, int load_flag);
+
+extern struct wtxapi_module_info *wtxapi_module_load (pd_id_t pd_id,
+                                                      char *filename,
+                                                      int load_flag,
+                                                      int timeout);
+
+/* Unload an obj module from target.  */
+
+extern int wtxapi_obj_module_unload (pd_id_t pd_id, module_id_t mod_id);
+
+extern int wtxapi_obj_module_by_name_unload (pd_id_t pd_id, char *name);
+
+/* Send events matching expression.  */
+
+extern int wtxapi_register_for_event (const char *reg_exp);
+
+/* Read register data from the target.  */
+
+extern int wtxapi_regs_get (WTX_CONTEXT_TYPE context_type,
+                            WTX_CONTEXT_ID_T context_id,
+                            WTX_REG_SET_TYPE reg_set,
+                            int first_byte, int num_bytes, void *reg_memory);
+
+/* Write to registers on the target.  */
+
+extern int wtxapi_regs_set (WTX_CONTEXT_TYPE context_type,
+                            WTX_CONTEXT_ID_T context_id,
+                            WTX_REG_SET_TYPE reg_set,
+                            int first_byte, int num_bytes, void *reg_memory);
+
+/* Convert str to a wtxapi_tgt_addr_t.  */
+
+extern wtxapi_tgt_addr_t wtxapi_str_to_tgt_addr (const char *str);
+
+/* Convert str to context ID.  */
+
+extern WTX_CONTEXT_ID_T wtxapi_str_to_context_id (const char *str);
+
+/* Convert str ton context type.  */
+
+extern WTX_CONTEXT_TYPE wtxapi_str_to_context_type (const char *str);
+
+/* Convert str to an INT32.  */
+
+extern int wtxapi_str_to_int32 (const char *str);
+
+/* Convert string to event type.  */
+
+extern WTX_EVENT_TYPE wtxapi_str_to_event_type (const char *str);
+
+/* Add symbol with given params.  */
+
+extern int wtxapi_sym_add (pd_id_t pd_id, const char *sym_name,
+                           wtxapi_tgt_addr_t sym_value, int sym_type);
+
+/* Find info on symbol.  Based on wtxSymFind WTX 2.0, with two differences:
+   _ one additional parameter: the protection domain ID (PD_ID);
+   _ no filter on the type.  */
+
+extern struct wtxapi_symbol_list *wtxapi_sym_find (pd_id_t pd_id,
+                                                   char *sym_name,
+                                                   wtxapi_tgt_addr_t sym_value,
+                                                   int exact_name);
+
+/* Get list of symbols.  Based on wtxSymListGet WTX 2.0, with three differences:
+   - one additional parameter: the protection domain ID (PD_ID);
+   - no filter on the unknown symbols;
+   - no filter on the module name/id.  */
+
+extern struct wtxapi_symbol_list
+  *wtxapi_sym_list_get (pd_id_t pd_id, char *substring,
+                        wtxapi_tgt_addr_t value);
+
+/* Get list of symbols.  */
+
+extern struct wtxapi_symbol_list
+  *wtxapi_sym_list_by_module_id_get (pd_id_t pd_id, const char *string,
+                                     module_id_t module_id,
+                                     wtxapi_tgt_addr_t value,
+                                     int list_unknown);
+
+/* Get list of symbols.  */
+
+extern struct wtxapi_symbol_list
+  *wtxapi_sym_list_by_module_name_get (pd_id_t pd_id,
+                                       const char *string,
+                                       const char *module_name,
+                                       wtxapi_tgt_addr_t value,
+                                       int list_unknown);
+
+/* Remove a symbol from sym table.  */
+
+extern int wtxapi_sym_remove (pd_id_t pd_id, const char *sym_name,
+                              int sym_type);
+
+/* Get the symbol table info.  */
+
+extern struct wtxapi_sym_tbl_info *wtxapi_sym_tbl_info_get (pd_id_t pd_id);
+
+/* Reset the target.  */
+
+extern int wtxapi_target_reset ();
+
+/* Get target server name.  */
+
+extern const char *wtxapi_ts_name_get ();
+
+/* Get target-runtime version.  */
+
+extern const char *wtxapi_target_rt_version_get ();
+
+/* Get the target CPU type code.  */
+
+extern int wtxapi_target_cpu_type_get ();
+
+/* Check for floating point processor.  */
+
+extern int wtxapi_target_has_fpp_get ();
+
+/* Get edianness of target.  */
+
+extern WTX_ENDIAN_T wtxapi_target_endian_get ();
+
+/* Get target boot line info.  */
+
+extern const char *wtxapi_target_bootline_get ();
+
+/* Return name of current tool.  */
+
+extern const char *wtxapi_tool_name_get ();
+
+/* Return the Tornado version.  */
+
+extern const char *wtxapi_ts_version_get ();
+
+/* Unregister for some events.  */
+
+extern int wtxapi_unregister_for_event (char *reg_exp);
+
+/* Call func on target within agent.  */
+
+extern int wtxapi_direct_call (wtxapi_tgt_addr_t entry, void *p_ret_val,
+                               wtxapi_tgt_arg_t arg0, wtxapi_tgt_arg_t arg1,
+                               wtxapi_tgt_arg_t arg2, wtxapi_tgt_arg_t arg3,
+                               wtxapi_tgt_arg_t arg4, wtxapi_tgt_arg_t arg5,
+                               wtxapi_tgt_arg_t arg6, wtxapi_tgt_arg_t arg7,
+                               wtxapi_tgt_arg_t arg8, wtxapi_tgt_arg_t arg9);
+
+/* Get info about target and server.  */
+
+extern struct wtxapi_ts_info *wtxapi_ts_info_get ();
+
+/* Reattach to the target.  */
+
+extern int wtxapi_target_attach ();
+
+/* Probe to see if registry is running.  */
+
+extern int wtxapi_probe ();
+
+/* Set WTX timeout.  */
+
+extern int wtxapi_timeout_set (int msec);
+
+/* Get the current timeout.  */
+
+extern int wtxapi_timeout_get (int *p_msec);
+
+/* Create a new protection domain.  */
+
+extern wtxapi_tgt_addr_t wtxapi_pd_create (const char *name, int options,
+                                           int heap_size, int low_priority,
+                                           int high_priority,
+                                           wtxapi_tgt_addr_t page_pool_list,
+                                           const char *link_path);
+
+/* Get kernel Protection Domain ID.  */
+
+extern pd_id_t wtxapi_pd_kernel_get ();
+
+/* Get the current Protection Domain.  */
+
+extern pd_id_t wtxapi_pd_current_get ();
+
+/* Set the current Protection Domain.  */
+
+extern int wtxapi_pd_current_set (pd_id_t pd_id);
+
+/* Get the list of allocated PDs.  */
+
+extern struct wtxapi_pd_desc_q *wtxapi_pd_info_q_get ();
+
+/* Check whether the module has been fully linked or not.  */
+
+extern int wtxapi_load_fully_linked (const struct wtxapi_module_info
+                                     *module_info);
+
+/* Simple additional functions.  */
+
+/* Test target server availability.  */
+
+extern int wtxapi_target_server_available_p ();
+
+/* Symbol list handling.  The symbol list contain a 'current symbol'.
+   This current symbol is used to go through the list.  */
+
+/* Get a copy of the current symbol.  */
+
+extern struct wtxapi_symbol
+  *get_current_wtxapi_symbol (struct wtxapi_symbol_list *list);
+
+
+/* Copy current symbol of LIST into TO.
+
+   OPTIONS is used to avoid uneeded dynamic allocation.
+
+   If OPTIONS is set to wtxapi_symbol_copy_full, the fields name and
+   module_name of TO are null pointers, these string fields of TO are
+   allocated and fully copied from the current symbol, and should be
+   deallocated by the caller.
+
+   If OPTIONS is set to wtxapi_symbol_copy_name (resp.
+   wtxapi_symbol_copy_module_name), the field name (resp. the
+   module_name) of TO is copied.  If not, it is is set to NULL.
+
+   If OPTIONS is set to wtxapi_symbol_copy_none, the field name and
+   module_name of TO are not copied and are set to NULL.  In this case
+   and only in this case no dynamic allocation is performed by this
+   function.  */
+
+extern void copy_current_wtxapi_symbol (struct wtxapi_symbol_list *list,
+                                        struct wtxapi_symbol *to,
+                                        int options);
+
+/* Return the name of the current symbol inside LIST.
+   The result must be deallocated after use.  */
+
+extern char *current_wtxapi_symbol_name (struct wtxapi_symbol_list *list);
+
+/* Change the current symbol to the first element of the list.If there
+   is no next element, return 0.  */
+
+int go_to_first_element_in_wtxapi_sym_list (struct wtxapi_symbol_list *list);
+
+/* Change the current symbol to the next element of the list.  If there
+   is no next element, return 0.  */
+
+int go_to_next_element_in_wtxapi_sym_list (struct wtxapi_symbol_list *list);
+
+/* Deallocation functions for the structures,lists returned by the
+   function defined in this file.  It frees "everything", i.e. it go
+   through every element of the list and deallocate it, and also
+   deallocate strings and arrays referenced by a field.  */
+
+extern void free_wtxapi_evtpt_list (struct wtxapi_evtpt_list *to_free);
+
+extern void free_wtxapi_module_list (struct wtxapi_module_list *to_free);
+
+extern void free_wtxapi_pd_desc_q (struct wtxapi_pd_desc_q *to_free);
+
+extern void free_wtxapi_symbol (struct wtxapi_symbol *to_free);
+
+extern void free_wtxapi_symbol_list (struct wtxapi_symbol_list *to_free);
+
+extern void free_wtxapi_module_info (struct wtxapi_module_info *to_free);
+
+extern void free_wtxapi_ts_info (struct wtxapi_ts_info *to_free);
+
+extern void free_wtxapi_event_desc (struct wtxapi_event_desc *to_free);
+
+/* Stubs for GDB cleanup functions.  */
+
+extern void cleanup_wtxapi_evtpt_list (void *to_free);
+
+extern void cleanup_wtxapi_module_list (void *to_free);
+
+extern void cleanup_wtxapi_pd_desc_q (void *to_free);
+
+extern void cleanup_wtxapi_symbol (void *to_free);
+
+extern void cleanup_wtxapi_symbol_list (void *to_free);
+
+extern void cleanup_wtxapi_module_info (void *to_free);
+
+extern void cleanup_wtxapi_ts_info (void *to_free);
+
+extern void cleanup_wtxapi_result_free (void *to_free);
+
+/* Helpers.  */
+
+int remote_wtxapi_get_symbol_address (char *symbol_name,
+                                      CORE_ADDR *symbol_addr);
+
+int wtxapi_target_has_BoDA (void);
+
+/* A list of threads running on the target system.  */
+
+struct wtxapi_thread_info
+{
+  struct wtxapi_thread_info *next;
+  WTX_CONTEXT_ID_T id;
+  char *name;
+
+  /* The address where the task GP registers are stored when the task
+     is not being executed.  This is necessary to retrieve the registers
+     of this task when in system mode, because wtxapi_regs_get/set
+     will only get/set the registers of the current task (ie the
+     task currently being scheduled by the system).  */
+  CORE_ADDR regs_addr;
+
+  /* Similarly, we need to store the address where the FP registers
+     are stored.  Computing this address requires support from the system,
+     and thus may not be available - in this case, this address should
+     be set to zero.  */
+  CORE_ADDR fp_regs_addr;
+};
+
+extern void free_wtxapi_thread_info (struct wtxapi_thread_info *threads);
+
+/* The WTX protocol does not have all the necessary features needed
+   to implement a remote backend.  So this module relies on other
+   modules provided by the target system (typically a TCL interpreter,
+   or a DFW server).  Unfortunately, which module to use is dependent
+   on the target.  So we maintain a vector with pointers to functions
+   that provide the missing features of WTX.  */
+   
+struct wtxapi_support_ops
+{
+  /* Perform all necessary actions following the establishing of
+     the given WTX connection.  */
+  void (*wtx_connection_established_callback) (HWTX wtx_handle);
+
+  /* Get the list of threads currently running on the target system.  */
+  struct wtxapi_thread_info * (*get_thread_list) (void);
+
+  /* Find the Partition ID of the given task ID.
+     If successful, then set TASK_PD with the result, and return non-zero.
+     Otherwise, return zero and leave the value of TASK_PD undefined.  */
+  int (*get_task_pd) (int task_id, pd_id_t *task_pd);
+
+  /* Return 1 if system-mode is supported, 0 otherwise.  Warn if
+     some features are unsupported.  */
+  int (*system_mode_support_p) (void);
+
+  /* Find the context id of the task currently being executed
+     by the system.  This function assumes that the target is
+     currently running in system mode.  */
+  WTX_CONTEXT_ID_T (*system_mode_get_current_context_id) (void);
+};
+
+extern void wtxapi_set_support_ops (struct wtxapi_support_ops *ops);
+
+extern void wtxapi_notify_connection_established (void);
+
+extern struct wtxapi_thread_info *wtxapi_get_thread_list (void);
+
+extern int wtxapi_get_task_pd (int task_id, pd_id_t *task_pd);
+
+extern int wtxapi_system_mode_support_p (void);
+
+extern WTX_CONTEXT_ID_T wtxapi_system_mode_get_current_context_id (void);
+
+extern int wtxapi_vx_fp_task ();
+
+extern int wtxapi_has_target_variant (const char *variant);
+#endif
-- 
1.7.0.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]