Revert "Add symbol called __nm_<name> to exported symbols created by dlltool."
[deliverable/binutils-gdb.git] / gdb / disasm.c
CommitLineData
92df71f0 1/* Disassemble support for GDB.
1bac305b 2
61baf725 3 Copyright (C) 2000-2017 Free Software Foundation, Inc.
92df71f0
FN
4
5 This file is part of GDB.
6
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
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
92df71f0
FN
10 (at your option) any later version.
11
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.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
92df71f0
FN
19
20#include "defs.h"
21#include "target.h"
22#include "value.h"
23#include "ui-out.h"
92df71f0 24#include "disasm.h"
810ecf9f 25#include "gdbcore.h"
a89aa300 26#include "dis-asm.h"
6ff0ba5f 27#include "source.h"
325fac50 28#include <algorithm>
92df71f0
FN
29
30/* Disassemble functions.
31 FIXME: We should get rid of all the duplicate code in gdb that does
0963b4bd 32 the same thing: disassemble_command() and the gdbtk variation. */
92df71f0 33
6ff0ba5f
DE
34/* This structure is used to store line number information for the
35 deprecated /m option.
92df71f0
FN
36 We need a different sort of line table from the normal one cuz we can't
37 depend upon implicit line-end pc's for lines to do the
38 reordering in this function. */
39
6ff0ba5f 40struct deprecated_dis_line_entry
92df71f0
FN
41{
42 int line;
43 CORE_ADDR start_pc;
44 CORE_ADDR end_pc;
45};
46
6ff0ba5f
DE
47/* This Structure is used to store line number information.
48 We need a different sort of line table from the normal one cuz we can't
49 depend upon implicit line-end pc's for lines to do the
50 reordering in this function. */
51
52struct dis_line_entry
53{
54 struct symtab *symtab;
55 int line;
56};
57
58/* Hash function for dis_line_entry. */
59
60static hashval_t
61hash_dis_line_entry (const void *item)
62{
9a3c8263 63 const struct dis_line_entry *dle = (const struct dis_line_entry *) item;
6ff0ba5f
DE
64
65 return htab_hash_pointer (dle->symtab) + dle->line;
66}
67
68/* Equal function for dis_line_entry. */
69
70static int
71eq_dis_line_entry (const void *item_lhs, const void *item_rhs)
72{
9a3c8263
SM
73 const struct dis_line_entry *lhs = (const struct dis_line_entry *) item_lhs;
74 const struct dis_line_entry *rhs = (const struct dis_line_entry *) item_rhs;
6ff0ba5f
DE
75
76 return (lhs->symtab == rhs->symtab
77 && lhs->line == rhs->line);
78}
79
80/* Create the table to manage lines for mixed source/disassembly. */
81
82static htab_t
83allocate_dis_line_table (void)
84{
85 return htab_create_alloc (41,
86 hash_dis_line_entry, eq_dis_line_entry,
87 xfree, xcalloc, xfree);
88}
89
4a099de2 90/* Add a new dis_line_entry containing SYMTAB and LINE to TABLE. */
6ff0ba5f
DE
91
92static void
4a099de2 93add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
6ff0ba5f
DE
94{
95 void **slot;
96 struct dis_line_entry dle, *dlep;
97
98 dle.symtab = symtab;
99 dle.line = line;
100 slot = htab_find_slot (table, &dle, INSERT);
101 if (*slot == NULL)
102 {
103 dlep = XNEW (struct dis_line_entry);
104 dlep->symtab = symtab;
105 dlep->line = line;
106 *slot = dlep;
107 }
108}
109
110/* Return non-zero if SYMTAB, LINE are in TABLE. */
111
112static int
113line_has_code_p (htab_t table, struct symtab *symtab, int line)
114{
115 struct dis_line_entry dle;
116
117 dle.symtab = symtab;
118 dle.line = line;
119 return htab_find (table, &dle) != NULL;
120}
121
e47ad6c0
YQ
122/* Wrapper of target_read_code. */
123
124int
125gdb_disassembler::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr,
126 unsigned int len,
127 struct disassemble_info *info)
810ecf9f 128{
283f7163 129 return target_read_code (memaddr, myaddr, len);
810ecf9f
AC
130}
131
e47ad6c0
YQ
132/* Wrapper of memory_error. */
133
134void
135gdb_disassembler::dis_asm_memory_error (int err, bfd_vma memaddr,
136 struct disassemble_info *info)
810ecf9f 137{
d8b49cf0
YQ
138 gdb_disassembler *self
139 = static_cast<gdb_disassembler *>(info->application_data);
140
141 self->m_err_memaddr = memaddr;
810ecf9f
AC
142}
143
e47ad6c0
YQ
144/* Wrapper of print_address. */
145
146void
147gdb_disassembler::dis_asm_print_address (bfd_vma addr,
148 struct disassemble_info *info)
810ecf9f 149{
e47ad6c0
YQ
150 gdb_disassembler *self
151 = static_cast<gdb_disassembler *>(info->application_data);
9a619af0 152
e47ad6c0 153 print_address (self->arch (), addr, self->stream ());
810ecf9f
AC
154}
155
92df71f0 156static int
bde58177 157compare_lines (const void *mle1p, const void *mle2p)
92df71f0 158{
6ff0ba5f 159 struct deprecated_dis_line_entry *mle1, *mle2;
92df71f0
FN
160 int val;
161
6ff0ba5f
DE
162 mle1 = (struct deprecated_dis_line_entry *) mle1p;
163 mle2 = (struct deprecated_dis_line_entry *) mle2p;
92df71f0 164
9011945e
AB
165 /* End of sequence markers have a line number of 0 but don't want to
166 be sorted to the head of the list, instead sort by PC. */
167 if (mle1->line == 0 || mle2->line == 0)
168 {
169 val = mle1->start_pc - mle2->start_pc;
170 if (val == 0)
171 val = mle1->line - mle2->line;
172 }
173 else
174 {
175 val = mle1->line - mle2->line;
176 if (val == 0)
177 val = mle1->start_pc - mle2->start_pc;
178 }
179 return val;
92df71f0
FN
180}
181
a50a4026 182/* See disasm.h. */
af70908d 183
a50a4026 184int
8b172ce7
PA
185gdb_pretty_print_disassembler::pretty_print_insn (struct ui_out *uiout,
186 const struct disasm_insn *insn,
187 int flags)
92df71f0 188{
92df71f0
FN
189 /* parts of the symbolic representation of the address */
190 int unmapped;
92df71f0
FN
191 int offset;
192 int line;
af70908d 193 int size;
3b31d625 194 struct cleanup *ui_out_chain;
af70908d
MM
195 char *filename = NULL;
196 char *name = NULL;
a50a4026 197 CORE_ADDR pc;
8b172ce7 198 struct gdbarch *gdbarch = arch ();
af70908d
MM
199
200 ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
a50a4026
MM
201 pc = insn->addr;
202
203 if (insn->number != 0)
204 {
112e8700
SM
205 uiout->field_fmt ("insn-number", "%u", insn->number);
206 uiout->text ("\t");
a50a4026 207 }
92df71f0 208
a50a4026
MM
209 if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
210 {
211 if (insn->is_speculative)
212 {
112e8700 213 uiout->field_string ("is-speculative", "?");
a50a4026
MM
214
215 /* The speculative execution indication overwrites the first
216 character of the PC prefix.
217 We assume a PC prefix length of 3 characters. */
218 if ((flags & DISASSEMBLY_OMIT_PC) == 0)
112e8700 219 uiout->text (pc_prefix (pc) + 1);
a50a4026 220 else
112e8700 221 uiout->text (" ");
a50a4026
MM
222 }
223 else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
112e8700 224 uiout->text (pc_prefix (pc));
a50a4026 225 else
112e8700 226 uiout->text (" ");
a50a4026
MM
227 }
228 else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
112e8700
SM
229 uiout->text (pc_prefix (pc));
230 uiout->field_core_addr ("address", gdbarch, pc);
af70908d
MM
231
232 if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
233 &line, &unmapped))
92df71f0 234 {
af70908d
MM
235 /* We don't care now about line, filename and unmapped. But we might in
236 the future. */
112e8700 237 uiout->text (" <");
af70908d 238 if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
112e8700
SM
239 uiout->field_string ("func-name", name);
240 uiout->text ("+");
241 uiout->field_int ("offset", offset);
242 uiout->text (">:\t");
af70908d
MM
243 }
244 else
112e8700 245 uiout->text (":\t");
1211bce3 246
af70908d
MM
247 if (filename != NULL)
248 xfree (filename);
249 if (name != NULL)
250 xfree (name);
251
8b172ce7 252 m_insn_stb.clear ();
187808b0 253
af70908d
MM
254 if (flags & DISASSEMBLY_RAW_INSN)
255 {
256 CORE_ADDR end_pc;
257 bfd_byte data;
258 int err;
259 const char *spacer = "";
260
261 /* Build the opcodes using a temporary stream so we can
262 write them out in a single go for the MI. */
8b172ce7 263 m_opcode_stb.clear ();
946287b7 264
8b172ce7 265 size = m_di.print_insn (pc);
af70908d 266 end_pc = pc + size;
92df71f0 267
af70908d 268 for (;pc < end_pc; ++pc)
92df71f0 269 {
187808b0 270 read_code (pc, &data, 1);
8b172ce7 271 m_opcode_stb.printf ("%s%02x", spacer, (unsigned) data);
af70908d 272 spacer = " ";
92df71f0 273 }
af70908d 274
8b172ce7 275 uiout->field_stream ("opcodes", m_opcode_stb);
112e8700 276 uiout->text ("\t");
af70908d
MM
277 }
278 else
8b172ce7 279 size = m_di.print_insn (pc);
af70908d 280
8b172ce7 281 uiout->field_stream ("inst", m_insn_stb);
af70908d 282 do_cleanups (ui_out_chain);
112e8700 283 uiout->text ("\n");
af70908d
MM
284
285 return size;
286}
287
288static int
187808b0
PA
289dump_insns (struct gdbarch *gdbarch,
290 struct ui_out *uiout, CORE_ADDR low, CORE_ADDR high,
291 int how_many, int flags, CORE_ADDR *end_pc)
af70908d 292{
a50a4026 293 struct disasm_insn insn;
af70908d
MM
294 int num_displayed = 0;
295
a50a4026
MM
296 memset (&insn, 0, sizeof (insn));
297 insn.addr = low;
298
8b172ce7
PA
299 gdb_pretty_print_disassembler disasm (gdbarch);
300
a50a4026 301 while (insn.addr < high && (how_many < 0 || num_displayed < how_many))
af70908d
MM
302 {
303 int size;
304
8b172ce7 305 size = disasm.pretty_print_insn (uiout, &insn, flags);
af70908d
MM
306 if (size <= 0)
307 break;
308
309 ++num_displayed;
a50a4026 310 insn.addr += size;
af70908d
MM
311
312 /* Allow user to bail out with ^C. */
313 QUIT;
92df71f0 314 }
6ff0ba5f
DE
315
316 if (end_pc != NULL)
a50a4026 317 *end_pc = insn.addr;
af70908d 318
92df71f0
FN
319 return num_displayed;
320}
321
322/* The idea here is to present a source-O-centric view of a
323 function to the user. This means that things are presented
324 in source order, with (possibly) out of order assembly
6ff0ba5f
DE
325 immediately following.
326
327 N.B. This view is deprecated. */
0963b4bd 328
92df71f0 329static void
6ff0ba5f 330do_mixed_source_and_assembly_deprecated
187808b0
PA
331 (struct gdbarch *gdbarch, struct ui_out *uiout,
332 struct symtab *symtab,
6ff0ba5f 333 CORE_ADDR low, CORE_ADDR high,
e47ad6c0 334 int how_many, int flags)
92df71f0
FN
335{
336 int newlines = 0;
6ff0ba5f
DE
337 int nlines;
338 struct linetable_entry *le;
339 struct deprecated_dis_line_entry *mle;
92df71f0
FN
340 struct symtab_and_line sal;
341 int i;
342 int out_of_order = 0;
343 int next_line = 0;
92df71f0 344 int num_displayed = 0;
8d297bbf 345 print_source_lines_flags psl_flags = 0;
3b31d625 346 struct cleanup *ui_out_chain;
0127c0d3
JJ
347 struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
348 struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
92df71f0 349
6ff0ba5f
DE
350 gdb_assert (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL);
351
352 nlines = SYMTAB_LINETABLE (symtab)->nitems;
353 le = SYMTAB_LINETABLE (symtab)->item;
354
4cd29721
MM
355 if (flags & DISASSEMBLY_FILENAME)
356 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
357
6ff0ba5f
DE
358 mle = (struct deprecated_dis_line_entry *)
359 alloca (nlines * sizeof (struct deprecated_dis_line_entry));
92df71f0
FN
360
361 /* Copy linetable entries for this function into our data
362 structure, creating end_pc's and setting out_of_order as
363 appropriate. */
364
365 /* First, skip all the preceding functions. */
366
367 for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
368
369 /* Now, copy all entries before the end of this function. */
370
371 for (; i < nlines - 1 && le[i].pc < high; i++)
372 {
373 if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
0963b4bd 374 continue; /* Ignore duplicates. */
92df71f0
FN
375
376 /* Skip any end-of-function markers. */
377 if (le[i].line == 0)
378 continue;
379
380 mle[newlines].line = le[i].line;
381 if (le[i].line > le[i + 1].line)
382 out_of_order = 1;
383 mle[newlines].start_pc = le[i].pc;
384 mle[newlines].end_pc = le[i + 1].pc;
385 newlines++;
386 }
387
388 /* If we're on the last line, and it's part of the function,
389 then we need to get the end pc in a special way. */
390
391 if (i == nlines - 1 && le[i].pc < high)
392 {
393 mle[newlines].line = le[i].line;
394 mle[newlines].start_pc = le[i].pc;
395 sal = find_pc_line (le[i].pc, 0);
396 mle[newlines].end_pc = sal.end;
397 newlines++;
398 }
399
6ff0ba5f 400 /* Now, sort mle by line #s (and, then by addresses within lines). */
92df71f0
FN
401
402 if (out_of_order)
6ff0ba5f
DE
403 qsort (mle, newlines, sizeof (struct deprecated_dis_line_entry),
404 compare_lines);
92df71f0
FN
405
406 /* Now, for each line entry, emit the specified lines (unless
407 they have been emitted before), followed by the assembly code
408 for that line. */
409
3b31d625 410 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
92df71f0
FN
411
412 for (i = 0; i < newlines; i++)
413 {
92df71f0
FN
414 /* Print out everything from next_line to the current line. */
415 if (mle[i].line >= next_line)
416 {
417 if (next_line != 0)
418 {
0963b4bd 419 /* Just one line to print. */
92df71f0
FN
420 if (next_line == mle[i].line)
421 {
3b31d625
EZ
422 ui_out_tuple_chain
423 = make_cleanup_ui_out_tuple_begin_end (uiout,
424 "src_and_asm_line");
4cd29721 425 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
92df71f0
FN
426 }
427 else
428 {
0963b4bd 429 /* Several source lines w/o asm instructions associated. */
92df71f0
FN
430 for (; next_line < mle[i].line; next_line++)
431 {
3b31d625
EZ
432 struct cleanup *ui_out_list_chain_line;
433 struct cleanup *ui_out_tuple_chain_line;
434
435 ui_out_tuple_chain_line
436 = make_cleanup_ui_out_tuple_begin_end (uiout,
437 "src_and_asm_line");
92df71f0 438 print_source_lines (symtab, next_line, next_line + 1,
4cd29721 439 psl_flags);
3b31d625
EZ
440 ui_out_list_chain_line
441 = make_cleanup_ui_out_list_begin_end (uiout,
442 "line_asm_insn");
443 do_cleanups (ui_out_list_chain_line);
444 do_cleanups (ui_out_tuple_chain_line);
92df71f0
FN
445 }
446 /* Print the last line and leave list open for
0963b4bd 447 asm instructions to be added. */
3b31d625
EZ
448 ui_out_tuple_chain
449 = make_cleanup_ui_out_tuple_begin_end (uiout,
450 "src_and_asm_line");
4cd29721 451 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
92df71f0
FN
452 }
453 }
454 else
455 {
3b31d625 456 ui_out_tuple_chain
3e43a32a
MS
457 = make_cleanup_ui_out_tuple_begin_end (uiout,
458 "src_and_asm_line");
4cd29721 459 print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
92df71f0
FN
460 }
461
462 next_line = mle[i].line + 1;
3b31d625
EZ
463 ui_out_list_chain
464 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
92df71f0
FN
465 }
466
187808b0 467 num_displayed += dump_insns (gdbarch, uiout,
13274fc3 468 mle[i].start_pc, mle[i].end_pc,
e47ad6c0 469 how_many, flags, NULL);
0127c0d3
JJ
470
471 /* When we've reached the end of the mle array, or we've seen the last
472 assembly range for this source line, close out the list/tuple. */
473 if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
92df71f0 474 {
3b31d625
EZ
475 do_cleanups (ui_out_list_chain);
476 do_cleanups (ui_out_tuple_chain);
0127c0d3
JJ
477 ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
478 ui_out_list_chain = make_cleanup (null_cleanup, 0);
112e8700 479 uiout->text ("\n");
92df71f0 480 }
0127c0d3
JJ
481 if (how_many >= 0 && num_displayed >= how_many)
482 break;
92df71f0 483 }
3b31d625 484 do_cleanups (ui_out_chain);
92df71f0
FN
485}
486
6ff0ba5f
DE
487/* The idea here is to present a source-O-centric view of a
488 function to the user. This means that things are presented
489 in source order, with (possibly) out of order assembly
490 immediately following. */
491
492static void
e47ad6c0
YQ
493do_mixed_source_and_assembly (struct gdbarch *gdbarch,
494 struct ui_out *uiout,
6ff0ba5f
DE
495 struct symtab *main_symtab,
496 CORE_ADDR low, CORE_ADDR high,
e47ad6c0 497 int how_many, int flags)
6ff0ba5f 498{
6ff0ba5f 499 const struct linetable_entry *le, *first_le;
6ff0ba5f 500 int i, nlines;
6ff0ba5f 501 int num_displayed = 0;
8d297bbf 502 print_source_lines_flags psl_flags = 0;
6ff0ba5f
DE
503 struct cleanup *ui_out_chain;
504 struct cleanup *ui_out_tuple_chain;
505 struct cleanup *ui_out_list_chain;
506 CORE_ADDR pc;
507 struct symtab *last_symtab;
508 int last_line;
6ff0ba5f
DE
509
510 gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
511
512 /* First pass: collect the list of all source files and lines.
513 We do this so that we can only print lines containing code once.
514 We try to print the source text leading up to the next instruction,
515 but if that text is for code that will be disassembled later, then
516 we'll want to defer printing it until later with its associated code. */
517
fc4007c9 518 htab_up dis_line_table (allocate_dis_line_table ());
6ff0ba5f
DE
519
520 pc = low;
521
522 /* The prologue may be empty, but there may still be a line number entry
523 for the opening brace which is distinct from the first line of code.
524 If the prologue has been eliminated find_pc_line may return the source
525 line after the opening brace. We still want to print this opening brace.
526 first_le is used to implement this. */
527
528 nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
529 le = SYMTAB_LINETABLE (main_symtab)->item;
530 first_le = NULL;
531
532 /* Skip all the preceding functions. */
533 for (i = 0; i < nlines && le[i].pc < low; i++)
534 continue;
535
536 if (i < nlines && le[i].pc < high)
537 first_le = &le[i];
538
539 /* Add lines for every pc value. */
540 while (pc < high)
541 {
542 struct symtab_and_line sal;
543 int length;
544
545 sal = find_pc_line (pc, 0);
546 length = gdb_insn_length (gdbarch, pc);
547 pc += length;
548
549 if (sal.symtab != NULL)
fc4007c9 550 add_dis_line_entry (dis_line_table.get (), sal.symtab, sal.line);
6ff0ba5f
DE
551 }
552
553 /* Second pass: print the disassembly.
554
555 Output format, from an MI perspective:
556 The result is a ui_out list, field name "asm_insns", where elements have
557 name "src_and_asm_line".
558 Each element is a tuple of source line specs (field names line, file,
559 fullname), and field "line_asm_insn" which contains the disassembly.
560 Field "line_asm_insn" is a list of tuples: address, func-name, offset,
561 opcodes, inst.
562
563 CLI output works on top of this because MI ignores ui_out_text output,
564 which is where we put file name and source line contents output.
565
566 Cleanup usage:
6ff0ba5f
DE
567 ui_out_chain
568 Handles the outer "asm_insns" list.
569 ui_out_tuple_chain
570 The tuples for each group of consecutive disassemblies.
571 ui_out_list_chain
572 List of consecutive source lines or disassembled insns. */
573
574 if (flags & DISASSEMBLY_FILENAME)
575 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
576
577 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
578
579 ui_out_tuple_chain = NULL;
580 ui_out_list_chain = NULL;
581
582 last_symtab = NULL;
583 last_line = 0;
584 pc = low;
585
586 while (pc < high)
587 {
6ff0ba5f
DE
588 struct symtab_and_line sal;
589 CORE_ADDR end_pc;
590 int start_preceding_line_to_display = 0;
591 int end_preceding_line_to_display = 0;
592 int new_source_line = 0;
593
594 sal = find_pc_line (pc, 0);
595
596 if (sal.symtab != last_symtab)
597 {
598 /* New source file. */
599 new_source_line = 1;
600
601 /* If this is the first line of output, check for any preceding
602 lines. */
603 if (last_line == 0
604 && first_le != NULL
605 && first_le->line < sal.line)
606 {
607 start_preceding_line_to_display = first_le->line;
608 end_preceding_line_to_display = sal.line;
609 }
610 }
611 else
612 {
613 /* Same source file as last time. */
614 if (sal.symtab != NULL)
615 {
616 if (sal.line > last_line + 1 && last_line != 0)
617 {
618 int l;
619
620 /* Several preceding source lines. Print the trailing ones
621 not associated with code that we'll print later. */
622 for (l = sal.line - 1; l > last_line; --l)
623 {
fc4007c9
TT
624 if (line_has_code_p (dis_line_table.get (),
625 sal.symtab, l))
6ff0ba5f
DE
626 break;
627 }
628 if (l < sal.line - 1)
629 {
630 start_preceding_line_to_display = l + 1;
631 end_preceding_line_to_display = sal.line;
632 }
633 }
634 if (sal.line != last_line)
635 new_source_line = 1;
636 else
637 {
638 /* Same source line as last time. This can happen, depending
639 on the debug info. */
640 }
641 }
642 }
643
644 if (new_source_line)
645 {
646 /* Skip the newline if this is the first instruction. */
647 if (pc > low)
112e8700 648 uiout->text ("\n");
6ff0ba5f
DE
649 if (ui_out_tuple_chain != NULL)
650 {
651 gdb_assert (ui_out_list_chain != NULL);
652 do_cleanups (ui_out_list_chain);
653 do_cleanups (ui_out_tuple_chain);
654 }
655 if (sal.symtab != last_symtab
656 && !(flags & DISASSEMBLY_FILENAME))
657 {
658 /* Remember MI ignores ui_out_text.
659 We don't have to do anything here for MI because MI
660 output includes the source specs for each line. */
661 if (sal.symtab != NULL)
662 {
112e8700 663 uiout->text (symtab_to_filename_for_display (sal.symtab));
6ff0ba5f
DE
664 }
665 else
112e8700
SM
666 uiout->text ("unknown");
667 uiout->text (":\n");
6ff0ba5f
DE
668 }
669 if (start_preceding_line_to_display > 0)
670 {
671 /* Several source lines w/o asm instructions associated.
672 We need to preserve the structure of the output, so output
673 a bunch of line tuples with no asm entries. */
674 int l;
675 struct cleanup *ui_out_list_chain_line;
676 struct cleanup *ui_out_tuple_chain_line;
677
678 gdb_assert (sal.symtab != NULL);
679 for (l = start_preceding_line_to_display;
680 l < end_preceding_line_to_display;
681 ++l)
682 {
683 ui_out_tuple_chain_line
684 = make_cleanup_ui_out_tuple_begin_end (uiout,
685 "src_and_asm_line");
686 print_source_lines (sal.symtab, l, l + 1, psl_flags);
687 ui_out_list_chain_line
688 = make_cleanup_ui_out_list_begin_end (uiout,
689 "line_asm_insn");
690 do_cleanups (ui_out_list_chain_line);
691 do_cleanups (ui_out_tuple_chain_line);
692 }
693 }
694 ui_out_tuple_chain
695 = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
696 if (sal.symtab != NULL)
697 print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
698 else
112e8700 699 uiout->text (_("--- no source info for this pc ---\n"));
6ff0ba5f
DE
700 ui_out_list_chain
701 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
702 }
703 else
704 {
705 /* Here we're appending instructions to an existing line.
706 By construction the very first insn will have a symtab
707 and follow the new_source_line path above. */
708 gdb_assert (ui_out_tuple_chain != NULL);
709 gdb_assert (ui_out_list_chain != NULL);
710 }
711
712 if (sal.end != 0)
325fac50 713 end_pc = std::min (sal.end, high);
6ff0ba5f
DE
714 else
715 end_pc = pc + 1;
187808b0 716 num_displayed += dump_insns (gdbarch, uiout, pc, end_pc,
e47ad6c0 717 how_many, flags, &end_pc);
6ff0ba5f
DE
718 pc = end_pc;
719
720 if (how_many >= 0 && num_displayed >= how_many)
721 break;
722
723 last_symtab = sal.symtab;
724 last_line = sal.line;
725 }
726
727 do_cleanups (ui_out_chain);
6ff0ba5f 728}
92df71f0
FN
729
730static void
187808b0 731do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
92df71f0 732 CORE_ADDR low, CORE_ADDR high,
e47ad6c0 733 int how_many, int flags)
92df71f0 734{
3b31d625 735 struct cleanup *ui_out_chain;
92df71f0 736
3b31d625 737 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
92df71f0 738
187808b0 739 dump_insns (gdbarch, uiout, low, high, how_many, flags, NULL);
92df71f0 740
3b31d625 741 do_cleanups (ui_out_chain);
92df71f0
FN
742}
743
92bf2b80
AC
744/* Initialize the disassemble info struct ready for the specified
745 stream. */
746
a0b31db1 747static int ATTRIBUTE_PRINTF (2, 3)
242e8be5
AC
748fprintf_disasm (void *stream, const char *format, ...)
749{
750 va_list args;
9a619af0 751
242e8be5 752 va_start (args, format);
9a3c8263 753 vfprintf_filtered ((struct ui_file *) stream, format, args);
242e8be5
AC
754 va_end (args);
755 /* Something non -ve. */
756 return 0;
757}
758
e47ad6c0
YQ
759gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch,
760 struct ui_file *file,
761 di_read_memory_ftype read_memory_func)
d8b49cf0
YQ
762 : m_gdbarch (gdbarch),
763 m_err_memaddr (0)
92df71f0 764{
e47ad6c0
YQ
765 init_disassemble_info (&m_di, file, fprintf_disasm);
766 m_di.flavour = bfd_target_unknown_flavour;
767 m_di.memory_error_func = dis_asm_memory_error;
768 m_di.print_address_func = dis_asm_print_address;
2b6fd0d8
AC
769 /* NOTE: cagney/2003-04-28: The original code, from the old Insight
770 disassembler had a local optomization here. By default it would
771 access the executable file, instead of the target memory (there
ce2826aa 772 was a growing list of exceptions though). Unfortunately, the
2b6fd0d8
AC
773 heuristic was flawed. Commands like "disassemble &variable"
774 didn't work as they relied on the access going to the target.
775 Further, it has been supperseeded by trust-read-only-sections
776 (although that should be superseeded by target_trust..._p()). */
e47ad6c0
YQ
777 m_di.read_memory_func = read_memory_func;
778 m_di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
779 m_di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
780 m_di.endian = gdbarch_byte_order (gdbarch);
781 m_di.endian_code = gdbarch_byte_order_for_code (gdbarch);
782 m_di.application_data = this;
783 disassemble_init_for_target (&m_di);
784}
785
786int
787gdb_disassembler::print_insn (CORE_ADDR memaddr,
788 int *branch_delay_insns)
789{
d8b49cf0
YQ
790 m_err_memaddr = 0;
791
e47ad6c0
YQ
792 int length = gdbarch_print_insn (arch (), memaddr, &m_di);
793
d8b49cf0
YQ
794 if (length < 0)
795 memory_error (TARGET_XFER_E_IO, m_err_memaddr);
796
e47ad6c0
YQ
797 if (branch_delay_insns != NULL)
798 {
799 if (m_di.insn_info_valid)
800 *branch_delay_insns = m_di.branch_delay_insns;
801 else
802 *branch_delay_insns = 0;
803 }
804 return length;
92bf2b80
AC
805}
806
807void
13274fc3 808gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
7a8eb317 809 int flags, int how_many,
9c419145 810 CORE_ADDR low, CORE_ADDR high)
92bf2b80 811{
34248c3a 812 struct symtab *symtab;
92bf2b80 813 int nlines = -1;
92df71f0 814
0963b4bd 815 /* Assume symtab is valid for whole PC range. */
34248c3a 816 symtab = find_pc_line_symtab (low);
92df71f0 817
8435453b 818 if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
6ff0ba5f 819 nlines = SYMTAB_LINETABLE (symtab)->nitems;
92df71f0 820
6ff0ba5f
DE
821 if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
822 || nlines <= 0)
187808b0 823 do_assembly_only (gdbarch, uiout, low, high, how_many, flags);
92df71f0 824
e6158f16 825 else if (flags & DISASSEMBLY_SOURCE)
187808b0 826 do_mixed_source_and_assembly (gdbarch, uiout, symtab, low, high,
e47ad6c0 827 how_many, flags);
6ff0ba5f
DE
828
829 else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
187808b0 830 do_mixed_source_and_assembly_deprecated (gdbarch, uiout, symtab,
e47ad6c0 831 low, high, how_many, flags);
92df71f0
FN
832
833 gdb_flush (gdb_stdout);
834}
810ecf9f 835
92bf2b80 836/* Print the instruction at address MEMADDR in debugged memory,
a4642986
MR
837 on STREAM. Returns the length of the instruction, in bytes,
838 and, if requested, the number of branch delay slot instructions. */
92bf2b80
AC
839
840int
13274fc3
UW
841gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
842 struct ui_file *stream, int *branch_delay_insns)
92bf2b80 843{
a4642986 844
e47ad6c0
YQ
845 gdb_disassembler di (gdbarch, stream);
846
847 return di.print_insn (memaddr, branch_delay_insns);
92bf2b80 848}
eda5a4d7 849
eda5a4d7
PA
850/* Return the length in bytes of the instruction at address MEMADDR in
851 debugged memory. */
852
853int
854gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
855{
d7e74731 856 return gdb_print_insn (gdbarch, addr, &null_stream, NULL);
eda5a4d7
PA
857}
858
859/* fprintf-function for gdb_buffered_insn_length. This function is a
860 nop, we don't want to print anything, we just want to compute the
861 length of the insn. */
862
863static int ATTRIBUTE_PRINTF (2, 3)
864gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
865{
866 return 0;
867}
868
869/* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
870
871static void
872gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
873 struct disassemble_info *di,
874 const gdb_byte *insn, int max_len,
875 CORE_ADDR addr)
876{
877 init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
878
879 /* init_disassemble_info installs buffer_read_memory, etc.
880 so we don't need to do that here.
881 The cast is necessary until disassemble_info is const-ified. */
882 di->buffer = (gdb_byte *) insn;
883 di->buffer_length = max_len;
884 di->buffer_vma = addr;
885
886 di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
887 di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
888 di->endian = gdbarch_byte_order (gdbarch);
889 di->endian_code = gdbarch_byte_order_for_code (gdbarch);
890
891 disassemble_init_for_target (di);
892}
893
894/* Return the length in bytes of INSN. MAX_LEN is the size of the
895 buffer containing INSN. */
896
897int
898gdb_buffered_insn_length (struct gdbarch *gdbarch,
899 const gdb_byte *insn, int max_len, CORE_ADDR addr)
900{
901 struct disassemble_info di;
902
903 gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
904
905 return gdbarch_print_insn (gdbarch, addr, &di);
906}
This page took 0.98882 seconds and 4 git commands to generate.