* tuiIO.c (CTRL_CHAR): Redefine and use readline 4.3 definition.
[deliverable/binutils-gdb.git] / gdb / tui / tuiDisassem.c
1 /* Disassembly display.
2
3 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
4 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 2 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, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA. */
24
25 /* FIXME: cagney/2002-02-28: The GDB coding standard indicates that
26 "defs.h" should be included first. Unfortunatly some systems
27 (currently Debian GNU/Linux) include the <stdbool.h> via <curses.h>
28 and they clash with "bfd.h"'s definiton of true/false. The correct
29 fix is to remove true/false from "bfd.h", however, until that
30 happens, hack around it by including "config.h" and <curses.h>
31 first. */
32
33 #include "config.h"
34 #ifdef HAVE_NCURSES_H
35 #include <ncurses.h>
36 #else
37 #ifdef HAVE_CURSES_H
38 #include <curses.h>
39 #endif
40 #endif
41
42 #include "defs.h"
43 #include "symtab.h"
44 #include "breakpoint.h"
45 #include "frame.h"
46 #include "value.h"
47
48 #include "tui.h"
49 #include "tuiData.h"
50 #include "tuiWin.h"
51 #include "tuiLayout.h"
52 #include "tuiSourceWin.h"
53 #include "tuiStack.h"
54 #include "tui-file.h"
55
56
57 /*
58 ** tuiSetDisassemContent().
59 ** Function to set the disassembly window's content.
60 */
61 TuiStatus
62 tuiSetDisassemContent (struct symtab *s, CORE_ADDR startAddr)
63 {
64 TuiStatus ret = TUI_FAILURE;
65 struct ui_file *gdb_dis_out;
66
67 if (startAddr != 0)
68 {
69 register int i, desc;
70
71 if ((ret = tuiAllocSourceBuffer (disassemWin)) == TUI_SUCCESS)
72 {
73 register int offset = disassemWin->detail.sourceInfo.horizontalOffset;
74 register int threshold, curLine = 0, lineWidth, maxLines;
75 CORE_ADDR newpc, pc;
76 disassemble_info asmInfo;
77 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
78 extern void strcat_address (CORE_ADDR, char *, int);
79 extern void strcat_address_numeric (CORE_ADDR, int, char *, int);
80 int curLen = 0;
81 int tab_len = tuiDefaultTabLen ();
82
83 maxLines = disassemWin->generic.height - 2; /* account for hilite */
84 lineWidth = disassemWin->generic.width - 1;
85 threshold = (lineWidth - 1) + offset;
86
87 /* now init the ui_file structure */
88 gdb_dis_out = tui_sfileopen (threshold);
89
90 asmInfo = tm_print_insn_info;
91 asmInfo.stream = gdb_dis_out;
92
93 disassemWin->detail.sourceInfo.startLineOrAddr.addr = startAddr;
94
95 /* Now construct each line */
96 for (curLine = 0, pc = startAddr; (curLine < maxLines);)
97 {
98 TuiWinElementPtr element = (TuiWinElementPtr) disassemWin->generic.content[curLine];
99
100 print_address (pc, gdb_dis_out);
101
102 curLen = strlen (tui_file_get_strbuf (gdb_dis_out));
103 i = curLen - ((curLen / tab_len) * tab_len);
104
105 /* adjust buffer length if necessary */
106 tui_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i) : 0, gdb_dis_out);
107
108 /* Add spaces to make the instructions start onthe same column */
109 while (i < tab_len)
110 {
111 tui_file_get_strbuf (gdb_dis_out)[curLen] = ' ';
112 i++;
113 curLen++;
114 }
115 tui_file_get_strbuf (gdb_dis_out)[curLen] = '\0';
116
117 newpc = pc + ((*tm_print_insn) (pc, &asmInfo));
118
119 /* Now copy the line taking the offset into account */
120 if (strlen (tui_file_get_strbuf (gdb_dis_out)) > offset)
121 strcpy (element->whichElement.source.line,
122 &(tui_file_get_strbuf (gdb_dis_out)[offset]));
123 else
124 element->whichElement.source.line[0] = '\0';
125 element->whichElement.source.lineOrAddr.addr = pc;
126 element->whichElement.source.isExecPoint =
127 (pc == (CORE_ADDR) ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr);
128 element->whichElement.source.hasBreak =
129 (breakpoint_here_p (pc) != no_breakpoint_here
130 && !element->whichElement.source.isExecPoint);
131 curLine++;
132 pc = newpc;
133 /* reset the buffer to empty */
134 tui_file_get_strbuf (gdb_dis_out)[0] = '\0';
135 }
136 ui_file_delete (gdb_dis_out);
137 gdb_dis_out = NULL;
138 disassemWin->generic.contentSize = curLine;
139 ret = TUI_SUCCESS;
140 }
141 }
142
143 return ret;
144 } /* tuiSetDisassemContent */
145
146
147 /*
148 ** tuiShowDisassem().
149 ** Function to display the disassembly window with disassembled code.
150 */
151 void
152 tuiShowDisassem (CORE_ADDR startAddr)
153 {
154 struct symtab *s = find_pc_symtab (startAddr);
155 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
156 TuiLineOrAddress val;
157
158 val.addr = startAddr;
159 tuiAddWinToLayout (DISASSEM_WIN);
160 tuiUpdateSourceWindow (disassemWin, s, val, FALSE);
161 /*
162 ** if the focus was in the src win, put it in the asm win, if the
163 ** source view isn't split
164 */
165 if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin)
166 tuiSetWinFocusTo (disassemWin);
167
168 return;
169 } /* tuiShowDisassem */
170
171
172 /*
173 ** tuiShowDisassemAndUpdateSource().
174 ** Function to display the disassembly window.
175 */
176 void
177 tuiShowDisassemAndUpdateSource (CORE_ADDR startAddr)
178 {
179 struct symtab_and_line sal;
180
181 tuiShowDisassem (startAddr);
182 if (currentLayout () == SRC_DISASSEM_COMMAND)
183 {
184 TuiLineOrAddress val;
185 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
186 /*
187 ** Update what is in the source window if it is displayed too,
188 ** note that it follows what is in the disassembly window and visa-versa
189 */
190 sal = find_pc_line (startAddr, 0);
191 val.lineNo = sal.line;
192 tuiUpdateSourceWindow (srcWin, sal.symtab, val, TRUE);
193 if (sal.symtab)
194 {
195 current_source_symtab = sal.symtab;
196 tuiUpdateLocatorFilename (sal.symtab->filename);
197 }
198 else
199 tuiUpdateLocatorFilename ("?");
200 }
201
202 return;
203 } /* tuiShowDisassemAndUpdateSource */
204
205 /*
206 ** tuiGetBeginAsmAddress().
207 */
208 CORE_ADDR
209 tuiGetBeginAsmAddress (void)
210 {
211 TuiGenWinInfoPtr locator;
212 TuiLocatorElementPtr element;
213 CORE_ADDR addr;
214
215 locator = locatorWinInfoPtr ();
216 element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
217
218 if (element->addr == 0)
219 {
220 struct minimal_symbol *main_symbol;
221
222 /* Find address of the start of program.
223 Note: this should be language specific. */
224 main_symbol = lookup_minimal_symbol ("main", NULL, NULL);
225 if (main_symbol == 0)
226 main_symbol = lookup_minimal_symbol ("MAIN", NULL, NULL);
227 if (main_symbol == 0)
228 main_symbol = lookup_minimal_symbol ("_start", NULL, NULL);
229 if (main_symbol)
230 addr = SYMBOL_VALUE_ADDRESS (main_symbol);
231 else
232 addr = 0;
233 }
234 else /* the target is executing */
235 addr = element->addr;
236
237 return addr;
238 }
239
240
241 /*
242 ** tuiVerticalDisassemScroll().
243 ** Scroll the disassembly forward or backward vertically
244 */
245 void
246 tuiVerticalDisassemScroll (TuiScrollDirection scrollDirection,
247 int numToScroll)
248 {
249 if (disassemWin->generic.content != (OpaquePtr) NULL)
250 {
251 CORE_ADDR pc, lowAddr;
252 TuiWinContent content;
253 struct symtab *s;
254
255 content = (TuiWinContent) disassemWin->generic.content;
256 if (current_source_symtab == (struct symtab *) NULL)
257 s = find_pc_symtab (selected_frame->pc);
258 else
259 s = current_source_symtab;
260
261 pc = content[0]->whichElement.source.lineOrAddr.addr;
262 if (find_pc_partial_function (pc, (char **) NULL, &lowAddr,
263 (CORE_ADDR) 0) == 0)
264 error ("No function contains program counter for selected frame.\n");
265 else
266 {
267 register int line = 0;
268 register CORE_ADDR newLow;
269 bfd_byte buffer[4];
270 TuiLineOrAddress val;
271
272 newLow = pc;
273 if (scrollDirection == FORWARD_SCROLL)
274 {
275 for (; line < numToScroll; line++)
276 newLow += sizeof (bfd_getb32 (buffer));
277 }
278 else
279 {
280 for (; newLow != 0 && line < numToScroll; line++)
281 newLow -= sizeof (bfd_getb32 (buffer));
282 }
283 val.addr = newLow;
284 tuiUpdateSourceWindowAsIs (disassemWin, s, val, FALSE);
285 }
286 }
287
288 return;
289 } /* tuiVerticalDisassemScroll */
This page took 0.035453 seconds and 4 git commands to generate.