1 /* Disassembly display.
3 Copyright 1998, 1999, 2000, 2001, 2002 Free Software Foundation,
6 Contributed by Hewlett-Packard Company.
8 This file is part of GDB.
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.
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.
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. */
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>
44 #include "breakpoint.h"
51 #include "tuiLayout.h"
52 #include "tuiSourceWin.h"
58 ** tuiSetDisassemContent().
59 ** Function to set the disassembly window's content.
62 tuiSetDisassemContent (struct symtab
*s
, CORE_ADDR startAddr
)
64 TuiStatus ret
= TUI_FAILURE
;
65 struct ui_file
*gdb_dis_out
;
71 if ((ret
= tuiAllocSourceBuffer (disassemWin
)) == TUI_SUCCESS
)
73 register int offset
= disassemWin
->detail
.sourceInfo
.horizontalOffset
;
74 register int threshold
, curLine
= 0, lineWidth
, maxLines
;
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);
81 int tab_len
= tuiDefaultTabLen ();
83 maxLines
= disassemWin
->generic
.height
- 2; /* account for hilite */
84 lineWidth
= disassemWin
->generic
.width
- 1;
85 threshold
= (lineWidth
- 1) + offset
;
87 /* now init the ui_file structure */
88 gdb_dis_out
= tui_sfileopen (threshold
);
90 asmInfo
= tm_print_insn_info
;
91 asmInfo
.stream
= gdb_dis_out
;
93 disassemWin
->detail
.sourceInfo
.startLineOrAddr
.addr
= startAddr
;
95 /* Now construct each line */
96 for (curLine
= 0, pc
= startAddr
; (curLine
< maxLines
);)
98 TuiWinElementPtr element
= (TuiWinElementPtr
) disassemWin
->generic
.content
[curLine
];
100 print_address (pc
, gdb_dis_out
);
102 curLen
= strlen (tui_file_get_strbuf (gdb_dis_out
));
103 i
= curLen
- ((curLen
/ tab_len
) * tab_len
);
105 /* adjust buffer length if necessary */
106 tui_file_adjust_strbuf ((tab_len
- i
> 0) ? (tab_len
- i
) : 0, gdb_dis_out
);
108 /* Add spaces to make the instructions start onthe same column */
111 tui_file_get_strbuf (gdb_dis_out
)[curLen
] = ' ';
115 tui_file_get_strbuf (gdb_dis_out
)[curLen
] = '\0';
117 newpc
= pc
+ ((*tm_print_insn
) (pc
, &asmInfo
));
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
]));
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
);
133 /* reset the buffer to empty */
134 tui_file_get_strbuf (gdb_dis_out
)[0] = '\0';
136 ui_file_delete (gdb_dis_out
);
138 disassemWin
->generic
.contentSize
= curLine
;
144 } /* tuiSetDisassemContent */
148 ** tuiShowDisassem().
149 ** Function to display the disassembly window with disassembled code.
152 tuiShowDisassem (CORE_ADDR startAddr
)
154 struct symtab
*s
= find_pc_symtab (startAddr
);
155 TuiWinInfoPtr winWithFocus
= tuiWinWithFocus ();
156 TuiLineOrAddress val
;
158 val
.addr
= startAddr
;
159 tuiAddWinToLayout (DISASSEM_WIN
);
160 tuiUpdateSourceWindow (disassemWin
, s
, val
, FALSE
);
162 ** if the focus was in the src win, put it in the asm win, if the
163 ** source view isn't split
165 if (currentLayout () != SRC_DISASSEM_COMMAND
&& winWithFocus
== srcWin
)
166 tuiSetWinFocusTo (disassemWin
);
169 } /* tuiShowDisassem */
173 ** tuiShowDisassemAndUpdateSource().
174 ** Function to display the disassembly window.
177 tuiShowDisassemAndUpdateSource (CORE_ADDR startAddr
)
179 struct symtab_and_line sal
;
181 tuiShowDisassem (startAddr
);
182 if (currentLayout () == SRC_DISASSEM_COMMAND
)
184 TuiLineOrAddress val
;
185 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
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
190 sal
= find_pc_line (startAddr
, 0);
191 val
.lineNo
= sal
.line
;
192 tuiUpdateSourceWindow (srcWin
, sal
.symtab
, val
, TRUE
);
195 current_source_symtab
= sal
.symtab
;
196 tuiUpdateLocatorFilename (sal
.symtab
->filename
);
199 tuiUpdateLocatorFilename ("?");
203 } /* tuiShowDisassemAndUpdateSource */
206 ** tuiGetBeginAsmAddress().
209 tuiGetBeginAsmAddress (void)
211 TuiGenWinInfoPtr locator
;
212 TuiLocatorElementPtr element
;
215 locator
= locatorWinInfoPtr ();
216 element
= &((TuiWinElementPtr
) locator
->content
[0])->whichElement
.locator
;
218 if (element
->addr
== 0)
220 struct minimal_symbol
*main_symbol
;
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
);
230 addr
= SYMBOL_VALUE_ADDRESS (main_symbol
);
234 else /* the target is executing */
235 addr
= element
->addr
;
242 ** tuiVerticalDisassemScroll().
243 ** Scroll the disassembly forward or backward vertically
246 tuiVerticalDisassemScroll (TuiScrollDirection scrollDirection
,
249 if (disassemWin
->generic
.content
!= (OpaquePtr
) NULL
)
251 CORE_ADDR pc
, lowAddr
;
252 TuiWinContent content
;
255 content
= (TuiWinContent
) disassemWin
->generic
.content
;
256 if (current_source_symtab
== (struct symtab
*) NULL
)
257 s
= find_pc_symtab (selected_frame
->pc
);
259 s
= current_source_symtab
;
261 pc
= content
[0]->whichElement
.source
.lineOrAddr
.addr
;
262 if (find_pc_partial_function (pc
, (char **) NULL
, &lowAddr
,
264 error ("No function contains program counter for selected frame.\n");
267 register int line
= 0;
268 register CORE_ADDR newLow
;
270 TuiLineOrAddress val
;
273 if (scrollDirection
== FORWARD_SCROLL
)
275 for (; line
< numToScroll
; line
++)
276 newLow
+= sizeof (bfd_getb32 (buffer
));
280 for (; newLow
!= 0 && line
< numToScroll
; line
++)
281 newLow
-= sizeof (bfd_getb32 (buffer
));
284 tuiUpdateSourceWindowAsIs (disassemWin
, s
, val
, FALSE
);
289 } /* tuiVerticalDisassemScroll */