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