Implement CLOCK_MONOTONIC using getnanouptime(), which in DragonFly is
[dragonfly.git] / contrib / gdb / gdb / tui / tuiDisassem.c
1 /*
2 ** tuiDisassem.c
3 **         This module contains functions for handling disassembly display.
4 */
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 /*
31 ** tuiSetDisassemContent().
32 **        Function to set the disassembly window's content.
33 */
34 TuiStatus
35 #ifdef __STDC__
36 tuiSetDisassemContent (
37                        struct symtab *s,
38                        Opaque startAddr)
39 #else
40      tuiSetDisassemContent (s, startAddr)
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 */
69           gdb_dis_out = gdb_file_init_astring (threshold);
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             {
80               TuiWinElementPtr element = (TuiWinElementPtr)disassemWin->generic.content[curLine];
81               struct breakpoint *bp;
82
83               print_address (pc, gdb_dis_out);
84
85               curLen = strlen (gdb_file_get_strbuf (gdb_dis_out));
86               i = curLen - ((curLen / tab_len) * tab_len);
87
88               /* adjust buffer length if necessary */
89               gdb_file_adjust_strbuf ((tab_len - i > 0) ? (tab_len - i ) : 0, gdb_dis_out);
90                 
91               /* Add spaces to make the instructions start onthe same column */
92               while (i < tab_len)
93                 {
94                   gdb_file_get_strbuf (gdb_dis_out)[curLen] = ' ';
95                   i++;
96                   curLen++;
97                 }
98               gdb_file_get_strbuf (gdb_dis_out)[curLen] = '\0';
99
100               newpc = pc + ((*tm_print_insn) (pc, &asmInfo));
101
102               /* Now copy the line taking the offset into account */
103               if (strlen (gdb_file_get_strbuf (gdb_dis_out)) > offset)
104                 strcpy (element->whichElement.source.line,
105                         &(gdb_file_get_strbuf (gdb_dis_out)[offset]));
106               else
107                 element->whichElement.source.line[0] = '\0';
108               element->whichElement.source.lineOrAddr.addr = (Opaque) pc;
109               element->whichElement.source.isExecPoint =
110                 (pc == (CORE_ADDR) ((TuiWinElementPtr)locator->content[0])->whichElement.locator.addr);
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;
118               /* reset the buffer to empty */
119               gdb_file_get_strbuf (gdb_dis_out)[0] = '\0';
120             }
121           gdb_file_deallocate (&gdb_dis_out);
122           disassemWin->generic.contentSize = curLine;
123           ret = TUI_SUCCESS;
124         }
125     }
126
127   return ret;
128 }                               /* tuiSetDisassemContent */
129
130
131 /*
132 ** tuiShowDisassem().
133 **        Function to display the disassembly window with disassembled code.
134 */
135 void
136 #ifdef __STDC__
137 tuiShowDisassem (
138                   Opaque startAddr)
139 #else
140 tuiShowDisassem (startAddr)
141      Opaque startAddr;
142 #endif
143 {
144   struct symtab *s = find_pc_symtab ((CORE_ADDR) startAddr);
145   TuiWinInfoPtr winWithFocus = tuiWinWithFocus ();
146
147   tuiAddWinToLayout (DISASSEM_WIN);
148   tuiUpdateSourceWindow (disassemWin, s, startAddr, FALSE);
149   /*
150     ** if the focus was in the src win, put it in the asm win, if the
151     ** source view isn't split
152     */
153   if (currentLayout () != SRC_DISASSEM_COMMAND && winWithFocus == srcWin)
154     tuiSetWinFocusTo (disassemWin);
155
156   return;
157 }                               /* tuiShowDisassem */
158
159
160 /*
161 ** tuiShowDisassemAndUpdateSource().
162 **        Function to display the disassembly window.
163 */
164 void
165 #ifdef __STDC__
166 tuiShowDisassemAndUpdateSource (
167                                  Opaque startAddr)
168 #else
169 tuiShowDisassemAndUpdateSource (startAddr)
170      Opaque startAddr;
171 #endif
172 {
173   struct symtab_and_line sal;
174
175   tuiShowDisassem (startAddr);
176   if (currentLayout () == SRC_DISASSEM_COMMAND)
177     {
178       TuiGenWinInfoPtr locator = locatorWinInfoPtr ();
179       /*
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         */
183       sal = find_pc_line ((CORE_ADDR) startAddr, 0);
184       current_source_symtab = sal.symtab;
185       tuiUpdateSourceWindow (srcWin, sal.symtab, (Opaque) sal.line, TRUE);
186       tuiUpdateLocatorFilename (sal.symtab->filename);
187     }
188
189   return;
190 }                               /* tuiShowDisassemAndUpdateSource */
191
192
193 /*
194 ** tuiShowDisassemAsIs().
195 **        Function to display the disassembly window.  This function shows
196 **        the disassembly as specified by the horizontal offset.
197 */
198 void
199 #ifdef __STDC__
200 tuiShowDisassemAsIs (
201                       Opaque addr)
202 #else
203 tuiShowDisassemAsIs (addr)
204      Opaque addr;
205 #endif
206 {
207   tuiAddWinToLayout (DISASSEM_WIN);
208   tuiUpdateSourceWindowAsIs (disassemWin, (struct symtab *) NULL, addr, FALSE);
209   /*
210     ** Update what is in the source window if it is displayed too, not that it
211     ** follows what is in the disassembly window and visa-versa
212     */
213   if (currentLayout () == SRC_DISASSEM_COMMAND)
214     tuiShowSourceContent (srcWin);      /*????  Need to do more? */
215
216   return;
217 }                               /* tuiShowDisassem */
218
219
220 /*
221 ** tuiGetBeginAsmAddress().
222 */
223 Opaque
224 #ifdef __STDC__
225 tuiGetBeginAsmAddress (void)
226 #else
227 tuiGetBeginAsmAddress ()
228 #endif
229 {
230   TuiGenWinInfoPtr locator;
231   TuiLocatorElementPtr element;
232   Opaque addr;
233
234   locator = locatorWinInfoPtr ();
235   element = &((TuiWinElementPtr) locator->content[0])->whichElement.locator;
236
237   if (element->addr == (Opaque) 0)
238     {
239       /*the target is not executing, because the pc is 0*/
240
241       addr = (Opaque) parse_and_eval_address ("main");
242
243       if (addr == (Opaque) 0)
244         addr = (Opaque) parse_and_eval_address ("MAIN");
245
246     }
247   else                          /* the target is executing */
248     addr = element->addr;
249
250   return addr;
251 }                               /* tuiGetBeginAsmAddress */
252
253
254 /*
255 ** tuiVerticalDisassemScroll().
256 **      Scroll the disassembly forward or backward vertically
257 */
258 void
259 #ifdef __STDC__
260 tuiVerticalDisassemScroll (
261                             TuiScrollDirection scrollDirection,
262                             int numToScroll)
263 #else
264 tuiVerticalDisassemScroll (scrollDirection, numToScroll)
265      TuiScrollDirection scrollDirection;
266      int numToScroll;
267 #endif
268 {
269   if (disassemWin->generic.content != (OpaquePtr) NULL)
270     {
271       Opaque pc, lowAddr;
272       TuiWinContent content;
273       struct symtab *s;
274
275       content = (TuiWinContent) disassemWin->generic.content;
276       if (current_source_symtab == (struct symtab *) NULL)
277         s = find_pc_symtab (selected_frame->pc);
278       else
279         s = current_source_symtab;
280
281       pc = content[0]->whichElement.source.lineOrAddr.addr;
282       if (find_pc_partial_function ((CORE_ADDR) pc,
283                                     (char **) NULL,
284                                     (CORE_ADDR *) & lowAddr,
285                                     (CORE_ADDR) NULL) == 0)
286         error ("No function contains prgram counter for selected frame.\n");
287       else
288         {
289           register int line = 0;
290           register Opaque newLow;
291           bfd_byte buffer[4];
292
293           newLow = pc;
294           if (scrollDirection == FORWARD_SCROLL)
295             {
296               for (; line < numToScroll; line++)
297                 newLow += sizeof (bfd_getb32 (buffer));
298             }
299           else
300             {
301               for (; newLow >= (Opaque) 0 && line < numToScroll; line++)
302                 newLow -= sizeof (bfd_getb32 (buffer));
303             }
304           tuiUpdateSourceWindowAsIs (disassemWin, s, newLow, FALSE);
305         }
306     }
307
308   return;
309 }                               /* tuiVerticalDisassemScroll */
310
311
312
313 /*****************************************
314 ** STATIC LOCAL FUNCTIONS                 **
315 ******************************************/
316 /*
317 ** _hasBreak().
318 **      Answer whether there is a break point at the input line in the
319 **      source file indicated
320 */
321 static struct breakpoint *
322 #ifdef __STDC__
323 _hasBreak (
324             CORE_ADDR addr)
325 #else
326 _hasBreak (addr)
327      CORE_ADDR addr;
328 #endif
329 {
330   struct breakpoint *bpWithBreak = (struct breakpoint *) NULL;
331   struct breakpoint *bp;
332   extern struct breakpoint *breakpoint_chain;
333
334
335   for (bp = breakpoint_chain;
336        (bp != (struct breakpoint *) NULL &&
337         bpWithBreak == (struct breakpoint *) NULL);
338        bp = bp->next)
339     if (addr == bp->address)
340       bpWithBreak = bp;
341
342   return bpWithBreak;
343 }                               /* _hasBreak */