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