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


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

[PATCH 11/18] Add partition support.


This is the module which is providing partition support.  Since our
implementation is not entirely clean (see other message - right now,
we do some nasty swapping of objfiles in and out of the object_files
list), the code that is being provided here has been cleaned up a bit.
All the nasties have been removed, allowing us to keep the interface
and sufficient implementation for partition-less systems (VxWorks 5.x
and 6.x), but leaving out support for VxWorks 653.

I will look at implementing proper partition support independently of
this effort.

gdb/ChangeLog:

        * remote-wtx-pd.h, remote-wtx-pd.c: New files.
---
 gdb/remote-wtx-pd.c |  348 +++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/remote-wtx-pd.h |   58 +++++++++
 2 files changed, 406 insertions(+), 0 deletions(-)
 create mode 100644 gdb/remote-wtx-pd.c
 create mode 100644 gdb/remote-wtx-pd.h

diff --git a/gdb/remote-wtx-pd.c b/gdb/remote-wtx-pd.c
new file mode 100644
index 0000000..5d58c3c
--- /dev/null
+++ b/gdb/remote-wtx-pd.c
@@ -0,0 +1,348 @@
+/* Support for the WTX protocol.
+
+   Copyright (C) 2007, 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 "gdb_assert.h"
+#include "objfiles.h"
+#include "source.h"
+#include "remote-wtx-pd.h"
+#include "remote-wtx-opt.h"
+#include "ada-lang.h"
+#include "language.h"
+#include "observer.h"
+#include "command.h"
+#include "gdbcmd.h"
+
+#include <ctype.h>
+
+/* We need to keep the symbols in each PD separate from the others.
+   One of the reasons is that 2 symbols with the same name are allowed to
+   coexist in 653 provided that these 2 symbols live in 2 separate PDs.
+   Another important reason is that virtual memory regions can overlap
+   between PDs, and one symbol address in a PD is not suitable in the
+   context of another PD.
+   
+   GDB maintains a global list of objfiles where the symbols can be found.
+   To achieve this separation, we simply maintain one such list per PD in
+   this module.  At each PD change, we simply save the objfile list for
+   the current PD, and restore it for the new PD.  The net effect is that
+   GDB will only recognize symbols in the current PD, and will complain if
+   a user tries to do any operation that needs symbols from other PDs.
+
+   In practice, GDB maintains a few other global variables that also
+   need to be saved/restored, but the principle remains valid.
+   
+   If would have been slicker to actually maintain one list of objfiles
+   for all PDs and modify GDB to automatically switch to the right PD
+   when performing an operation such as inserting a BP in some code that's
+   in a different partition.  This would probably not be such a great
+   improvment in terms of usability, but this would require a major
+   overall rework.  So we dropped this idea.  */
+
+/* Return nonzero if the target system supports PDs.  */
+
+int
+wtx_pd_system_has_pds ()
+{
+#if WTX_PROT_VERSION > 2
+  return 1;
+#else
+  return 0;
+#endif
+}
+
+/* Return the name of the PD which ID is equal to PD_ID.  If the given PD
+   could not be found, then return "<none>".  */
+
+char *
+wtx_pd_get_pd_name (pd_id_t pd_id)
+{
+  struct wtxapi_pd_desc_q *pds;
+
+  pds = wtxapi_pd_info_q_get ();
+  make_cleanup (cleanup_wtxapi_pd_desc_q, pds);
+
+  for (; pds != NULL; pds = pds->next)
+    if (pds->pd_desc.pd_id == pd_id)
+      return xstrdup (pds->pd_desc.pd_name);
+
+  /* Fallback, if we did not find the PD, or if the system does not support
+     PDs, then return a string saying that the given PD does not have a name
+     associated to it.  */
+  return xstrdup ("<none>");
+}
+
+/* Return the PD ID for the Protection Domain which name is NAME.
+   Raise an error if this PD does not exist.  */
+
+static pd_id_t
+wtx_pd_pd_id_from_name (const char *name)
+{
+  struct wtxapi_pd_desc_q *pds;
+
+  pds = wtxapi_pd_info_q_get ();
+  make_cleanup (cleanup_wtxapi_pd_desc_q, pds);
+
+  while (pds != NULL)
+    if (strcmp (pds->pd_desc.pd_name, name) == 0)
+      return pds->pd_desc.pd_id;
+    else
+      pds = pds->next;
+
+  error (_("Unable to find partition: %s.\n"), name);
+}
+
+/* Set the curent Protection Domain to the given PD ID.  No-op on less
+   recent versions of Tornado (T2) where the notion of PD is not supported.  */
+
+static void
+switch_to_pd_internal (pd_id_t pd_id, int from_tty)
+{
+  pd_id_t current_pd;
+
+  if (!wtxapi_tool_connected ())
+    error (_("Not attached to a target. Use \"target wtx\" first."));
+
+  current_pd = wtxapi_pd_current_get ();
+
+  if (pd_id == current_pd)
+    {
+      /* Emit a warning when the PD switch has been requested explicitely
+         by the user, to make sure he knows the operation was meaningless
+         and has been aborted.  */
+      if (from_tty)
+        warning (_("Partition unchanged, as already set to 0x%lx."), pd_id);
+      return;
+    }
+
+  if (wtx_pd_system_has_pds ())
+    error (_("Operation not implemented yet."));
+}
+
+/* Equivalent to switch_to_pd_internal (pd_id, 1).  Useful either as a
+   shortcut to switch_to_pd_internal, or in conjunction with the
+   make_cleanup mechanism.  */
+
+void
+wtx_pd_switch_to_pd (pd_id_t pd_id)
+{
+  switch_to_pd_internal (pd_id, 1);
+}
+
+/* On systems where Protection Domains are supported, return the ID of
+   the PD where the given module is loaded.  Return NULL_PD if the system
+   does not support PD.  */
+
+pd_id_t
+wtx_pd_get_module_pd (module_id_t module_id)
+{
+  int i;
+  struct wtxapi_module_list *module_list =
+    wtxapi_obj_module_list_get (WTX_MOD_FIND_IN_ALL_PD);
+
+  if (module_list == NULL)
+    error (_("Failed to get target list of modules: %s"), wtxapi_err_msg_get ());
+  else
+    make_cleanup (cleanup_wtxapi_module_list, module_list);
+
+  for (i = 0; i < module_list->num_obj_mod; i++)
+    if (module_list->mod_id_array [i] == module_id)
+      return module_list->pd_id_array [i];
+
+  /* If we reach this point, it means we did not find the given module.  */
+  error (_("Failed to find module by ID: 0x%x"), module_id);
+}
+
+/* Given the name of a module that has just been unloaded, returni
+   the PD ID where it was loaded.  The modules loaded on the current PD
+   are searched first.
+   
+   The search is not performed by querying the target server as
+   the module has probably already been unloaded.  Instead, this function
+   searches the current object_files list first, and then the object_files
+   list that we have saved for each PD.
+   
+   On systems that do not support PDs, simply always return NULL_PD.
+   If the module is unknown to GDB, an error will be reported later
+   when searching the module in the list of objfiles.  */
+
+pd_id_t
+wtx_pd_get_unloaded_module_pd (const char *module_name)
+{
+  /* FIXME: Not properly implemented for VxWorks 653 systems yet.  */
+  return NULL_PD;
+}
+
+static void
+switch_to_pd_stub (void *pd_id)
+{
+  wtx_pd_switch_to_pd ((pd_id_t) pd_id);
+}
+
+struct cleanup *
+wtx_pd_make_switch_to_pd_cleanup (pd_id_t pd_id)
+{
+  return make_cleanup (switch_to_pd_stub, (void *) pd_id);
+}
+
+/* Switch to the partition where the given task is running.
+   This function is a no-op if we are already in the right PD.  */
+
+void
+wtx_pd_switch_to_task_pd (int task_id)
+{
+  pd_id_t task_pd;
+  int success;
+
+  /* Try to retrieve ID of the PD inside which the module is running.
+     This operation may fail in normal conditions (eg when the event
+     we just received for this task is a CTX_EXIT), so abort silently
+     if the lookup fails.  */
+  success = wtxapi_get_task_pd (task_id, &task_pd);
+  if (!success)
+    return;
+
+  if (task_pd != wtxapi_pd_current_get ())
+    wtx_pd_switch_to_pd (task_pd);
+}
+
+/* Display the list of PDs on the target.  */
+
+static void
+info_partitions_command (char *arg, int from_tty)
+{
+  struct wtxapi_pd_desc_q *pds, *iter;
+  pd_id_t current_pd;
+
+  if (arg != NULL && arg[0] != '\000')
+    warning (_("Unexpected arguments at end of command, ignored."));
+
+  if (!wtxapi_tool_connected ())
+    error (_("Not attached to a target. "
+             "Use the \"target wtx\" command first."));
+
+  current_pd  = wtxapi_pd_current_get ();
+  pds = wtxapi_pd_info_q_get ();
+  iter = pds;
+
+  printf_filtered ("   PD-ID \t Name \n");
+  while (iter != NULL)
+    {
+      printf_filtered ("%s  ", iter->pd_desc.pd_id == current_pd ? "*" : " ");
+      printf_filtered ("0x%x \t %s \n",
+                       (unsigned int) iter->pd_desc.pd_id,
+                       iter->pd_desc.pd_name);
+      iter = iter->next;
+    }
+  free_wtxapi_pd_desc_q (pds);
+}
+
+/* Implement the "pd" command.  */
+
+static void
+partition_command (char *arg, int from_tty)
+{
+  pd_id_t pd_id;
+  STATUS result;
+
+  if (arg == NULL || arg[0] == '\000')
+    error (_("Please specify a partition ID. Use \"info partition\" to\n"
+             "see the IDs of the existing partitions."));
+
+  if (!isdigit (arg[0]))
+    pd_id = wtx_pd_pd_id_from_name (arg);
+  else
+    pd_id = strtol (arg, NULL, 0);
+
+  wtx_pd_switch_to_pd (pd_id);
+}
+
+/* Print a notification to the user if the current PD is no longer
+   the same as the PD that was current at the time when this function
+   was last called.  */
+
+static void
+wtx_pd_check_pd_change (void)
+{
+  static pd_id_t pd_after_last_command = NULL_PD;
+
+  pd_id_t previous_pd = pd_after_last_command;
+  pd_after_last_command = wtxapi_pd_current_get ();
+
+  if (pd_after_last_command != previous_pd)
+    {
+      char *pd_name = wtx_pd_get_pd_name (pd_after_last_command);
+      printf_filtered ("[Switching to Partition %s (0x%lx)]\n",
+                       pd_name, pd_after_last_command);
+      free (pd_name);
+    }
+}
+
+/* Observer for the "command_post" notification.  */
+
+static void
+wtx_pd_command_post_notification (void)
+{
+  /* If the current PD has changed as a consequence of the previous command,
+     then we notify the user about the new PD.  */
+  wtx_pd_check_pd_change ();
+}
+
+/* Print the Link Path of all PDs.  */
+
+static void
+maintenance_info_link_path (char *arg, int from_tty)
+{
+  struct wtxapi_pd_desc_q *pds, *iter;
+
+  pds = wtxapi_pd_info_q_get ();
+  iter = pds;
+
+  printf ("Partition \t Name \t [Link Path]\n");
+  while (iter != NULL)
+    {
+      const struct wtxapi_pd_desc desc = iter->pd_desc;
+      printf ("   0x%lx \t %s \t [%s]\n",
+              iter->pd_desc.pd_id, iter->pd_desc.pd_name,
+              desc.pd_link_path_str ? desc.pd_link_path_str
+                                    : "(no link path)");
+      iter = iter->next;
+    }
+  free_wtxapi_pd_desc_q (pds);
+}
+
+void
+_initialize_remote_wtx_pd (void)
+{
+  if (!wtx_pd_system_has_pds ())
+    return;
+
+  observer_attach_command_post (wtx_pd_command_post_notification);
+
+  add_info ("partitions", info_partitions_command,
+            _("Display the list of existing partitions."));
+
+  add_com ("partition", class_run, partition_command,
+           _("Set the current partition."));
+
+  add_cmd ("link-path", class_maintenance, maintenance_info_link_path,
+           _("Display the link path of each partition."),
+           &maintenanceinfolist);
+}
+
diff --git a/gdb/remote-wtx-pd.h b/gdb/remote-wtx-pd.h
new file mode 100644
index 0000000..27e813c
--- /dev/null
+++ b/gdb/remote-wtx-pd.h
@@ -0,0 +1,58 @@
+/* Support for the WTX protocol.
+
+   Copyright (C) 2007, 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/>.  */
+
+#ifndef REMOTE_WTX_PD_H
+#define REMOTE_WTX_PD_H
+
+#include "defs.h"
+#include "remote-wtxapi.h"
+
+/* This unit provides an abstraction layer to Partitions for both
+   Tornado 2.x & Tornado 653.  Although only Tornado 653 systems
+   really support the concept of partitions, we can apply the same
+   concept to Tornado 2.x by imagining that these systems are a
+   special case where there is only one (kernel) partition.
+
+   For historical reasons (in the defunct produce Tornado AE), Partitions
+   are also refered as PD, an accronym for Protection Domain, the technical
+   term used to refer to partitions in Tornado AE.  This accronym is very
+   short and handy, so we'll use it in place of partition.  */
+
+struct cleanup;
+
+/* On Tornado 2.x, we will use the following NULL_PD to emulate the
+   system unique PD ID.  On Tornado 653, we will be using the real
+   PD IDs.  */
+#define NULL_PD (0)
+
+int wtx_pd_system_has_pds ();
+
+char *wtx_pd_get_pd_name (pd_id_t pd_id);
+
+void wtx_pd_switch_to_pd (pd_id_t pd_id);
+
+pd_id_t wtx_pd_get_module_pd (module_id_t module_id);
+
+pd_id_t wtx_pd_get_unloaded_module_pd (const char *module_name);
+
+struct cleanup *wtx_pd_make_switch_to_pd_cleanup (pd_id_t pd_id);
+
+void wtx_pd_switch_to_task_pd (int task_id);
+
+#endif
-- 
1.7.0.4


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