]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tui-winsource.c
Remove the TUI execution info window
[thirdparty/binutils-gdb.git] / gdb / tui / tui-winsource.c
CommitLineData
f377b406 1/* TUI display source/assembly window.
f33c6cbf 2
42a4f53d 3 Copyright (C) 1998-2019 Free Software Foundation, Inc.
f33c6cbf 4
f377b406
SC
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
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
23#include <ctype.h>
24#include "symtab.h"
25#include "frame.h"
26#include "breakpoint.h"
fd0407d6 27#include "value.h"
52575520 28#include "source.h"
13274fc3 29#include "objfiles.h"
a7417d46 30#include "filenames.h"
c906108c 31
d7b2e967
AC
32#include "tui/tui.h"
33#include "tui/tui-data.h"
62f29fda 34#include "tui/tui-io.h"
d7b2e967
AC
35#include "tui/tui-stack.h"
36#include "tui/tui-win.h"
37#include "tui/tui-wingeneral.h"
38#include "tui/tui-winsource.h"
39#include "tui/tui-source.h"
40#include "tui/tui-disasm.h"
6a83354a 41#include "gdb_curses.h"
c906108c 42
1f393769 43/* Function to display the "main" routine. */
c906108c 44void
b4eb2452 45tui_display_main ()
c906108c 46{
3891b65e
TT
47 auto adapter = tui_source_windows ();
48 if (adapter.begin () != adapter.end ())
c906108c 49 {
13274fc3 50 struct gdbarch *gdbarch;
c906108c
SS
51 CORE_ADDR addr;
52
13274fc3 53 tui_get_begin_asm_address (&gdbarch, &addr);
c774cec6 54 if (addr != (CORE_ADDR) 0)
c906108c 55 {
34248c3a 56 struct symtab *s;
c906108c 57
13274fc3 58 tui_update_source_windows_with_addr (gdbarch, addr);
34248c3a
DE
59 s = find_pc_line_symtab (addr);
60 if (s != NULL)
61 tui_update_locator_fullname (symtab_to_fullname (s));
2e17b763 62 else
56d397a3 63 tui_update_locator_fullname ("??");
c906108c
SS
64 }
65 }
2e17b763 66}
c906108c
SS
67
68
69
f80bda8e
AC
70/* Function to display source in the source window. This function
71 initializes the horizontal scroll to 0. */
c906108c 72void
017f9828
TT
73tui_source_window_base::update_source_window
74 (struct gdbarch *gdbarch,
75 struct symtab *s,
76 struct tui_line_or_address line_or_addr)
c906108c 77{
017f9828
TT
78 horizontal_offset = 0;
79 update_source_window_as_is (gdbarch, s, line_or_addr);
f80bda8e 80}
c906108c
SS
81
82
f80bda8e
AC
83/* Function to display source in the source/asm window. This function
84 shows the source as specified by the horizontal offset. */
c906108c 85void
ed8358e9
TT
86tui_source_window_base::update_source_window_as_is
87 (struct gdbarch *gdbarch,
88 struct symtab *s,
89 struct tui_line_or_address line_or_addr)
c906108c 90{
81c82c4b
TT
91 enum tui_status ret
92 = set_contents (gdbarch, s, line_or_addr);
c906108c
SS
93
94 if (ret == TUI_FAILURE)
ed8358e9 95 erase_source_content ();
c906108c
SS
96 else
97 {
2ddaf614 98 update_breakpoint_info (nullptr, false);
ed8358e9
TT
99 show_source_content ();
100 update_exec_info ();
101 if (type == SRC_WIN)
c906108c 102 {
51abb421
PA
103 symtab_and_line sal;
104
ed8358e9 105 sal.line = line_or_addr.u.line_no + (content.size () - 2);
52575520 106 sal.symtab = s;
eb822aa6 107 sal.pspace = SYMTAB_PSPACE (s);
51abb421 108 set_current_source_symtab_and_line (sal);
ef5eab5a
MS
109 /* If the focus was in the asm win, put it in the src win if
110 we don't have a split layout. */
e5908723
MS
111 if (tui_win_with_focus () == TUI_DISASM_WIN
112 && tui_current_layout () != SRC_DISASSEM_COMMAND)
ed8358e9 113 tui_set_win_focus_to (this);
c906108c
SS
114 }
115 }
f80bda8e 116}
c906108c
SS
117
118
f80bda8e
AC
119/* Function to ensure that the source and/or disassemly windows
120 reflect the input address. */
c906108c 121void
13274fc3 122tui_update_source_windows_with_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
c906108c 123{
c774cec6 124 if (addr != 0)
c906108c
SS
125 {
126 struct symtab_and_line sal;
362c05fe 127 struct tui_line_or_address l;
a4b99e53 128
dd1abb8c 129 switch (tui_current_layout ())
c906108c
SS
130 {
131 case DISASSEM_COMMAND:
132 case DISASSEM_DATA_COMMAND:
13274fc3 133 tui_show_disassem (gdbarch, addr);
c906108c
SS
134 break;
135 case SRC_DISASSEM_COMMAND:
13274fc3 136 tui_show_disassem_and_update_source (gdbarch, addr);
c906108c
SS
137 break;
138 default:
c774cec6 139 sal = find_pc_line (addr, 0);
362c05fe
AS
140 l.loa = LOA_LINE;
141 l.u.line_no = sal.line;
bb01dbfc 142 TUI_SRC_WIN->show_symtab_source (gdbarch, sal.symtab, l);
c906108c
SS
143 break;
144 }
145 }
146 else
147 {
ad54d15b 148 for (struct tui_source_window_base *win_info : tui_source_windows ())
c398c3d0 149 win_info->erase_source_content ();
c906108c 150 }
6ba8e26f 151}
c906108c 152
f80bda8e
AC
153/* Function to ensure that the source and/or disassemly windows
154 reflect the input address. */
c906108c 155void
f80bda8e 156tui_update_source_windows_with_line (struct symtab *s, int line)
c906108c 157{
13274fc3 158 struct gdbarch *gdbarch;
84b1e7c7 159 CORE_ADDR pc;
362c05fe 160 struct tui_line_or_address l;
13274fc3
UW
161
162 if (!s)
163 return;
164
eb822aa6 165 gdbarch = get_objfile_arch (SYMTAB_OBJFILE (s));
13274fc3 166
dd1abb8c 167 switch (tui_current_layout ())
c906108c
SS
168 {
169 case DISASSEM_COMMAND:
170 case DISASSEM_DATA_COMMAND:
84b1e7c7 171 find_line_pc (s, line, &pc);
13274fc3 172 tui_update_source_windows_with_addr (gdbarch, pc);
c906108c
SS
173 break;
174 default:
362c05fe
AS
175 l.loa = LOA_LINE;
176 l.u.line_no = line;
bb01dbfc 177 TUI_SRC_WIN->show_symtab_source (gdbarch, s, l);
dd1abb8c 178 if (tui_current_layout () == SRC_DISASSEM_COMMAND)
84b1e7c7
SC
179 {
180 find_line_pc (s, line, &pc);
13274fc3 181 tui_show_disassem (gdbarch, pc);
84b1e7c7 182 }
c906108c
SS
183 break;
184 }
f80bda8e 185}
c906108c 186
c906108c 187void
e25d2004 188tui_source_window_base::do_erase_source_content (const char *str)
c906108c 189{
6ba8e26f 190 int x_pos;
e25d2004 191 int half_width = (width - 2) / 2;
c906108c 192
c398c3d0 193 content.clear ();
e25d2004 194 if (handle != NULL)
c906108c 195 {
e25d2004
TT
196 werase (handle);
197 check_and_display_highlight_if_needed ();
caf0bc4e 198
e25d2004 199 if (strlen (str) >= half_width)
caf0bc4e
TT
200 x_pos = 1;
201 else
e25d2004
TT
202 x_pos = half_width - strlen (str);
203 mvwaddstr (handle,
204 (height / 2),
caf0bc4e 205 x_pos,
e25d2004 206 (char *) str);
93858ad3 207
e25d2004 208 refresh_window ();
c906108c 209 }
6ba8e26f 210}
c906108c
SS
211
212
bc712bbf
SC
213/* Redraw the complete line of a source or disassembly window. */
214static void
53e7cdba 215tui_show_source_line (struct tui_source_window_base *win_info, int lineno)
bc712bbf 216{
53e7cdba 217 struct tui_source_element *line;
798e1c30 218 int x;
bc712bbf 219
53e7cdba
TT
220 line = &win_info->content[lineno - 1];
221 if (line->is_exec_point)
cb2ce893 222 tui_set_reverse_mode (win_info->handle, true);
bc712bbf 223
398fdd60 224 wmove (win_info->handle, lineno, TUI_EXECINFO_SIZE);
53e7cdba 225 tui_puts (line->line,
cb2ce893 226 win_info->handle);
53e7cdba 227 if (line->is_exec_point)
cb2ce893 228 tui_set_reverse_mode (win_info->handle, false);
bc712bbf
SC
229
230 /* Clear to end of line but stop before the border. */
cb2ce893
TT
231 x = getcurx (win_info->handle);
232 while (x + 1 < win_info->width)
798e1c30 233 {
cb2ce893
TT
234 waddch (win_info->handle, ' ');
235 x = getcurx (win_info->handle);
798e1c30 236 }
bc712bbf
SC
237}
238
c906108c 239void
0bd27e07 240tui_source_window_base::show_source_content ()
c906108c 241{
0bd27e07 242 if (!content.empty ())
c906108c 243 {
bc712bbf
SC
244 int lineno;
245
0bd27e07
TT
246 for (lineno = 1; lineno <= content.size (); lineno++)
247 tui_show_source_line (this, lineno);
c906108c 248 }
bc712bbf 249 else
e25d2004 250 erase_source_content ();
bc712bbf 251
0bd27e07
TT
252 check_and_display_highlight_if_needed ();
253 refresh_window ();
bc712bbf 254}
c906108c 255
ad54d15b 256/* See tui-data.h. */
6f11e682 257
5104fe36
TT
258void
259tui_source_window_base::clear_detail ()
260{
261 gdbarch = NULL;
262 start_line_or_addr.loa = LOA_ADDRESS;
263 start_line_or_addr.u.addr = 0;
264 horizontal_offset = 0;
265}
266
267tui_source_window_base::tui_source_window_base (enum tui_win_type type)
398fdd60 268 : tui_win_info (type)
5104fe36
TT
269{
270 gdb_assert (type == SRC_WIN || type == DISASSEM_WIN);
271 start_line_or_addr.loa = LOA_ADDRESS;
272 start_line_or_addr.u.addr = 0;
273}
274
275
276tui_source_window_base::~tui_source_window_base ()
277{
278 xfree (fullname);
5104fe36
TT
279}
280
5104fe36
TT
281/* See tui-data.h. */
282
283void
284tui_source_window_base::refresh_all ()
285{
0bd27e07 286 show_source_content ();
b4ef5aeb 287 check_and_display_highlight_if_needed ();
7ba913dc 288 update_exec_info ();
5104fe36
TT
289}
290
291/* See tui-data.h. */
292
293void
294tui_source_window_base::update_tab_width ()
295{
3df505f6
TT
296 werase (handle);
297 rerender ();
5104fe36
TT
298}
299
5104fe36 300void
3df505f6 301tui_source_window_base::rerender ()
5104fe36 302{
5104fe36
TT
303 if (!content.empty ())
304 {
305 struct tui_line_or_address line_or_addr;
306 struct symtab_and_line cursal
307 = get_current_source_symtab_and_line ();
308
309 line_or_addr = start_line_or_addr;
017f9828 310 update_source_window (gdbarch, cursal.symtab, line_or_addr);
5104fe36
TT
311 }
312 else if (deprecated_safe_get_selected_frame () != NULL)
313 {
314 struct tui_line_or_address line;
315 struct symtab_and_line cursal
316 = get_current_source_symtab_and_line ();
317 struct frame_info *frame = deprecated_safe_get_selected_frame ();
318 struct gdbarch *gdbarch = get_frame_arch (frame);
319
320 struct symtab *s = find_pc_line_symtab (get_frame_pc (frame));
321 if (type == SRC_WIN)
322 {
323 line.loa = LOA_LINE;
324 line.u.line_no = cursal.line;
325 }
326 else
327 {
328 line.loa = LOA_ADDRESS;
329 find_line_pc (s, cursal.line, &line.u.addr);
330 }
017f9828 331 update_source_window (gdbarch, s, line);
5104fe36 332 }
3df505f6
TT
333 else
334 erase_source_content ();
5104fe36
TT
335}
336
337/* See tui-data.h. */
338
6f11e682 339void
ad54d15b 340tui_source_window_base::refill ()
6f11e682
TT
341{
342 symtab *s = nullptr;
343
cb2ce893 344 if (type == SRC_WIN)
6f11e682
TT
345 {
346 symtab_and_line cursal = get_current_source_symtab_and_line ();
347 s = (cursal.symtab == NULL
348 ? find_pc_line_symtab (get_frame_pc (get_selected_frame (NULL)))
349 : cursal.symtab);
350 }
351
ed8358e9 352 update_source_window_as_is (gdbarch, s, content[0].line_or_addr);
6f11e682 353}
c906108c 354
f80bda8e 355/* Scroll the source forward or backward horizontally. */
6f11e682 356
c906108c 357void
c3bd716f 358tui_source_window_base::do_scroll_horizontal (int num_to_scroll)
c906108c 359{
53e7cdba 360 if (!content.empty ())
c906108c 361 {
c3bd716f
TT
362 int offset = horizontal_offset + num_to_scroll;
363 if (offset < 0)
364 offset = 0;
e6e41501 365 horizontal_offset = offset;
ad54d15b 366 refill ();
c906108c 367 }
6ba8e26f 368}
c906108c
SS
369
370
0598af48 371/* Set or clear the is_exec_point flag in the line whose line is
1cc6d956
MS
372 line_no. */
373
c906108c 374void
ad54d15b 375tui_source_window_base::set_is_exec_point_at (struct tui_line_or_address l)
c906108c 376{
02c28df0 377 bool changed = false;
c906108c 378 int i;
c906108c
SS
379
380 i = 0;
53e7cdba 381 while (i < content.size ())
c906108c 382 {
02c28df0 383 bool new_state;
362c05fe 384 struct tui_line_or_address content_loa =
53e7cdba 385 content[i].line_or_addr;
362c05fe
AS
386
387 gdb_assert (l.loa == LOA_ADDRESS || l.loa == LOA_LINE);
388 gdb_assert (content_loa.loa == LOA_LINE
389 || content_loa.loa == LOA_ADDRESS);
390 if (content_loa.loa == l.loa
391 && ((l.loa == LOA_LINE && content_loa.u.line_no == l.u.line_no)
f7952c57 392 || (l.loa == LOA_ADDRESS && content_loa.u.addr == l.u.addr)))
02c28df0 393 new_state = true;
c906108c 394 else
02c28df0 395 new_state = false;
53e7cdba 396 if (new_state != content[i].is_exec_point)
00b90ae2 397 {
02c28df0 398 changed = true;
53e7cdba 399 content[i].is_exec_point = new_state;
ad54d15b 400 tui_show_source_line (this, i + 1);
00b90ae2 401 }
c906108c
SS
402 i++;
403 }
00b90ae2 404 if (changed)
ad54d15b 405 refill ();
00b90ae2 406}
c906108c 407
0807ab7b
TT
408/* See tui-winsource.h. */
409
c906108c 410void
0807ab7b 411tui_update_all_breakpoint_info (struct breakpoint *being_deleted)
c906108c 412{
ad54d15b 413 for (tui_source_window_base *win : tui_source_windows ())
c906108c 414 {
2ddaf614
TT
415 if (win->update_breakpoint_info (being_deleted, false))
416 win->update_exec_info ();
c906108c 417 }
00b2bad4 418}
c906108c
SS
419
420
0807ab7b 421/* Scan the source window and the breakpoints to update the break_mode
1cc6d956
MS
422 information for each line.
423
0807ab7b 424 Returns true if something changed and the execution window must be
1cc6d956
MS
425 refreshed. */
426
0807ab7b 427bool
2ddaf614
TT
428tui_source_window_base::update_breakpoint_info
429 (struct breakpoint *being_deleted, bool current_only)
c906108c
SS
430{
431 int i;
0807ab7b 432 bool need_refresh = false;
c906108c 433
2ddaf614 434 for (i = 0; i < content.size (); i++)
00b2bad4
SC
435 {
436 struct breakpoint *bp;
437 extern struct breakpoint *breakpoint_chain;
5b6fe301 438 struct tui_source_element *line;
00b2bad4 439
2ddaf614 440 line = &content[i];
6d012f14 441 if (current_only && !line->is_exec_point)
00b2bad4
SC
442 continue;
443
444 /* Scan each breakpoint to see if the current line has something to
445 do with it. Identify enable/disabled breakpoints as well as
446 those that we already hit. */
0598af48 447 tui_bp_flags mode = 0;
00b2bad4 448 for (bp = breakpoint_chain;
cafb3438 449 bp != NULL;
00b2bad4
SC
450 bp = bp->next)
451 {
f8eba3c6
TT
452 struct bp_location *loc;
453
362c05fe
AS
454 gdb_assert (line->line_or_addr.loa == LOA_LINE
455 || line->line_or_addr.loa == LOA_ADDRESS);
f8eba3c6 456
0807ab7b
TT
457 if (bp == being_deleted)
458 continue;
459
f8eba3c6
TT
460 for (loc = bp->loc; loc != NULL; loc = loc->next)
461 {
2ddaf614 462 if (location_matches_p (loc, i))
f8eba3c6
TT
463 {
464 if (bp->enable_state == bp_disabled)
465 mode |= TUI_BP_DISABLED;
466 else
467 mode |= TUI_BP_ENABLED;
468 if (bp->hit_count)
469 mode |= TUI_BP_HIT;
470 if (bp->loc->cond)
471 mode |= TUI_BP_CONDITIONAL;
472 if (bp->type == bp_hardware_breakpoint)
473 mode |= TUI_BP_HARDWARE;
474 }
475 }
00b2bad4 476 }
0598af48 477 if (line->break_mode != mode)
00b2bad4 478 {
0598af48
TT
479 line->break_mode = mode;
480 need_refresh = true;
00b2bad4
SC
481 }
482 }
483 return need_refresh;
484}
c906108c 485
6ba8e26f
AC
486/* Function to initialize the content of the execution info window,
487 based upon the input window which is either the source or
488 disassembly window. */
73fbdc65 489void
5216580d 490tui_source_window_base::update_exec_info ()
c906108c 491{
2ddaf614 492 update_breakpoint_info (nullptr, true);
37a4a131 493 for (int i = 0; i < content.size (); i++)
098f9ed4 494 {
5216580d
TT
495 struct tui_source_element *src_element = &content[i];
496 char element[TUI_EXECINFO_SIZE] = " ";
098f9ed4
TT
497
498 /* Now update the exec info content based upon the state
499 of each line as indicated by the source content. */
5216580d 500 tui_bp_flags mode = src_element->break_mode;
098f9ed4
TT
501 if (mode & TUI_BP_HIT)
502 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'H' : 'B';
503 else if (mode & (TUI_BP_ENABLED | TUI_BP_DISABLED))
504 element[TUI_BP_HIT_POS] = (mode & TUI_BP_HARDWARE) ? 'h' : 'b';
505
506 if (mode & TUI_BP_ENABLED)
507 element[TUI_BP_BREAK_POS] = '+';
508 else if (mode & TUI_BP_DISABLED)
509 element[TUI_BP_BREAK_POS] = '-';
510
511 if (src_element->is_exec_point)
512 element[TUI_EXEC_POS] = '>';
c906108c 513
398fdd60 514 mvwaddstr (handle, i + 1, 1, element);
5216580d 515 }
398fdd60 516 refresh_window ();
f80bda8e 517}