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