* tuiData.h (TuiLocatorElement): Use CORE_ADDR for address member.
[deliverable/binutils-gdb.git] / gdb / tui / tuiDisassem.c
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. */
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"
29 #include "tuiWin.h"
30 #include "tuiLayout.h"
31 #include "tuiSourceWin.h"
32 #include "tuiStack.h"
33 #include "tui-file.h"
34
35
36 /*****************************************
37 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
38 ******************************************/
39
40 static struct breakpoint *_hasBreak (CORE_ADDR);
41
42
43 /*****************************************
44 ** PUBLIC FUNCTIONS **
45 ******************************************/
46
47 /*
48 ** tuiSetDisassemContent().
49 ** Function to set the disassembly window's content.
50 */
51 TuiStatus
52 tuiSetDisassemContent (struct symtab *s, CORE_ADDR startAddr)
53 {
54 TuiStatus ret = TUI_FAILURE;
55 struct ui_file *gdb_dis_out;
56
57 if (startAddr != 0)
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 ();
68 extern void strcat_address (CORE_ADDR, char *, int);
69 extern void strcat_address_numeric (CORE_ADDR, int, char *, int);
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
77 /* now init the ui_file structure */
78 gdb_dis_out = tui_sfileopen (threshold);
79
80 asmInfo = tm_print_insn_info;
81 asmInfo.stream = gdb_dis_out;
82
83 disassemWin->detail.sourceInfo.startLineOrAddr.addr = startAddr;
84
85 /* Now construct each line */
86 for (curLine = 0, pc = startAddr; (curLine < maxLines);)
87 {
88 TuiWinElementPtr element = (TuiWinElementPtr) disassemWin->generic.content[curLine];
89 struct breakpoint *bp;
90
91 print_address (pc, gdb_dis_out);
92
93 curLen = strlen (tui_file_get_strbuf (gdb_dis_out));
94 i = curLen - ((curLen / tab_len) * tab_len);
95
96 /* adjust buffer length if necessary */
97 tui_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i) : 0, gdb_dis_out);
98
99 /* Add spaces to make the instructions start onthe same column */
100 while (i < tab_len)
101 {
102 tui_file_get_strbuf (gdb_dis_out)[curLen] = ' ';
103 i++;
104 curLen++;
105 }
106 tui_file_get_strbuf (gdb_dis_out)[curLen] = '\0';
107
108 newpc = pc + ((*tm_print_insn) (pc, &asmInfo));
109
110 /* Now copy the line taking the offset into account */
111 if (strlen (tui_file_get_strbuf (gdb_dis_out)) > offset)
112 strcpy (element->whichElement.source.line,
113 &(tui_file_get_strbuf (gdb_dis_out)[offset]));
114 else
115 element->whichElement.source.line[0] = '\0';
116 element->whichElement.source.lineOrAddr.addr = (Opaque) pc;
117 element->whichElement.source.isExecPoint =
118 (pc == (CORE_ADDR) ((TuiWinElementPtr) locator->content[0])->whichElement.locator.addr);
119 bp = _hasBreak (pc);
120 element->whichElement.source.hasBreak =
121 (bp != (struct breakpoint *) NULL &&
122 (!element->whichElement.source.isExecPoint ||
123 (bp->disposition != del || bp->hit_count <= 0)));
124 curLine++;
125 pc = newpc;
126 /* reset the buffer to empty */
127 tui_file_get_strbuf (gdb_dis_out)[0] = '\0';
128 }
129 ui_file_delete (gdb_dis_out);
130 gdb_dis_out = NULL;
131 disassemWin->generic.contentSize = curLine;
132 ret = TUI_SUCCESS;
133 }
134 }
135
136 return ret;
137 } /* tuiSetDisassemContent */
138
139
140 /*
141 ** tuiShowDisassem().
142 ** Function to display the disassembly window with disassembled code.
143 */
144 void
145 tuiShowDisassem (CORE_ADDR startAddr)
146 {
147 struct symtab *s = find_pc_symtab (startAddr);
148 TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
149
150 tuiAddWinToLayout (DISASSEM_WIN);
151 tuiUpdateSourceWindow (disassemWin, s, startAddr, FALSE);
152 /*
153 ** if the focus was in the src win, put it in the asm win, if the
154 ** source view isn't split
155 */
156 if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin)
157 tuiSetWinFocusTo (disassemWin);
158
159 return;
160 } /* tuiShowDisassem */
161
162
163 /*
164 ** tuiShowDisassemAndUpdateSource().
165 ** Function to display the disassembly window.
166 */
167 void
168 tuiShowDisassemAndUpdateSource (CORE_ADDR startAddr)
169 {
170 struct symtab_and_line sal;
171
172 tuiShowDisassem (startAddr);
173 if (currentLayout () == SRC_DISASSEM_COMMAND)
174 {
175 TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
176 /*
177 ** Update what is in the source window if it is displayed too,
178 ** note that it follows what is in the disassembly window and visa-versa
179 */
180 sal = find_pc_line (startAddr, 0);
181 current_source_symtab = sal.symtab;
182 tuiUpdateSourceWindow (srcWin, sal.symtab, (Opaque) sal.line, TRUE);
183 tuiUpdateLocatorFilename (sal.symtab->filename);
184 }
185
186 return;
187 } /* tuiShowDisassemAndUpdateSource */
188
189
190 /*
191 ** tuiShowDisassemAsIs().
192 ** Function to display the disassembly window. This function shows
193 ** the disassembly as specified by the horizontal offset.
194 */
195 void
196 tuiShowDisassemAsIs (Opaque addr)
197 {
198 tuiAddWinToLayout (DISASSEM_WIN);
199 tuiUpdateSourceWindowAsIs (disassemWin, (struct symtab *) NULL, addr, FALSE);
200 /*
201 ** Update what is in the source window if it is displayed too, not that it
202 ** follows what is in the disassembly window and visa-versa
203 */
204 if (currentLayout () == SRC_DISASSEM_COMMAND)
205 tuiShowSourceContent (srcWin); /*???? Need to do more? */
206
207 return;
208 } /* tuiShowDisassem */
209
210
211 /*
212 ** tuiGetBeginAsmAddress().
213 */
214 CORE_ADDR
215 tuiGetBeginAsmAddress (void)
216 {
217 TuiGenWinInfoPtr locator;
218 TuiLocatorElementPtr element;
219 CORE_ADDR addr;
220
221 locator = locatorWinInfoPtr ();
222 element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
223
224 if (element->addr == 0)
225 {
226 /*the target is not executing, because the pc is 0 */
227
228 addr = parse_and_eval_address ("main");
229
230 if (addr == 0)
231 addr = parse_and_eval_address ("MAIN");
232
233 }
234 else /* the target is executing */
235 addr = element->addr;
236
237 return addr;
238 } /* tuiGetBeginAsmAddress */
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 Opaque 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 ((CORE_ADDR) pc,
263 (char **) NULL,
264 (CORE_ADDR *) & lowAddr,
265 (CORE_ADDR) NULL) == 0)
266 error ("No function contains prgram counter for selected frame.\n");
267 else
268 {
269 register int line = 0;
270 register Opaque newLow;
271 bfd_byte buffer[4];
272
273 newLow = pc;
274 if (scrollDirection == FORWARD_SCROLL)
275 {
276 for (; line < numToScroll; line++)
277 newLow += sizeof (bfd_getb32 (buffer));
278 }
279 else
280 {
281 for (; newLow >= (Opaque) 0 && line < numToScroll; line++)
282 newLow -= sizeof (bfd_getb32 (buffer));
283 }
284 tuiUpdateSourceWindowAsIs (disassemWin, s, newLow, FALSE);
285 }
286 }
287
288 return;
289 } /* tuiVerticalDisassemScroll */
290
291
292
293 /*****************************************
294 ** STATIC LOCAL FUNCTIONS **
295 ******************************************/
296 /*
297 ** _hasBreak().
298 ** Answer whether there is a break point at the input line in the
299 ** source file indicated
300 */
301 static struct breakpoint *
302 _hasBreak (CORE_ADDR addr)
303 {
304 struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
305 struct breakpoint *bp;
306 extern struct breakpoint *breakpoint_chain;
307
308
309 for (bp = breakpoint_chain;
310 (bp != (struct breakpoint *) NULL &&
311 bpWithBreak == (struct breakpoint *) NULL);
312 bp = bp->next)
313 if (addr == bp->address)
314 bpWithBreak = bp;
315
316 return bpWithBreak;
317 } /* _hasBreak */
This page took 0.036618 seconds and 4 git commands to generate.