1 /* Disassembly display.
2 Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
3 Contributed by Hewlett-Packard Company.
5 This file is part of GDB.
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.
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.
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. */
24 #include "breakpoint.h"
30 #include "tuiLayout.h"
31 #include "tuiSourceWin.h"
36 /*****************************************
37 ** STATIC LOCAL FUNCTIONS FORWARD DECLS **
38 ******************************************/
40 static struct breakpoint
*_hasBreak (CORE_ADDR
);
43 /*****************************************
44 ** PUBLIC FUNCTIONS **
45 ******************************************/
48 ** tuiSetDisassemContent().
49 ** Function to set the disassembly window's content.
52 tuiSetDisassemContent (struct symtab
*s
, CORE_ADDR startAddr
)
54 TuiStatus ret
= TUI_FAILURE
;
55 struct ui_file
*gdb_dis_out
;
61 if ((ret
= tuiAllocSourceBuffer (disassemWin
)) == TUI_SUCCESS
)
63 register int offset
= disassemWin
->detail
.sourceInfo
.horizontalOffset
;
64 register int threshold
, curLine
= 0, lineWidth
, maxLines
;
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);
71 int tab_len
= tuiDefaultTabLen ();
73 maxLines
= disassemWin
->generic
.height
- 2; /* account for hilite */
74 lineWidth
= disassemWin
->generic
.width
- 1;
75 threshold
= (lineWidth
- 1) + offset
;
77 /* now init the ui_file structure */
78 gdb_dis_out
= tui_sfileopen (threshold
);
80 asmInfo
= tm_print_insn_info
;
81 asmInfo
.stream
= gdb_dis_out
;
83 disassemWin
->detail
.sourceInfo
.startLineOrAddr
.addr
= startAddr
;
85 /* Now construct each line */
86 for (curLine
= 0, pc
= startAddr
; (curLine
< maxLines
);)
88 TuiWinElementPtr element
= (TuiWinElementPtr
) disassemWin
->generic
.content
[curLine
];
89 struct breakpoint
*bp
;
91 print_address (pc
, gdb_dis_out
);
93 curLen
= strlen (tui_file_get_strbuf (gdb_dis_out
));
94 i
= curLen
- ((curLen
/ tab_len
) * tab_len
);
96 /* adjust buffer length if necessary */
97 tui_file_adjust_strbuf ((tab_len
- i
> 0) ? (tab_len
- i
) : 0, gdb_dis_out
);
99 /* Add spaces to make the instructions start onthe same column */
102 tui_file_get_strbuf (gdb_dis_out
)[curLen
] = ' ';
106 tui_file_get_strbuf (gdb_dis_out
)[curLen
] = '\0';
108 newpc
= pc
+ ((*tm_print_insn
) (pc
, &asmInfo
));
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
]));
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
);
120 element
->whichElement
.source
.hasBreak
=
121 (bp
!= (struct breakpoint
*) NULL
&&
122 (!element
->whichElement
.source
.isExecPoint
||
123 (bp
->disposition
!= del
|| bp
->hit_count
<= 0)));
126 /* reset the buffer to empty */
127 tui_file_get_strbuf (gdb_dis_out
)[0] = '\0';
129 ui_file_delete (gdb_dis_out
);
131 disassemWin
->generic
.contentSize
= curLine
;
137 } /* tuiSetDisassemContent */
141 ** tuiShowDisassem().
142 ** Function to display the disassembly window with disassembled code.
145 tuiShowDisassem (CORE_ADDR startAddr
)
147 struct symtab
*s
= find_pc_symtab (startAddr
);
148 TuiWinInfoPtr winWithFocus
= tuiWinWithFocus ();
150 tuiAddWinToLayout (DISASSEM_WIN
);
151 tuiUpdateSourceWindow (disassemWin
, s
, startAddr
, FALSE
);
153 ** if the focus was in the src win, put it in the asm win, if the
154 ** source view isn't split
156 if (currentLayout () != SRC_DISASSEM_COMMAND
&& winWithFocus
== srcWin
)
157 tuiSetWinFocusTo (disassemWin
);
160 } /* tuiShowDisassem */
164 ** tuiShowDisassemAndUpdateSource().
165 ** Function to display the disassembly window.
168 tuiShowDisassemAndUpdateSource (CORE_ADDR startAddr
)
170 struct symtab_and_line sal
;
172 tuiShowDisassem (startAddr
);
173 if (currentLayout () == SRC_DISASSEM_COMMAND
)
175 TuiGenWinInfoPtr locator
= locatorWinInfoPtr ();
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
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
);
187 } /* tuiShowDisassemAndUpdateSource */
191 ** tuiShowDisassemAsIs().
192 ** Function to display the disassembly window. This function shows
193 ** the disassembly as specified by the horizontal offset.
196 tuiShowDisassemAsIs (Opaque addr
)
198 tuiAddWinToLayout (DISASSEM_WIN
);
199 tuiUpdateSourceWindowAsIs (disassemWin
, (struct symtab
*) NULL
, addr
, FALSE
);
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
204 if (currentLayout () == SRC_DISASSEM_COMMAND
)
205 tuiShowSourceContent (srcWin
); /*???? Need to do more? */
208 } /* tuiShowDisassem */
212 ** tuiGetBeginAsmAddress().
215 tuiGetBeginAsmAddress (void)
217 TuiGenWinInfoPtr locator
;
218 TuiLocatorElementPtr element
;
221 locator
= locatorWinInfoPtr ();
222 element
= &((TuiWinElementPtr
) locator
->content
[0])->whichElement
.locator
;
224 if (element
->addr
== 0)
226 /*the target is not executing, because the pc is 0 */
228 addr
= parse_and_eval_address ("main");
231 addr
= parse_and_eval_address ("MAIN");
234 else /* the target is executing */
235 addr
= element
->addr
;
238 } /* tuiGetBeginAsmAddress */
242 ** tuiVerticalDisassemScroll().
243 ** Scroll the disassembly forward or backward vertically
246 tuiVerticalDisassemScroll (TuiScrollDirection scrollDirection
,
249 if (disassemWin
->generic
.content
!= (OpaquePtr
) NULL
)
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 ((CORE_ADDR
) pc
,
264 (CORE_ADDR
*) & lowAddr
,
265 (CORE_ADDR
) NULL
) == 0)
266 error ("No function contains prgram counter for selected frame.\n");
269 register int line
= 0;
270 register Opaque newLow
;
274 if (scrollDirection
== FORWARD_SCROLL
)
276 for (; line
< numToScroll
; line
++)
277 newLow
+= sizeof (bfd_getb32 (buffer
));
281 for (; newLow
>= (Opaque
) 0 && line
< numToScroll
; line
++)
282 newLow
-= sizeof (bfd_getb32 (buffer
));
284 tuiUpdateSourceWindowAsIs (disassemWin
, s
, newLow
, FALSE
);
289 } /* tuiVerticalDisassemScroll */
293 /*****************************************
294 ** STATIC LOCAL FUNCTIONS **
295 ******************************************/
298 ** Answer whether there is a break point at the input line in the
299 ** source file indicated
301 static struct breakpoint
*
302 _hasBreak (CORE_ADDR addr
)
304 struct breakpoint
*bpWithBreak
= (struct breakpoint
*) NULL
;
305 struct breakpoint
*bp
;
306 extern struct breakpoint
*breakpoint_chain
;
309 for (bp
= breakpoint_chain
;
310 (bp
!= (struct breakpoint
*) NULL
&&
311 bpWithBreak
== (struct breakpoint
*) NULL
);
313 if (addr
== bp
->address
)