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