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