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