This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[VxWorks 09/20] remote-wtxapi: The WTX API abstraction layer.
- From: Joel Brobecker <brobecker at adacore dot com>
- To: gdb-patches at sourceware dot org
- Cc: Joel Brobecker <brobecker at adacore dot com>
- Date: Fri, 4 Mar 2011 01:21:49 -0500
- Subject: [VxWorks 09/20] remote-wtxapi: The WTX API abstraction layer.
- References: <1299219720-13398-1-git-send-email-brobecker@adacore.com>
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 | 3044 +++++++++++++++++++++++++++++++++++++++++++++++++++
gdb/remote-wtxapi.h | 1221 +++++++++++++++++++++
2 files changed, 4265 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..05097b4
--- /dev/null
+++ b/gdb/remote-wtxapi.c
@@ -0,0 +1,3044 @@
+/* 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"
+#include "cli/cli-utils.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 (¤t_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_token (event_str, &context_type_str);
+ event_str = get_token (event_str, &context_id_str);
+ event_str = skip_token (event_str);
+ event_str = get_token (event_str, &exit_code_str);
+ }
+ else
+ {
+ /* Format: "Context_Type Context_ID Exit_Code". */
+ event_str = get_token (event_str, &context_type_str);
+ event_str = get_token (event_str, &context_id_str);
+ event_str = get_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_token (event_str, &task_id_str);
+ event_str = get_token (event_str, &context_type_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = get_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_token (event_str, &context_id_str);
+ event_str = get_token (event_str, &context_type_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = get_token (event_str, &data_addr_str);
+ event_str = get_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_token (event_str);
+ event_str = get_token (event_str, &context_type_str);
+ event_str = get_token (event_str, &context_id_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = get_token (event_str, &task_id_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = get_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_token (event_str, &context_type_str);
+ event_str = get_token (event_str, &context_id_str);
+ event_str = get_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_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = get_token (event_str, &context_type_str);
+ event_str = get_token (event_str, &context_id_str);
+ event_str = skip_token (event_str);
+ event_str = get_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_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_token (event_str);
+ event_str = get_token (event_str, &event->module_filename);
+
+ wtx_opt_events_debug (1, "OBJ_UNLOADED: 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_token (event_str, &task_id_str);
+ event_str = get_token (event_str, &context_type_str);
+ event_str = get_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_token (event_str, &context_id_str);
+ event_str = get_token (event_str, &context_type_str);
+ event_str = get_token (event_str, &text_addr_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = get_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_token (event_str);
+ event_str = get_token (event_str, &context_type_str);
+ event_str = get_token (event_str, &context_id_str);
+ event_str = skip_token (event_str);
+ event_str = skip_token (event_str);
+ event_str = get_token (event_str, &task_id_str);
+ event_str = skip_token (event_str);
+ event_str = get_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_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_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_vxworks_tasks_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 VxWorks task.\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_vxworks_tasks_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 ("wtxapi42");
+
+ if (!wtx_lib)
+ 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 ("vxworks-tasks", class_info, info_wtx_vxworks_tasks_command,
+ _("Display the list of VxWorks tasks running on the target."),
+ &info_wtx_list);
+
+ /* Provide an "info wtx threads" alias for "info wtx vxworks-tasks".
+ The latter command is clearer, but also more recent.
+
+ Having the alias helps us stay upward-compatible with the IDEs
+ out there that use the old command to get the list of VxWorks
+ tasks IDs running on the target in order to present a list that
+ the user can select from when he wants to attach to one of those
+ tasks (the alternative is for the user to connect to the target
+ console or start a target shell, and find the correct task ID
+ from there). */
+ add_alias_cmd ("threads", "vxworks-tasks", class_info, 1,
+ &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