1 /* Disassemble support for GDB.
3 Copyright (C) 2000-2017 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/>. */
30 /* Disassemble functions.
31 FIXME: We should get rid of all the duplicate code in gdb that does
32 the same thing: disassemble_command() and the gdbtk variation. */
34 /* This structure is used to store line number information for the
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. */
40 struct deprecated_dis_line_entry
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. */
54 struct symtab
*symtab
;
58 /* Hash function for dis_line_entry. */
61 hash_dis_line_entry (const void *item
)
63 const struct dis_line_entry
*dle
= (const struct dis_line_entry
*) item
;
65 return htab_hash_pointer (dle
->symtab
) + dle
->line
;
68 /* Equal function for dis_line_entry. */
71 eq_dis_line_entry (const void *item_lhs
, const void *item_rhs
)
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
;
76 return (lhs
->symtab
== rhs
->symtab
77 && lhs
->line
== rhs
->line
);
80 /* Create the table to manage lines for mixed source/disassembly. */
83 allocate_dis_line_table (void)
85 return htab_create_alloc (41,
86 hash_dis_line_entry
, eq_dis_line_entry
,
87 xfree
, xcalloc
, xfree
);
90 /* Add a new dis_line_entry containing SYMTAB and LINE to TABLE. */
93 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
;
176 gdb_pretty_print_insn (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
177 struct disassemble_info
* di
,
178 const struct disasm_insn
*insn
, int flags
,
181 /* parts of the symbolic representation of the address */
186 struct cleanup
*ui_out_chain
;
187 char *filename
= NULL
;
191 ui_out_chain
= make_cleanup_ui_out_tuple_begin_end (uiout
, NULL
);
194 if (insn
->number
!= 0)
196 uiout
->field_fmt ("insn-number", "%u", insn
->number
);
200 if ((flags
& DISASSEMBLY_SPECULATIVE
) != 0)
202 if (insn
->is_speculative
)
204 uiout
->field_string ("is-speculative", "?");
206 /* The speculative execution indication overwrites the first
207 character of the PC prefix.
208 We assume a PC prefix length of 3 characters. */
209 if ((flags
& DISASSEMBLY_OMIT_PC
) == 0)
210 uiout
->text (pc_prefix (pc
) + 1);
214 else if ((flags
& DISASSEMBLY_OMIT_PC
) == 0)
215 uiout
->text (pc_prefix (pc
));
219 else if ((flags
& DISASSEMBLY_OMIT_PC
) == 0)
220 uiout
->text (pc_prefix (pc
));
221 uiout
->field_core_addr ("address", gdbarch
, pc
);
223 if (!build_address_symbolic (gdbarch
, pc
, 0, &name
, &offset
, &filename
,
226 /* We don't care now about line, filename and unmapped. But we might in
229 if ((flags
& DISASSEMBLY_OMIT_FNAME
) == 0)
230 uiout
->field_string ("func-name", name
);
232 uiout
->field_int ("offset", offset
);
233 uiout
->text (">:\t");
238 if (filename
!= NULL
)
243 ui_file_rewind (stb
);
244 if (flags
& DISASSEMBLY_RAW_INSN
)
249 const char *spacer
= "";
251 /* Build the opcodes using a temporary stream so we can
252 write them out in a single go for the MI. */
253 struct ui_file
*opcode_stream
= mem_fileopen ();
254 struct cleanup
*cleanups
=
255 make_cleanup_ui_file_delete (opcode_stream
);
257 size
= gdbarch_print_insn (gdbarch
, pc
, di
);
260 for (;pc
< end_pc
; ++pc
)
262 err
= (*di
->read_memory_func
) (pc
, &data
, 1, di
);
264 (*di
->memory_error_func
) (err
, pc
, di
);
265 fprintf_filtered (opcode_stream
, "%s%02x",
266 spacer
, (unsigned) data
);
270 uiout
->field_stream ("opcodes", opcode_stream
);
273 do_cleanups (cleanups
);
276 size
= gdbarch_print_insn (gdbarch
, pc
, di
);
278 uiout
->field_stream ("inst", stb
);
279 ui_file_rewind (stb
);
280 do_cleanups (ui_out_chain
);
287 dump_insns (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
288 struct disassemble_info
* di
,
289 CORE_ADDR low
, CORE_ADDR high
,
290 int how_many
, int flags
, struct ui_file
*stb
,
293 struct disasm_insn insn
;
294 int num_displayed
= 0;
296 memset (&insn
, 0, sizeof (insn
));
299 while (insn
.addr
< high
&& (how_many
< 0 || num_displayed
< how_many
))
303 size
= gdb_pretty_print_insn (gdbarch
, uiout
, di
, &insn
, flags
, stb
);
310 /* Allow user to bail out with ^C. */
317 return num_displayed
;
320 /* The idea here is to present a source-O-centric view of a
321 function to the user. This means that things are presented
322 in source order, with (possibly) out of order assembly
323 immediately following.
325 N.B. This view is deprecated. */
328 do_mixed_source_and_assembly_deprecated
329 (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
330 struct disassemble_info
*di
, struct symtab
*symtab
,
331 CORE_ADDR low
, CORE_ADDR high
,
332 int how_many
, int flags
, struct ui_file
*stb
)
336 struct linetable_entry
*le
;
337 struct deprecated_dis_line_entry
*mle
;
338 struct symtab_and_line sal
;
340 int out_of_order
= 0;
342 int num_displayed
= 0;
343 print_source_lines_flags psl_flags
= 0;
344 struct cleanup
*ui_out_chain
;
345 struct cleanup
*ui_out_tuple_chain
= make_cleanup (null_cleanup
, 0);
346 struct cleanup
*ui_out_list_chain
= make_cleanup (null_cleanup
, 0);
348 gdb_assert (symtab
!= NULL
&& SYMTAB_LINETABLE (symtab
) != NULL
);
350 nlines
= SYMTAB_LINETABLE (symtab
)->nitems
;
351 le
= SYMTAB_LINETABLE (symtab
)->item
;
353 if (flags
& DISASSEMBLY_FILENAME
)
354 psl_flags
|= PRINT_SOURCE_LINES_FILENAME
;
356 mle
= (struct deprecated_dis_line_entry
*)
357 alloca (nlines
* sizeof (struct deprecated_dis_line_entry
));
359 /* Copy linetable entries for this function into our data
360 structure, creating end_pc's and setting out_of_order as
363 /* First, skip all the preceding functions. */
365 for (i
= 0; i
< nlines
- 1 && le
[i
].pc
< low
; i
++);
367 /* Now, copy all entries before the end of this function. */
369 for (; i
< nlines
- 1 && le
[i
].pc
< high
; i
++)
371 if (le
[i
].line
== le
[i
+ 1].line
&& le
[i
].pc
== le
[i
+ 1].pc
)
372 continue; /* Ignore duplicates. */
374 /* Skip any end-of-function markers. */
378 mle
[newlines
].line
= le
[i
].line
;
379 if (le
[i
].line
> le
[i
+ 1].line
)
381 mle
[newlines
].start_pc
= le
[i
].pc
;
382 mle
[newlines
].end_pc
= le
[i
+ 1].pc
;
386 /* If we're on the last line, and it's part of the function,
387 then we need to get the end pc in a special way. */
389 if (i
== nlines
- 1 && le
[i
].pc
< high
)
391 mle
[newlines
].line
= le
[i
].line
;
392 mle
[newlines
].start_pc
= le
[i
].pc
;
393 sal
= find_pc_line (le
[i
].pc
, 0);
394 mle
[newlines
].end_pc
= sal
.end
;
398 /* Now, sort mle by line #s (and, then by addresses within lines). */
401 qsort (mle
, newlines
, sizeof (struct deprecated_dis_line_entry
),
404 /* Now, for each line entry, emit the specified lines (unless
405 they have been emitted before), followed by the assembly code
408 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
410 for (i
= 0; i
< newlines
; i
++)
412 /* Print out everything from next_line to the current line. */
413 if (mle
[i
].line
>= next_line
)
417 /* Just one line to print. */
418 if (next_line
== mle
[i
].line
)
421 = make_cleanup_ui_out_tuple_begin_end (uiout
,
423 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, psl_flags
);
427 /* Several source lines w/o asm instructions associated. */
428 for (; next_line
< mle
[i
].line
; next_line
++)
430 struct cleanup
*ui_out_list_chain_line
;
431 struct cleanup
*ui_out_tuple_chain_line
;
433 ui_out_tuple_chain_line
434 = make_cleanup_ui_out_tuple_begin_end (uiout
,
436 print_source_lines (symtab
, next_line
, next_line
+ 1,
438 ui_out_list_chain_line
439 = make_cleanup_ui_out_list_begin_end (uiout
,
441 do_cleanups (ui_out_list_chain_line
);
442 do_cleanups (ui_out_tuple_chain_line
);
444 /* Print the last line and leave list open for
445 asm instructions to be added. */
447 = make_cleanup_ui_out_tuple_begin_end (uiout
,
449 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, psl_flags
);
455 = make_cleanup_ui_out_tuple_begin_end (uiout
,
457 print_source_lines (symtab
, mle
[i
].line
, mle
[i
].line
+ 1, psl_flags
);
460 next_line
= mle
[i
].line
+ 1;
462 = make_cleanup_ui_out_list_begin_end (uiout
, "line_asm_insn");
465 num_displayed
+= dump_insns (gdbarch
, uiout
, di
,
466 mle
[i
].start_pc
, mle
[i
].end_pc
,
467 how_many
, flags
, stb
, NULL
);
469 /* When we've reached the end of the mle array, or we've seen the last
470 assembly range for this source line, close out the list/tuple. */
471 if (i
== (newlines
- 1) || mle
[i
+ 1].line
> mle
[i
].line
)
473 do_cleanups (ui_out_list_chain
);
474 do_cleanups (ui_out_tuple_chain
);
475 ui_out_tuple_chain
= make_cleanup (null_cleanup
, 0);
476 ui_out_list_chain
= make_cleanup (null_cleanup
, 0);
479 if (how_many
>= 0 && num_displayed
>= how_many
)
482 do_cleanups (ui_out_chain
);
485 /* The idea here is to present a source-O-centric view of a
486 function to the user. This means that things are presented
487 in source order, with (possibly) out of order assembly
488 immediately following. */
491 do_mixed_source_and_assembly (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
492 struct disassemble_info
*di
,
493 struct symtab
*main_symtab
,
494 CORE_ADDR low
, CORE_ADDR high
,
495 int how_many
, int flags
, struct ui_file
*stb
)
497 const struct linetable_entry
*le
, *first_le
;
499 int num_displayed
= 0;
500 print_source_lines_flags psl_flags
= 0;
501 struct cleanup
*ui_out_chain
;
502 struct cleanup
*ui_out_tuple_chain
;
503 struct cleanup
*ui_out_list_chain
;
505 struct symtab
*last_symtab
;
508 gdb_assert (main_symtab
!= NULL
&& SYMTAB_LINETABLE (main_symtab
) != NULL
);
510 /* First pass: collect the list of all source files and lines.
511 We do this so that we can only print lines containing code once.
512 We try to print the source text leading up to the next instruction,
513 but if that text is for code that will be disassembled later, then
514 we'll want to defer printing it until later with its associated code. */
516 htab_up
dis_line_table (allocate_dis_line_table ());
520 /* The prologue may be empty, but there may still be a line number entry
521 for the opening brace which is distinct from the first line of code.
522 If the prologue has been eliminated find_pc_line may return the source
523 line after the opening brace. We still want to print this opening brace.
524 first_le is used to implement this. */
526 nlines
= SYMTAB_LINETABLE (main_symtab
)->nitems
;
527 le
= SYMTAB_LINETABLE (main_symtab
)->item
;
530 /* Skip all the preceding functions. */
531 for (i
= 0; i
< nlines
&& le
[i
].pc
< low
; i
++)
534 if (i
< nlines
&& le
[i
].pc
< high
)
537 /* Add lines for every pc value. */
540 struct symtab_and_line sal
;
543 sal
= find_pc_line (pc
, 0);
544 length
= gdb_insn_length (gdbarch
, pc
);
547 if (sal
.symtab
!= NULL
)
548 add_dis_line_entry (dis_line_table
.get (), sal
.symtab
, sal
.line
);
551 /* Second pass: print the disassembly.
553 Output format, from an MI perspective:
554 The result is a ui_out list, field name "asm_insns", where elements have
555 name "src_and_asm_line".
556 Each element is a tuple of source line specs (field names line, file,
557 fullname), and field "line_asm_insn" which contains the disassembly.
558 Field "line_asm_insn" is a list of tuples: address, func-name, offset,
561 CLI output works on top of this because MI ignores ui_out_text output,
562 which is where we put file name and source line contents output.
566 Handles the outer "asm_insns" list.
568 The tuples for each group of consecutive disassemblies.
570 List of consecutive source lines or disassembled insns. */
572 if (flags
& DISASSEMBLY_FILENAME
)
573 psl_flags
|= PRINT_SOURCE_LINES_FILENAME
;
575 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
577 ui_out_tuple_chain
= NULL
;
578 ui_out_list_chain
= NULL
;
586 struct symtab_and_line sal
;
588 int start_preceding_line_to_display
= 0;
589 int end_preceding_line_to_display
= 0;
590 int new_source_line
= 0;
592 sal
= find_pc_line (pc
, 0);
594 if (sal
.symtab
!= last_symtab
)
596 /* New source file. */
599 /* If this is the first line of output, check for any preceding
603 && first_le
->line
< sal
.line
)
605 start_preceding_line_to_display
= first_le
->line
;
606 end_preceding_line_to_display
= sal
.line
;
611 /* Same source file as last time. */
612 if (sal
.symtab
!= NULL
)
614 if (sal
.line
> last_line
+ 1 && last_line
!= 0)
618 /* Several preceding source lines. Print the trailing ones
619 not associated with code that we'll print later. */
620 for (l
= sal
.line
- 1; l
> last_line
; --l
)
622 if (line_has_code_p (dis_line_table
.get (),
626 if (l
< sal
.line
- 1)
628 start_preceding_line_to_display
= l
+ 1;
629 end_preceding_line_to_display
= sal
.line
;
632 if (sal
.line
!= last_line
)
636 /* Same source line as last time. This can happen, depending
637 on the debug info. */
644 /* Skip the newline if this is the first instruction. */
647 if (ui_out_tuple_chain
!= NULL
)
649 gdb_assert (ui_out_list_chain
!= NULL
);
650 do_cleanups (ui_out_list_chain
);
651 do_cleanups (ui_out_tuple_chain
);
653 if (sal
.symtab
!= last_symtab
654 && !(flags
& DISASSEMBLY_FILENAME
))
656 /* Remember MI ignores ui_out_text.
657 We don't have to do anything here for MI because MI
658 output includes the source specs for each line. */
659 if (sal
.symtab
!= NULL
)
661 uiout
->text (symtab_to_filename_for_display (sal
.symtab
));
664 uiout
->text ("unknown");
667 if (start_preceding_line_to_display
> 0)
669 /* Several source lines w/o asm instructions associated.
670 We need to preserve the structure of the output, so output
671 a bunch of line tuples with no asm entries. */
673 struct cleanup
*ui_out_list_chain_line
;
674 struct cleanup
*ui_out_tuple_chain_line
;
676 gdb_assert (sal
.symtab
!= NULL
);
677 for (l
= start_preceding_line_to_display
;
678 l
< end_preceding_line_to_display
;
681 ui_out_tuple_chain_line
682 = make_cleanup_ui_out_tuple_begin_end (uiout
,
684 print_source_lines (sal
.symtab
, l
, l
+ 1, psl_flags
);
685 ui_out_list_chain_line
686 = make_cleanup_ui_out_list_begin_end (uiout
,
688 do_cleanups (ui_out_list_chain_line
);
689 do_cleanups (ui_out_tuple_chain_line
);
693 = make_cleanup_ui_out_tuple_begin_end (uiout
, "src_and_asm_line");
694 if (sal
.symtab
!= NULL
)
695 print_source_lines (sal
.symtab
, sal
.line
, sal
.line
+ 1, psl_flags
);
697 uiout
->text (_("--- no source info for this pc ---\n"));
699 = make_cleanup_ui_out_list_begin_end (uiout
, "line_asm_insn");
703 /* Here we're appending instructions to an existing line.
704 By construction the very first insn will have a symtab
705 and follow the new_source_line path above. */
706 gdb_assert (ui_out_tuple_chain
!= NULL
);
707 gdb_assert (ui_out_list_chain
!= NULL
);
711 end_pc
= std::min (sal
.end
, high
);
714 num_displayed
+= dump_insns (gdbarch
, uiout
, di
, pc
, end_pc
,
715 how_many
, flags
, stb
, &end_pc
);
718 if (how_many
>= 0 && num_displayed
>= how_many
)
721 last_symtab
= sal
.symtab
;
722 last_line
= sal
.line
;
725 do_cleanups (ui_out_chain
);
729 do_assembly_only (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
730 struct disassemble_info
* di
,
731 CORE_ADDR low
, CORE_ADDR high
,
732 int how_many
, int flags
, struct ui_file
*stb
)
734 struct cleanup
*ui_out_chain
;
736 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
738 dump_insns (gdbarch
, uiout
, di
, low
, high
, how_many
, flags
, stb
, NULL
);
740 do_cleanups (ui_out_chain
);
743 /* Initialize the disassemble info struct ready for the specified
746 static int ATTRIBUTE_PRINTF (2, 3)
747 fprintf_disasm (void *stream
, const char *format
, ...)
751 va_start (args
, format
);
752 vfprintf_filtered ((struct ui_file
*) stream
, format
, args
);
754 /* Something non -ve. */
758 struct disassemble_info
759 gdb_disassemble_info (struct gdbarch
*gdbarch
, struct ui_file
*file
)
761 struct disassemble_info di
;
763 init_disassemble_info (&di
, file
, fprintf_disasm
);
764 di
.flavour
= bfd_target_unknown_flavour
;
765 di
.memory_error_func
= dis_asm_memory_error
;
766 di
.print_address_func
= dis_asm_print_address
;
767 /* NOTE: cagney/2003-04-28: The original code, from the old Insight
768 disassembler had a local optomization here. By default it would
769 access the executable file, instead of the target memory (there
770 was a growing list of exceptions though). Unfortunately, the
771 heuristic was flawed. Commands like "disassemble &variable"
772 didn't work as they relied on the access going to the target.
773 Further, it has been supperseeded by trust-read-only-sections
774 (although that should be superseeded by target_trust..._p()). */
775 di
.read_memory_func
= dis_asm_read_memory
;
776 di
.arch
= gdbarch_bfd_arch_info (gdbarch
)->arch
;
777 di
.mach
= gdbarch_bfd_arch_info (gdbarch
)->mach
;
778 di
.endian
= gdbarch_byte_order (gdbarch
);
779 di
.endian_code
= gdbarch_byte_order_for_code (gdbarch
);
780 di
.application_data
= gdbarch
;
781 disassemble_init_for_target (&di
);
786 gdb_disassembly (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
787 char *file_string
, int flags
, int how_many
,
788 CORE_ADDR low
, CORE_ADDR high
)
790 struct ui_file
*stb
= mem_fileopen ();
791 struct cleanup
*cleanups
= make_cleanup_ui_file_delete (stb
);
792 struct disassemble_info di
= gdb_disassemble_info (gdbarch
, stb
);
793 struct symtab
*symtab
;
796 /* Assume symtab is valid for whole PC range. */
797 symtab
= find_pc_line_symtab (low
);
799 if (symtab
!= NULL
&& SYMTAB_LINETABLE (symtab
) != NULL
)
800 nlines
= SYMTAB_LINETABLE (symtab
)->nitems
;
802 if (!(flags
& (DISASSEMBLY_SOURCE_DEPRECATED
| DISASSEMBLY_SOURCE
))
804 do_assembly_only (gdbarch
, uiout
, &di
, low
, high
, how_many
, flags
, stb
);
806 else if (flags
& DISASSEMBLY_SOURCE
)
807 do_mixed_source_and_assembly (gdbarch
, uiout
, &di
, symtab
, low
, high
,
808 how_many
, flags
, stb
);
810 else if (flags
& DISASSEMBLY_SOURCE_DEPRECATED
)
811 do_mixed_source_and_assembly_deprecated (gdbarch
, uiout
, &di
, symtab
,
812 low
, high
, how_many
, flags
, stb
);
814 do_cleanups (cleanups
);
815 gdb_flush (gdb_stdout
);
818 /* Print the instruction at address MEMADDR in debugged memory,
819 on STREAM. Returns the length of the instruction, in bytes,
820 and, if requested, the number of branch delay slot instructions. */
823 gdb_print_insn (struct gdbarch
*gdbarch
, CORE_ADDR memaddr
,
824 struct ui_file
*stream
, int *branch_delay_insns
)
826 struct disassemble_info di
;
829 di
= gdb_disassemble_info (gdbarch
, stream
);
830 length
= gdbarch_print_insn (gdbarch
, memaddr
, &di
);
831 if (branch_delay_insns
)
833 if (di
.insn_info_valid
)
834 *branch_delay_insns
= di
.branch_delay_insns
;
836 *branch_delay_insns
= 0;
841 /* Return the length in bytes of the instruction at address MEMADDR in
845 gdb_insn_length (struct gdbarch
*gdbarch
, CORE_ADDR addr
)
847 return gdb_print_insn (gdbarch
, addr
, null_stream (), NULL
);
850 /* fprintf-function for gdb_buffered_insn_length. This function is a
851 nop, we don't want to print anything, we just want to compute the
852 length of the insn. */
854 static int ATTRIBUTE_PRINTF (2, 3)
855 gdb_buffered_insn_length_fprintf (void *stream
, const char *format
, ...)
860 /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
863 gdb_buffered_insn_length_init_dis (struct gdbarch
*gdbarch
,
864 struct disassemble_info
*di
,
865 const gdb_byte
*insn
, int max_len
,
868 init_disassemble_info (di
, NULL
, gdb_buffered_insn_length_fprintf
);
870 /* init_disassemble_info installs buffer_read_memory, etc.
871 so we don't need to do that here.
872 The cast is necessary until disassemble_info is const-ified. */
873 di
->buffer
= (gdb_byte
*) insn
;
874 di
->buffer_length
= max_len
;
875 di
->buffer_vma
= addr
;
877 di
->arch
= gdbarch_bfd_arch_info (gdbarch
)->arch
;
878 di
->mach
= gdbarch_bfd_arch_info (gdbarch
)->mach
;
879 di
->endian
= gdbarch_byte_order (gdbarch
);
880 di
->endian_code
= gdbarch_byte_order_for_code (gdbarch
);
882 disassemble_init_for_target (di
);
885 /* Return the length in bytes of INSN. MAX_LEN is the size of the
886 buffer containing INSN. */
889 gdb_buffered_insn_length (struct gdbarch
*gdbarch
,
890 const gdb_byte
*insn
, int max_len
, CORE_ADDR addr
)
892 struct disassemble_info di
;
894 gdb_buffered_insn_length_init_dis (gdbarch
, &di
, insn
, max_len
, addr
);
896 return gdbarch_print_insn (gdbarch
, addr
, &di
);