]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/tui/tuiDisassem.c
2001-10-21 H.J. Lu <hjl@gnu.org>
[thirdparty/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
SS
21
22#include "defs.h"
23#include "symtab.h"
24#include "breakpoint.h"
25#include "frame.h"
26
27#include "tui.h"
28#include "tuiData.h"
a8080b7f 29#include "tuiWin.h"
c906108c
SS
30#include "tuiLayout.h"
31#include "tuiSourceWin.h"
32#include "tuiStack.h"
a8080b7f 33#include "tui-file.h"
c906108c
SS
34
35
36/*****************************************
37** STATIC LOCAL FUNCTIONS FORWARD DECLS **
38******************************************/
39
a14ed312 40static struct breakpoint *_hasBreak (CORE_ADDR);
c906108c
SS
41
42
43/*****************************************
44** PUBLIC FUNCTIONS **
45******************************************/
46
47/*
c5aa993b
JM
48 ** tuiSetDisassemContent().
49 ** Function to set the disassembly window's content.
50 */
c906108c 51TuiStatus
c774cec6 52tuiSetDisassemContent (struct symtab *s, CORE_ADDR startAddr)
c906108c
SS
53{
54 TuiStatus ret = TUI_FAILURE;
d9fcf2fb 55 struct ui_file *gdb_dis_out;
c906108c 56
c774cec6 57 if (startAddr != 0)
c906108c
SS
58 {
59 register int i, desc;
60
61 if ((ret = tuiAllocSourceBuffer (disassemWin)) == TUI_SUCCESS)
62 {
63 register int offset = disassemWin->detail.sourceInfo.horizontalOffset;
64 register int threshold, curLine = 0, lineWidth, maxLines;
65 CORE_ADDR newpc, pc;
66 disassemble_info asmInfo;
67 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
a14ed312
KB
68extern void strcat_address (CORE_ADDR, char *, int);
69extern void strcat_address_numeric (CORE_ADDR, int, char *, int);
c906108c
SS
70 int curLen = 0;
71 int tab_len = tuiDefaultTabLen ();
72
73 maxLines = disassemWin->generic.height - 2; /* account for hilite */
74 lineWidth = disassemWin->generic.width - 1;
75 threshold = (lineWidth - 1) + offset;
76
d9fcf2fb 77 /* now init the ui_file structure */
11cf8741 78 gdb_dis_out = tui_sfileopen (threshold);
c906108c 79
a8080b7f
SC
80 asmInfo = tm_print_insn_info;
81 asmInfo.stream = gdb_dis_out;
c906108c
SS
82
83 disassemWin->detail.sourceInfo.startLineOrAddr.addr = startAddr;
84
85 /* Now construct each line */
c774cec6 86 for (curLine = 0, pc = startAddr; (curLine < maxLines);)
c906108c 87 {
c5aa993b 88 TuiWinElementPtr element = (TuiWinElementPtr) disassemWin->generic.content[curLine];
c906108c
SS
89 struct breakpoint *bp;
90
91 print_address (pc, gdb_dis_out);
92
11cf8741 93 curLen = strlen (tui_file_get_strbuf (gdb_dis_out));
c906108c
SS
94 i = curLen - ((curLen / tab_len) * tab_len);
95
c5aa993b 96 /* adjust buffer length if necessary */
11cf8741 97 tui_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i) : 0, gdb_dis_out);
c5aa993b 98
c906108c
SS
99 /* Add spaces to make the instructions start onthe same column */
100 while (i < tab_len)
101 {
11cf8741 102 tui_file_get_strbuf (gdb_dis_out)[curLen] = ' ';
c906108c
SS
103 i++;
104 curLen++;
105 }
11cf8741 106 tui_file_get_strbuf (gdb_dis_out)[curLen] = '\0';
c906108c
SS
107
108 newpc = pc + ((*tm_print_insn) (pc, &asmInfo));
109
110 /* Now copy the line taking the offset into account */
11cf8741 111 if (strlen (tui_file_get_strbuf (gdb_dis_out)) > offset)
c906108c 112 strcpy (element->whichElement.source.line,
11cf8741 113 &(tui_file_get_strbuf (gdb_dis_out)[offset]));
c906108c
SS
114 else
115 element->whichElement.source.line[0] = '\0';
a4b99e53 116 element->whichElement.source.lineOrAddr.addr = pc;
c906108c 117 element->whichElement.source.isExecPoint =
c5aa993b 118 (pc == (CORE_ADDR) ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr);
c906108c
SS
119 bp = _hasBreak (pc);
120 element->whichElement.source.hasBreak =
121 (bp != (struct breakpoint *) NULL &&
122 (!element->whichElement.source.isExecPoint ||
b5de0fa7 123 (bp->disposition != disp_del || bp->hit_count <= 0)));
c906108c
SS
124 curLine++;
125 pc = newpc;
c5aa993b 126 /* reset the buffer to empty */
11cf8741 127 tui_file_get_strbuf (gdb_dis_out)[0] = '\0';
c906108c 128 }
d9fcf2fb 129 ui_file_delete (gdb_dis_out);
11cf8741 130 gdb_dis_out = NULL;
c906108c
SS
131 disassemWin->generic.contentSize = curLine;
132 ret = TUI_SUCCESS;
133 }
134 }
135
136 return ret;
137} /* tuiSetDisassemContent */
138
139
140/*
c5aa993b
JM
141 ** tuiShowDisassem().
142 ** Function to display the disassembly window with disassembled code.
143 */
c906108c 144void
c774cec6 145tuiShowDisassem (CORE_ADDR startAddr)
c906108c 146{
c774cec6 147 struct symtab *s = find_pc_symtab (startAddr);
c906108c 148 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
a4b99e53 149 TuiLineOrAddress val;
c906108c 150
a4b99e53 151 val.addr = startAddr;
c906108c 152 tuiAddWinToLayout (DISASSEM_WIN);
a4b99e53 153 tuiUpdateSourceWindow (disassemWin, s, val, FALSE);
c906108c 154 /*
c5aa993b
JM
155 ** if the focus was in the src win, put it in the asm win, if the
156 ** source view isn't split
157 */
c906108c
SS
158 if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin)
159 tuiSetWinFocusTo (disassemWin);
160
161 return;
162} /* tuiShowDisassem */
163
164
165/*
c5aa993b
JM
166 ** tuiShowDisassemAndUpdateSource().
167 ** Function to display the disassembly window.
168 */
c906108c 169void
c774cec6 170tuiShowDisassemAndUpdateSource (CORE_ADDR startAddr)
c906108c
SS
171{
172 struct symtab_and_line sal;
173
174 tuiShowDisassem (startAddr);
175 if (currentLayout () == SRC_DISASSEM_COMMAND)
176 {
a4b99e53 177 TuiLineOrAddress val;
c906108c
SS
178 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
179 /*
c5aa993b
JM
180 ** Update what is in the source window if it is displayed too,
181 ** note that it follows what is in the disassembly window and visa-versa
182 */
c774cec6 183 sal = find_pc_line (startAddr, 0);
a4b99e53
SC
184 val.lineNo = sal.line;
185 tuiUpdateSourceWindow (srcWin, sal.symtab, val, TRUE);
3024f13a
SC
186 if (sal.symtab)
187 {
188 current_source_symtab = sal.symtab;
189 tuiUpdateLocatorFilename (sal.symtab->filename);
190 }
191 else
192 tuiUpdateLocatorFilename ("?");
c906108c
SS
193 }
194
195 return;
196} /* tuiShowDisassemAndUpdateSource */
197
c906108c 198/*
c5aa993b
JM
199 ** tuiGetBeginAsmAddress().
200 */
c774cec6 201CORE_ADDR
c906108c 202tuiGetBeginAsmAddress (void)
c906108c
SS
203{
204 TuiGenWinInfoPtr locator;
205 TuiLocatorElementPtr element;
c774cec6 206 CORE_ADDR addr;
c906108c
SS
207
208 locator = locatorWinInfoPtr ();
209 element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
210
c774cec6 211 if (element->addr == 0)
c906108c 212 {
c5aa993b 213 /*the target is not executing, because the pc is 0 */
c906108c 214
c774cec6 215 addr = parse_and_eval_address ("main");
c906108c 216
c774cec6
SC
217 if (addr == 0)
218 addr = parse_and_eval_address ("MAIN");
c906108c
SS
219
220 }
221 else /* the target is executing */
222 addr = element->addr;
223
224 return addr;
225} /* tuiGetBeginAsmAddress */
226
227
228/*
c5aa993b
JM
229 ** tuiVerticalDisassemScroll().
230 ** Scroll the disassembly forward or backward vertically
231 */
c906108c 232void
eca6576c
SC
233tuiVerticalDisassemScroll (TuiScrollDirection scrollDirection,
234 int numToScroll)
c906108c
SS
235{
236 if (disassemWin->generic.content != (OpaquePtr) NULL)
237 {
3024f13a 238 CORE_ADDR pc, lowAddr;
c906108c
SS
239 TuiWinContent content;
240 struct symtab *s;
241
242 content = (TuiWinContent) disassemWin->generic.content;
243 if (current_source_symtab == (struct symtab *) NULL)
244 s = find_pc_symtab (selected_frame->pc);
245 else
246 s = current_source_symtab;
247
248 pc = content[0]->whichElement.source.lineOrAddr.addr;
3024f13a
SC
249 if (find_pc_partial_function (pc, (char **) NULL, &lowAddr,
250 (CORE_ADDR) 0) == 0)
251 error ("No function contains program counter for selected frame.\n");
c906108c
SS
252 else
253 {
254 register int line = 0;
3024f13a 255 register CORE_ADDR newLow;
c906108c 256 bfd_byte buffer[4];
a4b99e53 257 TuiLineOrAddress val;
c906108c
SS
258
259 newLow = pc;
260 if (scrollDirection == FORWARD_SCROLL)
261 {
262 for (; line < numToScroll; line++)
263 newLow += sizeof (bfd_getb32 (buffer));
264 }
265 else
266 {
a4b99e53 267 for (; newLow != 0 && line < numToScroll; line++)
c906108c
SS
268 newLow -= sizeof (bfd_getb32 (buffer));
269 }
a4b99e53
SC
270 val.addr = newLow;
271 tuiUpdateSourceWindowAsIs (disassemWin, s, val, FALSE);
c906108c
SS
272 }
273 }
274
275 return;
276} /* tuiVerticalDisassemScroll */
277
278
279
280/*****************************************
281** STATIC LOCAL FUNCTIONS **
282******************************************/
283/*
c5aa993b
JM
284 ** _hasBreak().
285 ** Answer whether there is a break point at the input line in the
286 ** source file indicated
287 */
c906108c 288static struct breakpoint *
eca6576c 289_hasBreak (CORE_ADDR addr)
c906108c
SS
290{
291 struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
292 struct breakpoint *bp;
293 extern struct breakpoint *breakpoint_chain;
294
295
296 for (bp = breakpoint_chain;
297 (bp != (struct breakpoint *) NULL &&
298 bpWithBreak == (struct breakpoint *) NULL);
299 bp = bp->next)
300 if (addr == bp->address)
301 bpWithBreak = bp;
302
303 return bpWithBreak;
304} /* _hasBreak */