2002-02-08 Daniel Jacobowitz <drow@mvista.com>
[deliverable/binutils-gdb.git] / gdb / tui / tuiDisassem.c
CommitLineData
f377b406
SC
1/* Disassembly display.
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Hewlett-Packard Company.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
c906108c 21
4e8f7a8b
DJ
22/* If we need <curses.h>, we must include it before we get "bfd.h". */
23#include "config.h"
24#ifdef HAVE_NCURSES_H
25#include <ncurses.h>
26#else
27#ifdef HAVE_CURSES_H
28#include <curses.h>
29#endif
30#endif
31
c906108c
SS
32#include "defs.h"
33#include "symtab.h"
34#include "breakpoint.h"
35#include "frame.h"
fd0407d6 36#include "value.h"
c906108c
SS
37
38#include "tui.h"
39#include "tuiData.h"
a8080b7f 40#include "tuiWin.h"
c906108c
SS
41#include "tuiLayout.h"
42#include "tuiSourceWin.h"
43#include "tuiStack.h"
a8080b7f 44#include "tui-file.h"
c906108c
SS
45
46
47/*****************************************
48** STATIC LOCAL FUNCTIONS FORWARD DECLS **
49******************************************/
50
a14ed312 51static struct breakpoint *_hasBreak (CORE_ADDR);
c906108c
SS
52
53
54/*****************************************
55** PUBLIC FUNCTIONS **
56******************************************/
57
58/*
c5aa993b
JM
59 ** tuiSetDisassemContent().
60 ** Function to set the disassembly window's content.
61 */
c906108c 62TuiStatus
c774cec6 63tuiSetDisassemContent (struct symtab *s, CORE_ADDR startAddr)
c906108c
SS
64{
65 TuiStatus ret = TUI_FAILURE;
d9fcf2fb 66 struct ui_file *gdb_dis_out;
c906108c 67
c774cec6 68 if (startAddr != 0)
c906108c
SS
69 {
70 register int i, desc;
71
72 if ((ret = tuiAllocSourceBuffer (disassemWin)) == TUI_SUCCESS)
73 {
74 register int offset = disassemWin->detail.sourceInfo.horizontalOffset;
75 register int threshold, curLine = 0, lineWidth, maxLines;
76 CORE_ADDR newpc, pc;
77 disassemble_info asmInfo;
78 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
a14ed312
KB
79extern void strcat_address (CORE_ADDR, char *, int);
80extern void strcat_address_numeric (CORE_ADDR, int, char *, int);
c906108c
SS
81 int curLen = 0;
82 int tab_len = tuiDefaultTabLen ();
83
84 maxLines = disassemWin->generic.height - 2; /* account for hilite */
85 lineWidth = disassemWin->generic.width - 1;
86 threshold = (lineWidth - 1) + offset;
87
d9fcf2fb 88 /* now init the ui_file structure */
11cf8741 89 gdb_dis_out = tui_sfileopen (threshold);
c906108c 90
a8080b7f
SC
91 asmInfo = tm_print_insn_info;
92 asmInfo.stream = gdb_dis_out;
c906108c
SS
93
94 disassemWin->detail.sourceInfo.startLineOrAddr.addr = startAddr;
95
96 /* Now construct each line */
c774cec6 97 for (curLine = 0, pc = startAddr; (curLine < maxLines);)
c906108c 98 {
c5aa993b 99 TuiWinElementPtr element = (TuiWinElementPtr) disassemWin->generic.content[curLine];
c906108c
SS
100 struct breakpoint *bp;
101
102 print_address (pc, gdb_dis_out);
103
11cf8741 104 curLen = strlen (tui_file_get_strbuf (gdb_dis_out));
c906108c
SS
105 i = curLen - ((curLen / tab_len) * tab_len);
106
c5aa993b 107 /* adjust buffer length if necessary */
11cf8741 108 tui_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i) : 0, gdb_dis_out);
c5aa993b 109
c906108c
SS
110 /* Add spaces to make the instructions start onthe same column */
111 while (i < tab_len)
112 {
11cf8741 113 tui_file_get_strbuf (gdb_dis_out)[curLen] = ' ';
c906108c
SS
114 i++;
115 curLen++;
116 }
11cf8741 117 tui_file_get_strbuf (gdb_dis_out)[curLen] = '\0';
c906108c
SS
118
119 newpc = pc + ((*tm_print_insn) (pc, &asmInfo));
120
121 /* Now copy the line taking the offset into account */
11cf8741 122 if (strlen (tui_file_get_strbuf (gdb_dis_out)) > offset)
c906108c 123 strcpy (element->whichElement.source.line,
11cf8741 124 &(tui_file_get_strbuf (gdb_dis_out)[offset]));
c906108c
SS
125 else
126 element->whichElement.source.line[0] = '\0';
a4b99e53 127 element->whichElement.source.lineOrAddr.addr = pc;
c906108c 128 element->whichElement.source.isExecPoint =
c5aa993b 129 (pc == (CORE_ADDR) ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr);
c906108c
SS
130 bp = _hasBreak (pc);
131 element->whichElement.source.hasBreak =
132 (bp != (struct breakpoint *) NULL &&
133 (!element->whichElement.source.isExecPoint ||
b5de0fa7 134 (bp->disposition != disp_del || bp->hit_count <= 0)));
c906108c
SS
135 curLine++;
136 pc = newpc;
c5aa993b 137 /* reset the buffer to empty */
11cf8741 138 tui_file_get_strbuf (gdb_dis_out)[0] = '\0';
c906108c 139 }
d9fcf2fb 140 ui_file_delete (gdb_dis_out);
11cf8741 141 gdb_dis_out = NULL;
c906108c
SS
142 disassemWin->generic.contentSize = curLine;
143 ret = TUI_SUCCESS;
144 }
145 }
146
147 return ret;
148} /* tuiSetDisassemContent */
149
150
151/*
c5aa993b
JM
152 ** tuiShowDisassem().
153 ** Function to display the disassembly window with disassembled code.
154 */
c906108c 155void
c774cec6 156tuiShowDisassem (CORE_ADDR startAddr)
c906108c 157{
c774cec6 158 struct symtab *s = find_pc_symtab (startAddr);
c906108c 159 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
a4b99e53 160 TuiLineOrAddress val;
c906108c 161
a4b99e53 162 val.addr = startAddr;
c906108c 163 tuiAddWinToLayout (DISASSEM_WIN);
a4b99e53 164 tuiUpdateSourceWindow (disassemWin, s, val, FALSE);
c906108c 165 /*
c5aa993b
JM
166 ** if the focus was in the src win, put it in the asm win, if the
167 ** source view isn't split
168 */
c906108c
SS
169 if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin)
170 tuiSetWinFocusTo (disassemWin);
171
172 return;
173} /* tuiShowDisassem */
174
175
176/*
c5aa993b
JM
177 ** tuiShowDisassemAndUpdateSource().
178 ** Function to display the disassembly window.
179 */
c906108c 180void
c774cec6 181tuiShowDisassemAndUpdateSource (CORE_ADDR startAddr)
c906108c
SS
182{
183 struct symtab_and_line sal;
184
185 tuiShowDisassem (startAddr);
186 if (currentLayout () == SRC_DISASSEM_COMMAND)
187 {
a4b99e53 188 TuiLineOrAddress val;
c906108c
SS
189 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
190 /*
c5aa993b
JM
191 ** Update what is in the source window if it is displayed too,
192 ** note that it follows what is in the disassembly window and visa-versa
193 */
c774cec6 194 sal = find_pc_line (startAddr, 0);
a4b99e53
SC
195 val.lineNo = sal.line;
196 tuiUpdateSourceWindow (srcWin, sal.symtab, val, TRUE);
3024f13a
SC
197 if (sal.symtab)
198 {
199 current_source_symtab = sal.symtab;
200 tuiUpdateLocatorFilename (sal.symtab->filename);
201 }
202 else
203 tuiUpdateLocatorFilename ("?");
c906108c
SS
204 }
205
206 return;
207} /* tuiShowDisassemAndUpdateSource */
208
c906108c 209/*
c5aa993b
JM
210 ** tuiGetBeginAsmAddress().
211 */
c774cec6 212CORE_ADDR
c906108c 213tuiGetBeginAsmAddress (void)
c906108c
SS
214{
215 TuiGenWinInfoPtr locator;
216 TuiLocatorElementPtr element;
c774cec6 217 CORE_ADDR addr;
c906108c
SS
218
219 locator = locatorWinInfoPtr ();
220 element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
221
c774cec6 222 if (element->addr == 0)
c906108c 223 {
c5aa993b 224 /*the target is not executing, because the pc is 0 */
c906108c 225
c774cec6 226 addr = parse_and_eval_address ("main");
c906108c 227
c774cec6
SC
228 if (addr == 0)
229 addr = parse_and_eval_address ("MAIN");
c906108c
SS
230
231 }
232 else /* the target is executing */
233 addr = element->addr;
234
235 return addr;
236} /* tuiGetBeginAsmAddress */
237
238
239/*
c5aa993b
JM
240 ** tuiVerticalDisassemScroll().
241 ** Scroll the disassembly forward or backward vertically
242 */
c906108c 243void
eca6576c
SC
244tuiVerticalDisassemScroll (TuiScrollDirection scrollDirection,
245 int numToScroll)
c906108c
SS
246{
247 if (disassemWin->generic.content != (OpaquePtr) NULL)
248 {
3024f13a 249 CORE_ADDR pc, lowAddr;
c906108c
SS
250 TuiWinContent content;
251 struct symtab *s;
252
253 content = (TuiWinContent) disassemWin->generic.content;
254 if (current_source_symtab == (struct symtab *) NULL)
255 s = find_pc_symtab (selected_frame->pc);
256 else
257 s = current_source_symtab;
258
259 pc = content[0]->whichElement.source.lineOrAddr.addr;
3024f13a
SC
260 if (find_pc_partial_function (pc, (char **) NULL, &lowAddr,
261 (CORE_ADDR) 0) == 0)
262 error ("No function contains program counter for selected frame.\n");
c906108c
SS
263 else
264 {
265 register int line = 0;
3024f13a 266 register CORE_ADDR newLow;
c906108c 267 bfd_byte buffer[4];
a4b99e53 268 TuiLineOrAddress val;
c906108c
SS
269
270 newLow = pc;
271 if (scrollDirection == FORWARD_SCROLL)
272 {
273 for (; line < numToScroll; line++)
274 newLow += sizeof (bfd_getb32 (buffer));
275 }
276 else
277 {
a4b99e53 278 for (; newLow != 0 && line < numToScroll; line++)
c906108c
SS
279 newLow -= sizeof (bfd_getb32 (buffer));
280 }
a4b99e53
SC
281 val.addr = newLow;
282 tuiUpdateSourceWindowAsIs (disassemWin, s, val, FALSE);
c906108c
SS
283 }
284 }
285
286 return;
287} /* tuiVerticalDisassemScroll */
288
289
290
291/*****************************************
292** STATIC LOCAL FUNCTIONS **
293******************************************/
294/*
c5aa993b
JM
295 ** _hasBreak().
296 ** Answer whether there is a break point at the input line in the
297 ** source file indicated
298 */
c906108c 299static struct breakpoint *
eca6576c 300_hasBreak (CORE_ADDR addr)
c906108c
SS
301{
302 struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
303 struct breakpoint *bp;
304 extern struct breakpoint *breakpoint_chain;
305
306
307 for (bp = breakpoint_chain;
308 (bp != (struct breakpoint *) NULL &&
309 bpWithBreak == (struct breakpoint *) NULL);
310 bp = bp->next)
311 if (addr == bp->address)
312 bpWithBreak = bp;
313
314 return bpWithBreak;
315} /* _hasBreak */
This page took 0.396034 seconds and 4 git commands to generate.