1 /* TUI display registers in window. 2 3 Copyright (C) 1998-2019 Free Software Foundation, Inc. 4 5 Contributed by Hewlett-Packard Company. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 #include "defs.h" 23 #include "arch-utils.h" 24 #include "tui/tui.h" 25 #include "tui/tui-data.h" 26 #include "symtab.h" 27 #include "gdbtypes.h" 28 #include "gdbcmd.h" 29 #include "frame.h" 30 #include "regcache.h" 31 #include "inferior.h" 32 #include "target.h" 33 #include "tui/tui-layout.h" 34 #include "tui/tui-win.h" 35 #include "tui/tui-windata.h" 36 #include "tui/tui-wingeneral.h" 37 #include "tui/tui-file.h" 38 #include "tui/tui-regs.h" 39 #include "tui/tui-io.h" 40 #include "reggroups.h" 41 #include "valprint.h" 42 #include "completer.h" 43 44 #include "gdb_curses.h" 45 46 47 /***************************************** 48 ** STATIC LOCAL FUNCTIONS FORWARD DECLS ** 49 ******************************************/ 50 static void 51 tui_display_register (struct tui_data_element *data, 52 struct tui_gen_win_info *win_info); 53 54 static enum tui_status tui_show_register_group (struct reggroup *group, 55 struct frame_info *frame, 56 int refresh_values_only); 57 58 static enum tui_status tui_get_register (struct frame_info *frame, 59 struct tui_data_element *data, 60 int regnum, int *changedp); 61 62 63 64 /***************************************** 65 ** PUBLIC FUNCTIONS ** 66 ******************************************/ 67 68 /* Answer the number of the last line in the regs display. If there 69 are no registers (-1) is returned. */ 70 int 71 tui_last_regs_line_no (void) 72 { 73 int num_lines = (-1); 74 75 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) 76 { 77 num_lines = (TUI_DATA_WIN->detail.data_display_info.regs_content_count / 78 TUI_DATA_WIN->detail.data_display_info.regs_column_count); 79 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count % 80 TUI_DATA_WIN->detail.data_display_info.regs_column_count) 81 num_lines++; 82 } 83 return num_lines; 84 } 85 86 87 /* Answer the line number that the register element at element_no is 88 on. If element_no is greater than the number of register elements 89 there are, -1 is returned. */ 90 int 91 tui_line_from_reg_element_no (int element_no) 92 { 93 if (element_no < TUI_DATA_WIN->detail.data_display_info.regs_content_count) 94 { 95 int i, line = (-1); 96 97 i = 1; 98 while (line == (-1)) 99 { 100 if (element_no < 101 (TUI_DATA_WIN->detail.data_display_info.regs_column_count * i)) 102 line = i - 1; 103 else 104 i++; 105 } 106 107 return line; 108 } 109 else 110 return (-1); 111 } 112 113 114 /* Answer the index of the first element in line_no. If line_no is 115 past the register area (-1) is returned. */ 116 int 117 tui_first_reg_element_no_inline (int line_no) 118 { 119 if ((line_no * TUI_DATA_WIN->detail.data_display_info.regs_column_count) 120 <= TUI_DATA_WIN->detail.data_display_info.regs_content_count) 121 return ((line_no + 1) * 122 TUI_DATA_WIN->detail.data_display_info.regs_column_count) - 123 TUI_DATA_WIN->detail.data_display_info.regs_column_count; 124 else 125 return (-1); 126 } 127 128 129 /* Show the registers of the given group in the data window 130 and refresh the window. */ 131 void 132 tui_show_registers (struct reggroup *group) 133 { 134 enum tui_status ret = TUI_FAILURE; 135 struct tui_data_info *display_info; 136 137 /* Make sure the curses mode is enabled. */ 138 tui_enable (); 139 140 /* Make sure the register window is visible. If not, select an 141 appropriate layout. */ 142 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible) 143 tui_set_layout_by_name (DATA_NAME); 144 145 display_info = &TUI_DATA_WIN->detail.data_display_info; 146 if (group == 0) 147 group = general_reggroup; 148 149 /* Say that registers should be displayed, even if there is a 150 problem. */ 151 display_info->display_regs = TRUE; 152 153 if (target_has_registers && target_has_stack && target_has_memory) 154 { 155 ret = tui_show_register_group (group, get_selected_frame (NULL), 156 group == display_info->current_group); 157 } 158 if (ret == TUI_FAILURE) 159 { 160 display_info->current_group = 0; 161 tui_erase_data_content (NO_REGS_STRING); 162 } 163 else 164 { 165 int i; 166 167 /* Clear all notation of changed values. */ 168 for (i = 0; i < display_info->regs_content_count; i++) 169 { 170 struct tui_gen_win_info *data_item_win; 171 struct tui_win_element *win; 172 173 data_item_win = &display_info->regs_content[i] 174 ->which_element.data_window; 175 win = data_item_win->content[0]; 176 win->which_element.data.highlight = FALSE; 177 } 178 display_info->current_group = group; 179 tui_display_all_data (); 180 } 181 } 182 183 184 /* Set the data window to display the registers of the register group 185 using the given frame. Values are refreshed only when 186 refresh_values_only is TRUE. */ 187 188 static enum tui_status 189 tui_show_register_group (struct reggroup *group, 190 struct frame_info *frame, 191 int refresh_values_only) 192 { 193 struct gdbarch *gdbarch = get_frame_arch (frame); 194 enum tui_status ret = TUI_FAILURE; 195 int nr_regs; 196 int allocated_here = FALSE; 197 int regnum, pos; 198 char title[80]; 199 struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info; 200 201 /* Make a new title showing which group we display. */ 202 snprintf (title, sizeof (title) - 1, "Register group: %s", 203 reggroup_name (group)); 204 xfree (TUI_DATA_WIN->generic.title); 205 TUI_DATA_WIN->generic.title = xstrdup (title); 206 207 /* See how many registers must be displayed. */ 208 nr_regs = 0; 209 for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) 210 { 211 const char *name; 212 213 /* Must be in the group. */ 214 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group)) 215 continue; 216 217 /* If the register name is empty, it is undefined for this 218 processor, so don't display anything. */ 219 name = gdbarch_register_name (gdbarch, regnum); 220 if (name == 0 || *name == '\0') 221 continue; 222 223 nr_regs++; 224 } 225 226 if (display_info->regs_content_count > 0 && !refresh_values_only) 227 { 228 tui_free_data_content (display_info->regs_content, 229 display_info->regs_content_count); 230 display_info->regs_content_count = 0; 231 } 232 233 if (display_info->regs_content_count <= 0) 234 { 235 display_info->regs_content = tui_alloc_content (nr_regs, DATA_WIN); 236 allocated_here = TRUE; 237 refresh_values_only = FALSE; 238 } 239 240 if (display_info->regs_content != (tui_win_content) NULL) 241 { 242 if (!refresh_values_only || allocated_here) 243 { 244 TUI_DATA_WIN->generic.content = NULL; 245 TUI_DATA_WIN->generic.content_size = 0; 246 tui_add_content_elements (&TUI_DATA_WIN->generic, nr_regs); 247 display_info->regs_content = TUI_DATA_WIN->generic.content; 248 display_info->regs_content_count = nr_regs; 249 } 250 251 /* Now set the register names and values. */ 252 pos = 0; 253 for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) 254 { 255 struct tui_gen_win_info *data_item_win; 256 struct tui_data_element *data; 257 const char *name; 258 259 /* Must be in the group. */ 260 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group)) 261 continue; 262 263 /* If the register name is empty, it is undefined for this 264 processor, so don't display anything. */ 265 name = gdbarch_register_name (gdbarch, regnum); 266 if (name == 0 || *name == '\0') 267 continue; 268 269 data_item_win = 270 &display_info->regs_content[pos]->which_element.data_window; 271 data = &data_item_win->content[0]->which_element.data; 272 if (data) 273 { 274 if (!refresh_values_only) 275 { 276 data->item_no = regnum; 277 data->name = name; 278 data->highlight = FALSE; 279 } 280 tui_get_register (frame, data, regnum, 0); 281 } 282 pos++; 283 } 284 285 TUI_DATA_WIN->generic.content_size = 286 display_info->regs_content_count + display_info->data_content_count; 287 ret = TUI_SUCCESS; 288 } 289 290 return ret; 291 } 292 293 /* Function to display the registers in the content from 294 'start_element_no' until the end of the register content or the end 295 of the display height. No checking for displaying past the end of 296 the registers is done here. */ 297 void 298 tui_display_registers_from (int start_element_no) 299 { 300 struct tui_data_info *display_info = &TUI_DATA_WIN->detail.data_display_info; 301 302 if (display_info->regs_content != (tui_win_content) NULL 303 && display_info->regs_content_count > 0) 304 { 305 int i = start_element_no; 306 int j, item_win_width, cur_y; 307 308 int max_len = 0; 309 for (i = 0; i < display_info->regs_content_count; i++) 310 { 311 struct tui_data_element *data; 312 struct tui_gen_win_info *data_item_win; 313 char *p; 314 int len; 315 316 data_item_win 317 = &display_info->regs_content[i]->which_element.data_window; 318 data = &data_item_win->content[0]->which_element.data; 319 len = 0; 320 p = data->content; 321 if (p != 0) 322 while (*p) 323 { 324 if (*p++ == '\t') 325 len = 8 * ((len / 8) + 1); 326 else 327 len++; 328 } 329 330 if (len > max_len) 331 max_len = len; 332 } 333 item_win_width = max_len + 1; 334 i = start_element_no; 335 336 display_info->regs_column_count = 337 (TUI_DATA_WIN->generic.width - 2) / item_win_width; 338 if (display_info->regs_column_count == 0) 339 display_info->regs_column_count = 1; 340 item_win_width = 341 (TUI_DATA_WIN->generic.width - 2) / display_info->regs_column_count; 342 343 /* Now create each data "sub" window, and write the display into 344 it. */ 345 cur_y = 1; 346 while (i < display_info->regs_content_count 347 && cur_y <= TUI_DATA_WIN->generic.viewport_height) 348 { 349 for (j = 0; 350 j < display_info->regs_column_count 351 && i < display_info->regs_content_count; 352 j++) 353 { 354 struct tui_gen_win_info *data_item_win; 355 struct tui_data_element *data_element_ptr; 356 357 /* Create the window if necessary. */ 358 data_item_win = &display_info->regs_content[i] 359 ->which_element.data_window; 360 data_element_ptr = &data_item_win->content[0]->which_element.data; 361 if (data_item_win->handle != (WINDOW*) NULL 362 && (data_item_win->height != 1 363 || data_item_win->width != item_win_width 364 || data_item_win->origin.x != (item_win_width * j) + 1 365 || data_item_win->origin.y != cur_y)) 366 { 367 tui_delete_win (data_item_win->handle); 368 data_item_win->handle = 0; 369 } 370 371 if (data_item_win->handle == (WINDOW *) NULL) 372 { 373 data_item_win->height = 1; 374 data_item_win->width = item_win_width; 375 data_item_win->origin.x = (item_win_width * j) + 1; 376 data_item_win->origin.y = cur_y; 377 tui_make_window (data_item_win, DONT_BOX_WINDOW); 378 scrollok (data_item_win->handle, FALSE); 379 } 380 touchwin (data_item_win->handle); 381 382 /* Get the printable representation of the register 383 and display it. */ 384 tui_display_register (data_element_ptr, data_item_win); 385 i++; /* Next register. */ 386 } 387 cur_y++; /* Next row. */ 388 } 389 } 390 } 391 392 393 /* Function to display the registers in the content from 394 'start_element_no' on 'start_line_no' until the end of the register 395 content or the end of the display height. This function checks 396 that we won't display off the end of the register display. */ 397 static void 398 tui_display_reg_element_at_line (int start_element_no, 399 int start_line_no) 400 { 401 if (TUI_DATA_WIN->detail.data_display_info.regs_content 402 != (tui_win_content) NULL 403 && TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) 404 { 405 int element_no = start_element_no; 406 407 if (start_element_no != 0 && start_line_no != 0) 408 { 409 int last_line_no, first_line_on_last_page; 410 411 last_line_no = tui_last_regs_line_no (); 412 first_line_on_last_page 413 = last_line_no - (TUI_DATA_WIN->generic.height - 2); 414 if (first_line_on_last_page < 0) 415 first_line_on_last_page = 0; 416 417 /* If there is no other data displayed except registers, and 418 the element_no causes us to scroll past the end of the 419 registers, adjust what element to really start the 420 display at. */ 421 if (TUI_DATA_WIN->detail.data_display_info.data_content_count <= 0 422 && start_line_no > first_line_on_last_page) 423 element_no 424 = tui_first_reg_element_no_inline (first_line_on_last_page); 425 } 426 tui_display_registers_from (element_no); 427 } 428 } 429 430 431 432 /* Function to display the registers starting at line line_no in the 433 data window. Answers the line number that the display actually 434 started from. If nothing is displayed (-1) is returned. */ 435 int 436 tui_display_registers_from_line (int line_no, 437 int force_display) 438 { 439 if (TUI_DATA_WIN->detail.data_display_info.regs_content_count > 0) 440 { 441 int line, element_no; 442 443 if (line_no < 0) 444 line = 0; 445 else if (force_display) 446 { /* If we must display regs (force_display is true), then 447 make sure that we don't display off the end of the 448 registers. */ 449 if (line_no >= tui_last_regs_line_no ()) 450 { 451 if ((line = tui_line_from_reg_element_no ( 452 TUI_DATA_WIN->detail.data_display_info.regs_content_count - 1)) < 0) 453 line = 0; 454 } 455 else 456 line = line_no; 457 } 458 else 459 line = line_no; 460 461 element_no = tui_first_reg_element_no_inline (line); 462 if (element_no 463 < TUI_DATA_WIN->detail.data_display_info.regs_content_count) 464 tui_display_reg_element_at_line (element_no, line); 465 else 466 line = (-1); 467 468 return line; 469 } 470 471 return (-1); /* Nothing was displayed. */ 472 } 473 474 475 /* This function check all displayed registers for changes in values, 476 given a particular frame. If the values have changed, they are 477 updated with the new value and highlighted. */ 478 void 479 tui_check_register_values (struct frame_info *frame) 480 { 481 if (TUI_DATA_WIN != NULL 482 && TUI_DATA_WIN->generic.is_visible) 483 { 484 struct tui_data_info *display_info 485 = &TUI_DATA_WIN->detail.data_display_info; 486 487 if (display_info->regs_content_count <= 0 488 && display_info->display_regs) 489 tui_show_registers (display_info->current_group); 490 else 491 { 492 int i; 493 494 for (i = 0; (i < display_info->regs_content_count); i++) 495 { 496 struct tui_data_element *data; 497 struct tui_gen_win_info *data_item_win_ptr; 498 int was_hilighted; 499 500 data_item_win_ptr = &display_info->regs_content[i]-> 501 which_element.data_window; 502 data = &data_item_win_ptr->content[0]->which_element.data; 503 was_hilighted = data->highlight; 504 505 tui_get_register (frame, data, 506 data->item_no, &data->highlight); 507 508 if (data->highlight || was_hilighted) 509 { 510 tui_display_register (data, data_item_win_ptr); 511 } 512 } 513 } 514 } 515 } 516 517 /* Display a register in a window. If hilite is TRUE, then the value 518 will be displayed in reverse video. */ 519 static void 520 tui_display_register (struct tui_data_element *data, 521 struct tui_gen_win_info *win_info) 522 { 523 if (win_info->handle != (WINDOW *) NULL) 524 { 525 int i; 526 527 if (data->highlight) 528 /* We ignore the return value, casting it to void in order to avoid 529 a compiler warning. The warning itself was introduced by a patch 530 to ncurses 5.7 dated 2009-08-29, changing this macro to expand 531 to code that causes the compiler to generate an unused-value 532 warning. */ 533 (void) wstandout (win_info->handle); 534 535 wmove (win_info->handle, 0, 0); 536 for (i = 1; i < win_info->width; i++) 537 waddch (win_info->handle, ' '); 538 wmove (win_info->handle, 0, 0); 539 if (data->content) 540 waddstr (win_info->handle, data->content); 541 542 if (data->highlight) 543 /* We ignore the return value, casting it to void in order to avoid 544 a compiler warning. The warning itself was introduced by a patch 545 to ncurses 5.7 dated 2009-08-29, changing this macro to expand 546 to code that causes the compiler to generate an unused-value 547 warning. */ 548 (void) wstandend (win_info->handle); 549 tui_refresh_win (win_info); 550 } 551 } 552 553 /* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap 554 around behaviour. Returns the next register group, or NULL if the 555 register window is not currently being displayed. */ 556 557 static struct reggroup * 558 tui_reg_next (struct gdbarch *gdbarch) 559 { 560 struct reggroup *group = NULL; 561 562 if (TUI_DATA_WIN != NULL) 563 { 564 group = TUI_DATA_WIN->detail.data_display_info.current_group; 565 group = reggroup_next (gdbarch, group); 566 if (group == NULL) 567 group = reggroup_next (gdbarch, NULL); 568 } 569 return group; 570 } 571 572 /* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap 573 around behaviour. Returns the previous register group, or NULL if the 574 register window is not currently being displayed. */ 575 576 static struct reggroup * 577 tui_reg_prev (struct gdbarch *gdbarch) 578 { 579 struct reggroup *group = NULL; 580 581 if (TUI_DATA_WIN != NULL) 582 { 583 group = TUI_DATA_WIN->detail.data_display_info.current_group; 584 group = reggroup_prev (gdbarch, group); 585 if (group == NULL) 586 group = reggroup_prev (gdbarch, NULL); 587 } 588 return group; 589 } 590 591 /* Implement the 'tui reg' command. Changes the register group displayed 592 in the tui register window. Displays the tui register window if it is 593 not already on display. */ 594 595 static void 596 tui_reg_command (const char *args, int from_tty) 597 { 598 struct gdbarch *gdbarch = get_current_arch (); 599 600 if (args != NULL) 601 { 602 struct reggroup *group, *match = NULL; 603 size_t len = strlen (args); 604 605 /* Make sure the curses mode is enabled. */ 606 tui_enable (); 607 608 /* Make sure the register window is visible. If not, select an 609 appropriate layout. We need to do this before trying to run the 610 'next' or 'prev' commands. */ 611 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->generic.is_visible) 612 tui_set_layout_by_name (DATA_NAME); 613 614 if (strncmp (args, "next", len) == 0) 615 match = tui_reg_next (gdbarch); 616 else if (strncmp (args, "prev", len) == 0) 617 match = tui_reg_prev (gdbarch); 618 619 /* This loop matches on the initial part of a register group 620 name. If this initial part in ARGS matches only one register 621 group then the switch is made. */ 622 for (group = reggroup_next (gdbarch, NULL); 623 group != NULL; 624 group = reggroup_next (gdbarch, group)) 625 { 626 if (strncmp (reggroup_name (group), args, len) == 0) 627 { 628 if (match != NULL) 629 error (_("ambiguous register group name '%s'"), args); 630 match = group; 631 } 632 } 633 634 if (match == NULL) 635 error (_("unknown register group '%s'"), args); 636 637 tui_show_registers (match); 638 } 639 else 640 { 641 struct reggroup *group; 642 int first; 643 644 printf_unfiltered (_("\"tui reg\" must be followed by the name of " 645 "either a register group,\nor one of 'next' " 646 "or 'prev'. Known register groups are:\n")); 647 648 for (first = 1, group = reggroup_next (gdbarch, NULL); 649 group != NULL; 650 first = 0, group = reggroup_next (gdbarch, group)) 651 { 652 if (!first) 653 printf_unfiltered (", "); 654 printf_unfiltered ("%s", reggroup_name (group)); 655 } 656 657 printf_unfiltered ("\n"); 658 } 659 } 660 661 /* Complete names of register groups, and add the special "prev" and "next" 662 names. */ 663 664 static void 665 tui_reggroup_completer (struct cmd_list_element *ignore, 666 completion_tracker &tracker, 667 const char *text, const char *word) 668 { 669 static const char *extra[] = { "next", "prev", NULL }; 670 size_t len = strlen (word); 671 const char **tmp; 672 673 reggroup_completer (ignore, tracker, text, word); 674 675 /* XXXX use complete_on_enum instead? */ 676 for (tmp = extra; *tmp != NULL; ++tmp) 677 { 678 if (strncmp (word, *tmp, len) == 0) 679 tracker.add_completion (gdb::unique_xmalloc_ptr<char> (xstrdup (*tmp))); 680 } 681 } 682 683 void 684 _initialize_tui_regs (void) 685 { 686 struct cmd_list_element **tuicmd, *cmd; 687 688 tuicmd = tui_get_cmd_list (); 689 690 cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\ 691 TUI command to control the register window."), tuicmd); 692 set_cmd_completer (cmd, tui_reggroup_completer); 693 } 694 695 696 /***************************************** 697 ** STATIC LOCAL FUNCTIONS ** 698 ******************************************/ 699 700 /* Get the register from the frame and return a printable 701 representation of it. */ 702 703 static char * 704 tui_register_format (struct frame_info *frame, int regnum) 705 { 706 struct gdbarch *gdbarch = get_frame_arch (frame); 707 708 string_file stream; 709 710 scoped_restore save_pagination 711 = make_scoped_restore (&pagination_enabled, 0); 712 scoped_restore save_stdout 713 = make_scoped_restore (&gdb_stdout, &stream); 714 715 gdbarch_print_registers_info (gdbarch, &stream, frame, regnum, 1); 716 717 /* Remove the possible \n. */ 718 std::string &str = stream.string (); 719 if (!str.empty () && str.back () == '\n') 720 str.resize (str.size () - 1); 721 722 /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */ 723 return tui_expand_tabs (str.c_str (), 0); 724 } 725 726 /* Get the register value from the given frame and format it for the 727 display. When changep is set, check if the new register value has 728 changed with respect to the previous call. */ 729 static enum tui_status 730 tui_get_register (struct frame_info *frame, 731 struct tui_data_element *data, 732 int regnum, int *changedp) 733 { 734 enum tui_status ret = TUI_FAILURE; 735 736 if (changedp) 737 *changedp = FALSE; 738 if (target_has_registers) 739 { 740 char *prev_content = data->content; 741 742 data->content = tui_register_format (frame, regnum); 743 744 if (changedp != NULL 745 && strcmp (prev_content, data->content) != 0) 746 *changedp = 1; 747 748 xfree (prev_content); 749 750 ret = TUI_SUCCESS; 751 } 752 return ret; 753 } 754