1 /* Disassemble support for GDB.
3 Copyright (C) 2000-2015 Free Software Foundation, Inc.
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 3 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, see <http://www.gnu.org/licenses/>. */
29 /* Disassemble functions.
30 FIXME: We should get rid of all the duplicate code in gdb that does
31 the same thing: disassemble_command() and the gdbtk variation. */
33 /* This structure is used to store line number information for the
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. */
39 struct deprecated_dis_line_entry
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. */
53 struct symtab
*symtab
;
57 /* Hash function for dis_line_entry. */
60 hash_dis_line_entry (const void *item
)
62 const struct dis_line_entry
*dle
= (const struct dis_line_entry
*) item
;
64 return htab_hash_pointer (dle
->symtab
) + dle
->line
;
67 /* Equal function for dis_line_entry. */
70 eq_dis_line_entry (const void *item_lhs
, const void *item_rhs
)
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
;
75 return (lhs
->symtab
== rhs
->symtab
76 && lhs
->line
== rhs
->line
);
79 /* Create the table to manage lines for mixed source/disassembly. */
82 allocate_dis_line_table (void)
84 return htab_create_alloc (41,
85 hash_dis_line_entry
, eq_dis_line_entry
,
86 xfree
, xcalloc
, xfree
);
90 Returns 1 if added, 0 if already present. */
93 maybe_add_dis_line_entry (htab_t table
, struct symtab
*symtab
, int line
)
96 struct dis_line_entry dle
, *dlep
;
100 slot
= htab_find_slot (table
, &dle
, INSERT
);
103 dlep
= XNEW (struct dis_line_entry
);
104 dlep
->symtab
= symtab
;
110 /* Return non-zero if SYMTAB, LINE are in TABLE. */
113 line_has_code_p (htab_t table
, struct symtab
*symtab
, int line
)
115 struct dis_line_entry dle
;
119 return htab_find (table
, &dle
) != NULL
;
122 /* Like target_read_memory, but slightly different parameters. */
124 dis_asm_read_memory (bfd_vma memaddr
, gdb_byte
*myaddr
, unsigned int len
,
125 struct disassemble_info
*info
)
127 return target_read_code (memaddr
, myaddr
, len
);
130 /* Like memory_error with slightly different parameters. */
132 dis_asm_memory_error (int err
, bfd_vma memaddr
,
133 struct disassemble_info
*info
)
135 memory_error (TARGET_XFER_E_IO
, memaddr
);
138 /* Like print_address with slightly different parameters. */
140 dis_asm_print_address (bfd_vma addr
, struct disassemble_info
*info
)
142 struct gdbarch
*gdbarch
= (struct gdbarch
*) info
->application_data
;
144 print_address (gdbarch
, addr
, (struct ui_file
*) info
->stream
);
148 compare_lines (const void *mle1p
, const void *mle2p
)
150 struct deprecated_dis_line_entry
*mle1
, *mle2
;
153 mle1
= (struct deprecated_dis_line_entry
*) mle1p
;
154 mle2
= (struct deprecated_dis_line_entry
*) mle2p
;
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)
160 val
= mle1
->start_pc
- mle2
->start_pc
;
162 val
= mle1
->line
- mle2
->line
;
166 val
= mle1
->line
- mle2
->line
;
168 val
= mle1
->start_pc
- mle2
->start_pc
;
173 /* Prints the instruction at PC into UIOUT and returns the length of the
174 printed instruction in bytes. */
177 gdb_pretty_print_insn (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
178 struct disassemble_info
* di
, CORE_ADDR pc
, int flags
,
181 /* parts of the symbolic representation of the address */
186 struct cleanup
*ui_out_chain
;
187 char *filename
= NULL
;
190 ui_out_chain
= make_cleanup_ui_out_tuple_begin_end (uiout
, NULL
);
192 if ((flags
& DISASSEMBLY_OMIT_PC
) == 0)
193 ui_out_text (uiout
, pc_prefix (pc
));
194 ui_out_field_core_addr (uiout
, "address", gdbarch
, pc
);
196 if (!build_address_symbolic (gdbarch
, pc
, 0, &name
, &offset
, &filename
,
199 /* We don't care now about line, filename and unmapped. But we might in
201 ui_out_text (uiout
, " <");
202 if ((flags
& DISASSEMBLY_OMIT_FNAME
) == 0)
203 ui_out_field_string (uiout
, "func-name", name
);
204 ui_out_text (uiout
, "+");
205 ui_out_field_int (uiout
, "offset", offset
);
206 ui_out_text (uiout
, ">:\t");
209 ui_out_text (uiout
, ":\t");
211 if (filename
!= NULL
)
216 ui_file_rewind (stb
);
217 if (flags
& DISASSEMBLY_RAW_INSN
)
222 const char *spacer
= "";
224 /* Build the opcodes using a temporary stream so we can
225 write them out in a single go for the MI. */
226 struct ui_file
*opcode_stream
= mem_fileopen ();
227 struct cleanup
*cleanups
=
228 make_cleanup_ui_file_delete (opcode_stream
);
230 size
= gdbarch_print_insn (gdbarch
, pc
, di
);
233 for (;pc
< end_pc
; ++pc
)
235 err
= (*di
->read_memory_func
) (pc
, &data
, 1, di
);
237 (*di
->memory_error_func
) (err
, pc
, di
);
238 fprintf_filtered (opcode_stream
, "%s%02x",
239 spacer
, (unsigned) data
);
243 ui_out_field_stream (uiout
, "opcodes", opcode_stream
);
244 ui_out_text (uiout
, "\t");
246 do_cleanups (cleanups
);
249 size
= gdbarch_print_insn (gdbarch
, pc
, di
);
251 ui_out_field_stream (uiout
, "inst", stb
);
252 ui_file_rewind (stb
);
253 do_cleanups (ui_out_chain
);
254 ui_out_text (uiout
, "\n");
260 dump_insns (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
261 struct disassemble_info
* di
,
262 CORE_ADDR low
, CORE_ADDR high
,
263 int how_many
, int flags
, struct ui_file
*stb
,
266 int num_displayed
= 0;
268 while (low
< high
&& (how_many
< 0 || num_displayed
< how_many
))
272 size
= gdb_pretty_print_insn (gdbarch
, uiout
, di
, low
, flags
, stb
);
279 /* Allow user to bail out with ^C. */
286 return num_displayed
;
289 /* The idea here is to present a source-O-centric view of a
290 function to the user. This means that things are presented
291 in source order, with (possibly) out of order assembly
292 immediately following.
294 N.B. This view is deprecated. */
297 do_mixed_source_and_assembly_deprecated
298 (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
299 struct disassemble_info
*di
, struct symtab
*symtab
,
300 CORE_ADDR low
, CORE_ADDR high
,
301 int how_many
, int flags
, struct ui_file
*stb
)
305 struct linetable_entry
*le
;
306 struct deprecated_dis_line_entry
*mle
;
307 struct symtab_and_line sal
;
309 int out_of_order
= 0;
311 int num_displayed
= 0;
312 enum print_source_lines_flags psl_flags
= 0;
313 struct cleanup
*ui_out_chain
;
314 struct cleanup
*ui_out_tuple_chain
= make_cleanup (null_cleanup
, 0);
315 struct cleanup
*ui_out_list_chain
= make_cleanup (null_cleanup
, 0);
317 gdb_assert (symtab
!= NULL
&& SYMTAB_LINETABLE (symtab
) != NULL
);
319 nlines
= SYMTAB_LINETABLE (symtab
)->nitems
;
320 le
= SYMTAB_LINETABLE (symtab
)->item
;
322 if (flags
& DISASSEMBLY_FILENAME
)
323 psl_flags
|= PRINT_SOURCE_LINES_FILENAME
;
325 mle
= (struct deprecated_dis_line_entry
*)
326 alloca (nlines
* sizeof (struct deprecated_dis_line_entry
));
328 /* Copy linetable entries for this function into our data
329 structure, creating end_pc's and setting out_of_order as
332 /* First, skip all the preceding functions. */
334 for (i
= 0; i
< nlines
- 1 && le
[i
].pc
< low
; i
++);
336 /* Now, copy all entries before the end of this function. */
338 for (; i
< nlines
- 1 && le
[i
].pc
< high
; i
++)
340 if (le
[i
].line
== le
[i
+ 1].line
&& le
[i
].pc
== le
[i
+ 1].pc
)
341 continue; /* Ignore duplicates. */
343 /* Skip any end-of-function markers. */
347 mle
[newlines
].line
= le
[i
].line
;
348 if (le
[i
].line
> le
[i
+ 1].line
)
350 mle
[newlines
].start_pc
= le
[i
].pc
;
351 mle
[newlines
].end_pc
= le
[i
+ 1].pc
;
355 /* If we're on the last line, and it's part of the function,
356 then we need to get the end pc in a special way. */
358 if (i
== nlines
- 1 && le
[i
].pc
< high
)
360 mle
[newlines
].line
= le
[i
].line
;
361 mle
[newlines
].start_pc
= le
[i
].pc
;
362 sal
= find_pc_line (le
[i
].pc
, 0);
363 mle
[newlines
].end_pc
= sal
.end
;
367 /* Now, sort mle by line #s (and, then by addresses within lines). */
370 qsort (mle
, newlines
, sizeof (struct deprecated_dis_line_entry
),
373 /* Now, for each line entry, emit the specified lines (unless
374 they have been emitted before), followed by the assembly code
377 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
379 for (i
= 0; i
< newlines
; i
++)
381 /* Print out everything from next_line to the current line. */
382 if (mle
[i
].line
>= next_line
)
386 /* Just one line to print. */
387 if (next_line
== mle
[i
].line
)
390 = make_cleanup_ui_out_tuple_begin_end (uiout
,
392 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, psl_flags
);
396 /* Several source lines w/o asm instructions associated. */
397 for (; next_line
< mle
[i
].line
; next_line
++)
399 struct cleanup
*ui_out_list_chain_line
;
400 struct cleanup
*ui_out_tuple_chain_line
;
402 ui_out_tuple_chain_line
403 = make_cleanup_ui_out_tuple_begin_end (uiout
,
405 print_source_lines (symtab
, next_line
, next_line
+ 1,
407 ui_out_list_chain_line
408 = make_cleanup_ui_out_list_begin_end (uiout
,
410 do_cleanups (ui_out_list_chain_line
);
411 do_cleanups (ui_out_tuple_chain_line
);
413 /* Print the last line and leave list open for
414 asm instructions to be added. */
416 = make_cleanup_ui_out_tuple_begin_end (uiout
,
418 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, psl_flags
);
424 = make_cleanup_ui_out_tuple_begin_end (uiout
,
426 print_source_lines (symtab
, mle
[i
].line
, mle
[i
].line
+ 1, psl_flags
);
429 next_line
= mle
[i
].line
+ 1;
431 = make_cleanup_ui_out_list_begin_end (uiout
, "line_asm_insn");
434 num_displayed
+= dump_insns (gdbarch
, uiout
, di
,
435 mle
[i
].start_pc
, mle
[i
].end_pc
,
436 how_many
, flags
, stb
, NULL
);
438 /* When we've reached the end of the mle array, or we've seen the last
439 assembly range for this source line, close out the list/tuple. */
440 if (i
== (newlines
- 1) || mle
[i
+ 1].line
> mle
[i
].line
)
442 do_cleanups (ui_out_list_chain
);
443 do_cleanups (ui_out_tuple_chain
);
444 ui_out_tuple_chain
= make_cleanup (null_cleanup
, 0);
445 ui_out_list_chain
= make_cleanup (null_cleanup
, 0);
446 ui_out_text (uiout
, "\n");
448 if (how_many
>= 0 && num_displayed
>= how_many
)
451 do_cleanups (ui_out_chain
);
454 /* The idea here is to present a source-O-centric view of a
455 function to the user. This means that things are presented
456 in source order, with (possibly) out of order assembly
457 immediately following. */
460 do_mixed_source_and_assembly (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
461 struct disassemble_info
*di
,
462 struct symtab
*main_symtab
,
463 CORE_ADDR low
, CORE_ADDR high
,
464 int how_many
, int flags
, struct ui_file
*stb
)
467 const struct linetable_entry
*le
, *first_le
;
468 struct symtab_and_line sal
;
470 int out_of_order
= 0;
472 int num_displayed
= 0;
473 enum print_source_lines_flags psl_flags
= 0;
474 struct cleanup
*cleanups
;
475 struct cleanup
*ui_out_chain
;
476 struct cleanup
*ui_out_tuple_chain
;
477 struct cleanup
*ui_out_list_chain
;
479 struct symtab
*last_symtab
;
481 htab_t dis_line_table
;
483 gdb_assert (main_symtab
!= NULL
&& SYMTAB_LINETABLE (main_symtab
) != NULL
);
485 /* First pass: collect the list of all source files and lines.
486 We do this so that we can only print lines containing code once.
487 We try to print the source text leading up to the next instruction,
488 but if that text is for code that will be disassembled later, then
489 we'll want to defer printing it until later with its associated code. */
491 dis_line_table
= allocate_dis_line_table ();
492 cleanups
= make_cleanup_htab_delete (dis_line_table
);
496 /* The prologue may be empty, but there may still be a line number entry
497 for the opening brace which is distinct from the first line of code.
498 If the prologue has been eliminated find_pc_line may return the source
499 line after the opening brace. We still want to print this opening brace.
500 first_le is used to implement this. */
502 nlines
= SYMTAB_LINETABLE (main_symtab
)->nitems
;
503 le
= SYMTAB_LINETABLE (main_symtab
)->item
;
506 /* Skip all the preceding functions. */
507 for (i
= 0; i
< nlines
&& le
[i
].pc
< low
; i
++)
510 if (i
< nlines
&& le
[i
].pc
< high
)
513 /* Add lines for every pc value. */
516 struct symtab_and_line sal
;
519 sal
= find_pc_line (pc
, 0);
520 length
= gdb_insn_length (gdbarch
, pc
);
523 if (sal
.symtab
!= NULL
)
524 maybe_add_dis_line_entry (dis_line_table
, sal
.symtab
, sal
.line
);
527 /* Second pass: print the disassembly.
529 Output format, from an MI perspective:
530 The result is a ui_out list, field name "asm_insns", where elements have
531 name "src_and_asm_line".
532 Each element is a tuple of source line specs (field names line, file,
533 fullname), and field "line_asm_insn" which contains the disassembly.
534 Field "line_asm_insn" is a list of tuples: address, func-name, offset,
537 CLI output works on top of this because MI ignores ui_out_text output,
538 which is where we put file name and source line contents output.
542 For things created at the beginning of this function and need to be
543 kept until the end of this function.
545 Handles the outer "asm_insns" list.
547 The tuples for each group of consecutive disassemblies.
549 List of consecutive source lines or disassembled insns. */
551 if (flags
& DISASSEMBLY_FILENAME
)
552 psl_flags
|= PRINT_SOURCE_LINES_FILENAME
;
554 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
556 ui_out_tuple_chain
= NULL
;
557 ui_out_list_chain
= NULL
;
565 struct linetable_entry
*le
= NULL
;
566 struct symtab_and_line sal
;
568 int start_preceding_line_to_display
= 0;
569 int end_preceding_line_to_display
= 0;
570 int new_source_line
= 0;
572 sal
= find_pc_line (pc
, 0);
574 if (sal
.symtab
!= last_symtab
)
576 /* New source file. */
579 /* If this is the first line of output, check for any preceding
583 && first_le
->line
< sal
.line
)
585 start_preceding_line_to_display
= first_le
->line
;
586 end_preceding_line_to_display
= sal
.line
;
591 /* Same source file as last time. */
592 if (sal
.symtab
!= NULL
)
594 if (sal
.line
> last_line
+ 1 && last_line
!= 0)
598 /* Several preceding source lines. Print the trailing ones
599 not associated with code that we'll print later. */
600 for (l
= sal
.line
- 1; l
> last_line
; --l
)
602 if (line_has_code_p (dis_line_table
, sal
.symtab
, l
))
605 if (l
< sal
.line
- 1)
607 start_preceding_line_to_display
= l
+ 1;
608 end_preceding_line_to_display
= sal
.line
;
611 if (sal
.line
!= last_line
)
615 /* Same source line as last time. This can happen, depending
616 on the debug info. */
623 /* Skip the newline if this is the first instruction. */
625 ui_out_text (uiout
, "\n");
626 if (ui_out_tuple_chain
!= NULL
)
628 gdb_assert (ui_out_list_chain
!= NULL
);
629 do_cleanups (ui_out_list_chain
);
630 do_cleanups (ui_out_tuple_chain
);
632 if (sal
.symtab
!= last_symtab
633 && !(flags
& DISASSEMBLY_FILENAME
))
635 /* Remember MI ignores ui_out_text.
636 We don't have to do anything here for MI because MI
637 output includes the source specs for each line. */
638 if (sal
.symtab
!= NULL
)
641 symtab_to_filename_for_display (sal
.symtab
));
644 ui_out_text (uiout
, "unknown");
645 ui_out_text (uiout
, ":\n");
647 if (start_preceding_line_to_display
> 0)
649 /* Several source lines w/o asm instructions associated.
650 We need to preserve the structure of the output, so output
651 a bunch of line tuples with no asm entries. */
653 struct cleanup
*ui_out_list_chain_line
;
654 struct cleanup
*ui_out_tuple_chain_line
;
656 gdb_assert (sal
.symtab
!= NULL
);
657 for (l
= start_preceding_line_to_display
;
658 l
< end_preceding_line_to_display
;
661 ui_out_tuple_chain_line
662 = make_cleanup_ui_out_tuple_begin_end (uiout
,
664 print_source_lines (sal
.symtab
, l
, l
+ 1, psl_flags
);
665 ui_out_list_chain_line
666 = make_cleanup_ui_out_list_begin_end (uiout
,
668 do_cleanups (ui_out_list_chain_line
);
669 do_cleanups (ui_out_tuple_chain_line
);
673 = make_cleanup_ui_out_tuple_begin_end (uiout
, "src_and_asm_line");
674 if (sal
.symtab
!= NULL
)
675 print_source_lines (sal
.symtab
, sal
.line
, sal
.line
+ 1, psl_flags
);
677 ui_out_text (uiout
, _("--- no source info for this pc ---\n"));
679 = make_cleanup_ui_out_list_begin_end (uiout
, "line_asm_insn");
683 /* Here we're appending instructions to an existing line.
684 By construction the very first insn will have a symtab
685 and follow the new_source_line path above. */
686 gdb_assert (ui_out_tuple_chain
!= NULL
);
687 gdb_assert (ui_out_list_chain
!= NULL
);
691 end_pc
= min (sal
.end
, high
);
694 num_displayed
+= dump_insns (gdbarch
, uiout
, di
, pc
, end_pc
,
695 how_many
, flags
, stb
, &end_pc
);
698 if (how_many
>= 0 && num_displayed
>= how_many
)
701 last_symtab
= sal
.symtab
;
702 last_line
= sal
.line
;
705 do_cleanups (ui_out_chain
);
706 do_cleanups (cleanups
);
710 do_assembly_only (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
711 struct disassemble_info
* di
,
712 CORE_ADDR low
, CORE_ADDR high
,
713 int how_many
, int flags
, struct ui_file
*stb
)
715 int num_displayed
= 0;
716 struct cleanup
*ui_out_chain
;
718 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
720 num_displayed
= dump_insns (gdbarch
, uiout
, di
, low
, high
, how_many
,
723 do_cleanups (ui_out_chain
);
726 /* Initialize the disassemble info struct ready for the specified
729 static int ATTRIBUTE_PRINTF (2, 3)
730 fprintf_disasm (void *stream
, const char *format
, ...)
734 va_start (args
, format
);
735 vfprintf_filtered ((struct ui_file
*) stream
, format
, args
);
737 /* Something non -ve. */
741 struct disassemble_info
742 gdb_disassemble_info (struct gdbarch
*gdbarch
, struct ui_file
*file
)
744 struct disassemble_info di
;
746 init_disassemble_info (&di
, file
, fprintf_disasm
);
747 di
.flavour
= bfd_target_unknown_flavour
;
748 di
.memory_error_func
= dis_asm_memory_error
;
749 di
.print_address_func
= dis_asm_print_address
;
750 /* NOTE: cagney/2003-04-28: The original code, from the old Insight
751 disassembler had a local optomization here. By default it would
752 access the executable file, instead of the target memory (there
753 was a growing list of exceptions though). Unfortunately, the
754 heuristic was flawed. Commands like "disassemble &variable"
755 didn't work as they relied on the access going to the target.
756 Further, it has been supperseeded by trust-read-only-sections
757 (although that should be superseeded by target_trust..._p()). */
758 di
.read_memory_func
= dis_asm_read_memory
;
759 di
.arch
= gdbarch_bfd_arch_info (gdbarch
)->arch
;
760 di
.mach
= gdbarch_bfd_arch_info (gdbarch
)->mach
;
761 di
.endian
= gdbarch_byte_order (gdbarch
);
762 di
.endian_code
= gdbarch_byte_order_for_code (gdbarch
);
763 di
.application_data
= gdbarch
;
764 disassemble_init_for_target (&di
);
769 gdb_disassembly (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
770 char *file_string
, int flags
, int how_many
,
771 CORE_ADDR low
, CORE_ADDR high
)
773 struct ui_file
*stb
= mem_fileopen ();
774 struct cleanup
*cleanups
= make_cleanup_ui_file_delete (stb
);
775 struct disassemble_info di
= gdb_disassemble_info (gdbarch
, stb
);
776 struct symtab
*symtab
;
777 struct linetable_entry
*le
= NULL
;
780 /* Assume symtab is valid for whole PC range. */
781 symtab
= find_pc_line_symtab (low
);
783 if (symtab
!= NULL
&& SYMTAB_LINETABLE (symtab
) != NULL
)
784 nlines
= SYMTAB_LINETABLE (symtab
)->nitems
;
786 if (!(flags
& (DISASSEMBLY_SOURCE_DEPRECATED
| DISASSEMBLY_SOURCE
))
788 do_assembly_only (gdbarch
, uiout
, &di
, low
, high
, how_many
, flags
, stb
);
790 else if (flags
& DISASSEMBLY_SOURCE
)
791 do_mixed_source_and_assembly (gdbarch
, uiout
, &di
, symtab
, low
, high
,
792 how_many
, flags
, stb
);
794 else if (flags
& DISASSEMBLY_SOURCE_DEPRECATED
)
795 do_mixed_source_and_assembly_deprecated (gdbarch
, uiout
, &di
, symtab
,
796 low
, high
, how_many
, flags
, stb
);
798 do_cleanups (cleanups
);
799 gdb_flush (gdb_stdout
);
802 /* Print the instruction at address MEMADDR in debugged memory,
803 on STREAM. Returns the length of the instruction, in bytes,
804 and, if requested, the number of branch delay slot instructions. */
807 gdb_print_insn (struct gdbarch
*gdbarch
, CORE_ADDR memaddr
,
808 struct ui_file
*stream
, int *branch_delay_insns
)
810 struct disassemble_info di
;
813 di
= gdb_disassemble_info (gdbarch
, stream
);
814 length
= gdbarch_print_insn (gdbarch
, memaddr
, &di
);
815 if (branch_delay_insns
)
817 if (di
.insn_info_valid
)
818 *branch_delay_insns
= di
.branch_delay_insns
;
820 *branch_delay_insns
= 0;
826 do_ui_file_delete (void *arg
)
828 ui_file_delete ((struct ui_file
*) arg
);
831 /* Return the length in bytes of the instruction at address MEMADDR in
835 gdb_insn_length (struct gdbarch
*gdbarch
, CORE_ADDR addr
)
837 static struct ui_file
*null_stream
= NULL
;
839 /* Dummy file descriptor for the disassembler. */
842 null_stream
= ui_file_new ();
843 make_final_cleanup (do_ui_file_delete
, null_stream
);
846 return gdb_print_insn (gdbarch
, addr
, null_stream
, NULL
);
849 /* fprintf-function for gdb_buffered_insn_length. This function is a
850 nop, we don't want to print anything, we just want to compute the
851 length of the insn. */
853 static int ATTRIBUTE_PRINTF (2, 3)
854 gdb_buffered_insn_length_fprintf (void *stream
, const char *format
, ...)
859 /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
862 gdb_buffered_insn_length_init_dis (struct gdbarch
*gdbarch
,
863 struct disassemble_info
*di
,
864 const gdb_byte
*insn
, int max_len
,
867 init_disassemble_info (di
, NULL
, gdb_buffered_insn_length_fprintf
);
869 /* init_disassemble_info installs buffer_read_memory, etc.
870 so we don't need to do that here.
871 The cast is necessary until disassemble_info is const-ified. */
872 di
->buffer
= (gdb_byte
*) insn
;
873 di
->buffer_length
= max_len
;
874 di
->buffer_vma
= addr
;
876 di
->arch
= gdbarch_bfd_arch_info (gdbarch
)->arch
;
877 di
->mach
= gdbarch_bfd_arch_info (gdbarch
)->mach
;
878 di
->endian
= gdbarch_byte_order (gdbarch
);
879 di
->endian_code
= gdbarch_byte_order_for_code (gdbarch
);
881 disassemble_init_for_target (di
);
884 /* Return the length in bytes of INSN. MAX_LEN is the size of the
885 buffer containing INSN. */
888 gdb_buffered_insn_length (struct gdbarch
*gdbarch
,
889 const gdb_byte
*insn
, int max_len
, CORE_ADDR addr
)
891 struct disassemble_info di
;
893 gdb_buffered_insn_length_init_dis (gdbarch
, &di
, insn
, max_len
, addr
);
895 return gdbarch_print_insn (gdbarch
, addr
, &di
);