GDB (API)
/home/stan/gdb/src/gdb/mi/mi-main.c
Go to the documentation of this file.
00001 /* MI Command Set.
00002 
00003    Copyright (C) 2000-2013 Free Software Foundation, Inc.
00004 
00005    Contributed by Cygnus Solutions (a Red Hat company).
00006 
00007    This file is part of GDB.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 3 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00021 
00022 #include "defs.h"
00023 #include "arch-utils.h"
00024 #include "target.h"
00025 #include "inferior.h"
00026 #include "gdb_string.h"
00027 #include "exceptions.h"
00028 #include "top.h"
00029 #include "gdbthread.h"
00030 #include "mi-cmds.h"
00031 #include "mi-parse.h"
00032 #include "mi-getopt.h"
00033 #include "mi-console.h"
00034 #include "ui-out.h"
00035 #include "mi-out.h"
00036 #include "interps.h"
00037 #include "event-loop.h"
00038 #include "event-top.h"
00039 #include "gdbcore.h"            /* For write_memory().  */
00040 #include "value.h"
00041 #include "regcache.h"
00042 #include "gdb.h"
00043 #include "frame.h"
00044 #include "mi-main.h"
00045 #include "mi-common.h"
00046 #include "language.h"
00047 #include "valprint.h"
00048 #include "inferior.h"
00049 #include "osdata.h"
00050 #include "splay-tree.h"
00051 #include "tracepoint.h"
00052 #include "ctf.h"
00053 #include "ada-lang.h"
00054 #include "linespec.h"
00055 #ifdef HAVE_PYTHON
00056 #include "python/python-internal.h"
00057 #endif
00058 
00059 #include <ctype.h>
00060 #include <sys/time.h>
00061 
00062 #if defined HAVE_SYS_RESOURCE_H
00063 #include <sys/resource.h>
00064 #endif
00065 
00066 #ifdef HAVE_GETRUSAGE
00067 struct rusage rusage;
00068 #endif
00069 
00070 enum
00071   {
00072     FROM_TTY = 0
00073   };
00074 
00075 int mi_debug_p;
00076 
00077 struct ui_file *raw_stdout;
00078 
00079 /* This is used to pass the current command timestamp down to
00080    continuation routines.  */
00081 static struct mi_timestamp *current_command_ts;
00082 
00083 static int do_timings = 0;
00084 
00085 char *current_token;
00086 /* Few commands would like to know if options like --thread-group were
00087    explicitly specified.  This variable keeps the current parsed
00088    command including all option, and make it possible.  */
00089 static struct mi_parse *current_context;
00090 
00091 int running_result_record_printed = 1;
00092 
00093 /* Flag indicating that the target has proceeded since the last
00094    command was issued.  */
00095 int mi_proceeded;
00096 
00097 extern void _initialize_mi_main (void);
00098 static void mi_cmd_execute (struct mi_parse *parse);
00099 
00100 static void mi_execute_cli_command (const char *cmd, int args_p,
00101                                     const char *args);
00102 static void mi_execute_async_cli_command (char *cli_command, 
00103                                           char **argv, int argc);
00104 static int register_changed_p (int regnum, struct regcache *,
00105                                struct regcache *);
00106 static void output_register (struct frame_info *, int regnum, int format,
00107                              int skip_unavailable);
00108 
00109 /* Command implementations.  FIXME: Is this libgdb?  No.  This is the MI
00110    layer that calls libgdb.  Any operation used in the below should be
00111    formalized.  */
00112 
00113 static void timestamp (struct mi_timestamp *tv);
00114 
00115 static void print_diff_now (struct mi_timestamp *start);
00116 static void print_diff (struct mi_timestamp *start, struct mi_timestamp *end);
00117 
00118 void
00119 mi_cmd_gdb_exit (char *command, char **argv, int argc)
00120 {
00121   /* We have to print everything right here because we never return.  */
00122   if (current_token)
00123     fputs_unfiltered (current_token, raw_stdout);
00124   fputs_unfiltered ("^exit\n", raw_stdout);
00125   mi_out_put (current_uiout, raw_stdout);
00126   gdb_flush (raw_stdout);
00127   /* FIXME: The function called is not yet a formal libgdb function.  */
00128   quit_force (NULL, FROM_TTY);
00129 }
00130 
00131 void
00132 mi_cmd_exec_next (char *command, char **argv, int argc)
00133 {
00134   /* FIXME: Should call a libgdb function, not a cli wrapper.  */
00135   if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
00136     mi_execute_async_cli_command ("reverse-next", argv + 1, argc - 1);
00137   else
00138     mi_execute_async_cli_command ("next", argv, argc);
00139 }
00140 
00141 void
00142 mi_cmd_exec_next_instruction (char *command, char **argv, int argc)
00143 {
00144   /* FIXME: Should call a libgdb function, not a cli wrapper.  */
00145   if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
00146     mi_execute_async_cli_command ("reverse-nexti", argv + 1, argc - 1);
00147   else
00148     mi_execute_async_cli_command ("nexti", argv, argc);
00149 }
00150 
00151 void
00152 mi_cmd_exec_step (char *command, char **argv, int argc)
00153 {
00154   /* FIXME: Should call a libgdb function, not a cli wrapper.  */
00155   if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
00156     mi_execute_async_cli_command ("reverse-step", argv + 1, argc - 1);
00157   else
00158     mi_execute_async_cli_command ("step", argv, argc);
00159 }
00160 
00161 void
00162 mi_cmd_exec_step_instruction (char *command, char **argv, int argc)
00163 {
00164   /* FIXME: Should call a libgdb function, not a cli wrapper.  */
00165   if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
00166     mi_execute_async_cli_command ("reverse-stepi", argv + 1, argc - 1);
00167   else
00168     mi_execute_async_cli_command ("stepi", argv, argc);
00169 }
00170 
00171 void
00172 mi_cmd_exec_finish (char *command, char **argv, int argc)
00173 {
00174   /* FIXME: Should call a libgdb function, not a cli wrapper.  */
00175   if (argc > 0 && strcmp(argv[0], "--reverse") == 0)
00176     mi_execute_async_cli_command ("reverse-finish", argv + 1, argc - 1);
00177   else
00178     mi_execute_async_cli_command ("finish", argv, argc);
00179 }
00180 
00181 void
00182 mi_cmd_exec_return (char *command, char **argv, int argc)
00183 {
00184   /* This command doesn't really execute the target, it just pops the
00185      specified number of frames.  */
00186   if (argc)
00187     /* Call return_command with from_tty argument equal to 0 so as to
00188        avoid being queried.  */
00189     return_command (*argv, 0);
00190   else
00191     /* Call return_command with from_tty argument equal to 0 so as to
00192        avoid being queried.  */
00193     return_command (NULL, 0);
00194 
00195   /* Because we have called return_command with from_tty = 0, we need
00196      to print the frame here.  */
00197   print_stack_frame (get_selected_frame (NULL), 1, LOC_AND_ADDRESS, 1);
00198 }
00199 
00200 void
00201 mi_cmd_exec_jump (char *args, char **argv, int argc)
00202 {
00203   /* FIXME: Should call a libgdb function, not a cli wrapper.  */
00204   mi_execute_async_cli_command ("jump", argv, argc);
00205 }
00206  
00207 static void
00208 proceed_thread (struct thread_info *thread, int pid)
00209 {
00210   if (!is_stopped (thread->ptid))
00211     return;
00212 
00213   if (pid != 0 && ptid_get_pid (thread->ptid) != pid)
00214     return;
00215 
00216   switch_to_thread (thread->ptid);
00217   clear_proceed_status ();
00218   proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT, 0);
00219 }
00220 
00221 static int
00222 proceed_thread_callback (struct thread_info *thread, void *arg)
00223 {
00224   int pid = *(int *)arg;
00225 
00226   proceed_thread (thread, pid);
00227   return 0;
00228 }
00229 
00230 static void
00231 exec_continue (char **argv, int argc)
00232 {
00233   if (non_stop)
00234     {
00235       /* In non-stop mode, 'resume' always resumes a single thread.
00236          Therefore, to resume all threads of the current inferior, or
00237          all threads in all inferiors, we need to iterate over
00238          threads.
00239 
00240          See comment on infcmd.c:proceed_thread_callback for rationale.  */
00241       if (current_context->all || current_context->thread_group != -1)
00242         {
00243           int pid = 0;
00244           struct cleanup *back_to = make_cleanup_restore_current_thread ();
00245 
00246           if (!current_context->all)
00247             {
00248               struct inferior *inf
00249                 = find_inferior_id (current_context->thread_group);
00250 
00251               pid = inf->pid;
00252             }
00253           iterate_over_threads (proceed_thread_callback, &pid);
00254           do_cleanups (back_to);
00255         }
00256       else
00257         {
00258           continue_1 (0);
00259         }
00260     }
00261   else
00262     {
00263       struct cleanup *back_to = make_cleanup_restore_integer (&sched_multi);
00264 
00265       if (current_context->all)
00266         {
00267           sched_multi = 1;
00268           continue_1 (0);
00269         }
00270       else
00271         {
00272           /* In all-stop mode, -exec-continue traditionally resumed
00273              either all threads, or one thread, depending on the
00274              'scheduler-locking' variable.  Let's continue to do the
00275              same.  */
00276           continue_1 (1);
00277         }
00278       do_cleanups (back_to);
00279     }
00280 }
00281 
00282 static void
00283 exec_direction_forward (void *notused)
00284 {
00285   execution_direction = EXEC_FORWARD;
00286 }
00287 
00288 static void
00289 exec_reverse_continue (char **argv, int argc)
00290 {
00291   enum exec_direction_kind dir = execution_direction;
00292   struct cleanup *old_chain;
00293 
00294   if (dir == EXEC_REVERSE)
00295     error (_("Already in reverse mode."));
00296 
00297   if (!target_can_execute_reverse)
00298     error (_("Target %s does not support this command."), target_shortname);
00299 
00300   old_chain = make_cleanup (exec_direction_forward, NULL);
00301   execution_direction = EXEC_REVERSE;
00302   exec_continue (argv, argc);
00303   do_cleanups (old_chain);
00304 }
00305 
00306 void
00307 mi_cmd_exec_continue (char *command, char **argv, int argc)
00308 {
00309   if (argc > 0 && strcmp (argv[0], "--reverse") == 0)
00310     exec_reverse_continue (argv + 1, argc - 1);
00311   else
00312     exec_continue (argv, argc);
00313 }
00314 
00315 static int
00316 interrupt_thread_callback (struct thread_info *thread, void *arg)
00317 {
00318   int pid = *(int *)arg;
00319 
00320   if (!is_running (thread->ptid))
00321     return 0;
00322 
00323   if (ptid_get_pid (thread->ptid) != pid)
00324     return 0;
00325 
00326   target_stop (thread->ptid);
00327   return 0;
00328 }
00329 
00330 /* Interrupt the execution of the target.  Note how we must play
00331    around with the token variables, in order to display the current
00332    token in the result of the interrupt command, and the previous
00333    execution token when the target finally stops.  See comments in
00334    mi_cmd_execute.  */
00335 
00336 void
00337 mi_cmd_exec_interrupt (char *command, char **argv, int argc)
00338 {
00339   /* In all-stop mode, everything stops, so we don't need to try
00340      anything specific.  */
00341   if (!non_stop)
00342     {
00343       interrupt_target_1 (0);
00344       return;
00345     }
00346 
00347   if (current_context->all)
00348     {
00349       /* This will interrupt all threads in all inferiors.  */
00350       interrupt_target_1 (1);
00351     }
00352   else if (current_context->thread_group != -1)
00353     {
00354       struct inferior *inf = find_inferior_id (current_context->thread_group);
00355 
00356       iterate_over_threads (interrupt_thread_callback, &inf->pid);
00357     }
00358   else
00359     {
00360       /* Interrupt just the current thread -- either explicitly
00361          specified via --thread or whatever was current before
00362          MI command was sent.  */
00363       interrupt_target_1 (0);
00364     }
00365 }
00366 
00367 /* Callback for iterate_over_inferiors which starts the execution
00368    of the given inferior.
00369 
00370    ARG is a pointer to an integer whose value, if non-zero, indicates
00371    that the program should be stopped when reaching the main subprogram
00372    (similar to what the CLI "start" command does).  */
00373 
00374 static int
00375 run_one_inferior (struct inferior *inf, void *arg)
00376 {
00377   int start_p = *(int *) arg;
00378   const char *run_cmd = start_p ? "start" : "run";
00379 
00380   if (inf->pid != 0)
00381     {
00382       if (inf->pid != ptid_get_pid (inferior_ptid))
00383         {
00384           struct thread_info *tp;
00385 
00386           tp = any_thread_of_process (inf->pid);
00387           if (!tp)
00388             error (_("Inferior has no threads."));
00389 
00390           switch_to_thread (tp->ptid);
00391         }
00392     }
00393   else
00394     {
00395       set_current_inferior (inf);
00396       switch_to_thread (null_ptid);
00397       set_current_program_space (inf->pspace);
00398     }
00399   mi_execute_cli_command (run_cmd, target_can_async_p (),
00400                           target_can_async_p () ? "&" : NULL);
00401   return 0;
00402 }
00403 
00404 void
00405 mi_cmd_exec_run (char *command, char **argv, int argc)
00406 {
00407   int i;
00408   int start_p = 0;
00409 
00410   /* Parse the command options.  */
00411   enum opt
00412     {
00413       START_OPT,
00414     };
00415   static const struct mi_opt opts[] =
00416     {
00417         {"-start", START_OPT, 0},
00418         {NULL, 0, 0},
00419     };
00420 
00421   int oind = 0;
00422   char *oarg;
00423 
00424   while (1)
00425     {
00426       int opt = mi_getopt ("-exec-run", argc, argv, opts, &oind, &oarg);
00427 
00428       if (opt < 0)
00429         break;
00430       switch ((enum opt) opt)
00431         {
00432         case START_OPT:
00433           start_p = 1;
00434           break;
00435         }
00436     }
00437 
00438   /* This command does not accept any argument.  Make sure the user
00439      did not provide any.  */
00440   if (oind != argc)
00441     error (_("Invalid argument: %s"), argv[oind]);
00442 
00443   if (current_context->all)
00444     {
00445       struct cleanup *back_to = save_current_space_and_thread ();
00446 
00447       iterate_over_inferiors (run_one_inferior, &start_p);
00448       do_cleanups (back_to);
00449     }
00450   else
00451     {
00452       const char *run_cmd = start_p ? "start" : "run";
00453 
00454       mi_execute_cli_command (run_cmd, target_can_async_p (),
00455                               target_can_async_p () ? "&" : NULL);
00456     }
00457 }
00458 
00459 
00460 static int
00461 find_thread_of_process (struct thread_info *ti, void *p)
00462 {
00463   int pid = *(int *)p;
00464 
00465   if (ptid_get_pid (ti->ptid) == pid && !is_exited (ti->ptid))
00466     return 1;
00467 
00468   return 0;
00469 }
00470 
00471 void
00472 mi_cmd_target_detach (char *command, char **argv, int argc)
00473 {
00474   if (argc != 0 && argc != 1)
00475     error (_("Usage: -target-detach [pid | thread-group]"));
00476 
00477   if (argc == 1)
00478     {
00479       struct thread_info *tp;
00480       char *end = argv[0];
00481       int pid;
00482 
00483       /* First see if we are dealing with a thread-group id.  */
00484       if (*argv[0] == 'i')
00485         {
00486           struct inferior *inf;
00487           int id = strtoul (argv[0] + 1, &end, 0);
00488 
00489           if (*end != '\0')
00490             error (_("Invalid syntax of thread-group id '%s'"), argv[0]);
00491 
00492           inf = find_inferior_id (id);
00493           if (!inf)
00494             error (_("Non-existent thread-group id '%d'"), id);
00495 
00496           pid = inf->pid;
00497         }
00498       else
00499         {
00500           /* We must be dealing with a pid.  */
00501           pid = strtol (argv[0], &end, 10);
00502 
00503           if (*end != '\0')
00504             error (_("Invalid identifier '%s'"), argv[0]);
00505         }
00506 
00507       /* Pick any thread in the desired process.  Current
00508          target_detach detaches from the parent of inferior_ptid.  */
00509       tp = iterate_over_threads (find_thread_of_process, &pid);
00510       if (!tp)
00511         error (_("Thread group is empty"));
00512 
00513       switch_to_thread (tp->ptid);
00514     }
00515 
00516   detach_command (NULL, 0);
00517 }
00518 
00519 void
00520 mi_cmd_thread_select (char *command, char **argv, int argc)
00521 {
00522   enum gdb_rc rc;
00523   char *mi_error_message;
00524 
00525   if (argc != 1)
00526     error (_("-thread-select: USAGE: threadnum."));
00527 
00528   rc = gdb_thread_select (current_uiout, argv[0], &mi_error_message);
00529 
00530   if (rc == GDB_RC_FAIL)
00531     {
00532       make_cleanup (xfree, mi_error_message);
00533       error ("%s", mi_error_message);
00534     }
00535 }
00536 
00537 void
00538 mi_cmd_thread_list_ids (char *command, char **argv, int argc)
00539 {
00540   enum gdb_rc rc;
00541   char *mi_error_message;
00542 
00543   if (argc != 0)
00544     error (_("-thread-list-ids: No arguments required."));
00545 
00546   rc = gdb_list_thread_ids (current_uiout, &mi_error_message);
00547 
00548   if (rc == GDB_RC_FAIL)
00549     {
00550       make_cleanup (xfree, mi_error_message);
00551       error ("%s", mi_error_message);
00552     }
00553 }
00554 
00555 void
00556 mi_cmd_thread_info (char *command, char **argv, int argc)
00557 {
00558   if (argc != 0 && argc != 1)
00559     error (_("Invalid MI command"));
00560 
00561   print_thread_info (current_uiout, argv[0], -1);
00562 }
00563 
00564 struct collect_cores_data
00565 {
00566   int pid;
00567 
00568   VEC (int) *cores;
00569 };
00570 
00571 static int
00572 collect_cores (struct thread_info *ti, void *xdata)
00573 {
00574   struct collect_cores_data *data = xdata;
00575 
00576   if (ptid_get_pid (ti->ptid) == data->pid)
00577     {
00578       int core = target_core_of_thread (ti->ptid);
00579 
00580       if (core != -1)
00581         VEC_safe_push (int, data->cores, core);
00582     }
00583 
00584   return 0;
00585 }
00586 
00587 static int *
00588 unique (int *b, int *e)
00589 {
00590   int *d = b;
00591 
00592   while (++b != e)
00593     if (*d != *b)
00594       *++d = *b;
00595   return ++d;
00596 }
00597 
00598 struct print_one_inferior_data
00599 {
00600   int recurse;
00601   VEC (int) *inferiors;
00602 };
00603 
00604 static int
00605 print_one_inferior (struct inferior *inferior, void *xdata)
00606 {
00607   struct print_one_inferior_data *top_data = xdata;
00608   struct ui_out *uiout = current_uiout;
00609 
00610   if (VEC_empty (int, top_data->inferiors)
00611       || bsearch (&(inferior->pid), VEC_address (int, top_data->inferiors),
00612                   VEC_length (int, top_data->inferiors), sizeof (int),
00613                   compare_positive_ints))
00614     {
00615       struct collect_cores_data data;
00616       struct cleanup *back_to
00617         = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
00618 
00619       ui_out_field_fmt (uiout, "id", "i%d", inferior->num);
00620       ui_out_field_string (uiout, "type", "process");
00621       if (inferior->pid != 0)
00622         ui_out_field_int (uiout, "pid", inferior->pid);
00623 
00624       if (inferior->pspace->pspace_exec_filename != NULL)
00625         {
00626           ui_out_field_string (uiout, "executable",
00627                                inferior->pspace->pspace_exec_filename);
00628         }
00629 
00630       data.cores = 0;
00631       if (inferior->pid != 0)
00632         {
00633           data.pid = inferior->pid;
00634           iterate_over_threads (collect_cores, &data);
00635         }
00636 
00637       if (!VEC_empty (int, data.cores))
00638         {
00639           int *b, *e;
00640           struct cleanup *back_to_2 =
00641             make_cleanup_ui_out_list_begin_end (uiout, "cores");
00642 
00643           qsort (VEC_address (int, data.cores),
00644                  VEC_length (int, data.cores), sizeof (int),
00645                  compare_positive_ints);
00646 
00647           b = VEC_address (int, data.cores);
00648           e = b + VEC_length (int, data.cores);
00649           e = unique (b, e);
00650 
00651           for (; b != e; ++b)
00652             ui_out_field_int (uiout, NULL, *b);
00653 
00654           do_cleanups (back_to_2);
00655         }
00656 
00657       if (top_data->recurse)
00658         print_thread_info (uiout, NULL, inferior->pid);
00659 
00660       do_cleanups (back_to);
00661     }
00662 
00663   return 0;
00664 }
00665 
00666 /* Output a field named 'cores' with a list as the value.  The
00667    elements of the list are obtained by splitting 'cores' on
00668    comma.  */
00669 
00670 static void
00671 output_cores (struct ui_out *uiout, const char *field_name, const char *xcores)
00672 {
00673   struct cleanup *back_to = make_cleanup_ui_out_list_begin_end (uiout,
00674                                                                 field_name);
00675   char *cores = xstrdup (xcores);
00676   char *p = cores;
00677 
00678   make_cleanup (xfree, cores);
00679 
00680   for (p = strtok (p, ","); p;  p = strtok (NULL, ","))
00681     ui_out_field_string (uiout, NULL, p);
00682 
00683   do_cleanups (back_to);
00684 }
00685 
00686 static void
00687 free_vector_of_ints (void *xvector)
00688 {
00689   VEC (int) **vector = xvector;
00690 
00691   VEC_free (int, *vector);
00692 }
00693 
00694 static void
00695 do_nothing (splay_tree_key k)
00696 {
00697 }
00698 
00699 static void
00700 free_vector_of_osdata_items (splay_tree_value xvalue)
00701 {
00702   VEC (osdata_item_s) *value = (VEC (osdata_item_s) *) xvalue;
00703 
00704   /* We don't free the items itself, it will be done separately.  */
00705   VEC_free (osdata_item_s, value);
00706 }
00707 
00708 static int
00709 splay_tree_int_comparator (splay_tree_key xa, splay_tree_key xb)
00710 {
00711   int a = xa;
00712   int b = xb;
00713 
00714   return a - b;
00715 }
00716 
00717 static void
00718 free_splay_tree (void *xt)
00719 {
00720   splay_tree t = xt;
00721   splay_tree_delete (t);
00722 }
00723 
00724 static void
00725 list_available_thread_groups (VEC (int) *ids, int recurse)
00726 {
00727   struct osdata *data;
00728   struct osdata_item *item;
00729   int ix_items;
00730   struct ui_out *uiout = current_uiout;
00731   struct cleanup *cleanup;
00732 
00733   /* This keeps a map from integer (pid) to VEC (struct osdata_item *)*
00734      The vector contains information about all threads for the given pid.
00735      This is assigned an initial value to avoid "may be used uninitialized"
00736      warning from gcc.  */
00737   splay_tree tree = NULL;
00738 
00739   /* get_osdata will throw if it cannot return data.  */
00740   data = get_osdata ("processes");
00741   cleanup = make_cleanup_osdata_free (data);
00742 
00743   if (recurse)
00744     {
00745       struct osdata *threads = get_osdata ("threads");
00746 
00747       make_cleanup_osdata_free (threads);
00748       tree = splay_tree_new (splay_tree_int_comparator,
00749                              do_nothing,
00750                              free_vector_of_osdata_items);
00751       make_cleanup (free_splay_tree, tree);
00752 
00753       for (ix_items = 0;
00754            VEC_iterate (osdata_item_s, threads->items,
00755                         ix_items, item);
00756            ix_items++)
00757         {
00758           const char *pid = get_osdata_column (item, "pid");
00759           int pid_i = strtoul (pid, NULL, 0);
00760           VEC (osdata_item_s) *vec = 0;
00761 
00762           splay_tree_node n = splay_tree_lookup (tree, pid_i);
00763           if (!n)
00764             {
00765               VEC_safe_push (osdata_item_s, vec, item);
00766               splay_tree_insert (tree, pid_i, (splay_tree_value)vec);
00767             }
00768           else
00769             {
00770               vec = (VEC (osdata_item_s) *) n->value;
00771               VEC_safe_push (osdata_item_s, vec, item);
00772               n->value = (splay_tree_value) vec;
00773             }
00774         }
00775     }
00776 
00777   make_cleanup_ui_out_list_begin_end (uiout, "groups");
00778 
00779   for (ix_items = 0;
00780        VEC_iterate (osdata_item_s, data->items,
00781                     ix_items, item);
00782        ix_items++)
00783     {
00784       struct cleanup *back_to;
00785 
00786       const char *pid = get_osdata_column (item, "pid");
00787       const char *cmd = get_osdata_column (item, "command");
00788       const char *user = get_osdata_column (item, "user");
00789       const char *cores = get_osdata_column (item, "cores");
00790 
00791       int pid_i = strtoul (pid, NULL, 0);
00792 
00793       /* At present, the target will return all available processes
00794          and if information about specific ones was required, we filter
00795          undesired processes here.  */
00796       if (ids && bsearch (&pid_i, VEC_address (int, ids),
00797                           VEC_length (int, ids),
00798                           sizeof (int), compare_positive_ints) == NULL)
00799         continue;
00800 
00801 
00802       back_to = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
00803 
00804       ui_out_field_fmt (uiout, "id", "%s", pid);
00805       ui_out_field_string (uiout, "type", "process");
00806       if (cmd)
00807         ui_out_field_string (uiout, "description", cmd);
00808       if (user)
00809         ui_out_field_string (uiout, "user", user);
00810       if (cores)
00811         output_cores (uiout, "cores", cores);
00812 
00813       if (recurse)
00814         {
00815           splay_tree_node n = splay_tree_lookup (tree, pid_i);
00816           if (n)
00817             {
00818               VEC (osdata_item_s) *children = (VEC (osdata_item_s) *) n->value;
00819               struct osdata_item *child;
00820               int ix_child;
00821 
00822               make_cleanup_ui_out_list_begin_end (uiout, "threads");
00823 
00824               for (ix_child = 0;
00825                    VEC_iterate (osdata_item_s, children, ix_child, child);
00826                    ++ix_child)
00827                 {
00828                   struct cleanup *back_to_2 =
00829                     make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
00830                   const char *tid = get_osdata_column (child, "tid");
00831                   const char *tcore = get_osdata_column (child, "core");
00832 
00833                   ui_out_field_string (uiout, "id", tid);
00834                   if (tcore)
00835                     ui_out_field_string (uiout, "core", tcore);
00836 
00837                   do_cleanups (back_to_2);
00838                 }
00839             }
00840         }
00841 
00842       do_cleanups (back_to);
00843     }
00844 
00845   do_cleanups (cleanup);
00846 }
00847 
00848 void
00849 mi_cmd_list_thread_groups (char *command, char **argv, int argc)
00850 {
00851   struct ui_out *uiout = current_uiout;
00852   struct cleanup *back_to;
00853   int available = 0;
00854   int recurse = 0;
00855   VEC (int) *ids = 0;
00856 
00857   enum opt
00858   {
00859     AVAILABLE_OPT, RECURSE_OPT
00860   };
00861   static const struct mi_opt opts[] =
00862     {
00863       {"-available", AVAILABLE_OPT, 0},
00864       {"-recurse", RECURSE_OPT, 1},
00865       { 0, 0, 0 }
00866     };
00867 
00868   int oind = 0;
00869   char *oarg;
00870 
00871   while (1)
00872     {
00873       int opt = mi_getopt ("-list-thread-groups", argc, argv, opts,
00874                            &oind, &oarg);
00875 
00876       if (opt < 0)
00877         break;
00878       switch ((enum opt) opt)
00879         {
00880         case AVAILABLE_OPT:
00881           available = 1;
00882           break;
00883         case RECURSE_OPT:
00884           if (strcmp (oarg, "0") == 0)
00885             ;
00886           else if (strcmp (oarg, "1") == 0)
00887             recurse = 1;
00888           else
00889             error (_("only '0' and '1' are valid values "
00890                      "for the '--recurse' option"));
00891           break;
00892         }
00893     }
00894 
00895   for (; oind < argc; ++oind)
00896     {
00897       char *end;
00898       int inf;
00899 
00900       if (*(argv[oind]) != 'i')
00901         error (_("invalid syntax of group id '%s'"), argv[oind]);
00902 
00903       inf = strtoul (argv[oind] + 1, &end, 0);
00904 
00905       if (*end != '\0')
00906         error (_("invalid syntax of group id '%s'"), argv[oind]);
00907       VEC_safe_push (int, ids, inf);
00908     }
00909   if (VEC_length (int, ids) > 1)
00910     qsort (VEC_address (int, ids),
00911            VEC_length (int, ids),
00912            sizeof (int), compare_positive_ints);
00913 
00914   back_to = make_cleanup (free_vector_of_ints, &ids);
00915 
00916   if (available)
00917     {
00918       list_available_thread_groups (ids, recurse);
00919     }
00920   else if (VEC_length (int, ids) == 1)
00921     {
00922       /* Local thread groups, single id.  */
00923       int id = *VEC_address (int, ids);
00924       struct inferior *inf = find_inferior_id (id);
00925 
00926       if (!inf)
00927         error (_("Non-existent thread group id '%d'"), id);
00928       
00929       print_thread_info (uiout, NULL, inf->pid);
00930     }
00931   else
00932     {
00933       struct print_one_inferior_data data;
00934 
00935       data.recurse = recurse;
00936       data.inferiors = ids;
00937 
00938       /* Local thread groups.  Either no explicit ids -- and we
00939          print everything, or several explicit ids.  In both cases,
00940          we print more than one group, and have to use 'groups'
00941          as the top-level element.  */
00942       make_cleanup_ui_out_list_begin_end (uiout, "groups");
00943       update_thread_list ();
00944       iterate_over_inferiors (print_one_inferior, &data);
00945     }
00946 
00947   do_cleanups (back_to);
00948 }
00949 
00950 void
00951 mi_cmd_data_list_register_names (char *command, char **argv, int argc)
00952 {
00953   struct gdbarch *gdbarch;
00954   struct ui_out *uiout = current_uiout;
00955   int regnum, numregs;
00956   int i;
00957   struct cleanup *cleanup;
00958 
00959   /* Note that the test for a valid register must include checking the
00960      gdbarch_register_name because gdbarch_num_regs may be allocated
00961      for the union of the register sets within a family of related
00962      processors.  In this case, some entries of gdbarch_register_name
00963      will change depending upon the particular processor being
00964      debugged.  */
00965 
00966   gdbarch = get_current_arch ();
00967   numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
00968 
00969   cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-names");
00970 
00971   if (argc == 0)                /* No args, just do all the regs.  */
00972     {
00973       for (regnum = 0;
00974            regnum < numregs;
00975            regnum++)
00976         {
00977           if (gdbarch_register_name (gdbarch, regnum) == NULL
00978               || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
00979             ui_out_field_string (uiout, NULL, "");
00980           else
00981             ui_out_field_string (uiout, NULL,
00982                                  gdbarch_register_name (gdbarch, regnum));
00983         }
00984     }
00985 
00986   /* Else, list of register #s, just do listed regs.  */
00987   for (i = 0; i < argc; i++)
00988     {
00989       regnum = atoi (argv[i]);
00990       if (regnum < 0 || regnum >= numregs)
00991         error (_("bad register number"));
00992 
00993       if (gdbarch_register_name (gdbarch, regnum) == NULL
00994           || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
00995         ui_out_field_string (uiout, NULL, "");
00996       else
00997         ui_out_field_string (uiout, NULL,
00998                              gdbarch_register_name (gdbarch, regnum));
00999     }
01000   do_cleanups (cleanup);
01001 }
01002 
01003 void
01004 mi_cmd_data_list_changed_registers (char *command, char **argv, int argc)
01005 {
01006   static struct regcache *this_regs = NULL;
01007   struct ui_out *uiout = current_uiout;
01008   struct regcache *prev_regs;
01009   struct gdbarch *gdbarch;
01010   int regnum, numregs, changed;
01011   int i;
01012   struct cleanup *cleanup;
01013 
01014   /* The last time we visited this function, the current frame's
01015      register contents were saved in THIS_REGS.  Move THIS_REGS over
01016      to PREV_REGS, and refresh THIS_REGS with the now-current register
01017      contents.  */
01018 
01019   prev_regs = this_regs;
01020   this_regs = frame_save_as_regcache (get_selected_frame (NULL));
01021   cleanup = make_cleanup_regcache_xfree (prev_regs);
01022 
01023   /* Note that the test for a valid register must include checking the
01024      gdbarch_register_name because gdbarch_num_regs may be allocated
01025      for the union of the register sets within a family of related
01026      processors.  In this case, some entries of gdbarch_register_name
01027      will change depending upon the particular processor being
01028      debugged.  */
01029 
01030   gdbarch = get_regcache_arch (this_regs);
01031   numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
01032 
01033   make_cleanup_ui_out_list_begin_end (uiout, "changed-registers");
01034 
01035   if (argc == 0)
01036     {
01037       /* No args, just do all the regs.  */
01038       for (regnum = 0;
01039            regnum < numregs;
01040            regnum++)
01041         {
01042           if (gdbarch_register_name (gdbarch, regnum) == NULL
01043               || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
01044             continue;
01045           changed = register_changed_p (regnum, prev_regs, this_regs);
01046           if (changed < 0)
01047             error (_("-data-list-changed-registers: "
01048                      "Unable to read register contents."));
01049           else if (changed)
01050             ui_out_field_int (uiout, NULL, regnum);
01051         }
01052     }
01053 
01054   /* Else, list of register #s, just do listed regs.  */
01055   for (i = 0; i < argc; i++)
01056     {
01057       regnum = atoi (argv[i]);
01058 
01059       if (regnum >= 0
01060           && regnum < numregs
01061           && gdbarch_register_name (gdbarch, regnum) != NULL
01062           && *gdbarch_register_name (gdbarch, regnum) != '\000')
01063         {
01064           changed = register_changed_p (regnum, prev_regs, this_regs);
01065           if (changed < 0)
01066             error (_("-data-list-changed-registers: "
01067                      "Unable to read register contents."));
01068           else if (changed)
01069             ui_out_field_int (uiout, NULL, regnum);
01070         }
01071       else
01072         error (_("bad register number"));
01073     }
01074   do_cleanups (cleanup);
01075 }
01076 
01077 static int
01078 register_changed_p (int regnum, struct regcache *prev_regs,
01079                     struct regcache *this_regs)
01080 {
01081   struct gdbarch *gdbarch = get_regcache_arch (this_regs);
01082   gdb_byte prev_buffer[MAX_REGISTER_SIZE];
01083   gdb_byte this_buffer[MAX_REGISTER_SIZE];
01084   enum register_status prev_status;
01085   enum register_status this_status;
01086 
01087   /* First time through or after gdbarch change consider all registers
01088      as changed.  */
01089   if (!prev_regs || get_regcache_arch (prev_regs) != gdbarch)
01090     return 1;
01091 
01092   /* Get register contents and compare.  */
01093   prev_status = regcache_cooked_read (prev_regs, regnum, prev_buffer);
01094   this_status = regcache_cooked_read (this_regs, regnum, this_buffer);
01095 
01096   if (this_status != prev_status)
01097     return 1;
01098   else if (this_status == REG_VALID)
01099     return memcmp (prev_buffer, this_buffer,
01100                    register_size (gdbarch, regnum)) != 0;
01101   else
01102     return 0;
01103 }
01104 
01105 /* Return a list of register number and value pairs.  The valid
01106    arguments expected are: a letter indicating the format in which to
01107    display the registers contents.  This can be one of: x
01108    (hexadecimal), d (decimal), N (natural), t (binary), o (octal), r
01109    (raw).  After the format argument there can be a sequence of
01110    numbers, indicating which registers to fetch the content of.  If
01111    the format is the only argument, a list of all the registers with
01112    their values is returned.  */
01113 
01114 void
01115 mi_cmd_data_list_register_values (char *command, char **argv, int argc)
01116 {
01117   struct ui_out *uiout = current_uiout;
01118   struct frame_info *frame;
01119   struct gdbarch *gdbarch;
01120   int regnum, numregs, format;
01121   int i;
01122   struct cleanup *list_cleanup;
01123   int skip_unavailable = 0;
01124   int oind = 0;
01125   enum opt
01126   {
01127     SKIP_UNAVAILABLE,
01128   };
01129   static const struct mi_opt opts[] =
01130     {
01131       {"-skip-unavailable", SKIP_UNAVAILABLE, 0},
01132       { 0, 0, 0 }
01133     };
01134 
01135   /* Note that the test for a valid register must include checking the
01136      gdbarch_register_name because gdbarch_num_regs may be allocated
01137      for the union of the register sets within a family of related
01138      processors.  In this case, some entries of gdbarch_register_name
01139      will change depending upon the particular processor being
01140      debugged.  */
01141 
01142   while (1)
01143     {
01144       char *oarg;
01145       int opt = mi_getopt ("-data-list-register-values", argc, argv,
01146                            opts, &oind, &oarg);
01147 
01148       if (opt < 0)
01149         break;
01150       switch ((enum opt) opt)
01151         {
01152         case SKIP_UNAVAILABLE:
01153           skip_unavailable = 1;
01154           break;
01155         }
01156     }
01157 
01158   if (argc - oind < 1)
01159     error (_("-data-list-register-values: Usage: "
01160              "-data-list-register-values [--skip-unavailable] <format>"
01161              " [<regnum1>...<regnumN>]"));
01162 
01163   format = (int) argv[oind][0];
01164 
01165   frame = get_selected_frame (NULL);
01166   gdbarch = get_frame_arch (frame);
01167   numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
01168 
01169   list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "register-values");
01170 
01171   if (argc - oind == 1)
01172     {
01173       /* No args, beside the format: do all the regs.  */
01174       for (regnum = 0;
01175            regnum < numregs;
01176            regnum++)
01177         {
01178           if (gdbarch_register_name (gdbarch, regnum) == NULL
01179               || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
01180             continue;
01181 
01182           output_register (frame, regnum, format, skip_unavailable);
01183         }
01184     }
01185 
01186   /* Else, list of register #s, just do listed regs.  */
01187   for (i = 1 + oind; i < argc; i++)
01188     {
01189       regnum = atoi (argv[i]);
01190 
01191       if (regnum >= 0
01192           && regnum < numregs
01193           && gdbarch_register_name (gdbarch, regnum) != NULL
01194           && *gdbarch_register_name (gdbarch, regnum) != '\000')
01195         output_register (frame, regnum, format, skip_unavailable);
01196       else
01197         error (_("bad register number"));
01198     }
01199   do_cleanups (list_cleanup);
01200 }
01201 
01202 /* Output one register REGNUM's contents in the desired FORMAT.  If
01203    SKIP_UNAVAILABLE is true, skip the register if it is
01204    unavailable.  */
01205 
01206 static void
01207 output_register (struct frame_info *frame, int regnum, int format,
01208                  int skip_unavailable)
01209 {
01210   struct gdbarch *gdbarch = get_frame_arch (frame);
01211   struct ui_out *uiout = current_uiout;
01212   struct value *val = value_of_register (regnum, frame);
01213   struct cleanup *tuple_cleanup;
01214   struct value_print_options opts;
01215   struct ui_file *stb;
01216 
01217   if (skip_unavailable && !value_entirely_available (val))
01218     return;
01219 
01220   tuple_cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
01221   ui_out_field_int (uiout, "number", regnum);
01222 
01223   if (format == 'N')
01224     format = 0;
01225 
01226   if (format == 'r')
01227     format = 'z';
01228 
01229   stb = mem_fileopen ();
01230   make_cleanup_ui_file_delete (stb);
01231 
01232   get_formatted_print_options (&opts, format);
01233   opts.deref_ref = 1;
01234   val_print (value_type (val),
01235              value_contents_for_printing (val),
01236              value_embedded_offset (val), 0,
01237              stb, 0, val, &opts, current_language);
01238   ui_out_field_stream (uiout, "value", stb);
01239 
01240   do_cleanups (tuple_cleanup);
01241 }
01242 
01243 /* Write given values into registers. The registers and values are
01244    given as pairs.  The corresponding MI command is 
01245    -data-write-register-values <format>
01246                                [<regnum1> <value1>...<regnumN> <valueN>] */
01247 void
01248 mi_cmd_data_write_register_values (char *command, char **argv, int argc)
01249 {
01250   struct regcache *regcache;
01251   struct gdbarch *gdbarch;
01252   int numregs, i;
01253 
01254   /* Note that the test for a valid register must include checking the
01255      gdbarch_register_name because gdbarch_num_regs may be allocated
01256      for the union of the register sets within a family of related
01257      processors.  In this case, some entries of gdbarch_register_name
01258      will change depending upon the particular processor being
01259      debugged.  */
01260 
01261   regcache = get_current_regcache ();
01262   gdbarch = get_regcache_arch (regcache);
01263   numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
01264 
01265   if (argc == 0)
01266     error (_("-data-write-register-values: Usage: -data-write-register-"
01267              "values <format> [<regnum1> <value1>...<regnumN> <valueN>]"));
01268 
01269   if (!target_has_registers)
01270     error (_("-data-write-register-values: No registers."));
01271 
01272   if (!(argc - 1))
01273     error (_("-data-write-register-values: No regs and values specified."));
01274 
01275   if ((argc - 1) % 2)
01276     error (_("-data-write-register-values: "
01277              "Regs and vals are not in pairs."));
01278 
01279   for (i = 1; i < argc; i = i + 2)
01280     {
01281       int regnum = atoi (argv[i]);
01282 
01283       if (regnum >= 0 && regnum < numregs
01284           && gdbarch_register_name (gdbarch, regnum)
01285           && *gdbarch_register_name (gdbarch, regnum))
01286         {
01287           LONGEST value;
01288 
01289           /* Get the value as a number.  */
01290           value = parse_and_eval_address (argv[i + 1]);
01291 
01292           /* Write it down.  */
01293           regcache_cooked_write_signed (regcache, regnum, value);
01294         }
01295       else
01296         error (_("bad register number"));
01297     }
01298 }
01299 
01300 /* Evaluate the value of the argument.  The argument is an
01301    expression. If the expression contains spaces it needs to be
01302    included in double quotes.  */
01303 
01304 void
01305 mi_cmd_data_evaluate_expression (char *command, char **argv, int argc)
01306 {
01307   struct expression *expr;
01308   struct cleanup *old_chain;
01309   struct value *val;
01310   struct ui_file *stb;
01311   struct value_print_options opts;
01312   struct ui_out *uiout = current_uiout;
01313 
01314   stb = mem_fileopen ();
01315   old_chain = make_cleanup_ui_file_delete (stb);
01316 
01317   if (argc != 1)
01318     error (_("-data-evaluate-expression: "
01319              "Usage: -data-evaluate-expression expression"));
01320 
01321   expr = parse_expression (argv[0]);
01322 
01323   make_cleanup (free_current_contents, &expr);
01324 
01325   val = evaluate_expression (expr);
01326 
01327   /* Print the result of the expression evaluation.  */
01328   get_user_print_options (&opts);
01329   opts.deref_ref = 0;
01330   common_val_print (val, stb, 0, &opts, current_language);
01331 
01332   ui_out_field_stream (uiout, "value", stb);
01333 
01334   do_cleanups (old_chain);
01335 }
01336 
01337 /* This is the -data-read-memory command.
01338 
01339    ADDR: start address of data to be dumped.
01340    WORD-FORMAT: a char indicating format for the ``word''.  See 
01341    the ``x'' command.
01342    WORD-SIZE: size of each ``word''; 1,2,4, or 8 bytes.
01343    NR_ROW: Number of rows.
01344    NR_COL: The number of colums (words per row).
01345    ASCHAR: (OPTIONAL) Append an ascii character dump to each row.  Use
01346    ASCHAR for unprintable characters.
01347 
01348    Reads SIZE*NR_ROW*NR_COL bytes starting at ADDR from memory and
01349    displayes them.  Returns:
01350 
01351    {addr="...",rowN={wordN="..." ,... [,ascii="..."]}, ...}
01352 
01353    Returns: 
01354    The number of bytes read is SIZE*ROW*COL.  */
01355 
01356 void
01357 mi_cmd_data_read_memory (char *command, char **argv, int argc)
01358 {
01359   struct gdbarch *gdbarch = get_current_arch ();
01360   struct ui_out *uiout = current_uiout;
01361   struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
01362   CORE_ADDR addr;
01363   long total_bytes, nr_cols, nr_rows;
01364   char word_format;
01365   struct type *word_type;
01366   long word_size;
01367   char word_asize;
01368   char aschar;
01369   gdb_byte *mbuf;
01370   int nr_bytes;
01371   long offset = 0;
01372   int oind = 0;
01373   char *oarg;
01374   enum opt
01375   {
01376     OFFSET_OPT
01377   };
01378   static const struct mi_opt opts[] =
01379     {
01380       {"o", OFFSET_OPT, 1},
01381       { 0, 0, 0 }
01382     };
01383 
01384   while (1)
01385     {
01386       int opt = mi_getopt ("-data-read-memory", argc, argv, opts,
01387                            &oind, &oarg);
01388 
01389       if (opt < 0)
01390         break;
01391       switch ((enum opt) opt)
01392         {
01393         case OFFSET_OPT:
01394           offset = atol (oarg);
01395           break;
01396         }
01397     }
01398   argv += oind;
01399   argc -= oind;
01400 
01401   if (argc < 5 || argc > 6)
01402     error (_("-data-read-memory: Usage: "
01403              "ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR]."));
01404 
01405   /* Extract all the arguments. */
01406 
01407   /* Start address of the memory dump.  */
01408   addr = parse_and_eval_address (argv[0]) + offset;
01409   /* The format character to use when displaying a memory word.  See
01410      the ``x'' command.  */
01411   word_format = argv[1][0];
01412   /* The size of the memory word.  */
01413   word_size = atol (argv[2]);
01414   switch (word_size)
01415     {
01416     case 1:
01417       word_type = builtin_type (gdbarch)->builtin_int8;
01418       word_asize = 'b';
01419       break;
01420     case 2:
01421       word_type = builtin_type (gdbarch)->builtin_int16;
01422       word_asize = 'h';
01423       break;
01424     case 4:
01425       word_type = builtin_type (gdbarch)->builtin_int32;
01426       word_asize = 'w';
01427       break;
01428     case 8:
01429       word_type = builtin_type (gdbarch)->builtin_int64;
01430       word_asize = 'g';
01431       break;
01432     default:
01433       word_type = builtin_type (gdbarch)->builtin_int8;
01434       word_asize = 'b';
01435     }
01436   /* The number of rows.  */
01437   nr_rows = atol (argv[3]);
01438   if (nr_rows <= 0)
01439     error (_("-data-read-memory: invalid number of rows."));
01440 
01441   /* Number of bytes per row.  */
01442   nr_cols = atol (argv[4]);
01443   if (nr_cols <= 0)
01444     error (_("-data-read-memory: invalid number of columns."));
01445 
01446   /* The un-printable character when printing ascii.  */
01447   if (argc == 6)
01448     aschar = *argv[5];
01449   else
01450     aschar = 0;
01451 
01452   /* Create a buffer and read it in.  */
01453   total_bytes = word_size * nr_rows * nr_cols;
01454   mbuf = xcalloc (total_bytes, 1);
01455   make_cleanup (xfree, mbuf);
01456 
01457   /* Dispatch memory reads to the topmost target, not the flattened
01458      current_target.  */
01459   nr_bytes = target_read (current_target.beneath,
01460                           TARGET_OBJECT_MEMORY, NULL, mbuf,
01461                           addr, total_bytes);
01462   if (nr_bytes <= 0)
01463     error (_("Unable to read memory."));
01464 
01465   /* Output the header information.  */
01466   ui_out_field_core_addr (uiout, "addr", gdbarch, addr);
01467   ui_out_field_int (uiout, "nr-bytes", nr_bytes);
01468   ui_out_field_int (uiout, "total-bytes", total_bytes);
01469   ui_out_field_core_addr (uiout, "next-row",
01470                           gdbarch, addr + word_size * nr_cols);
01471   ui_out_field_core_addr (uiout, "prev-row",
01472                           gdbarch, addr - word_size * nr_cols);
01473   ui_out_field_core_addr (uiout, "next-page", gdbarch, addr + total_bytes);
01474   ui_out_field_core_addr (uiout, "prev-page", gdbarch, addr - total_bytes);
01475 
01476   /* Build the result as a two dimentional table.  */
01477   {
01478     struct ui_file *stream;
01479     struct cleanup *cleanup_stream;
01480     int row;
01481     int row_byte;
01482 
01483     stream = mem_fileopen ();
01484     cleanup_stream = make_cleanup_ui_file_delete (stream);
01485 
01486     make_cleanup_ui_out_list_begin_end (uiout, "memory");
01487     for (row = 0, row_byte = 0;
01488          row < nr_rows;
01489          row++, row_byte += nr_cols * word_size)
01490       {
01491         int col;
01492         int col_byte;
01493         struct cleanup *cleanup_tuple;
01494         struct cleanup *cleanup_list_data;
01495         struct value_print_options opts;
01496 
01497         cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
01498         ui_out_field_core_addr (uiout, "addr", gdbarch, addr + row_byte);
01499         /* ui_out_field_core_addr_symbolic (uiout, "saddr", addr +
01500            row_byte); */
01501         cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data");
01502         get_formatted_print_options (&opts, word_format);
01503         for (col = 0, col_byte = row_byte;
01504              col < nr_cols;
01505              col++, col_byte += word_size)
01506           {
01507             if (col_byte + word_size > nr_bytes)
01508               {
01509                 ui_out_field_string (uiout, NULL, "N/A");
01510               }
01511             else
01512               {
01513                 ui_file_rewind (stream);
01514                 print_scalar_formatted (mbuf + col_byte, word_type, &opts,
01515                                         word_asize, stream);
01516                 ui_out_field_stream (uiout, NULL, stream);
01517               }
01518           }
01519         do_cleanups (cleanup_list_data);
01520         if (aschar)
01521           {
01522             int byte;
01523 
01524             ui_file_rewind (stream);
01525             for (byte = row_byte;
01526                  byte < row_byte + word_size * nr_cols; byte++)
01527               {
01528                 if (byte >= nr_bytes)
01529                   fputc_unfiltered ('X', stream);
01530                 else if (mbuf[byte] < 32 || mbuf[byte] > 126)
01531                   fputc_unfiltered (aschar, stream);
01532                 else
01533                   fputc_unfiltered (mbuf[byte], stream);
01534               }
01535             ui_out_field_stream (uiout, "ascii", stream);
01536           }
01537         do_cleanups (cleanup_tuple);
01538       }
01539     do_cleanups (cleanup_stream);
01540   }
01541   do_cleanups (cleanups);
01542 }
01543 
01544 void
01545 mi_cmd_data_read_memory_bytes (char *command, char **argv, int argc)
01546 {
01547   struct gdbarch *gdbarch = get_current_arch ();
01548   struct ui_out *uiout = current_uiout;
01549   struct cleanup *cleanups;
01550   CORE_ADDR addr;
01551   LONGEST length;
01552   memory_read_result_s *read_result;
01553   int ix;
01554   VEC(memory_read_result_s) *result;
01555   long offset = 0;
01556   int oind = 0;
01557   char *oarg;
01558   enum opt
01559   {
01560     OFFSET_OPT
01561   };
01562   static const struct mi_opt opts[] =
01563     {
01564       {"o", OFFSET_OPT, 1},
01565       { 0, 0, 0 }
01566     };
01567 
01568   while (1)
01569     {
01570       int opt = mi_getopt ("-data-read-memory-bytes", argc, argv, opts,
01571                            &oind, &oarg);
01572       if (opt < 0)
01573         break;
01574       switch ((enum opt) opt)
01575         {
01576         case OFFSET_OPT:
01577           offset = atol (oarg);
01578           break;
01579         }
01580     }
01581   argv += oind;
01582   argc -= oind;
01583 
01584   if (argc != 2)
01585     error (_("Usage: [ -o OFFSET ] ADDR LENGTH."));
01586 
01587   addr = parse_and_eval_address (argv[0]) + offset;
01588   length = atol (argv[1]);
01589 
01590   result = read_memory_robust (current_target.beneath, addr, length);
01591 
01592   cleanups = make_cleanup (free_memory_read_result_vector, result);
01593 
01594   if (VEC_length (memory_read_result_s, result) == 0)
01595     error (_("Unable to read memory."));
01596 
01597   make_cleanup_ui_out_list_begin_end (uiout, "memory");
01598   for (ix = 0;
01599        VEC_iterate (memory_read_result_s, result, ix, read_result);
01600        ++ix)
01601     {
01602       struct cleanup *t = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
01603       char *data, *p;
01604       int i;
01605 
01606       ui_out_field_core_addr (uiout, "begin", gdbarch, read_result->begin);
01607       ui_out_field_core_addr (uiout, "offset", gdbarch, read_result->begin
01608                               - addr);
01609       ui_out_field_core_addr (uiout, "end", gdbarch, read_result->end);
01610 
01611       data = xmalloc ((read_result->end - read_result->begin) * 2 + 1);
01612 
01613       for (i = 0, p = data;
01614            i < (read_result->end - read_result->begin);
01615            ++i, p += 2)
01616         {
01617           sprintf (p, "%02x", read_result->data[i]);
01618         }
01619       ui_out_field_string (uiout, "contents", data);
01620       xfree (data);
01621       do_cleanups (t);
01622     }
01623   do_cleanups (cleanups);
01624 }
01625 
01626 /* Implementation of the -data-write_memory command.
01627 
01628    COLUMN_OFFSET: optional argument. Must be preceded by '-o'. The
01629    offset from the beginning of the memory grid row where the cell to
01630    be written is.
01631    ADDR: start address of the row in the memory grid where the memory
01632    cell is, if OFFSET_COLUMN is specified.  Otherwise, the address of
01633    the location to write to.
01634    FORMAT: a char indicating format for the ``word''.  See 
01635    the ``x'' command.
01636    WORD_SIZE: size of each ``word''; 1,2,4, or 8 bytes
01637    VALUE: value to be written into the memory address.
01638 
01639    Writes VALUE into ADDR + (COLUMN_OFFSET * WORD_SIZE).
01640 
01641    Prints nothing.  */
01642 
01643 void
01644 mi_cmd_data_write_memory (char *command, char **argv, int argc)
01645 {
01646   struct gdbarch *gdbarch = get_current_arch ();
01647   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
01648   CORE_ADDR addr;
01649   long word_size;
01650   /* FIXME: ezannoni 2000-02-17 LONGEST could possibly not be big
01651      enough when using a compiler other than GCC.  */
01652   LONGEST value;
01653   void *buffer;
01654   struct cleanup *old_chain;
01655   long offset = 0;
01656   int oind = 0;
01657   char *oarg;
01658   enum opt
01659   {
01660     OFFSET_OPT
01661   };
01662   static const struct mi_opt opts[] =
01663     {
01664       {"o", OFFSET_OPT, 1},
01665       { 0, 0, 0 }
01666     };
01667 
01668   while (1)
01669     {
01670       int opt = mi_getopt ("-data-write-memory", argc, argv, opts,
01671                            &oind, &oarg);
01672 
01673       if (opt < 0)
01674         break;
01675       switch ((enum opt) opt)
01676         {
01677         case OFFSET_OPT:
01678           offset = atol (oarg);
01679           break;
01680         }
01681     }
01682   argv += oind;
01683   argc -= oind;
01684 
01685   if (argc != 4)
01686     error (_("-data-write-memory: Usage: "
01687              "[-o COLUMN_OFFSET] ADDR FORMAT WORD-SIZE VALUE."));
01688 
01689   /* Extract all the arguments.  */
01690   /* Start address of the memory dump.  */
01691   addr = parse_and_eval_address (argv[0]);
01692   /* The size of the memory word.  */
01693   word_size = atol (argv[2]);
01694 
01695   /* Calculate the real address of the write destination.  */
01696   addr += (offset * word_size);
01697 
01698   /* Get the value as a number.  */
01699   value = parse_and_eval_address (argv[3]);
01700   /* Get the value into an array.  */
01701   buffer = xmalloc (word_size);
01702   old_chain = make_cleanup (xfree, buffer);
01703   store_signed_integer (buffer, word_size, byte_order, value);
01704   /* Write it down to memory.  */
01705   write_memory_with_notification (addr, buffer, word_size);
01706   /* Free the buffer.  */
01707   do_cleanups (old_chain);
01708 }
01709 
01710 /* Implementation of the -data-write-memory-bytes command.
01711 
01712    ADDR: start address
01713    DATA: string of bytes to write at that address
01714    COUNT: number of bytes to be filled (decimal integer).  */
01715 
01716 void
01717 mi_cmd_data_write_memory_bytes (char *command, char **argv, int argc)
01718 {
01719   CORE_ADDR addr;
01720   char *cdata;
01721   gdb_byte *data;
01722   gdb_byte *databuf;
01723   size_t len, i, steps, remainder;
01724   long int count, j;
01725   struct cleanup *back_to;
01726 
01727   if (argc != 2 && argc != 3)
01728     error (_("Usage: ADDR DATA [COUNT]."));
01729 
01730   addr = parse_and_eval_address (argv[0]);
01731   cdata = argv[1];
01732   if (strlen (cdata) % 2)
01733     error (_("Hex-encoded '%s' must have an even number of characters."),
01734            cdata);
01735 
01736   len = strlen (cdata)/2;
01737   if (argc == 3)
01738     count = strtoul (argv[2], NULL, 10);
01739   else
01740     count = len;
01741 
01742   databuf = xmalloc (len * sizeof (gdb_byte));
01743   back_to = make_cleanup (xfree, databuf);
01744 
01745   for (i = 0; i < len; ++i)
01746     {
01747       int x;
01748       if (sscanf (cdata + i * 2, "%02x", &x) != 1)
01749         error (_("Invalid argument"));
01750       databuf[i] = (gdb_byte) x;
01751     }
01752 
01753   if (len < count)
01754     {
01755       /* Pattern is made of less bytes than count: 
01756          repeat pattern to fill memory.  */
01757       data = xmalloc (count);
01758       make_cleanup (xfree, data);
01759     
01760       steps = count / len;
01761       remainder = count % len;
01762       for (j = 0; j < steps; j++)
01763         memcpy (data + j * len, databuf, len);
01764 
01765       if (remainder > 0)
01766         memcpy (data + steps * len, databuf, remainder);
01767     }
01768   else 
01769     {
01770       /* Pattern is longer than or equal to count: 
01771          just copy len bytes.  */
01772       data = databuf;
01773     }
01774 
01775   write_memory_with_notification (addr, data, count);
01776 
01777   do_cleanups (back_to);
01778 }
01779 
01780 void
01781 mi_cmd_enable_timings (char *command, char **argv, int argc)
01782 {
01783   if (argc == 0)
01784     do_timings = 1;
01785   else if (argc == 1)
01786     {
01787       if (strcmp (argv[0], "yes") == 0)
01788         do_timings = 1;
01789       else if (strcmp (argv[0], "no") == 0)
01790         do_timings = 0;
01791       else
01792         goto usage_error;
01793     }
01794   else
01795     goto usage_error;
01796     
01797   return;
01798 
01799  usage_error:
01800   error (_("-enable-timings: Usage: %s {yes|no}"), command);
01801 }
01802 
01803 void
01804 mi_cmd_list_features (char *command, char **argv, int argc)
01805 {
01806   if (argc == 0)
01807     {
01808       struct cleanup *cleanup = NULL;
01809       struct ui_out *uiout = current_uiout;
01810 
01811       cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");      
01812       ui_out_field_string (uiout, NULL, "frozen-varobjs");
01813       ui_out_field_string (uiout, NULL, "pending-breakpoints");
01814       ui_out_field_string (uiout, NULL, "thread-info");
01815       ui_out_field_string (uiout, NULL, "data-read-memory-bytes");
01816       ui_out_field_string (uiout, NULL, "breakpoint-notifications");
01817       ui_out_field_string (uiout, NULL, "ada-task-info");
01818       
01819 #if HAVE_PYTHON
01820       if (gdb_python_initialized)
01821         ui_out_field_string (uiout, NULL, "python");
01822 #endif
01823       
01824       do_cleanups (cleanup);
01825       return;
01826     }
01827 
01828   error (_("-list-features should be passed no arguments"));
01829 }
01830 
01831 void
01832 mi_cmd_list_target_features (char *command, char **argv, int argc)
01833 {
01834   if (argc == 0)
01835     {
01836       struct cleanup *cleanup = NULL;
01837       struct ui_out *uiout = current_uiout;
01838 
01839       cleanup = make_cleanup_ui_out_list_begin_end (uiout, "features");      
01840       if (target_can_async_p ())
01841         ui_out_field_string (uiout, NULL, "async");
01842       if (target_can_execute_reverse)
01843         ui_out_field_string (uiout, NULL, "reverse");
01844       
01845       do_cleanups (cleanup);
01846       return;
01847     }
01848 
01849   error (_("-list-target-features should be passed no arguments"));
01850 }
01851 
01852 void
01853 mi_cmd_add_inferior (char *command, char **argv, int argc)
01854 {
01855   struct inferior *inf;
01856 
01857   if (argc != 0)
01858     error (_("-add-inferior should be passed no arguments"));
01859 
01860   inf = add_inferior_with_spaces ();
01861 
01862   ui_out_field_fmt (current_uiout, "inferior", "i%d", inf->num);
01863 }
01864 
01865 /* Callback used to find the first inferior other than the current
01866    one.  */
01867    
01868 static int
01869 get_other_inferior (struct inferior *inf, void *arg)
01870 {
01871   if (inf == current_inferior ())
01872     return 0;
01873 
01874   return 1;
01875 }
01876 
01877 void
01878 mi_cmd_remove_inferior (char *command, char **argv, int argc)
01879 {
01880   int id;
01881   struct inferior *inf;
01882 
01883   if (argc != 1)
01884     error (_("-remove-inferior should be passed a single argument"));
01885 
01886   if (sscanf (argv[0], "i%d", &id) != 1)
01887     error (_("the thread group id is syntactically invalid"));
01888 
01889   inf = find_inferior_id (id);
01890   if (!inf)
01891     error (_("the specified thread group does not exist"));
01892 
01893   if (inf->pid != 0)
01894     error (_("cannot remove an active inferior"));
01895 
01896   if (inf == current_inferior ())
01897     {
01898       struct thread_info *tp = 0;
01899       struct inferior *new_inferior 
01900         = iterate_over_inferiors (get_other_inferior, NULL);
01901 
01902       if (new_inferior == NULL)
01903         error (_("Cannot remove last inferior"));
01904 
01905       set_current_inferior (new_inferior);
01906       if (new_inferior->pid != 0)
01907         tp = any_thread_of_process (new_inferior->pid);
01908       switch_to_thread (tp ? tp->ptid : null_ptid);
01909       set_current_program_space (new_inferior->pspace);
01910     }
01911 
01912   delete_inferior_1 (inf, 1 /* silent */);
01913 }
01914 
01915 
01916 
01917 /* Execute a command within a safe environment.
01918    Return <0 for error; >=0 for ok.
01919 
01920    args->action will tell mi_execute_command what action
01921    to perfrom after the given command has executed (display/suppress
01922    prompt, display error).  */
01923 
01924 static void
01925 captured_mi_execute_command (struct ui_out *uiout, struct mi_parse *context)
01926 {
01927   struct cleanup *cleanup;
01928 
01929   if (do_timings)
01930     current_command_ts = context->cmd_start;
01931 
01932   current_token = xstrdup (context->token);
01933   cleanup = make_cleanup (free_current_contents, &current_token);
01934 
01935   running_result_record_printed = 0;
01936   mi_proceeded = 0;
01937   switch (context->op)
01938     {
01939     case MI_COMMAND:
01940       /* A MI command was read from the input stream.  */
01941       if (mi_debug_p)
01942         /* FIXME: gdb_???? */
01943         fprintf_unfiltered (raw_stdout, " token=`%s' command=`%s' args=`%s'\n",
01944                             context->token, context->command, context->args);
01945 
01946       mi_cmd_execute (context);
01947 
01948       /* Print the result if there were no errors.
01949 
01950          Remember that on the way out of executing a command, you have
01951          to directly use the mi_interp's uiout, since the command
01952          could have reset the interpreter, in which case the current
01953          uiout will most likely crash in the mi_out_* routines.  */
01954       if (!running_result_record_printed)
01955         {
01956           fputs_unfiltered (context->token, raw_stdout);
01957           /* There's no particularly good reason why target-connect results
01958              in not ^done.  Should kill ^connected for MI3.  */
01959           fputs_unfiltered (strcmp (context->command, "target-select") == 0
01960                             ? "^connected" : "^done", raw_stdout);
01961           mi_out_put (uiout, raw_stdout);
01962           mi_out_rewind (uiout);
01963           mi_print_timing_maybe ();
01964           fputs_unfiltered ("\n", raw_stdout);
01965         }
01966       else
01967         /* The command does not want anything to be printed.  In that
01968            case, the command probably should not have written anything
01969            to uiout, but in case it has written something, discard it.  */
01970         mi_out_rewind (uiout);
01971       break;
01972 
01973     case CLI_COMMAND:
01974       {
01975         char *argv[2];
01976 
01977         /* A CLI command was read from the input stream.  */
01978         /* This "feature" will be removed as soon as we have a
01979            complete set of mi commands.  */
01980         /* Echo the command on the console.  */
01981         fprintf_unfiltered (gdb_stdlog, "%s\n", context->command);
01982         /* Call the "console" interpreter.  */
01983         argv[0] = "console";
01984         argv[1] = context->command;
01985         mi_cmd_interpreter_exec ("-interpreter-exec", argv, 2);
01986 
01987         /* If we changed interpreters, DON'T print out anything.  */
01988         if (current_interp_named_p (INTERP_MI)
01989             || current_interp_named_p (INTERP_MI1)
01990             || current_interp_named_p (INTERP_MI2)
01991             || current_interp_named_p (INTERP_MI3))
01992           {
01993             if (!running_result_record_printed)
01994               {
01995                 fputs_unfiltered (context->token, raw_stdout);
01996                 fputs_unfiltered ("^done", raw_stdout);
01997                 mi_out_put (uiout, raw_stdout);
01998                 mi_out_rewind (uiout);
01999                 mi_print_timing_maybe ();
02000                 fputs_unfiltered ("\n", raw_stdout);            
02001               }
02002             else
02003               mi_out_rewind (uiout);
02004           }
02005         break;
02006       }
02007     }
02008 
02009   do_cleanups (cleanup);
02010 }
02011 
02012 /* Print a gdb exception to the MI output stream.  */
02013 
02014 static void
02015 mi_print_exception (const char *token, struct gdb_exception exception)
02016 {
02017   fputs_unfiltered (token, raw_stdout);
02018   fputs_unfiltered ("^error,msg=\"", raw_stdout);
02019   if (exception.message == NULL)
02020     fputs_unfiltered ("unknown error", raw_stdout);
02021   else
02022     fputstr_unfiltered (exception.message, '"', raw_stdout);
02023   fputs_unfiltered ("\"\n", raw_stdout);
02024 }
02025 
02026 void
02027 mi_execute_command (const char *cmd, int from_tty)
02028 {
02029   char *token;
02030   struct mi_parse *command = NULL;
02031   volatile struct gdb_exception exception;
02032 
02033   /* This is to handle EOF (^D). We just quit gdb.  */
02034   /* FIXME: we should call some API function here.  */
02035   if (cmd == 0)
02036     quit_force (NULL, from_tty);
02037 
02038   target_log_command (cmd);
02039 
02040   TRY_CATCH (exception, RETURN_MASK_ALL)
02041     {
02042       command = mi_parse (cmd, &token);
02043     }
02044   if (exception.reason < 0)
02045     {
02046       mi_print_exception (token, exception);
02047       xfree (token);
02048     }
02049   else
02050     {
02051       volatile struct gdb_exception result;
02052       ptid_t previous_ptid = inferior_ptid;
02053 
02054       command->token = token;
02055 
02056       if (do_timings)
02057         {
02058           command->cmd_start = (struct mi_timestamp *)
02059             xmalloc (sizeof (struct mi_timestamp));
02060           timestamp (command->cmd_start);
02061         }
02062 
02063       TRY_CATCH (result, RETURN_MASK_ALL)
02064         {
02065           captured_mi_execute_command (current_uiout, command);
02066         }
02067       if (result.reason < 0)
02068         {
02069           /* The command execution failed and error() was called
02070              somewhere.  */
02071           mi_print_exception (command->token, result);
02072           mi_out_rewind (current_uiout);
02073         }
02074 
02075       bpstat_do_actions ();
02076 
02077       if (/* The notifications are only output when the top-level
02078              interpreter (specified on the command line) is MI.  */      
02079           ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ()))
02080           /* Don't try report anything if there are no threads -- 
02081              the program is dead.  */
02082           && thread_count () != 0
02083           /* -thread-select explicitly changes thread. If frontend uses that
02084              internally, we don't want to emit =thread-selected, since
02085              =thread-selected is supposed to indicate user's intentions.  */
02086           && strcmp (command->command, "thread-select") != 0)
02087         {
02088           struct mi_interp *mi = top_level_interpreter_data ();
02089           int report_change = 0;
02090 
02091           if (command->thread == -1)
02092             {
02093               report_change = (!ptid_equal (previous_ptid, null_ptid)
02094                                && !ptid_equal (inferior_ptid, previous_ptid)
02095                                && !ptid_equal (inferior_ptid, null_ptid));
02096             }
02097           else if (!ptid_equal (inferior_ptid, null_ptid))
02098             {
02099               struct thread_info *ti = inferior_thread ();
02100 
02101               report_change = (ti->num != command->thread);
02102             }
02103 
02104           if (report_change)
02105             {     
02106               struct thread_info *ti = inferior_thread ();
02107 
02108               target_terminal_ours ();
02109               fprintf_unfiltered (mi->event_channel, 
02110                                   "thread-selected,id=\"%d\"",
02111                                   ti->num);
02112               gdb_flush (mi->event_channel);
02113             }
02114         }
02115 
02116       mi_parse_free (command);
02117     }
02118 }
02119 
02120 static void
02121 mi_cmd_execute (struct mi_parse *parse)
02122 {
02123   struct cleanup *cleanup;
02124 
02125   cleanup = prepare_execute_command ();
02126 
02127   if (parse->all && parse->thread_group != -1)
02128     error (_("Cannot specify --thread-group together with --all"));
02129 
02130   if (parse->all && parse->thread != -1)
02131     error (_("Cannot specify --thread together with --all"));
02132 
02133   if (parse->thread_group != -1 && parse->thread != -1)
02134     error (_("Cannot specify --thread together with --thread-group"));
02135 
02136   if (parse->frame != -1 && parse->thread == -1)
02137     error (_("Cannot specify --frame without --thread"));
02138 
02139   if (parse->thread_group != -1)
02140     {
02141       struct inferior *inf = find_inferior_id (parse->thread_group);
02142       struct thread_info *tp = 0;
02143 
02144       if (!inf)
02145         error (_("Invalid thread group for the --thread-group option"));
02146 
02147       set_current_inferior (inf);
02148       /* This behaviour means that if --thread-group option identifies
02149          an inferior with multiple threads, then a random one will be
02150          picked.  This is not a problem -- frontend should always
02151          provide --thread if it wishes to operate on a specific
02152          thread.  */
02153       if (inf->pid != 0)
02154         tp = any_live_thread_of_process (inf->pid);
02155       switch_to_thread (tp ? tp->ptid : null_ptid);
02156       set_current_program_space (inf->pspace);
02157     }
02158 
02159   if (parse->thread != -1)
02160     {
02161       struct thread_info *tp = find_thread_id (parse->thread);
02162 
02163       if (!tp)
02164         error (_("Invalid thread id: %d"), parse->thread);
02165 
02166       if (is_exited (tp->ptid))
02167         error (_("Thread id: %d has terminated"), parse->thread);
02168 
02169       switch_to_thread (tp->ptid);
02170     }
02171 
02172   if (parse->frame != -1)
02173     {
02174       struct frame_info *fid;
02175       int frame = parse->frame;
02176 
02177       fid = find_relative_frame (get_current_frame (), &frame);
02178       if (frame == 0)
02179         /* find_relative_frame was successful */
02180         select_frame (fid);
02181       else
02182         error (_("Invalid frame id: %d"), frame);
02183     }
02184 
02185   current_context = parse;
02186 
02187   if (parse->cmd->suppress_notification != NULL)
02188     {
02189       make_cleanup_restore_integer (parse->cmd->suppress_notification);
02190       *parse->cmd->suppress_notification = 1;
02191     }
02192 
02193   if (parse->cmd->argv_func != NULL)
02194     {
02195       parse->cmd->argv_func (parse->command, parse->argv, parse->argc);
02196     }
02197   else if (parse->cmd->cli.cmd != 0)
02198     {
02199       /* FIXME: DELETE THIS. */
02200       /* The operation is still implemented by a cli command.  */
02201       /* Must be a synchronous one.  */
02202       mi_execute_cli_command (parse->cmd->cli.cmd, parse->cmd->cli.args_p,
02203                               parse->args);
02204     }
02205   else
02206     {
02207       /* FIXME: DELETE THIS.  */
02208       struct ui_file *stb;
02209 
02210       stb = mem_fileopen ();
02211 
02212       fputs_unfiltered ("Undefined mi command: ", stb);
02213       fputstr_unfiltered (parse->command, '"', stb);
02214       fputs_unfiltered (" (missing implementation)", stb);
02215 
02216       make_cleanup_ui_file_delete (stb);
02217       error_stream (stb);
02218     }
02219   do_cleanups (cleanup);
02220 }
02221 
02222 /* FIXME: This is just a hack so we can get some extra commands going.
02223    We don't want to channel things through the CLI, but call libgdb directly.
02224    Use only for synchronous commands.  */
02225 
02226 void
02227 mi_execute_cli_command (const char *cmd, int args_p, const char *args)
02228 {
02229   if (cmd != 0)
02230     {
02231       struct cleanup *old_cleanups;
02232       char *run;
02233 
02234       if (args_p)
02235         run = xstrprintf ("%s %s", cmd, args);
02236       else
02237         run = xstrdup (cmd);
02238       if (mi_debug_p)
02239         /* FIXME: gdb_???? */
02240         fprintf_unfiltered (gdb_stdout, "cli=%s run=%s\n",
02241                             cmd, run);
02242       old_cleanups = make_cleanup (xfree, run);
02243       execute_command (run, 0 /* from_tty */ );
02244       do_cleanups (old_cleanups);
02245       return;
02246     }
02247 }
02248 
02249 void
02250 mi_execute_async_cli_command (char *cli_command, char **argv, int argc)
02251 {
02252   struct cleanup *old_cleanups;
02253   char *run;
02254 
02255   if (target_can_async_p ())
02256     run = xstrprintf ("%s %s&", cli_command, argc ? *argv : "");
02257   else
02258     run = xstrprintf ("%s %s", cli_command, argc ? *argv : "");
02259   old_cleanups = make_cleanup (xfree, run);  
02260 
02261   execute_command (run, 0 /* from_tty */ );
02262 
02263   /* Do this before doing any printing.  It would appear that some
02264      print code leaves garbage around in the buffer.  */
02265   do_cleanups (old_cleanups);
02266 }
02267 
02268 void
02269 mi_load_progress (const char *section_name,
02270                   unsigned long sent_so_far,
02271                   unsigned long total_section,
02272                   unsigned long total_sent,
02273                   unsigned long grand_total)
02274 {
02275   struct timeval time_now, delta, update_threshold;
02276   static struct timeval last_update;
02277   static char *previous_sect_name = NULL;
02278   int new_section;
02279   struct ui_out *saved_uiout;
02280   struct ui_out *uiout;
02281 
02282   /* This function is called through deprecated_show_load_progress
02283      which means uiout may not be correct.  Fix it for the duration
02284      of this function.  */
02285   saved_uiout = current_uiout;
02286 
02287   if (current_interp_named_p (INTERP_MI)
02288       || current_interp_named_p (INTERP_MI2))
02289     current_uiout = mi_out_new (2);
02290   else if (current_interp_named_p (INTERP_MI1))
02291     current_uiout = mi_out_new (1);
02292   else if (current_interp_named_p (INTERP_MI3))
02293     current_uiout = mi_out_new (3);
02294   else
02295     return;
02296 
02297   uiout = current_uiout;
02298 
02299   update_threshold.tv_sec = 0;
02300   update_threshold.tv_usec = 500000;
02301   gettimeofday (&time_now, NULL);
02302 
02303   delta.tv_usec = time_now.tv_usec - last_update.tv_usec;
02304   delta.tv_sec = time_now.tv_sec - last_update.tv_sec;
02305 
02306   if (delta.tv_usec < 0)
02307     {
02308       delta.tv_sec -= 1;
02309       delta.tv_usec += 1000000L;
02310     }
02311 
02312   new_section = (previous_sect_name ?
02313                  strcmp (previous_sect_name, section_name) : 1);
02314   if (new_section)
02315     {
02316       struct cleanup *cleanup_tuple;
02317 
02318       xfree (previous_sect_name);
02319       previous_sect_name = xstrdup (section_name);
02320 
02321       if (current_token)
02322         fputs_unfiltered (current_token, raw_stdout);
02323       fputs_unfiltered ("+download", raw_stdout);
02324       cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
02325       ui_out_field_string (uiout, "section", section_name);
02326       ui_out_field_int (uiout, "section-size", total_section);
02327       ui_out_field_int (uiout, "total-size", grand_total);
02328       do_cleanups (cleanup_tuple);
02329       mi_out_put (uiout, raw_stdout);
02330       fputs_unfiltered ("\n", raw_stdout);
02331       gdb_flush (raw_stdout);
02332     }
02333 
02334   if (delta.tv_sec >= update_threshold.tv_sec &&
02335       delta.tv_usec >= update_threshold.tv_usec)
02336     {
02337       struct cleanup *cleanup_tuple;
02338 
02339       last_update.tv_sec = time_now.tv_sec;
02340       last_update.tv_usec = time_now.tv_usec;
02341       if (current_token)
02342         fputs_unfiltered (current_token, raw_stdout);
02343       fputs_unfiltered ("+download", raw_stdout);
02344       cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
02345       ui_out_field_string (uiout, "section", section_name);
02346       ui_out_field_int (uiout, "section-sent", sent_so_far);
02347       ui_out_field_int (uiout, "section-size", total_section);
02348       ui_out_field_int (uiout, "total-sent", total_sent);
02349       ui_out_field_int (uiout, "total-size", grand_total);
02350       do_cleanups (cleanup_tuple);
02351       mi_out_put (uiout, raw_stdout);
02352       fputs_unfiltered ("\n", raw_stdout);
02353       gdb_flush (raw_stdout);
02354     }
02355 
02356   xfree (uiout);
02357   current_uiout = saved_uiout;
02358 }
02359 
02360 static void 
02361 timestamp (struct mi_timestamp *tv)
02362 {
02363   gettimeofday (&tv->wallclock, NULL);
02364 #ifdef HAVE_GETRUSAGE
02365   getrusage (RUSAGE_SELF, &rusage);
02366   tv->utime.tv_sec = rusage.ru_utime.tv_sec;
02367   tv->utime.tv_usec = rusage.ru_utime.tv_usec;
02368   tv->stime.tv_sec = rusage.ru_stime.tv_sec;
02369   tv->stime.tv_usec = rusage.ru_stime.tv_usec;
02370 #else
02371   {
02372     long usec = get_run_time ();
02373 
02374     tv->utime.tv_sec = usec/1000000L;
02375     tv->utime.tv_usec = usec - 1000000L*tv->utime.tv_sec;
02376     tv->stime.tv_sec = 0;
02377     tv->stime.tv_usec = 0;
02378   }
02379 #endif
02380 }
02381 
02382 static void 
02383 print_diff_now (struct mi_timestamp *start)
02384 {
02385   struct mi_timestamp now;
02386 
02387   timestamp (&now);
02388   print_diff (start, &now);
02389 }
02390 
02391 void
02392 mi_print_timing_maybe (void)
02393 {
02394   /* If the command is -enable-timing then do_timings may be true
02395      whilst current_command_ts is not initialized.  */
02396   if (do_timings && current_command_ts)
02397     print_diff_now (current_command_ts);
02398 }
02399 
02400 static long 
02401 timeval_diff (struct timeval start, struct timeval end)
02402 {
02403   return ((end.tv_sec - start.tv_sec) * 1000000L)
02404     + (end.tv_usec - start.tv_usec);
02405 }
02406 
02407 static void 
02408 print_diff (struct mi_timestamp *start, struct mi_timestamp *end)
02409 {
02410   fprintf_unfiltered
02411     (raw_stdout,
02412      ",time={wallclock=\"%0.5f\",user=\"%0.5f\",system=\"%0.5f\"}", 
02413      timeval_diff (start->wallclock, end->wallclock) / 1000000.0, 
02414      timeval_diff (start->utime, end->utime) / 1000000.0, 
02415      timeval_diff (start->stime, end->stime) / 1000000.0);
02416 }
02417 
02418 void
02419 mi_cmd_trace_define_variable (char *command, char **argv, int argc)
02420 {
02421   struct expression *expr;
02422   LONGEST initval = 0;
02423   struct trace_state_variable *tsv;
02424   char *name = 0;
02425 
02426   if (argc != 1 && argc != 2)
02427     error (_("Usage: -trace-define-variable VARIABLE [VALUE]"));
02428 
02429   name = argv[0];
02430   if (*name++ != '$')
02431     error (_("Name of trace variable should start with '$'"));
02432 
02433   validate_trace_state_variable_name (name);
02434 
02435   tsv = find_trace_state_variable (name);
02436   if (!tsv)
02437     tsv = create_trace_state_variable (name);
02438 
02439   if (argc == 2)
02440     initval = value_as_long (parse_and_eval (argv[1]));
02441 
02442   tsv->initial_value = initval;
02443 }
02444 
02445 void
02446 mi_cmd_trace_list_variables (char *command, char **argv, int argc)
02447 {
02448   if (argc != 0)
02449     error (_("-trace-list-variables: no arguments allowed"));
02450 
02451   tvariables_info_1 ();
02452 }
02453 
02454 void
02455 mi_cmd_trace_find (char *command, char **argv, int argc)
02456 {
02457   char *mode;
02458 
02459   if (argc == 0)
02460     error (_("trace selection mode is required"));
02461 
02462   mode = argv[0];
02463 
02464   if (strcmp (mode, "none") == 0)
02465     {
02466       tfind_1 (tfind_number, -1, 0, 0, 0);
02467       return;
02468     }
02469 
02470   if (current_trace_status ()->running)
02471     error (_("May not look at trace frames while trace is running."));
02472 
02473   if (strcmp (mode, "frame-number") == 0)
02474     {
02475       if (argc != 2)
02476         error (_("frame number is required"));
02477       tfind_1 (tfind_number, atoi (argv[1]), 0, 0, 0);
02478     }
02479   else if (strcmp (mode, "tracepoint-number") == 0)
02480     {
02481       if (argc != 2)
02482         error (_("tracepoint number is required"));
02483       tfind_1 (tfind_tp, atoi (argv[1]), 0, 0, 0);
02484     }
02485   else if (strcmp (mode, "pc") == 0)
02486     {
02487       if (argc != 2)
02488         error (_("PC is required"));
02489       tfind_1 (tfind_pc, 0, parse_and_eval_address (argv[1]), 0, 0);
02490     }
02491   else if (strcmp (mode, "pc-inside-range") == 0)
02492     {
02493       if (argc != 3)
02494         error (_("Start and end PC are required"));
02495       tfind_1 (tfind_range, 0, parse_and_eval_address (argv[1]),
02496                parse_and_eval_address (argv[2]), 0);
02497     }
02498   else if (strcmp (mode, "pc-outside-range") == 0)
02499     {
02500       if (argc != 3)
02501         error (_("Start and end PC are required"));
02502       tfind_1 (tfind_outside, 0, parse_and_eval_address (argv[1]),
02503                parse_and_eval_address (argv[2]), 0);
02504     }
02505   else if (strcmp (mode, "line") == 0)
02506     {
02507       struct symtabs_and_lines sals;
02508       struct symtab_and_line sal;
02509       static CORE_ADDR start_pc, end_pc;
02510       struct cleanup *back_to;
02511 
02512       if (argc != 2)
02513         error (_("Line is required"));
02514 
02515       sals = decode_line_with_current_source (argv[1],
02516                                               DECODE_LINE_FUNFIRSTLINE);
02517       back_to = make_cleanup (xfree, sals.sals);
02518 
02519       sal = sals.sals[0];
02520 
02521       if (sal.symtab == 0)
02522         error (_("Could not find the specified line"));
02523 
02524       if (sal.line > 0 && find_line_pc_range (sal, &start_pc, &end_pc))
02525         tfind_1 (tfind_range, 0, start_pc, end_pc - 1, 0);
02526       else
02527         error (_("Could not find the specified line"));
02528 
02529       do_cleanups (back_to);
02530     }
02531   else
02532     error (_("Invalid mode '%s'"), mode);
02533 
02534   if (has_stack_frames () || get_traceframe_number () >= 0)
02535     print_stack_frame (get_selected_frame (NULL), 1, LOC_AND_ADDRESS, 1);
02536 }
02537 
02538 void
02539 mi_cmd_trace_save (char *command, char **argv, int argc)
02540 {
02541   int target_saves = 0;
02542   int generate_ctf = 0;
02543   char *filename;
02544   int oind = 0;
02545   char *oarg;
02546 
02547   enum opt
02548   {
02549     TARGET_SAVE_OPT, CTF_OPT
02550   };
02551   static const struct mi_opt opts[] =
02552     {
02553       {"r", TARGET_SAVE_OPT, 0},
02554       {"ctf", CTF_OPT, 0},
02555       { 0, 0, 0 }
02556     };
02557 
02558   while (1)
02559     {
02560       int opt = mi_getopt ("-trace-save", argc, argv, opts,
02561                            &oind, &oarg);
02562 
02563       if (opt < 0)
02564         break;
02565       switch ((enum opt) opt)
02566         {
02567         case TARGET_SAVE_OPT:
02568           target_saves = 1;
02569           break;
02570         case CTF_OPT:
02571           generate_ctf = 1;
02572           break;
02573         }
02574     }
02575   filename = argv[oind];
02576 
02577   if (generate_ctf)
02578     trace_save_ctf (filename, target_saves);
02579   else
02580     trace_save_tfile (filename, target_saves);
02581 }
02582 
02583 void
02584 mi_cmd_trace_start (char *command, char **argv, int argc)
02585 {
02586   start_tracing (NULL);
02587 }
02588 
02589 void
02590 mi_cmd_trace_status (char *command, char **argv, int argc)
02591 {
02592   trace_status_mi (0);
02593 }
02594 
02595 void
02596 mi_cmd_trace_stop (char *command, char **argv, int argc)
02597 {
02598   stop_tracing (NULL);
02599   trace_status_mi (1);
02600 }
02601 
02602 /* Implement the "-ada-task-info" command.  */
02603 
02604 void
02605 mi_cmd_ada_task_info (char *command, char **argv, int argc)
02606 {
02607   if (argc != 0 && argc != 1)
02608     error (_("Invalid MI command"));
02609 
02610   print_ada_task_info (current_uiout, argv[0], current_inferior ());
02611 }
02612 
02613 /* Print EXPRESSION according to VALUES.  */
02614 
02615 static void
02616 print_variable_or_computed (char *expression, enum print_values values)
02617 {
02618   struct expression *expr;
02619   struct cleanup *old_chain;
02620   struct value *val;
02621   struct ui_file *stb;
02622   struct value_print_options opts;
02623   struct type *type;
02624   struct ui_out *uiout = current_uiout;
02625 
02626   stb = mem_fileopen ();
02627   old_chain = make_cleanup_ui_file_delete (stb);
02628 
02629   expr = parse_expression (expression);
02630 
02631   make_cleanup (free_current_contents, &expr);
02632 
02633   if (values == PRINT_SIMPLE_VALUES)
02634     val = evaluate_type (expr);
02635   else
02636     val = evaluate_expression (expr);
02637 
02638   if (values != PRINT_NO_VALUES)
02639     make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
02640   ui_out_field_string (uiout, "name", expression);
02641 
02642   switch (values)
02643     {
02644     case PRINT_SIMPLE_VALUES:
02645       type = check_typedef (value_type (val));
02646       type_print (value_type (val), "", stb, -1);
02647       ui_out_field_stream (uiout, "type", stb);
02648       if (TYPE_CODE (type) != TYPE_CODE_ARRAY
02649           && TYPE_CODE (type) != TYPE_CODE_STRUCT
02650           && TYPE_CODE (type) != TYPE_CODE_UNION)
02651         {
02652           struct value_print_options opts;
02653 
02654           get_no_prettyformat_print_options (&opts);
02655           opts.deref_ref = 1;
02656           common_val_print (val, stb, 0, &opts, current_language);
02657           ui_out_field_stream (uiout, "value", stb);
02658         }
02659       break;
02660     case PRINT_ALL_VALUES:
02661       {
02662         struct value_print_options opts;
02663 
02664         get_no_prettyformat_print_options (&opts);
02665         opts.deref_ref = 1;
02666         common_val_print (val, stb, 0, &opts, current_language);
02667         ui_out_field_stream (uiout, "value", stb);
02668       }
02669       break;
02670     }
02671 
02672   do_cleanups (old_chain);
02673 }
02674 
02675 /* Implement the "-trace-frame-collected" command.  */
02676 
02677 void
02678 mi_cmd_trace_frame_collected (char *command, char **argv, int argc)
02679 {
02680   struct cleanup *old_chain;
02681   struct bp_location *tloc;
02682   int stepping_frame;
02683   struct collection_list *clist;
02684   struct collection_list tracepoint_list, stepping_list;
02685   struct traceframe_info *tinfo;
02686   int oind = 0;
02687   int var_print_values = PRINT_ALL_VALUES;
02688   int comp_print_values = PRINT_ALL_VALUES;
02689   int registers_format = 'x';
02690   int memory_contents = 0;
02691   struct ui_out *uiout = current_uiout;
02692   enum opt
02693   {
02694     VAR_PRINT_VALUES,
02695     COMP_PRINT_VALUES,
02696     REGISTERS_FORMAT,
02697     MEMORY_CONTENTS,
02698   };
02699   static const struct mi_opt opts[] =
02700     {
02701       {"-var-print-values", VAR_PRINT_VALUES, 1},
02702       {"-comp-print-values", COMP_PRINT_VALUES, 1},
02703       {"-registers-format", REGISTERS_FORMAT, 1},
02704       {"-memory-contents", MEMORY_CONTENTS, 0},
02705       { 0, 0, 0 }
02706     };
02707 
02708   while (1)
02709     {
02710       char *oarg;
02711       int opt = mi_getopt ("-trace-frame-collected", argc, argv, opts,
02712                            &oind, &oarg);
02713       if (opt < 0)
02714         break;
02715       switch ((enum opt) opt)
02716         {
02717         case VAR_PRINT_VALUES:
02718           var_print_values = mi_parse_print_values (oarg);
02719           break;
02720         case COMP_PRINT_VALUES:
02721           comp_print_values = mi_parse_print_values (oarg);
02722           break;
02723         case REGISTERS_FORMAT:
02724           registers_format = oarg[0];
02725         case MEMORY_CONTENTS:
02726           memory_contents = 1;
02727           break;
02728         }
02729     }
02730 
02731   if (oind != argc)
02732     error (_("Usage: -trace-frame-collected "
02733              "[--var-print-values PRINT_VALUES] "
02734              "[--comp-print-values PRINT_VALUES] "
02735              "[--registers-format FORMAT]"
02736              "[--memory-contents]"));
02737 
02738   /* This throws an error is not inspecting a trace frame.  */
02739   tloc = get_traceframe_location (&stepping_frame);
02740 
02741   /* This command only makes sense for the current frame, not the
02742      selected frame.  */
02743   old_chain = make_cleanup_restore_current_thread ();
02744   select_frame (get_current_frame ());
02745 
02746   encode_actions_and_make_cleanup (tloc, &tracepoint_list,
02747                                    &stepping_list);
02748 
02749   if (stepping_frame)
02750     clist = &stepping_list;
02751   else
02752     clist = &tracepoint_list;
02753 
02754   tinfo = get_traceframe_info ();
02755 
02756   /* Explicitly wholly collected variables.  */
02757   {
02758     struct cleanup *list_cleanup;
02759     char *p;
02760     int i;
02761 
02762     list_cleanup = make_cleanup_ui_out_list_begin_end (uiout,
02763                                                        "explicit-variables");
02764     for (i = 0; VEC_iterate (char_ptr, clist->wholly_collected, i, p); i++)
02765       print_variable_or_computed (p, var_print_values);
02766     do_cleanups (list_cleanup);
02767   }
02768 
02769   /* Computed expressions.  */
02770   {
02771     struct cleanup *list_cleanup;
02772     char *p;
02773     int i;
02774 
02775     list_cleanup
02776       = make_cleanup_ui_out_list_begin_end (uiout,
02777                                             "computed-expressions");
02778     for (i = 0; VEC_iterate (char_ptr, clist->computed, i, p); i++)
02779       print_variable_or_computed (p, comp_print_values);
02780     do_cleanups (list_cleanup);
02781   }
02782 
02783   /* Registers.  Given pseudo-registers, and that some architectures
02784      (like MIPS) actually hide the raw registers, we don't go through
02785      the trace frame info, but instead consult the register cache for
02786      register availability.  */
02787   {
02788     struct cleanup *list_cleanup;
02789     struct frame_info *frame;
02790     struct gdbarch *gdbarch;
02791     int regnum;
02792     int numregs;
02793 
02794     list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "registers");
02795 
02796     frame = get_selected_frame (NULL);
02797     gdbarch = get_frame_arch (frame);
02798     numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
02799 
02800     for (regnum = 0; regnum < numregs; regnum++)
02801       {
02802         if (gdbarch_register_name (gdbarch, regnum) == NULL
02803             || *(gdbarch_register_name (gdbarch, regnum)) == '\0')
02804           continue;
02805 
02806         output_register (frame, regnum, registers_format, 1);
02807       }
02808 
02809     do_cleanups (list_cleanup);
02810   }
02811 
02812   /* Trace state variables.  */
02813   {
02814     struct cleanup *list_cleanup;
02815     int tvar;
02816     char *tsvname;
02817     int i;
02818 
02819     list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "tvars");
02820 
02821     tsvname = NULL;
02822     make_cleanup (free_current_contents, &tsvname);
02823 
02824     for (i = 0; VEC_iterate (int, tinfo->tvars, i, tvar); i++)
02825       {
02826         struct cleanup *cleanup_child;
02827         struct trace_state_variable *tsv;
02828 
02829         tsv = find_trace_state_variable_by_number (tvar);
02830 
02831         cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
02832 
02833         if (tsv != NULL)
02834           {
02835             tsvname = xrealloc (tsvname, strlen (tsv->name) + 2);
02836             tsvname[0] = '$';
02837             strcpy (tsvname + 1, tsv->name);
02838             ui_out_field_string (uiout, "name", tsvname);
02839 
02840             tsv->value_known = target_get_trace_state_variable_value (tsv->number,
02841                                                                       &tsv->value);
02842             ui_out_field_int (uiout, "current", tsv->value);
02843           }
02844         else
02845           {
02846             ui_out_field_skip (uiout, "name");
02847             ui_out_field_skip (uiout, "current");
02848           }
02849 
02850         do_cleanups (cleanup_child);
02851       }
02852 
02853     do_cleanups (list_cleanup);
02854   }
02855 
02856   /* Memory.  */
02857   {
02858     struct cleanup *list_cleanup;
02859     VEC(mem_range_s) *available_memory = NULL;
02860     struct mem_range *r;
02861     int i;
02862 
02863     traceframe_available_memory (&available_memory, 0, ULONGEST_MAX);
02864     make_cleanup (VEC_cleanup(mem_range_s), &available_memory);
02865 
02866     list_cleanup = make_cleanup_ui_out_list_begin_end (uiout, "memory");
02867 
02868     for (i = 0; VEC_iterate (mem_range_s, available_memory, i, r); i++)
02869       {
02870         struct cleanup *cleanup_child;
02871         gdb_byte *data;
02872         struct gdbarch *gdbarch = target_gdbarch ();
02873 
02874         cleanup_child = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
02875 
02876         ui_out_field_core_addr (uiout, "address", gdbarch, r->start);
02877         ui_out_field_int (uiout, "length", r->length);
02878 
02879         data = xmalloc (r->length);
02880         make_cleanup (xfree, data);
02881 
02882         if (memory_contents)
02883           {
02884             if (target_read_memory (r->start, data, r->length) == 0)
02885               {
02886                 int m;
02887                 char *data_str, *p;
02888 
02889                 data_str = xmalloc (r->length * 2 + 1);
02890                 make_cleanup (xfree, data_str);
02891 
02892                 for (m = 0, p = data_str; m < r->length; ++m, p += 2)
02893                   sprintf (p, "%02x", data[m]);
02894                 ui_out_field_string (uiout, "contents", data_str);
02895               }
02896             else
02897               ui_out_field_skip (uiout, "contents");
02898           }
02899         do_cleanups (cleanup_child);
02900       }
02901 
02902     do_cleanups (list_cleanup);
02903   }
02904 
02905   do_cleanups (old_chain);
02906 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines