aboutsummaryrefslogtreecommitdiff
path: root/gdb/kod.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/kod.c')
-rw-r--r--gdb/kod.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/gdb/kod.c b/gdb/kod.c
new file mode 100644
index 00000000000..a0969109cf8
--- /dev/null
+++ b/gdb/kod.c
@@ -0,0 +1,239 @@
+/* Kernel Object Display generic routines and callbacks
+ Copyright 1998, 1999 Free Software Foundation, Inc.
+
+ Written by Fernando Nasser <fnasser@cygnus.com> for Cygnus Solutions.
+
+ 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 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+#include "command.h"
+#include "gdbcmd.h"
+#include "target.h"
+#include "gdb_string.h"
+
+/* Prototypes for exported functions. */
+void _initialize_kod (void);
+
+/* Prototypes for local functions. */
+static void show_kod (char *, int);
+static void info_kod_command (char *, int);
+static void load_kod_library (char *);
+
+/* Prototypes for callbacks. These are passed into the KOD modules. */
+static void gdb_kod_display (char *);
+static void gdb_kod_query (char *, char *, int *);
+
+/* These functions are imported from the KOD module.
+
+ gdb_kod_open - initiates the KOD connection to the remote. The
+ first argument is the display function the module should use to
+ communicate with the user. The second argument is the query
+ function the display should use to communicate with the target.
+ This should call error() if there is an error. Otherwise it should
+ return a malloc()d string of the form:
+
+ NAME VERSION - DESCRIPTION
+
+ Neither NAME nor VERSION should contain a hyphen.
+
+
+ gdb_kod_request - This is used when the user enters an "info
+ <module>" request. The remaining arguments are passed as the first
+ argument. The second argument is the standard `from_tty'
+ argument.
+
+
+ gdb_kod_close - This is called when the KOD connection to the
+ remote should be terminated. */
+
+static char *(*gdb_kod_open) (void *, void *);
+static void (*gdb_kod_request) (char *, int);
+static void (*gdb_kod_close) ();
+
+
+/* Name of inferior's operating system. */
+char *operating_system;
+
+/* We save a copy of the OS so that we can properly reset when
+ switching OS's. */
+static char *old_operating_system;
+
+/* Functions imported from the library for all supported OSes.
+ FIXME: we really should do something better, such as dynamically
+ loading the KOD modules. */
+extern char *ecos_kod_open (void *, void *);
+extern void ecos_kod_request (char *, int);
+extern void ecos_kod_close ();
+extern char *cisco_kod_open (void *, void *);
+extern void cisco_kod_request (char *, int);
+extern void cisco_kod_close ();
+
+
+/* Print a line of data generated by the module. */
+
+static void
+gdb_kod_display (char *arg)
+{
+ printf_filtered ("%s", arg);
+}
+
+/* Queries the target on behalf of the module. */
+
+static void
+gdb_kod_query (char *arg, char *result, int *maxsiz)
+{
+ int bufsiz = 0;
+
+ /* Check if current target has remote_query capabilities.
+ If not, it does not have kod either. */
+ if (! current_target.to_query)
+ {
+ strcpy (result,
+ "ERR: Kernel Object Display not supported by current target\n");
+ return;
+ }
+
+ /* Just get the maximum buffer size. */
+ target_query ((int) 'K', 0, 0, &bufsiz);
+
+ /* Check if *we* were called just for getting the buffer size. */
+ if (*maxsiz == 0)
+ {
+ *maxsiz = bufsiz;
+ strcpy (result, "OK");
+ return;
+ }
+
+ /* Check if caller can handle a buffer this large, if not, adjust. */
+ if (bufsiz > *maxsiz)
+ bufsiz = *maxsiz;
+
+ /* See if buffer can hold the query (usually it can, as the query is
+ short). */
+ if (strlen (arg) >= bufsiz)
+ error ("kod: query argument too long");
+
+ /* Send actual request. */
+ if (target_query ((int) 'K', arg, result, &bufsiz))
+ strcpy (result, "ERR: remote query failed");
+}
+
+/* Print name of kod command after selecting the appropriate kod
+ formatting library module. As a side effect we create a new "info"
+ subcommand which is what the user actually uses to query the OS. */
+
+static void
+kod_set_os (char *arg, int from_tty, struct cmd_list_element *command)
+{
+ char *p;
+
+ if (command->type != set_cmd)
+ return;
+
+ /* If we had already had an open OS, close it. */
+ if (gdb_kod_close)
+ (*gdb_kod_close) ();
+
+ /* Also remove the old OS's command. */
+ if (old_operating_system)
+ {
+ delete_cmd (old_operating_system, &infolist);
+ free (old_operating_system);
+ }
+ old_operating_system = strdup (operating_system);
+
+ if (! operating_system || ! *operating_system)
+ {
+ /* If user set operating system to empty, we want to forget we
+ had a module open. Setting these variables is just nice for
+ debugging and clarity. */
+ gdb_kod_open = NULL;
+ gdb_kod_request = NULL;
+ gdb_kod_close = NULL;
+ }
+ else
+ {
+ char *kodlib;
+
+ load_kod_library (operating_system);
+
+ kodlib = (*gdb_kod_open) (gdb_kod_display, gdb_kod_query);
+
+ /* Add kod related info commands to gdb. */
+ add_info (operating_system, info_kod_command,
+ "Displays information about Kernel Objects.");
+
+ p = strrchr (kodlib, '-');
+ if (p != NULL)
+ p++;
+ else
+ p = "Unknown KOD library";
+ printf_filtered ("%s - %s\n", operating_system, p);
+
+ free (kodlib);
+ }
+}
+
+/* Print information about currently known kernel objects of the
+ specified type or a list of all known kernel object types if
+ argument is empty. */
+
+static void
+info_kod_command (char *arg, int from_tty)
+{
+ (*gdb_kod_request) (arg, from_tty);
+}
+
+/* Print name of kod command after selecting the appropriate kod
+ formatting library module. */
+
+static void
+load_kod_library (char *lib)
+{
+#if 0
+ /* FIXME: Don't have the eCos code here. */
+ if (! strcmp (lib, "ecos"))
+ {
+ gdb_kod_open = ecos_kod_open;
+ gdb_kod_request = ecos_kod_request;
+ gdb_kod_close = ecos_kod_close;
+ }
+ else
+#endif /* 0 */
+ if (! strcmp (lib, "cisco"))
+ {
+ gdb_kod_open = cisco_kod_open;
+ gdb_kod_request = cisco_kod_request;
+ gdb_kod_close = cisco_kod_close;
+ }
+ else
+ error ("Unknown operating system: %s\n", operating_system);
+}
+
+void
+_initialize_kod ()
+{
+ struct cmd_list_element *c;
+
+ c = add_set_cmd ("os", no_class, var_string,
+ (char *) &operating_system,
+ "Set operating system",
+ &setlist);
+ c->function.sfunc = kod_set_os;
+ add_show_from_set (c, &showlist);
+}