record-full: Remove unused function netorder16
[deliverable/binutils-gdb.git] / gdb / tui / tui-disasm.c
CommitLineData
f377b406 1/* Disassembly display.
f33c6cbf 2
61baf725 3 Copyright (C) 1998-2017 Free Software Foundation, Inc.
f33c6cbf 4
f377b406
SC
5 Contributed by Hewlett-Packard Company.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
f377b406
SC
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
957b8b5a 23#include "arch-utils.h"
c906108c
SS
24#include "symtab.h"
25#include "breakpoint.h"
26#include "frame.h"
fd0407d6 27#include "value.h"
52575520 28#include "source.h"
f70a7d61 29#include "disasm.h"
d7b2e967
AC
30#include "tui/tui.h"
31#include "tui/tui-data.h"
32#include "tui/tui-win.h"
33#include "tui/tui-layout.h"
34#include "tui/tui-winsource.h"
35#include "tui/tui-stack.h"
36#include "tui/tui-file.h"
2c0b251b 37#include "tui/tui-disasm.h"
6c95b8df 38#include "progspace.h"
77e371c0 39#include "objfiles.h"
c906108c 40
6a83354a 41#include "gdb_curses.h"
96ec9981 42
aec2f747
SC
43struct tui_asm_line
44{
45 CORE_ADDR addr;
5b6fe301
MS
46 char *addr_string;
47 char *insn;
aec2f747
SC
48};
49
50/* Function to set the disassembly window's content.
51 Disassemble count lines starting at pc.
52 Return address of the count'th instruction after pc. */
53static CORE_ADDR
13274fc3 54tui_disassemble (struct gdbarch *gdbarch, struct tui_asm_line *asm_lines,
08ef48c5 55 CORE_ADDR pc, int count)
aec2f747 56{
d7e74731 57 string_file gdb_dis_out;
aec2f747 58
1cc6d956 59 /* Now construct each line. */
4cfcaf21 60 for (; count > 0; count--, asm_lines++)
aec2f747 61 {
4cfcaf21
JB
62 if (asm_lines->addr_string)
63 xfree (asm_lines->addr_string);
64 if (asm_lines->insn)
65 xfree (asm_lines->insn);
aec2f747 66
d7e74731 67 print_address (gdbarch, pc, &gdb_dis_out);
4cfcaf21 68 asm_lines->addr = pc;
d7e74731 69 asm_lines->addr_string = xstrdup (gdb_dis_out.c_str ());
aec2f747 70
d7e74731 71 gdb_dis_out.clear ();
aec2f747 72
d7e74731 73 pc = pc + gdb_print_insn (gdbarch, pc, &gdb_dis_out, NULL);
aec2f747 74
d7e74731 75 asm_lines->insn = xstrdup (gdb_dis_out.c_str ());
aec2f747 76
1cc6d956 77 /* Reset the buffer to empty. */
d7e74731 78 gdb_dis_out.clear ();
aec2f747 79 }
aec2f747
SC
80 return pc;
81}
82
1cc6d956
MS
83/* Find the disassembly address that corresponds to FROM lines above
84 or below the PC. Variable sized instructions are taken into
85 account by the algorithm. */
aec2f747 86static CORE_ADDR
13274fc3 87tui_find_disassembly_address (struct gdbarch *gdbarch, CORE_ADDR pc, int from)
aec2f747 88{
d02c80cd 89 CORE_ADDR new_low;
6ba8e26f 90 int max_lines;
aec2f747 91 int i;
5b6fe301 92 struct tui_asm_line *asm_lines;
aec2f747 93
6ba8e26f
AC
94 max_lines = (from > 0) ? from : - from;
95 if (max_lines <= 1)
aec2f747
SC
96 return pc;
97
8d749320 98 asm_lines = XALLOCAVEC (struct tui_asm_line, max_lines);
4cfcaf21 99 memset (asm_lines, 0, sizeof (struct tui_asm_line) * max_lines);
aec2f747 100
6ba8e26f 101 new_low = pc;
aec2f747
SC
102 if (from > 0)
103 {
13274fc3 104 tui_disassemble (gdbarch, asm_lines, pc, max_lines);
4cfcaf21 105 new_low = asm_lines[max_lines - 1].addr;
aec2f747
SC
106 }
107 else
108 {
109 CORE_ADDR last_addr;
110 int pos;
77e371c0 111 struct bound_minimal_symbol msymbol;
aec2f747 112
1cc6d956
MS
113 /* Find backward an address which is a symbol and for which
114 disassembling from that address will fill completely the
115 window. */
6ba8e26f 116 pos = max_lines - 1;
aec2f747 117 do {
6ba8e26f 118 new_low -= 1 * max_lines;
77e371c0 119 msymbol = lookup_minimal_symbol_by_pc_section (new_low, 0);
aec2f747 120
77e371c0
TT
121 if (msymbol.minsym)
122 new_low = BMSYMBOL_VALUE_ADDRESS (msymbol);
aec2f747 123 else
6ba8e26f 124 new_low += 1 * max_lines;
aec2f747 125
13274fc3 126 tui_disassemble (gdbarch, asm_lines, new_low, max_lines);
4cfcaf21 127 last_addr = asm_lines[pos].addr;
77e371c0 128 } while (last_addr > pc && msymbol.minsym);
aec2f747 129
1cc6d956
MS
130 /* Scan forward disassembling one instruction at a time until
131 the last visible instruction of the window matches the pc.
132 We keep the disassembled instructions in the 'lines' window
133 and shift it downward (increasing its addresses). */
aec2f747
SC
134 if (last_addr < pc)
135 do
136 {
137 CORE_ADDR next_addr;
138
139 pos++;
6ba8e26f 140 if (pos >= max_lines)
aec2f747
SC
141 pos = 0;
142
13274fc3
UW
143 next_addr = tui_disassemble (gdbarch, &asm_lines[pos],
144 last_addr, 1);
aec2f747
SC
145
146 /* If there are some problems while disassembling exit. */
147 if (next_addr <= last_addr)
148 break;
149 last_addr = next_addr;
150 } while (last_addr <= pc);
151 pos++;
6ba8e26f 152 if (pos >= max_lines)
aec2f747 153 pos = 0;
4cfcaf21 154 new_low = asm_lines[pos].addr;
aec2f747 155 }
6ba8e26f 156 for (i = 0; i < max_lines; i++)
aec2f747 157 {
4cfcaf21
JB
158 xfree (asm_lines[i].addr_string);
159 xfree (asm_lines[i].insn);
aec2f747 160 }
6ba8e26f 161 return new_low;
aec2f747
SC
162}
163
164/* Function to set the disassembly window's content. */
65f05602 165enum tui_status
13274fc3 166tui_set_disassem_content (struct gdbarch *gdbarch, CORE_ADDR pc)
c906108c 167{
22940a24 168 enum tui_status ret = TUI_FAILURE;
d02c80cd 169 int i;
6d012f14 170 int offset = TUI_DISASM_WIN->detail.source_info.horizontal_offset;
0bb65f1e 171 int max_lines, line_width;
aec2f747 172 CORE_ADDR cur_pc;
5b6fe301 173 struct tui_gen_win_info *locator = tui_locator_win_info_ptr ();
dd1abb8c 174 int tab_len = tui_default_tab_len ();
5b6fe301 175 struct tui_asm_line *asm_lines;
aec2f747 176 int insn_pos;
f5396833 177 int addr_size, insn_size;
5b6fe301 178 char *line;
aec2f747
SC
179
180 if (pc == 0)
181 return TUI_FAILURE;
182
6d012f14 183 ret = tui_alloc_source_buffer (TUI_DISASM_WIN);
aec2f747
SC
184 if (ret != TUI_SUCCESS)
185 return ret;
186
13274fc3 187 TUI_DISASM_WIN->detail.source_info.gdbarch = gdbarch;
362c05fe
AS
188 TUI_DISASM_WIN->detail.source_info.start_line_or_addr.loa = LOA_ADDRESS;
189 TUI_DISASM_WIN->detail.source_info.start_line_or_addr.u.addr = pc;
63ed8182 190 cur_pc = locator->content[0]->which_element.locator.addr;
aec2f747 191
0bb65f1e
AA
192 /* Window size, excluding highlight box. */
193 max_lines = TUI_DISASM_WIN->generic.height - 2;
194 line_width = TUI_DISASM_WIN->generic.width - 2;
aec2f747
SC
195
196 /* Get temporary table that will hold all strings (addr & insn). */
8d749320 197 asm_lines = XALLOCAVEC (struct tui_asm_line, max_lines);
4cfcaf21 198 memset (asm_lines, 0, sizeof (struct tui_asm_line) * max_lines);
aec2f747 199
13274fc3 200 tui_disassemble (gdbarch, asm_lines, pc, max_lines);
aec2f747 201
f5396833 202 /* Determine maximum address- and instruction lengths. */
aec2f747 203 addr_size = 0;
f5396833 204 insn_size = 0;
6ba8e26f 205 for (i = 0; i < max_lines; i++)
c906108c 206 {
4cfcaf21 207 size_t len = strlen (asm_lines[i].addr_string);
1c5313c5 208
aec2f747
SC
209 if (len > addr_size)
210 addr_size = len;
c906108c 211
f5396833
AA
212 len = strlen (asm_lines[i].insn);
213 if (len > insn_size)
214 insn_size = len;
c906108c 215 }
aec2f747 216
f5396833 217 /* Align instructions to the same column. */
aec2f747
SC
218 insn_pos = (1 + (addr_size / tab_len)) * tab_len;
219
f5396833
AA
220 /* Allocate memory to create each line. */
221 line = (char*) alloca (insn_pos + insn_size + 1);
222
1cc6d956 223 /* Now construct each line. */
6ba8e26f 224 for (i = 0; i < max_lines; i++)
aec2f747 225 {
5b6fe301
MS
226 struct tui_win_element *element;
227 struct tui_source_element *src;
6ba8e26f 228 int cur_len;
aec2f747 229
63ed8182 230 element = TUI_DISASM_WIN->generic.content[i];
6d012f14 231 src = &element->which_element.source;
4cfcaf21 232 strcpy (line, asm_lines[i].addr_string);
6ba8e26f 233 cur_len = strlen (line);
0bb65f1e
AA
234 memset (line + cur_len, ' ', insn_pos - cur_len);
235 strcpy (line + insn_pos, asm_lines[i].insn);
aec2f747 236
1cc6d956 237 /* Now copy the line taking the offset into account. */
aec2f747 238 if (strlen (line) > offset)
0bb65f1e
AA
239 {
240 strncpy (src->line, &line[offset], line_width);
241 src->line[line_width] = '\0';
242 }
aec2f747
SC
243 else
244 src->line[0] = '\0';
245
362c05fe
AS
246 src->line_or_addr.loa = LOA_ADDRESS;
247 src->line_or_addr.u.addr = asm_lines[i].addr;
4cfcaf21 248 src->is_exec_point = asm_lines[i].addr == cur_pc;
aec2f747
SC
249
250 /* See whether there is a breakpoint installed. */
6d012f14 251 src->has_break = (!src->is_exec_point
9a2b4c1b
MS
252 && breakpoint_here_p (current_program_space->aspace,
253 pc)
6c95b8df 254 != no_breakpoint_here);
c906108c 255
4cfcaf21
JB
256 xfree (asm_lines[i].addr_string);
257 xfree (asm_lines[i].insn);
aec2f747 258 }
6d012f14 259 TUI_DISASM_WIN->generic.content_size = i;
aec2f747
SC
260 return TUI_SUCCESS;
261}
c906108c
SS
262
263
1cc6d956 264/* Function to display the disassembly window with disassembled code. */
c906108c 265void
13274fc3 266tui_show_disassem (struct gdbarch *gdbarch, CORE_ADDR start_addr)
c906108c 267{
34248c3a 268 struct symtab *s = find_pc_line_symtab (start_addr);
5b6fe301 269 struct tui_win_info *win_with_focus = tui_win_with_focus ();
362c05fe 270 struct tui_line_or_address val;
c906108c 271
362c05fe
AS
272 val.loa = LOA_ADDRESS;
273 val.u.addr = start_addr;
080ce8c0 274 tui_add_win_to_layout (DISASSEM_WIN);
13274fc3 275 tui_update_source_window (TUI_DISASM_WIN, gdbarch, s, val, FALSE);
ef5eab5a
MS
276
277 /* If the focus was in the src win, put it in the asm win, if the
278 source view isn't split. */
e5908723
MS
279 if (tui_current_layout () != SRC_DISASSEM_COMMAND
280 && win_with_focus == TUI_SRC_WIN)
6d012f14 281 tui_set_win_focus_to (TUI_DISASM_WIN);
c906108c
SS
282
283 return;
65f05602 284}
c906108c
SS
285
286
1cc6d956 287/* Function to display the disassembly window. */
c906108c 288void
13274fc3
UW
289tui_show_disassem_and_update_source (struct gdbarch *gdbarch,
290 CORE_ADDR start_addr)
c906108c
SS
291{
292 struct symtab_and_line sal;
293
13274fc3 294 tui_show_disassem (gdbarch, start_addr);
dd1abb8c 295 if (tui_current_layout () == SRC_DISASSEM_COMMAND)
c906108c 296 {
362c05fe 297 struct tui_line_or_address val;
aec2f747 298
ef5eab5a
MS
299 /* Update what is in the source window if it is displayed too,
300 note that it follows what is in the disassembly window and
301 visa-versa. */
6ba8e26f 302 sal = find_pc_line (start_addr, 0);
362c05fe
AS
303 val.loa = LOA_LINE;
304 val.u.line_no = sal.line;
13274fc3 305 tui_update_source_window (TUI_SRC_WIN, gdbarch, sal.symtab, val, TRUE);
3024f13a
SC
306 if (sal.symtab)
307 {
52575520 308 set_current_source_symtab_and_line (&sal);
56d397a3 309 tui_update_locator_fullname (symtab_to_fullname (sal.symtab));
3024f13a
SC
310 }
311 else
56d397a3 312 tui_update_locator_fullname ("?");
c906108c
SS
313 }
314
315 return;
65f05602 316}
c906108c 317
13274fc3
UW
318void
319tui_get_begin_asm_address (struct gdbarch **gdbarch_p, CORE_ADDR *addr_p)
c906108c 320{
5b6fe301
MS
321 struct tui_gen_win_info *locator;
322 struct tui_locator_element *element;
957b8b5a 323 struct gdbarch *gdbarch = get_current_arch ();
c774cec6 324 CORE_ADDR addr;
c906108c 325
dd1abb8c 326 locator = tui_locator_win_info_ptr ();
63ed8182 327 element = &locator->content[0]->which_element.locator;
c906108c 328
c774cec6 329 if (element->addr == 0)
c906108c 330 {
3b7344d5 331 struct bound_minimal_symbol main_symbol;
0510ab86
SC
332
333 /* Find address of the start of program.
334 Note: this should be language specific. */
335 main_symbol = lookup_minimal_symbol ("main", NULL, NULL);
3b7344d5 336 if (main_symbol.minsym == 0)
0510ab86 337 main_symbol = lookup_minimal_symbol ("MAIN", NULL, NULL);
3b7344d5 338 if (main_symbol.minsym == 0)
0510ab86 339 main_symbol = lookup_minimal_symbol ("_start", NULL, NULL);
3b7344d5 340 if (main_symbol.minsym)
77e371c0 341 addr = BMSYMBOL_VALUE_ADDRESS (main_symbol);
0510ab86
SC
342 else
343 addr = 0;
c906108c 344 }
1cc6d956 345 else /* The target is executing. */
13274fc3
UW
346 {
347 gdbarch = element->gdbarch;
348 addr = element->addr;
349 }
c906108c 350
13274fc3
UW
351 *gdbarch_p = gdbarch;
352 *addr_p = addr;
65f05602 353}
c906108c 354
77cad3ba 355/* Determine what the low address will be to display in the TUI's
1cc6d956
MS
356 disassembly window. This may or may not be the same as the low
357 address input. */
77cad3ba 358CORE_ADDR
13274fc3
UW
359tui_get_low_disassembly_address (struct gdbarch *gdbarch,
360 CORE_ADDR low, CORE_ADDR pc)
77cad3ba
SC
361{
362 int pos;
363
1cc6d956
MS
364 /* Determine where to start the disassembly so that the pc is about
365 in the middle of the viewport. */
080ce8c0 366 pos = tui_default_win_viewport_height (DISASSEM_WIN, DISASSEM_COMMAND) / 2;
13274fc3 367 pc = tui_find_disassembly_address (gdbarch, pc, -pos);
77cad3ba
SC
368
369 if (pc < low)
370 pc = low;
371 return pc;
372}
373
65f05602 374/* Scroll the disassembly forward or backward vertically. */
c906108c 375void
6ba8e26f
AC
376tui_vertical_disassem_scroll (enum tui_scroll_direction scroll_direction,
377 int num_to_scroll)
c906108c 378{
6d012f14 379 if (TUI_DISASM_WIN->generic.content != NULL)
c906108c 380 {
13274fc3 381 struct gdbarch *gdbarch = TUI_DISASM_WIN->detail.source_info.gdbarch;
aec2f747 382 CORE_ADDR pc;
2a8854a7 383 tui_win_content content;
362c05fe 384 struct tui_line_or_address val;
aefc7064 385 int dir;
c906108c 386
6d012f14 387 content = (tui_win_content) TUI_DISASM_WIN->generic.content;
c906108c 388
362c05fe 389 pc = content[0]->which_element.source.line_or_addr.u.addr;
aefc7064 390 num_to_scroll++;
9a2b4c1b
MS
391 dir = (scroll_direction == FORWARD_SCROLL)
392 ? num_to_scroll : -num_to_scroll;
c906108c 393
362c05fe 394 val.loa = LOA_ADDRESS;
13274fc3 395 val.u.addr = tui_find_disassembly_address (gdbarch, pc, dir);
9a2b4c1b
MS
396 tui_update_source_window_as_is (TUI_DISASM_WIN, gdbarch,
397 NULL, val, FALSE);
aec2f747
SC
398 }
399}
This page took 1.832039 seconds and 4 git commands to generate.