From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13398 invoked by alias); 25 Apr 2010 15:48:12 -0000 Received: (qmail 12779 invoked by uid 22791); 25 Apr 2010 15:48:03 -0000 X-SWARE-Spam-Status: No, hits=0.9 required=5.0 tests=BAYES_50,TW_BJ,TW_WT,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 25 Apr 2010 15:47:56 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id DB3D72BAC91 for ; Sun, 25 Apr 2010 11:47:50 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id As0rdRznlcmP for ; Sun, 25 Apr 2010 11:47:50 -0400 (EDT) Received: from joel.gnat.com (localhost.localdomain [127.0.0.1]) by rock.gnat.com (Postfix) with ESMTP id 829842BAC95 for ; Sun, 25 Apr 2010 11:47:49 -0400 (EDT) Received: by joel.gnat.com (Postfix, from userid 1000) id 2809CF5896; Sun, 25 Apr 2010 11:47:49 -0400 (EDT) From: Joel Brobecker To: gdb-patches@sourceware.org Subject: [vxworks 08/14] Partition support. Date: Sun, 25 Apr 2010 15:48:00 -0000 Message-Id: <1272210447-13895-9-git-send-email-brobecker@adacore.com> In-Reply-To: <1272210447-13895-1-git-send-email-brobecker@adacore.com> References: <1272210447-13895-1-git-send-email-brobecker@adacore.com> Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-04/txt/msg00847.txt.bz2 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. 2010-04-24 Joel Brobecker * remote-wtx-pd.h, remote-wtx-pd.c: New files. --- gdb/remote-wtx-pd.c | 349 +++++++++++++++++++++++++++++++++++++++++++++++++++ gdb/remote-wtx-pd.h | 58 +++++++++ 2 files changed, 407 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..1bf4acd --- /dev/null +++ b/gdb/remote-wtx-pd.c @@ -0,0 +1,349 @@ +/* Support for the WTX protocol. + + Copyright (C) 2007, 2010 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 . */ + +#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 + +/* 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 "". */ + +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 (""); +} + +/* 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 Protection Domain: %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) +{ + STATUS result; + 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 (_("PD 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, return + 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: brobecker/2004-04-24: 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_pds_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 +pd_command (char *arg, int from_tty) +{ + pd_id_t pd_id; + STATUS result; + + if (arg == NULL || arg[0] == '\000') + error ("Please specify a protection domain ID. Use \"info pds\" to\n" + "see the IDs of the existing protection domains."); + + 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 ("pds", info_pds_command, + _("Display the list of existing protection domains.")); + + add_com ("pd", class_run, pd_command, + _("Set the current protection domain.")); + + 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..402be1f --- /dev/null +++ b/gdb/remote-wtx-pd.h @@ -0,0 +1,58 @@ +/* Support for the WTX protocol. + + Copyright (C) 2007, 2010 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 . */ + +#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 Partition 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.6.3.3