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