GDB (API)
|
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, ¤t_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 }