kod.c revision 98944
198944Sobrien/* Kernel Object Display generic routines and callbacks
298944Sobrien   Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
398944Sobrien
498944Sobrien   Written by Fernando Nasser <fnasser@cygnus.com> for Cygnus Solutions.
598944Sobrien
698944Sobrien   This file is part of GDB.
798944Sobrien
898944Sobrien   This program is free software; you can redistribute it and/or modify
998944Sobrien   it under the terms of the GNU General Public License as published by
1098944Sobrien   the Free Software Foundation; either version 2 of the License, or
1198944Sobrien   (at your option) any later version.
1298944Sobrien
1398944Sobrien   This program is distributed in the hope that it will be useful,
1498944Sobrien   but WITHOUT ANY WARRANTY; without even the implied warranty of
1598944Sobrien   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1698944Sobrien   GNU General Public License for more details.
1798944Sobrien
1898944Sobrien   You should have received a copy of the GNU General Public License
1998944Sobrien   along with this program; if not, write to the Free Software
2098944Sobrien   Foundation, Inc., 59 Temple Place - Suite 330,
2198944Sobrien   Boston, MA 02111-1307, USA.  */
2298944Sobrien
2398944Sobrien#include "defs.h"
2498944Sobrien#include "command.h"
2598944Sobrien#include "gdbcmd.h"
2698944Sobrien#include "target.h"
2798944Sobrien#include "gdb_string.h"
2898944Sobrien#include "kod.h"
2998944Sobrien
3098944Sobrien/* Prototypes for exported functions.  */
3198944Sobrienvoid _initialize_kod (void);
3298944Sobrien
3398944Sobrien/* Prototypes for local functions.  */
3498944Sobrienstatic void info_kod_command (char *, int);
3598944Sobrienstatic void load_kod_library (char *);
3698944Sobrien
3798944Sobrien/* Prototypes for callbacks.  These are passed into the KOD modules.  */
3898944Sobrienstatic void gdb_kod_display (char *);
3998944Sobrienstatic void gdb_kod_query (char *, char *, int *);
4098944Sobrien
4198944Sobrien/* These functions are imported from the KOD module.
4298944Sobrien
4398944Sobrien   gdb_kod_open - initiates the KOD connection to the remote.  The
4498944Sobrien   first argument is the display function the module should use to
4598944Sobrien   communicate with the user.  The second argument is the query
4698944Sobrien   function the display should use to communicate with the target.
4798944Sobrien   This should call error() if there is an error.  Otherwise it should
4898944Sobrien   return a malloc()d string of the form:
4998944Sobrien
5098944Sobrien   NAME VERSION - DESCRIPTION
5198944Sobrien
5298944Sobrien   Neither NAME nor VERSION should contain a hyphen.
5398944Sobrien
5498944Sobrien
5598944Sobrien   gdb_kod_request - This is used when the user enters an "info
5698944Sobrien   <module>" request.  The remaining arguments are passed as the first
5798944Sobrien   argument.  The second argument is the standard `from_tty'
5898944Sobrien   argument.
5998944Sobrien
6098944Sobrien
6198944Sobrien   gdb_kod_close - This is called when the KOD connection to the
6298944Sobrien   remote should be terminated.  */
6398944Sobrien
6498944Sobrienstatic char *(*gdb_kod_open) (kod_display_callback_ftype *display,
6598944Sobrien			      kod_query_callback_ftype *query);
6698944Sobrienstatic void (*gdb_kod_request) (char *, int);
6798944Sobrienstatic void (*gdb_kod_close) ();
6898944Sobrien
6998944Sobrien
7098944Sobrien/* Name of inferior's operating system.  */
7198944Sobrienchar *operating_system;
7298944Sobrien
7398944Sobrien/* We save a copy of the OS so that we can properly reset when
7498944Sobrien   switching OS's.  */
7598944Sobrienstatic char *old_operating_system;
7698944Sobrien
7798944Sobrien/* Print a line of data generated by the module.  */
7898944Sobrien
7998944Sobrienstatic void
8098944Sobriengdb_kod_display (char *arg)
8198944Sobrien{
8298944Sobrien  printf_filtered ("%s", arg);
8398944Sobrien}
8498944Sobrien
8598944Sobrien/* Queries the target on behalf of the module.  */
8698944Sobrien
8798944Sobrienstatic void
8898944Sobriengdb_kod_query (char *arg, char *result, int *maxsiz)
8998944Sobrien{
9098944Sobrien  int bufsiz = 0;
9198944Sobrien
9298944Sobrien  /* Check if current target has remote_query capabilities.
9398944Sobrien     If not, it does not have kod either.  */
9498944Sobrien  if (! current_target.to_query)
9598944Sobrien    {
9698944Sobrien      strcpy (result,
9798944Sobrien              "ERR: Kernel Object Display not supported by current target\n");
9898944Sobrien      return;
9998944Sobrien    }
10098944Sobrien
10198944Sobrien  /* Just get the maximum buffer size.  */
10298944Sobrien  target_query ((int) 'K', 0, 0, &bufsiz);
10398944Sobrien
10498944Sobrien  /* Check if *we* were called just for getting the buffer size.  */
10598944Sobrien  if (*maxsiz == 0)
10698944Sobrien    {
10798944Sobrien      *maxsiz = bufsiz;
10898944Sobrien      strcpy (result, "OK");
10998944Sobrien      return;
11098944Sobrien    }
11198944Sobrien
11298944Sobrien  /* Check if caller can handle a buffer this large, if not, adjust.  */
11398944Sobrien  if (bufsiz > *maxsiz)
11498944Sobrien    bufsiz = *maxsiz;
11598944Sobrien
11698944Sobrien  /* See if buffer can hold the query (usually it can, as the query is
11798944Sobrien     short).  */
11898944Sobrien  if (strlen (arg) >= bufsiz)
11998944Sobrien    error ("kod: query argument too long");
12098944Sobrien
12198944Sobrien  /* Send actual request.  */
12298944Sobrien  if (target_query ((int) 'K', arg, result, &bufsiz))
12398944Sobrien    strcpy (result, "ERR: remote query failed");
12498944Sobrien}
12598944Sobrien
12698944Sobrien/* Print name of kod command after selecting the appropriate kod
12798944Sobrien   formatting library module.  As a side effect we create a new "info"
12898944Sobrien   subcommand which is what the user actually uses to query the OS.  */
12998944Sobrien
13098944Sobrienstatic void
13198944Sobrienkod_set_os (char *arg, int from_tty, struct cmd_list_element *command)
13298944Sobrien{
13398944Sobrien  char *p;
13498944Sobrien
13598944Sobrien  if (command->type != set_cmd)
13698944Sobrien    return;
13798944Sobrien
13898944Sobrien  /* If we had already had an open OS, close it.  */
13998944Sobrien  if (gdb_kod_close)
14098944Sobrien    (*gdb_kod_close) ();
14198944Sobrien
14298944Sobrien  /* Also remove the old OS's command.  */
14398944Sobrien  if (old_operating_system)
14498944Sobrien    {
14598944Sobrien      delete_cmd (old_operating_system, &infolist);
14698944Sobrien      xfree (old_operating_system);
14798944Sobrien    }
14898944Sobrien  old_operating_system = xstrdup (operating_system);
14998944Sobrien
15098944Sobrien  if (! operating_system || ! *operating_system)
15198944Sobrien    {
15298944Sobrien      /* If user set operating system to empty, we want to forget we
15398944Sobrien	 had a module open.  Setting these variables is just nice for
15498944Sobrien	 debugging and clarity.  */
15598944Sobrien      gdb_kod_open = NULL;
15698944Sobrien      gdb_kod_request = NULL;
15798944Sobrien      gdb_kod_close = NULL;
15898944Sobrien    }
15998944Sobrien  else
16098944Sobrien    {
16198944Sobrien      char *kodlib;
16298944Sobrien
16398944Sobrien      load_kod_library (operating_system);
16498944Sobrien
16598944Sobrien      kodlib = (*gdb_kod_open) (gdb_kod_display, gdb_kod_query);
16698944Sobrien
16798944Sobrien      /* Add kod related info commands to gdb.  */
16898944Sobrien      add_info (operating_system, info_kod_command,
16998944Sobrien		"Displays information about Kernel Objects.");
17098944Sobrien
17198944Sobrien      p = strrchr (kodlib, '-');
17298944Sobrien      if (p != NULL)
17398944Sobrien	p++;
17498944Sobrien      else
17598944Sobrien	p = "Unknown KOD library";
17698944Sobrien      printf_filtered ("%s - %s\n", operating_system, p);
17798944Sobrien
17898944Sobrien      xfree (kodlib);
17998944Sobrien    }
18098944Sobrien}
18198944Sobrien
18298944Sobrien/* Print information about currently known kernel objects of the
18398944Sobrien   specified type or a list of all known kernel object types if
18498944Sobrien   argument is empty.  */
18598944Sobrien
18698944Sobrienstatic void
18798944Sobrieninfo_kod_command (char *arg, int from_tty)
18898944Sobrien{
18998944Sobrien  (*gdb_kod_request) (arg, from_tty);
19098944Sobrien}
19198944Sobrien
19298944Sobrien/* Print name of kod command after selecting the appropriate kod
19398944Sobrien   formatting library module.  */
19498944Sobrien
19598944Sobrienstatic void
19698944Sobrienload_kod_library (char *lib)
19798944Sobrien{
19898944Sobrien#if 0
19998944Sobrien  /* FIXME: Don't have the eCos code here.  */
20098944Sobrien  if (! strcmp (lib, "ecos"))
20198944Sobrien    {
20298944Sobrien      gdb_kod_open = ecos_kod_open;
20398944Sobrien      gdb_kod_request = ecos_kod_request;
20498944Sobrien      gdb_kod_close = ecos_kod_close;
20598944Sobrien    }
20698944Sobrien  else
20798944Sobrien#endif /* 0 */
20898944Sobrien   if (! strcmp (lib, "cisco"))
20998944Sobrien    {
21098944Sobrien      gdb_kod_open = cisco_kod_open;
21198944Sobrien      gdb_kod_request = cisco_kod_request;
21298944Sobrien      gdb_kod_close = cisco_kod_close;
21398944Sobrien    }
21498944Sobrien  else
21598944Sobrien    error ("Unknown operating system: %s\n", operating_system);
21698944Sobrien}
21798944Sobrien
21898944Sobrienvoid
21998944Sobrien_initialize_kod (void)
22098944Sobrien{
22198944Sobrien  struct cmd_list_element *c;
22298944Sobrien
22398944Sobrien  c = add_set_cmd ("os", no_class, var_string,
22498944Sobrien		   (char *) &operating_system,
22598944Sobrien		   "Set operating system",
22698944Sobrien		   &setlist);
22798944Sobrien  set_cmd_sfunc (c, kod_set_os);
22898944Sobrien  add_show_from_set (c, &showlist);
22998944Sobrien}
230