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