1b725ae77Skettenis /* Kernel Object Display generic routines and callbacks
2b725ae77Skettenis Copyright 1998, 1999, 2000 Free Software Foundation, Inc.
3b725ae77Skettenis
4b725ae77Skettenis Written by Fernando Nasser <fnasser@cygnus.com> for Cygnus Solutions.
5b725ae77Skettenis
6b725ae77Skettenis This file is part of GDB.
7b725ae77Skettenis
8b725ae77Skettenis This program is free software; you can redistribute it and/or modify
9b725ae77Skettenis it under the terms of the GNU General Public License as published by
10b725ae77Skettenis the Free Software Foundation; either version 2 of the License, or
11b725ae77Skettenis (at your option) any later version.
12b725ae77Skettenis
13b725ae77Skettenis This program is distributed in the hope that it will be useful,
14b725ae77Skettenis but WITHOUT ANY WARRANTY; without even the implied warranty of
15b725ae77Skettenis MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16b725ae77Skettenis GNU General Public License for more details.
17b725ae77Skettenis
18b725ae77Skettenis You should have received a copy of the GNU General Public License
19b725ae77Skettenis along with this program; if not, write to the Free Software
20b725ae77Skettenis Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis Boston, MA 02111-1307, USA. */
22b725ae77Skettenis
23b725ae77Skettenis #include "defs.h"
24b725ae77Skettenis #include "command.h"
25b725ae77Skettenis #include "gdbcmd.h"
26b725ae77Skettenis #include "target.h"
27b725ae77Skettenis #include "gdb_string.h"
28b725ae77Skettenis #include "kod.h"
29b725ae77Skettenis
30b725ae77Skettenis /* Prototypes for exported functions. */
31b725ae77Skettenis void _initialize_kod (void);
32b725ae77Skettenis
33b725ae77Skettenis /* Prototypes for local functions. */
34b725ae77Skettenis static void info_kod_command (char *, int);
35b725ae77Skettenis static void load_kod_library (char *);
36b725ae77Skettenis
37b725ae77Skettenis /* Prototypes for callbacks. These are passed into the KOD modules. */
38b725ae77Skettenis static void gdb_kod_display (char *);
39b725ae77Skettenis static void gdb_kod_query (char *, char *, int *);
40b725ae77Skettenis
41b725ae77Skettenis /* These functions are imported from the KOD module.
42b725ae77Skettenis
43b725ae77Skettenis gdb_kod_open - initiates the KOD connection to the remote. The
44b725ae77Skettenis first argument is the display function the module should use to
45b725ae77Skettenis communicate with the user. The second argument is the query
46b725ae77Skettenis function the display should use to communicate with the target.
47b725ae77Skettenis This should call error() if there is an error. Otherwise it should
48b725ae77Skettenis return a malloc()d string of the form:
49b725ae77Skettenis
50b725ae77Skettenis NAME VERSION - DESCRIPTION
51b725ae77Skettenis
52b725ae77Skettenis Neither NAME nor VERSION should contain a hyphen.
53b725ae77Skettenis
54b725ae77Skettenis
55b725ae77Skettenis gdb_kod_request - This is used when the user enters an "info
56b725ae77Skettenis <module>" request. The remaining arguments are passed as the first
57b725ae77Skettenis argument. The second argument is the standard `from_tty'
58b725ae77Skettenis argument.
59b725ae77Skettenis
60b725ae77Skettenis
61b725ae77Skettenis gdb_kod_close - This is called when the KOD connection to the
62b725ae77Skettenis remote should be terminated. */
63b725ae77Skettenis
64b725ae77Skettenis static char *(*gdb_kod_open) (kod_display_callback_ftype *display,
65b725ae77Skettenis kod_query_callback_ftype *query);
66b725ae77Skettenis static void (*gdb_kod_request) (char *, int);
67b725ae77Skettenis static void (*gdb_kod_close) ();
68b725ae77Skettenis
69b725ae77Skettenis
70b725ae77Skettenis /* Name of inferior's operating system. */
71b725ae77Skettenis char *operating_system;
72b725ae77Skettenis
73b725ae77Skettenis /* We save a copy of the OS so that we can properly reset when
74b725ae77Skettenis switching OS's. */
75b725ae77Skettenis static char *old_operating_system;
76b725ae77Skettenis
77b725ae77Skettenis /* Print a line of data generated by the module. */
78b725ae77Skettenis
79b725ae77Skettenis static void
gdb_kod_display(char * arg)80b725ae77Skettenis gdb_kod_display (char *arg)
81b725ae77Skettenis {
82b725ae77Skettenis printf_filtered ("%s", arg);
83b725ae77Skettenis }
84b725ae77Skettenis
85b725ae77Skettenis /* Queries the target on behalf of the module. */
86b725ae77Skettenis
87b725ae77Skettenis static void
gdb_kod_query(char * arg,char * result,int * maxsiz)88b725ae77Skettenis gdb_kod_query (char *arg, char *result, int *maxsiz)
89b725ae77Skettenis {
90b725ae77Skettenis LONGEST bufsiz = 0;
91b725ae77Skettenis
92b725ae77Skettenis /* Check if current target has remote_query capabilities. If not,
93b725ae77Skettenis it does not have kod either. */
94b725ae77Skettenis bufsiz = target_read_partial (¤t_target, TARGET_OBJECT_KOD,
95b725ae77Skettenis NULL, NULL, 0, 0);
96b725ae77Skettenis if (bufsiz < 0)
97b725ae77Skettenis {
98b725ae77Skettenis strcpy (result,
99b725ae77Skettenis "ERR: Kernel Object Display not supported by current target\n");
100b725ae77Skettenis return;
101b725ae77Skettenis }
102b725ae77Skettenis
103b725ae77Skettenis /* Just get the maximum buffer size. */
104b725ae77Skettenis
105b725ae77Skettenis /* Check if *we* were called just for getting the buffer size. */
106b725ae77Skettenis if (*maxsiz == 0)
107b725ae77Skettenis {
108b725ae77Skettenis *maxsiz = bufsiz;
109b725ae77Skettenis strcpy (result, "OK");
110b725ae77Skettenis return;
111b725ae77Skettenis }
112b725ae77Skettenis
113b725ae77Skettenis /* Check if caller can handle a buffer this large, if not, adjust. */
114b725ae77Skettenis if (bufsiz > *maxsiz)
115b725ae77Skettenis bufsiz = *maxsiz;
116b725ae77Skettenis
117b725ae77Skettenis /* See if buffer can hold the query (usually it can, as the query is
118b725ae77Skettenis short). */
119b725ae77Skettenis if (strlen (arg) >= bufsiz)
120b725ae77Skettenis error ("kod: query argument too long");
121b725ae77Skettenis
122b725ae77Skettenis /* Send actual request. */
123b725ae77Skettenis if (target_read_partial (¤t_target, TARGET_OBJECT_KOD,
124b725ae77Skettenis arg, result, 0, bufsiz) < 0)
125b725ae77Skettenis strcpy (result, "ERR: remote query failed");
126b725ae77Skettenis }
127b725ae77Skettenis
128b725ae77Skettenis /* Print name of kod command after selecting the appropriate kod
129b725ae77Skettenis formatting library module. As a side effect we create a new "info"
130b725ae77Skettenis subcommand which is what the user actually uses to query the OS. */
131b725ae77Skettenis
132b725ae77Skettenis static void
kod_set_os(char * arg,int from_tty,struct cmd_list_element * command)133b725ae77Skettenis kod_set_os (char *arg, int from_tty, struct cmd_list_element *command)
134b725ae77Skettenis {
135b725ae77Skettenis char *p;
136b725ae77Skettenis
137*11efff7fSkettenis /* NOTE: cagney/2002-03-17: The deprecated_add_show_from_set()
138*11efff7fSkettenis function clones the set command passed as a parameter. The clone
139*11efff7fSkettenis operation will include (BUG?) any ``set'' command callback, if
140*11efff7fSkettenis present. Commands like ``info set'' call all the ``show''
141*11efff7fSkettenis command callbacks. Unfortunately, for ``show'' commands cloned
142*11efff7fSkettenis from ``set'', this includes callbacks belonging to ``set''
143*11efff7fSkettenis commands. Making this worse, this only occures if
144*11efff7fSkettenis deprecated_add_show_from_set() is called after add_cmd_sfunc()
145*11efff7fSkettenis (BUG?). */
146b725ae77Skettenis
147b725ae77Skettenis if (cmd_type (command) != set_cmd)
148b725ae77Skettenis return;
149b725ae77Skettenis
150b725ae77Skettenis /* If we had already had an open OS, close it. */
151b725ae77Skettenis if (gdb_kod_close)
152b725ae77Skettenis (*gdb_kod_close) ();
153b725ae77Skettenis
154b725ae77Skettenis /* Also remove the old OS's command. */
155b725ae77Skettenis if (old_operating_system)
156b725ae77Skettenis {
157b725ae77Skettenis delete_cmd (old_operating_system, &infolist);
158b725ae77Skettenis xfree (old_operating_system);
159b725ae77Skettenis }
160b725ae77Skettenis
161b725ae77Skettenis if (! operating_system || ! *operating_system)
162b725ae77Skettenis {
163b725ae77Skettenis /* If user set operating system to empty, we want to forget we
164b725ae77Skettenis had a module open. Setting these variables is just nice for
165b725ae77Skettenis debugging and clarity. */
166b725ae77Skettenis gdb_kod_open = NULL;
167b725ae77Skettenis gdb_kod_request = NULL;
168b725ae77Skettenis gdb_kod_close = NULL;
169b725ae77Skettenis }
170b725ae77Skettenis else
171b725ae77Skettenis {
172b725ae77Skettenis char *kodlib;
173b725ae77Skettenis
174b725ae77Skettenis old_operating_system = xstrdup (operating_system);
175b725ae77Skettenis
176b725ae77Skettenis load_kod_library (operating_system);
177b725ae77Skettenis
178b725ae77Skettenis kodlib = (*gdb_kod_open) (gdb_kod_display, gdb_kod_query);
179b725ae77Skettenis
180b725ae77Skettenis /* Add kod related info commands to gdb. */
181b725ae77Skettenis add_info (operating_system, info_kod_command,
182b725ae77Skettenis "Displays information about Kernel Objects.");
183b725ae77Skettenis
184b725ae77Skettenis p = strrchr (kodlib, '-');
185b725ae77Skettenis if (p != NULL)
186b725ae77Skettenis p++;
187b725ae77Skettenis else
188b725ae77Skettenis p = "Unknown KOD library";
189b725ae77Skettenis printf_filtered ("%s - %s\n", operating_system, p);
190b725ae77Skettenis
191b725ae77Skettenis xfree (kodlib);
192b725ae77Skettenis }
193b725ae77Skettenis }
194b725ae77Skettenis
195b725ae77Skettenis /* Print information about currently known kernel objects of the
196b725ae77Skettenis specified type or a list of all known kernel object types if
197b725ae77Skettenis argument is empty. */
198b725ae77Skettenis
199b725ae77Skettenis static void
info_kod_command(char * arg,int from_tty)200b725ae77Skettenis info_kod_command (char *arg, int from_tty)
201b725ae77Skettenis {
202b725ae77Skettenis (*gdb_kod_request) (arg, from_tty);
203b725ae77Skettenis }
204b725ae77Skettenis
205b725ae77Skettenis /* Print name of kod command after selecting the appropriate kod
206b725ae77Skettenis formatting library module. */
207b725ae77Skettenis
208b725ae77Skettenis static void
load_kod_library(char * lib)209b725ae77Skettenis load_kod_library (char *lib)
210b725ae77Skettenis {
211b725ae77Skettenis #if 0
212b725ae77Skettenis /* FIXME: Don't have the eCos code here. */
213b725ae77Skettenis if (! strcmp (lib, "ecos"))
214b725ae77Skettenis {
215b725ae77Skettenis gdb_kod_open = ecos_kod_open;
216b725ae77Skettenis gdb_kod_request = ecos_kod_request;
217b725ae77Skettenis gdb_kod_close = ecos_kod_close;
218b725ae77Skettenis }
219b725ae77Skettenis else
220b725ae77Skettenis #endif /* 0 */
221b725ae77Skettenis if (! strcmp (lib, "cisco"))
222b725ae77Skettenis {
223b725ae77Skettenis gdb_kod_open = cisco_kod_open;
224b725ae77Skettenis gdb_kod_request = cisco_kod_request;
225b725ae77Skettenis gdb_kod_close = cisco_kod_close;
226b725ae77Skettenis }
227b725ae77Skettenis else
228b725ae77Skettenis error ("Unknown operating system: %s\n", operating_system);
229b725ae77Skettenis }
230b725ae77Skettenis
231b725ae77Skettenis void
_initialize_kod(void)232b725ae77Skettenis _initialize_kod (void)
233b725ae77Skettenis {
234b725ae77Skettenis struct cmd_list_element *c;
235b725ae77Skettenis
236b725ae77Skettenis c = add_set_cmd ("os", no_class, var_string,
237b725ae77Skettenis (char *) &operating_system,
238b725ae77Skettenis "Set operating system",
239b725ae77Skettenis &setlist);
240b725ae77Skettenis set_cmd_sfunc (c, kod_set_os);
241*11efff7fSkettenis deprecated_add_show_from_set (c, &showlist);
242b725ae77Skettenis }
243