gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / gdb / tui / tui-regs.c
CommitLineData
f377b406 1/* TUI display registers in window.
f33c6cbf 2
b811d2c2 3 Copyright (C) 1998-2020 Free Software Foundation, Inc.
f33c6cbf 4
f377b406 5 Contributed by Hewlett-Packard Company.
c906108c 6
f377b406 7 This file is part of GDB.
c906108c 8
f377b406
SC
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
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
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
e17c207e 23#include "arch-utils.h"
d7b2e967
AC
24#include "tui/tui.h"
25#include "tui/tui-data.h"
c906108c
SS
26#include "symtab.h"
27#include "gdbtypes.h"
28#include "gdbcmd.h"
29#include "frame.h"
bc77de56 30#include "regcache.h"
c906108c
SS
31#include "inferior.h"
32#include "target.h"
d7b2e967
AC
33#include "tui/tui-layout.h"
34#include "tui/tui-win.h"
d7b2e967
AC
35#include "tui/tui-wingeneral.h"
36#include "tui/tui-file.h"
2c0b251b 37#include "tui/tui-regs.h"
312809f8 38#include "tui/tui-io.h"
10f59415 39#include "reggroups.h"
79a45b7d 40#include "valprint.h"
51f0e40d 41#include "completer.h"
c906108c 42
6a83354a 43#include "gdb_curses.h"
96ec9981 44
1a4f81dd
TT
45/* Get the register from the frame and return a printable
46 representation of it. */
47
b9ad3686 48static gdb::unique_xmalloc_ptr<char>
1a4f81dd
TT
49tui_register_format (struct frame_info *frame, int regnum)
50{
51 struct gdbarch *gdbarch = get_frame_arch (frame);
5eccfcc2 52
1a4f81dd
TT
53 string_file stream;
54
55 scoped_restore save_pagination
56 = make_scoped_restore (&pagination_enabled, 0);
57 scoped_restore save_stdout
58 = make_scoped_restore (&gdb_stdout, &stream);
59
60 gdbarch_print_registers_info (gdbarch, &stream, frame, regnum, 1);
61
62 /* Remove the possible \n. */
63 std::string &str = stream.string ();
64 if (!str.empty () && str.back () == '\n')
65 str.resize (str.size () - 1);
66
67 /* Expand tabs into spaces, since ncurses on MS-Windows doesn't. */
b9ad3686 68 return tui_expand_tabs (str.c_str ());
1a4f81dd
TT
69}
70
71/* Get the register value from the given frame and format it for the
72 display. When changep is set, check if the new register value has
73 changed with respect to the previous call. */
74static void
75tui_get_register (struct frame_info *frame,
76 struct tui_data_item_window *data,
77 int regnum, bool *changedp)
78{
79 if (changedp)
80 *changedp = false;
81 if (target_has_registers)
82 {
b9ad3686
TT
83 gdb::unique_xmalloc_ptr<char> new_content
84 = tui_register_format (frame, regnum);
1a4f81dd
TT
85
86 if (changedp != NULL
b9ad3686 87 && strcmp (data->content.get (), new_content.get ()) != 0)
1a4f81dd
TT
88 *changedp = true;
89
b9ad3686 90 data->content = std::move (new_content);
1a4f81dd
TT
91 }
92}
96bd6233
TT
93
94/* See tui-regs.h. */
95
c906108c 96int
0b5ec218 97tui_data_window::last_regs_line_no () const
c906108c 98{
80df3337
TT
99 int num_lines = m_regs_content.size () / m_regs_column_count;
100 if (m_regs_content.size () % m_regs_column_count)
0670413d 101 num_lines++;
6ba8e26f 102 return num_lines;
55fb0713 103}
c906108c 104
18ab23af 105/* See tui-regs.h. */
c906108c 106
c906108c 107int
3b23c5f2 108tui_data_window::line_from_reg_element_no (int element_no) const
c906108c 109{
80df3337 110 if (element_no < m_regs_content.size ())
c906108c
SS
111 {
112 int i, line = (-1);
113
114 i = 1;
115 while (line == (-1))
116 {
80df3337 117 if (element_no < m_regs_column_count * i)
c906108c
SS
118 line = i - 1;
119 else
120 i++;
121 }
122
123 return line;
124 }
125 else
126 return (-1);
55fb0713 127}
c906108c 128
18ab23af 129/* See tui-regs.h. */
c906108c 130
c906108c 131int
baff0c28 132tui_data_window::first_reg_element_no_inline (int line_no) const
c906108c 133{
80df3337
TT
134 if (line_no * m_regs_column_count <= m_regs_content.size ())
135 return ((line_no + 1) * m_regs_column_count) - m_regs_column_count;
c906108c
SS
136 else
137 return (-1);
55fb0713 138}
c906108c 139
10f59415
SC
140/* Show the registers of the given group in the data window
141 and refresh the window. */
c906108c 142void
ca02d7c8 143tui_data_window::show_registers (struct reggroup *group)
c906108c 144{
10f59415
SC
145 if (group == 0)
146 group = general_reggroup;
c906108c 147
10f59415 148 if (target_has_registers && target_has_stack && target_has_memory)
c906108c 149 {
ca02d7c8 150 show_register_group (group, get_selected_frame (NULL),
80df3337 151 group == m_current_group);
368c1354 152
1cc6d956 153 /* Clear all notation of changed values. */
80df3337 154 for (auto &&data_item_win : m_regs_content)
fa4dc567 155 data_item_win.highlight = false;
80df3337 156 m_current_group = group;
c906108c 157 }
368c1354
TT
158 else
159 {
80df3337 160 m_current_group = 0;
a31bff9d 161 m_regs_content.clear ();
368c1354 162 }
a31bff9d
TT
163
164 rerender ();
55fb0713 165}
c906108c
SS
166
167
10f59415 168/* Set the data window to display the registers of the register group
1cc6d956 169 using the given frame. Values are refreshed only when
b5457826 170 refresh_values_only is true. */
10f59415 171
ca02d7c8
TT
172void
173tui_data_window::show_register_group (struct reggroup *group,
174 struct frame_info *frame,
b5457826 175 bool refresh_values_only)
10f59415 176{
5eccfcc2 177 struct gdbarch *gdbarch = get_frame_arch (frame);
10f59415 178 int nr_regs;
10f59415 179 int regnum, pos;
10f59415
SC
180
181 /* Make a new title showing which group we display. */
ab0e1f1a 182 title = string_printf ("Register group: %s", reggroup_name (group));
10f59415
SC
183
184 /* See how many registers must be displayed. */
185 nr_regs = 0;
f6efe3f8 186 for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
10f59415 187 {
d20c1c3f
PA
188 const char *name;
189
190 /* Must be in the group. */
191 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
192 continue;
193
194 /* If the register name is empty, it is undefined for this
195 processor, so don't display anything. */
196 name = gdbarch_register_name (gdbarch, regnum);
197 if (name == 0 || *name == '\0')
198 continue;
199
200 nr_regs++;
10f59415
SC
201 }
202
80df3337 203 m_regs_content.resize (nr_regs);
10f59415 204
21e1c91e
TT
205 /* Now set the register names and values. */
206 pos = 0;
207 for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); regnum++)
10f59415 208 {
21e1c91e
TT
209 struct tui_data_item_window *data_item_win;
210 const char *name;
10f59415 211
21e1c91e
TT
212 /* Must be in the group. */
213 if (!gdbarch_register_reggroup_p (gdbarch, regnum, group))
214 continue;
10f59415 215
21e1c91e
TT
216 /* If the register name is empty, it is undefined for this
217 processor, so don't display anything. */
218 name = gdbarch_register_name (gdbarch, regnum);
219 if (name == 0 || *name == '\0')
220 continue;
10f59415 221
80df3337 222 data_item_win = &m_regs_content[pos];
21e1c91e
TT
223 if (data_item_win)
224 {
225 if (!refresh_values_only)
226 {
227 data_item_win->item_no = regnum;
228 data_item_win->name = name;
229 data_item_win->highlight = false;
230 }
231 tui_get_register (frame, data_item_win, regnum, 0);
232 }
233 pos++;
234 }
10f59415
SC
235}
236
18ab23af 237/* See tui-regs.h. */
517e9505 238
c906108c 239void
517e9505 240tui_data_window::display_registers_from (int start_element_no)
c906108c 241{
0670413d
TT
242 int j, item_win_width, cur_y;
243
244 int max_len = 0;
80df3337 245 for (auto &&data_item_win : m_regs_content)
c906108c 246 {
0670413d
TT
247 const char *p;
248 int len;
10f59415 249
0670413d
TT
250 len = 0;
251 p = data_item_win.content.get ();
252 if (p != 0)
253 len = strlen (p);
254
255 if (len > max_len)
256 max_len = len;
257 }
258 item_win_width = max_len + 1;
259 int i = start_element_no;
260
80df3337
TT
261 m_regs_column_count = (width - 2) / item_win_width;
262 if (m_regs_column_count == 0)
263 m_regs_column_count = 1;
264 item_win_width = (width - 2) / m_regs_column_count;
0670413d
TT
265
266 /* Now create each data "sub" window, and write the display into
267 it. */
268 cur_y = 1;
1630140d 269 while (i < m_regs_content.size () && cur_y <= height - 2)
0670413d
TT
270 {
271 for (j = 0;
80df3337 272 j < m_regs_column_count && i < m_regs_content.size ();
0670413d 273 j++)
c906108c 274 {
0670413d 275 /* Create the window if necessary. */
80df3337 276 m_regs_content[i].resize (1, item_win_width,
3fe12b6d 277 x + (item_win_width * j) + 1, y + cur_y);
0670413d 278 i++; /* Next register. */
c906108c 279 }
0670413d 280 cur_y++; /* Next row. */
c906108c 281 }
55fb0713 282}
c906108c 283
18ab23af 284/* See tui-regs.h. */
c906108c 285
aca2dd16
TT
286void
287tui_data_window::display_reg_element_at_line (int start_element_no,
288 int start_line_no)
c906108c 289{
0670413d 290 int element_no = start_element_no;
c906108c 291
0670413d
TT
292 if (start_element_no != 0 && start_line_no != 0)
293 {
294 int last_line_no, first_line_on_last_page;
295
296 last_line_no = last_regs_line_no ();
297 first_line_on_last_page = last_line_no - (height - 2);
298 if (first_line_on_last_page < 0)
299 first_line_on_last_page = 0;
300
301 /* If the element_no causes us to scroll past the end of the
302 registers, adjust what element to really start the
303 display at. */
304 if (start_line_no > first_line_on_last_page)
305 element_no = first_reg_element_no_inline (first_line_on_last_page);
c906108c 306 }
0670413d 307 display_registers_from (element_no);
6ba8e26f 308}
c906108c 309
18ab23af 310/* See tui-regs.h. */
c906108c 311
c906108c 312int
517e9505 313tui_data_window::display_registers_from_line (int line_no)
c906108c 314{
0670413d
TT
315 int element_no;
316
317 if (line_no < 0)
318 line_no = 0;
319 else
320 {
321 /* Make sure that we don't display off the end of the
322 registers. */
323 if (line_no >= last_regs_line_no ())
80cb6c27 324 {
80df3337 325 line_no = line_from_reg_element_no (m_regs_content.size () - 1);
0670413d
TT
326 if (line_no < 0)
327 line_no = 0;
c906108c 328 }
c906108c
SS
329 }
330
0670413d 331 element_no = first_reg_element_no_inline (line_no);
80df3337 332 if (element_no < m_regs_content.size ())
0670413d
TT
333 display_reg_element_at_line (element_no, line_no);
334 else
335 line_no = (-1);
336
337 return line_no;
55fb0713 338}
c906108c
SS
339
340
18ab23af
TT
341/* Answer the index first element displayed. If none are displayed,
342 then return (-1). */
343int
344tui_data_window::first_data_item_displayed ()
345{
80df3337 346 for (int i = 0; i < m_regs_content.size (); i++)
18ab23af
TT
347 {
348 struct tui_gen_win_info *data_item_win;
349
80df3337 350 data_item_win = &m_regs_content[i];
2d83e710 351 if (data_item_win->is_visible ())
18ab23af
TT
352 return i;
353 }
354
355 return -1;
356}
357
358/* See tui-regs.h. */
359
360void
361tui_data_window::delete_data_content_windows ()
362{
80df3337 363 for (auto &&win : m_regs_content)
7523da63 364 win.handle.reset (nullptr);
18ab23af
TT
365}
366
367
368void
369tui_data_window::erase_data_content (const char *prompt)
370{
7523da63 371 werase (handle.get ());
b4ef5aeb 372 check_and_display_highlight_if_needed ();
18ab23af
TT
373 if (prompt != NULL)
374 {
375 int half_width = (width - 2) / 2;
376 int x_pos;
377
378 if (strlen (prompt) >= half_width)
379 x_pos = 1;
380 else
381 x_pos = half_width - strlen (prompt);
7523da63 382 mvwaddstr (handle.get (), (height / 2), x_pos, (char *) prompt);
18ab23af 383 }
45bbae5c 384 tui_wrefresh (handle.get ());
18ab23af
TT
385}
386
387/* See tui-regs.h. */
388
389void
18bb55c7 390tui_data_window::rerender ()
18ab23af 391{
80df3337 392 if (m_regs_content.empty ())
1f6d2f10 393 erase_data_content (_("[ Register Values Unavailable ]"));
18ab23af
TT
394 else
395 {
396 erase_data_content (NULL);
397 delete_data_content_windows ();
18ab23af
TT
398 display_registers_from (0);
399 }
400}
401
402
18ab23af
TT
403/* Scroll the data window vertically forward or backward. */
404void
405tui_data_window::do_scroll_vertical (int num_to_scroll)
406{
407 int first_element_no;
408 int first_line = (-1);
409
410 first_element_no = first_data_item_displayed ();
80df3337 411 if (first_element_no < m_regs_content.size ())
18ab23af
TT
412 first_line = line_from_reg_element_no (first_element_no);
413 else
414 { /* Calculate the first line from the element number which is in
415 the general data content. */
416 }
417
418 if (first_line >= 0)
419 {
420 first_line += num_to_scroll;
421 erase_data_content (NULL);
422 delete_data_content_windows ();
423 display_registers_from_line (first_line);
424 }
425}
426
427/* See tui-regs.h. */
428
18ab23af
TT
429void
430tui_data_window::refresh_window ()
431{
432 tui_gen_win_info::refresh_window ();
80df3337 433 for (auto &&win : m_regs_content)
fa4dc567 434 win.refresh_window ();
18ab23af
TT
435}
436
45bbae5c
TT
437void
438tui_data_window::no_refresh ()
439{
440 tui_gen_win_info::no_refresh ();
441 for (auto &&win : m_regs_content)
442 win.no_refresh ();
443}
444
55fb0713
AC
445/* This function check all displayed registers for changes in values,
446 given a particular frame. If the values have changed, they are
447 updated with the new value and highlighted. */
c906108c 448void
63356bfd 449tui_data_window::check_register_values (struct frame_info *frame)
c906108c 450{
80df3337
TT
451 if (m_regs_content.empty ())
452 show_registers (m_current_group);
63356bfd 453 else
c906108c 454 {
80df3337 455 for (auto &&data_item_win : m_regs_content)
c906108c 456 {
63356bfd 457 int was_hilighted;
c906108c 458
fa4dc567 459 was_hilighted = data_item_win.highlight;
10f59415 460
fa4dc567
TT
461 tui_get_register (frame, &data_item_win,
462 data_item_win.item_no,
463 &data_item_win.highlight);
10f59415 464
fa4dc567 465 if (data_item_win.highlight || was_hilighted)
cdaa6eb4 466 data_item_win.rerender ();
c906108c
SS
467 }
468 }
55fb0713 469}
c906108c 470
1cc6d956
MS
471/* Display a register in a window. If hilite is TRUE, then the value
472 will be displayed in reverse video. */
cdaa6eb4
TT
473void
474tui_data_item_window::rerender ()
10f59415 475{
cdaa6eb4
TT
476 int i;
477
7523da63 478 scrollok (handle.get (), FALSE);
cdaa6eb4
TT
479 if (highlight)
480 /* We ignore the return value, casting it to void in order to avoid
481 a compiler warning. The warning itself was introduced by a patch
482 to ncurses 5.7 dated 2009-08-29, changing this macro to expand
483 to code that causes the compiler to generate an unused-value
484 warning. */
7523da63 485 (void) wstandout (handle.get ());
10f59415 486
7523da63 487 wmove (handle.get (), 0, 0);
cdaa6eb4 488 for (i = 1; i < width; i++)
7523da63
TT
489 waddch (handle.get (), ' ');
490 wmove (handle.get (), 0, 0);
cdaa6eb4 491 if (content)
7523da63 492 waddstr (handle.get (), content.get ());
cdaa6eb4
TT
493
494 if (highlight)
495 /* We ignore the return value, casting it to void in order to avoid
496 a compiler warning. The warning itself was introduced by a patch
497 to ncurses 5.7 dated 2009-08-29, changing this macro to expand
498 to code that causes the compiler to generate an unused-value
499 warning. */
7523da63 500 (void) wstandend (handle.get ());
cdaa6eb4
TT
501 refresh_window ();
502}
503
504void
505tui_data_item_window::refresh_window ()
506{
507 if (handle != nullptr)
508 {
509 /* This seems to be needed because the data items are nested
510 windows, which according to the ncurses man pages aren't well
511 supported. */
7523da63 512 touchwin (handle.get ());
45bbae5c 513 tui_wrefresh (handle.get ());
10f59415
SC
514 }
515}
516
51f0e40d
AB
517/* Helper for "tui reg next", wraps a call to REGGROUP_NEXT, but adds wrap
518 around behaviour. Returns the next register group, or NULL if the
519 register window is not currently being displayed. */
520
521static struct reggroup *
fe3eaf1c 522tui_reg_next (struct reggroup *current_group, struct gdbarch *gdbarch)
c906108c 523{
51f0e40d 524 struct reggroup *group = NULL;
e17c207e 525
fe3eaf1c 526 if (current_group != NULL)
10f59415 527 {
fe3eaf1c 528 group = reggroup_next (gdbarch, current_group);
b75c69bb
AB
529 if (group == NULL)
530 group = reggroup_next (gdbarch, NULL);
10f59415 531 }
51f0e40d 532 return group;
10f59415
SC
533}
534
51f0e40d
AB
535/* Helper for "tui reg prev", wraps a call to REGGROUP_PREV, but adds wrap
536 around behaviour. Returns the previous register group, or NULL if the
537 register window is not currently being displayed. */
55b40027 538
51f0e40d 539static struct reggroup *
fe3eaf1c 540tui_reg_prev (struct reggroup *current_group, struct gdbarch *gdbarch)
55b40027 541{
51f0e40d 542 struct reggroup *group = NULL;
55b40027 543
fe3eaf1c 544 if (current_group != NULL)
55b40027 545 {
fe3eaf1c 546 group = reggroup_prev (gdbarch, current_group);
55b40027
AB
547 if (group == NULL)
548 group = reggroup_prev (gdbarch, NULL);
55b40027 549 }
51f0e40d 550 return group;
55b40027
AB
551}
552
51f0e40d
AB
553/* Implement the 'tui reg' command. Changes the register group displayed
554 in the tui register window. Displays the tui register window if it is
555 not already on display. */
c906108c 556
10f59415 557static void
e2d8ae16 558tui_reg_command (const char *args, int from_tty)
10f59415 559{
51f0e40d 560 struct gdbarch *gdbarch = get_current_arch ();
c906108c 561
51f0e40d
AB
562 if (args != NULL)
563 {
564 struct reggroup *group, *match = NULL;
565 size_t len = strlen (args);
566
567 /* Make sure the curses mode is enabled. */
568 tui_enable ();
569
45bbae5c
TT
570 tui_suppress_output suppress;
571
51f0e40d
AB
572 /* Make sure the register window is visible. If not, select an
573 appropriate layout. We need to do this before trying to run the
574 'next' or 'prev' commands. */
2d83e710 575 if (TUI_DATA_WIN == NULL || !TUI_DATA_WIN->is_visible ())
0dbc2fc7 576 tui_regs_layout ();
51f0e40d 577
89df7f90 578 struct reggroup *current_group = TUI_DATA_WIN->get_current_group ();
51f0e40d 579 if (strncmp (args, "next", len) == 0)
fe3eaf1c 580 match = tui_reg_next (current_group, gdbarch);
51f0e40d 581 else if (strncmp (args, "prev", len) == 0)
fe3eaf1c 582 match = tui_reg_prev (current_group, gdbarch);
51f0e40d
AB
583
584 /* This loop matches on the initial part of a register group
585 name. If this initial part in ARGS matches only one register
586 group then the switch is made. */
587 for (group = reggroup_next (gdbarch, NULL);
588 group != NULL;
589 group = reggroup_next (gdbarch, group))
590 {
591 if (strncmp (reggroup_name (group), args, len) == 0)
592 {
593 if (match != NULL)
594 error (_("ambiguous register group name '%s'"), args);
595 match = group;
596 }
597 }
598
599 if (match == NULL)
600 error (_("unknown register group '%s'"), args);
601
ca02d7c8 602 TUI_DATA_WIN->show_registers (match);
51f0e40d
AB
603 }
604 else
605 {
606 struct reggroup *group;
607 int first;
608
609 printf_unfiltered (_("\"tui reg\" must be followed by the name of "
610 "either a register group,\nor one of 'next' "
611 "or 'prev'. Known register groups are:\n"));
612
613 for (first = 1, group = reggroup_next (gdbarch, NULL);
614 group != NULL;
615 first = 0, group = reggroup_next (gdbarch, group))
616 {
617 if (!first)
618 printf_unfiltered (", ");
619 printf_unfiltered ("%s", reggroup_name (group));
620 }
621
622 printf_unfiltered ("\n");
623 }
10f59415
SC
624}
625
51f0e40d
AB
626/* Complete names of register groups, and add the special "prev" and "next"
627 names. */
c906108c 628
eb3ff9a5 629static void
51f0e40d 630tui_reggroup_completer (struct cmd_list_element *ignore,
eb3ff9a5 631 completion_tracker &tracker,
51f0e40d 632 const char *text, const char *word)
10f59415 633{
51f0e40d
AB
634 static const char *extra[] = { "next", "prev", NULL };
635 size_t len = strlen (word);
636 const char **tmp;
637
eb3ff9a5 638 reggroup_completer (ignore, tracker, text, word);
51f0e40d 639
eb3ff9a5 640 /* XXXX use complete_on_enum instead? */
51f0e40d
AB
641 for (tmp = extra; *tmp != NULL; ++tmp)
642 {
643 if (strncmp (word, *tmp, len) == 0)
b02f78f9 644 tracker.add_completion (make_unique_xstrdup (*tmp));
51f0e40d 645 }
10f59415 646}
c906108c 647
6c265988 648void _initialize_tui_regs ();
18ab23af 649void
6c265988 650_initialize_tui_regs ()
18ab23af
TT
651{
652 struct cmd_list_element **tuicmd, *cmd;
653
654 tuicmd = tui_get_cmd_list ();
655
656 cmd = add_cmd ("reg", class_tui, tui_reg_command, _("\
283be8bf
TT
657TUI command to control the register window.\n\
658Usage: tui reg NAME\n\
659NAME is the name of the register group to display"), tuicmd);
18ab23af
TT
660 set_cmd_completer (cmd, tui_reggroup_completer);
661}
This page took 3.233928 seconds and 4 git commands to generate.