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. */ 31void _initialize_kod (void); 32 33/* Prototypes for local functions. */ 34static void info_kod_command (char *, int); 35static void load_kod_library (char *); 36 37/* Prototypes for callbacks. These are passed into the KOD modules. */ 38static void gdb_kod_display (char *); 39static 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 64static char *(*gdb_kod_open) (kod_display_callback_ftype *display, 65 kod_query_callback_ftype *query); 66static void (*gdb_kod_request) (char *, int); 67static void (*gdb_kod_close) (); 68 69 70/* Name of inferior's operating system. */ 71char *operating_system; 72 73/* We save a copy of the OS so that we can properly reset when 74 switching OS's. */ 75static char *old_operating_system; 76 77/* Print a line of data generated by the module. */ 78 79static void 80gdb_kod_display (char *arg) 81{ 82 printf_filtered ("%s", arg); 83} 84 85/* Queries the target on behalf of the module. */ 86 87static void 88gdb_kod_query (char *arg, char *result, int *maxsiz) 89{ 90 LONGEST bufsiz = 0; 91 92 /* Check if current target has remote_query capabilities. If not, 93 it does not have kod either. */ 94 bufsiz = target_read_partial (¤t_target, TARGET_OBJECT_KOD, 95 NULL, NULL, 0, 0); 96 if (bufsiz < 0) 97 { 98 strcpy (result, 99 "ERR: Kernel Object Display not supported by current target\n"); 100 return; 101 } 102 103 /* Just get the maximum buffer size. */ 104 105 /* Check if *we* were called just for getting the buffer size. */ 106 if (*maxsiz == 0) 107 { 108 *maxsiz = bufsiz; 109 strcpy (result, "OK"); 110 return; 111 } 112 113 /* Check if caller can handle a buffer this large, if not, adjust. */ 114 if (bufsiz > *maxsiz) 115 bufsiz = *maxsiz; 116 117 /* See if buffer can hold the query (usually it can, as the query is 118 short). */ 119 if (strlen (arg) >= bufsiz) 120 error ("kod: query argument too long"); 121 122 /* Send actual request. */ 123 if (target_read_partial (¤t_target, TARGET_OBJECT_KOD, 124 arg, result, 0, bufsiz) < 0) 125 strcpy (result, "ERR: remote query failed"); 126} 127 128/* Print name of kod command after selecting the appropriate kod 129 formatting library module. As a side effect we create a new "info" 130 subcommand which is what the user actually uses to query the OS. */ 131 132static void 133kod_set_os (char *arg, int from_tty, struct cmd_list_element *command) 134{ 135 char *p; 136 137 /* NOTE: cagney/2002-03-17: The add_show_from_set() function clones 138 the set command passed as a parameter. The clone operation will 139 include (BUG?) any ``set'' command callback, if present. 140 Commands like ``info set'' call all the ``show'' command 141 callbacks. Unfortunately, for ``show'' commands cloned from 142 ``set'', this includes callbacks belonging to ``set'' commands. 143 Making this worse, this only occures if add_show_from_set() is 144 called after add_cmd_sfunc() (BUG?). */ 145 146 if (cmd_type (command) != set_cmd) 147 return; 148 149 /* If we had already had an open OS, close it. */ 150 if (gdb_kod_close) 151 (*gdb_kod_close) (); 152 153 /* Also remove the old OS's command. */ 154 if (old_operating_system) 155 { 156 delete_cmd (old_operating_system, &infolist); 157 xfree (old_operating_system); 158 } 159 160 if (! operating_system || ! *operating_system) 161 { 162 /* If user set operating system to empty, we want to forget we 163 had a module open. Setting these variables is just nice for 164 debugging and clarity. */ 165 gdb_kod_open = NULL; 166 gdb_kod_request = NULL; 167 gdb_kod_close = NULL; 168 } 169 else 170 { 171 char *kodlib; 172 173 old_operating_system = xstrdup (operating_system); 174 175 load_kod_library (operating_system); 176 177 kodlib = (*gdb_kod_open) (gdb_kod_display, gdb_kod_query); 178 179 /* Add kod related info commands to gdb. */ 180 add_info (operating_system, info_kod_command, 181 "Displays information about Kernel Objects."); 182 183 p = strrchr (kodlib, '-'); 184 if (p != NULL) 185 p++; 186 else 187 p = "Unknown KOD library"; 188 printf_filtered ("%s - %s\n", operating_system, p); 189 190 xfree (kodlib); 191 } 192} 193 194/* Print information about currently known kernel objects of the 195 specified type or a list of all known kernel object types if 196 argument is empty. */ 197 198static void 199info_kod_command (char *arg, int from_tty) 200{ 201 (*gdb_kod_request) (arg, from_tty); 202} 203 204/* Print name of kod command after selecting the appropriate kod 205 formatting library module. */ 206 207static void 208load_kod_library (char *lib) 209{ 210#if 0 211 /* FIXME: Don't have the eCos code here. */ 212 if (! strcmp (lib, "ecos")) 213 { 214 gdb_kod_open = ecos_kod_open; 215 gdb_kod_request = ecos_kod_request; 216 gdb_kod_close = ecos_kod_close; 217 } 218 else 219#endif /* 0 */ 220 if (! strcmp (lib, "cisco")) 221 { 222 gdb_kod_open = cisco_kod_open; 223 gdb_kod_request = cisco_kod_request; 224 gdb_kod_close = cisco_kod_close; 225 } 226 else 227 error ("Unknown operating system: %s\n", operating_system); 228} 229 230void 231_initialize_kod (void) 232{ 233 struct cmd_list_element *c; 234 235 c = add_set_cmd ("os", no_class, var_string, 236 (char *) &operating_system, 237 "Set operating system", 238 &setlist); 239 set_cmd_sfunc (c, kod_set_os); 240 add_show_from_set (c, &showlist); 241} 242