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 /* Wrapper of target_read_code. */
125 gdb_disassembler::dis_asm_read_memory (bfd_vma memaddr
, gdb_byte
*myaddr
,
127 struct disassemble_info
*info
)
129 return target_read_code (memaddr
, myaddr
, len
);
132 /* Wrapper of memory_error. */
135 gdb_disassembler::dis_asm_memory_error (int err
, bfd_vma memaddr
,
136 struct disassemble_info
*info
)
138 gdb_disassembler
*self
139 = static_cast<gdb_disassembler
*>(info
->application_data
);
141 self
->m_err_memaddr
= memaddr
;
144 /* Wrapper of print_address. */
147 gdb_disassembler::dis_asm_print_address (bfd_vma addr
,
148 struct disassemble_info
*info
)
150 gdb_disassembler
*self
151 = static_cast<gdb_disassembler
*>(info
->application_data
);
153 print_address (self
->arch (), addr
, self
->stream ());
157 compare_lines (const void *mle1p
, const void *mle2p
)
159 struct deprecated_dis_line_entry
*mle1
, *mle2
;
162 mle1
= (struct deprecated_dis_line_entry
*) mle1p
;
163 mle2
= (struct deprecated_dis_line_entry
*) mle2p
;
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)
169 val
= mle1
->start_pc
- mle2
->start_pc
;
171 val
= mle1
->line
- mle2
->line
;
175 val
= mle1
->line
- mle2
->line
;
177 val
= mle1
->start_pc
- mle2
->start_pc
;
185 gdb_pretty_print_insn (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
186 const struct disasm_insn
*insn
,
189 /* parts of the symbolic representation of the address */
194 struct cleanup
*ui_out_chain
;
195 char *filename
= NULL
;
199 ui_out_chain
= make_cleanup_ui_out_tuple_begin_end (uiout
, NULL
);
202 if (insn
->number
!= 0)
204 uiout
->field_fmt ("insn-number", "%u", insn
->number
);
208 if ((flags
& DISASSEMBLY_SPECULATIVE
) != 0)
210 if (insn
->is_speculative
)
212 uiout
->field_string ("is-speculative", "?");
214 /* The speculative execution indication overwrites the first
215 character of the PC prefix.
216 We assume a PC prefix length of 3 characters. */
217 if ((flags
& DISASSEMBLY_OMIT_PC
) == 0)
218 uiout
->text (pc_prefix (pc
) + 1);
222 else if ((flags
& DISASSEMBLY_OMIT_PC
) == 0)
223 uiout
->text (pc_prefix (pc
));
227 else if ((flags
& DISASSEMBLY_OMIT_PC
) == 0)
228 uiout
->text (pc_prefix (pc
));
229 uiout
->field_core_addr ("address", gdbarch
, pc
);
231 if (!build_address_symbolic (gdbarch
, pc
, 0, &name
, &offset
, &filename
,
234 /* We don't care now about line, filename and unmapped. But we might in
237 if ((flags
& DISASSEMBLY_OMIT_FNAME
) == 0)
238 uiout
->field_string ("func-name", name
);
240 uiout
->field_int ("offset", offset
);
241 uiout
->text (">:\t");
246 if (filename
!= NULL
)
253 if (flags
& DISASSEMBLY_RAW_INSN
)
258 const char *spacer
= "";
260 /* Build the opcodes using a temporary stream so we can
261 write them out in a single go for the MI. */
262 string_file opcode_stream
;
264 size
= gdb_print_insn (gdbarch
, pc
, &stb
, NULL
);
267 for (;pc
< end_pc
; ++pc
)
269 read_code (pc
, &data
, 1);
270 opcode_stream
.printf ("%s%02x", spacer
, (unsigned) data
);
274 uiout
->field_stream ("opcodes", opcode_stream
);
278 size
= gdb_print_insn (gdbarch
, pc
, &stb
, NULL
);
280 uiout
->field_stream ("inst", stb
);
281 do_cleanups (ui_out_chain
);
288 dump_insns (struct gdbarch
*gdbarch
,
289 struct ui_out
*uiout
, CORE_ADDR low
, CORE_ADDR high
,
290 int how_many
, int flags
, CORE_ADDR
*end_pc
)
292 struct disasm_insn insn
;
293 int num_displayed
= 0;
295 memset (&insn
, 0, sizeof (insn
));
298 while (insn
.addr
< high
&& (how_many
< 0 || num_displayed
< how_many
))
302 size
= gdb_pretty_print_insn (gdbarch
, uiout
, &insn
, flags
);
309 /* Allow user to bail out with ^C. */
316 return num_displayed
;
319 /* The idea here is to present a source-O-centric view of a
320 function to the user. This means that things are presented
321 in source order, with (possibly) out of order assembly
322 immediately following.
324 N.B. This view is deprecated. */
327 do_mixed_source_and_assembly_deprecated
328 (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
329 struct symtab
*symtab
,
330 CORE_ADDR low
, CORE_ADDR high
,
331 int how_many
, int flags
)
335 struct linetable_entry
*le
;
336 struct deprecated_dis_line_entry
*mle
;
337 struct symtab_and_line sal
;
339 int out_of_order
= 0;
341 int num_displayed
= 0;
342 print_source_lines_flags psl_flags
= 0;
343 struct cleanup
*ui_out_chain
;
344 struct cleanup
*ui_out_tuple_chain
= make_cleanup (null_cleanup
, 0);
345 struct cleanup
*ui_out_list_chain
= make_cleanup (null_cleanup
, 0);
347 gdb_assert (symtab
!= NULL
&& SYMTAB_LINETABLE (symtab
) != NULL
);
349 nlines
= SYMTAB_LINETABLE (symtab
)->nitems
;
350 le
= SYMTAB_LINETABLE (symtab
)->item
;
352 if (flags
& DISASSEMBLY_FILENAME
)
353 psl_flags
|= PRINT_SOURCE_LINES_FILENAME
;
355 mle
= (struct deprecated_dis_line_entry
*)
356 alloca (nlines
* sizeof (struct deprecated_dis_line_entry
));
358 /* Copy linetable entries for this function into our data
359 structure, creating end_pc's and setting out_of_order as
362 /* First, skip all the preceding functions. */
364 for (i
= 0; i
< nlines
- 1 && le
[i
].pc
< low
; i
++);
366 /* Now, copy all entries before the end of this function. */
368 for (; i
< nlines
- 1 && le
[i
].pc
< high
; i
++)
370 if (le
[i
].line
== le
[i
+ 1].line
&& le
[i
].pc
== le
[i
+ 1].pc
)
371 continue; /* Ignore duplicates. */
373 /* Skip any end-of-function markers. */
377 mle
[newlines
].line
= le
[i
].line
;
378 if (le
[i
].line
> le
[i
+ 1].line
)
380 mle
[newlines
].start_pc
= le
[i
].pc
;
381 mle
[newlines
].end_pc
= le
[i
+ 1].pc
;
385 /* If we're on the last line, and it's part of the function,
386 then we need to get the end pc in a special way. */
388 if (i
== nlines
- 1 && le
[i
].pc
< high
)
390 mle
[newlines
].line
= le
[i
].line
;
391 mle
[newlines
].start_pc
= le
[i
].pc
;
392 sal
= find_pc_line (le
[i
].pc
, 0);
393 mle
[newlines
].end_pc
= sal
.end
;
397 /* Now, sort mle by line #s (and, then by addresses within lines). */
400 qsort (mle
, newlines
, sizeof (struct deprecated_dis_line_entry
),
403 /* Now, for each line entry, emit the specified lines (unless
404 they have been emitted before), followed by the assembly code
407 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
409 for (i
= 0; i
< newlines
; i
++)
411 /* Print out everything from next_line to the current line. */
412 if (mle
[i
].line
>= next_line
)
416 /* Just one line to print. */
417 if (next_line
== mle
[i
].line
)
420 = make_cleanup_ui_out_tuple_begin_end (uiout
,
422 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, psl_flags
);
426 /* Several source lines w/o asm instructions associated. */
427 for (; next_line
< mle
[i
].line
; next_line
++)
429 struct cleanup
*ui_out_list_chain_line
;
430 struct cleanup
*ui_out_tuple_chain_line
;
432 ui_out_tuple_chain_line
433 = make_cleanup_ui_out_tuple_begin_end (uiout
,
435 print_source_lines (symtab
, next_line
, next_line
+ 1,
437 ui_out_list_chain_line
438 = make_cleanup_ui_out_list_begin_end (uiout
,
440 do_cleanups (ui_out_list_chain_line
);
441 do_cleanups (ui_out_tuple_chain_line
);
443 /* Print the last line and leave list open for
444 asm instructions to be added. */
446 = make_cleanup_ui_out_tuple_begin_end (uiout
,
448 print_source_lines (symtab
, next_line
, mle
[i
].line
+ 1, psl_flags
);
454 = make_cleanup_ui_out_tuple_begin_end (uiout
,
456 print_source_lines (symtab
, mle
[i
].line
, mle
[i
].line
+ 1, psl_flags
);
459 next_line
= mle
[i
].line
+ 1;
461 = make_cleanup_ui_out_list_begin_end (uiout
, "line_asm_insn");
464 num_displayed
+= dump_insns (gdbarch
, uiout
,
465 mle
[i
].start_pc
, mle
[i
].end_pc
,
466 how_many
, flags
, NULL
);
468 /* When we've reached the end of the mle array, or we've seen the last
469 assembly range for this source line, close out the list/tuple. */
470 if (i
== (newlines
- 1) || mle
[i
+ 1].line
> mle
[i
].line
)
472 do_cleanups (ui_out_list_chain
);
473 do_cleanups (ui_out_tuple_chain
);
474 ui_out_tuple_chain
= make_cleanup (null_cleanup
, 0);
475 ui_out_list_chain
= make_cleanup (null_cleanup
, 0);
478 if (how_many
>= 0 && num_displayed
>= how_many
)
481 do_cleanups (ui_out_chain
);
484 /* The idea here is to present a source-O-centric view of a
485 function to the user. This means that things are presented
486 in source order, with (possibly) out of order assembly
487 immediately following. */
490 do_mixed_source_and_assembly (struct gdbarch
*gdbarch
,
491 struct ui_out
*uiout
,
492 struct symtab
*main_symtab
,
493 CORE_ADDR low
, CORE_ADDR high
,
494 int how_many
, int flags
)
496 const struct linetable_entry
*le
, *first_le
;
498 int num_displayed
= 0;
499 print_source_lines_flags psl_flags
= 0;
500 struct cleanup
*ui_out_chain
;
501 struct cleanup
*ui_out_tuple_chain
;
502 struct cleanup
*ui_out_list_chain
;
504 struct symtab
*last_symtab
;
507 gdb_assert (main_symtab
!= NULL
&& SYMTAB_LINETABLE (main_symtab
) != NULL
);
509 /* First pass: collect the list of all source files and lines.
510 We do this so that we can only print lines containing code once.
511 We try to print the source text leading up to the next instruction,
512 but if that text is for code that will be disassembled later, then
513 we'll want to defer printing it until later with its associated code. */
515 htab_up
dis_line_table (allocate_dis_line_table ());
519 /* The prologue may be empty, but there may still be a line number entry
520 for the opening brace which is distinct from the first line of code.
521 If the prologue has been eliminated find_pc_line may return the source
522 line after the opening brace. We still want to print this opening brace.
523 first_le is used to implement this. */
525 nlines
= SYMTAB_LINETABLE (main_symtab
)->nitems
;
526 le
= SYMTAB_LINETABLE (main_symtab
)->item
;
529 /* Skip all the preceding functions. */
530 for (i
= 0; i
< nlines
&& le
[i
].pc
< low
; i
++)
533 if (i
< nlines
&& le
[i
].pc
< high
)
536 /* Add lines for every pc value. */
539 struct symtab_and_line sal
;
542 sal
= find_pc_line (pc
, 0);
543 length
= gdb_insn_length (gdbarch
, pc
);
546 if (sal
.symtab
!= NULL
)
547 add_dis_line_entry (dis_line_table
.get (), sal
.symtab
, sal
.line
);
550 /* Second pass: print the disassembly.
552 Output format, from an MI perspective:
553 The result is a ui_out list, field name "asm_insns", where elements have
554 name "src_and_asm_line".
555 Each element is a tuple of source line specs (field names line, file,
556 fullname), and field "line_asm_insn" which contains the disassembly.
557 Field "line_asm_insn" is a list of tuples: address, func-name, offset,
560 CLI output works on top of this because MI ignores ui_out_text output,
561 which is where we put file name and source line contents output.
565 Handles the outer "asm_insns" list.
567 The tuples for each group of consecutive disassemblies.
569 List of consecutive source lines or disassembled insns. */
571 if (flags
& DISASSEMBLY_FILENAME
)
572 psl_flags
|= PRINT_SOURCE_LINES_FILENAME
;
574 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
576 ui_out_tuple_chain
= NULL
;
577 ui_out_list_chain
= NULL
;
585 struct symtab_and_line sal
;
587 int start_preceding_line_to_display
= 0;
588 int end_preceding_line_to_display
= 0;
589 int new_source_line
= 0;
591 sal
= find_pc_line (pc
, 0);
593 if (sal
.symtab
!= last_symtab
)
595 /* New source file. */
598 /* If this is the first line of output, check for any preceding
602 && first_le
->line
< sal
.line
)
604 start_preceding_line_to_display
= first_le
->line
;
605 end_preceding_line_to_display
= sal
.line
;
610 /* Same source file as last time. */
611 if (sal
.symtab
!= NULL
)
613 if (sal
.line
> last_line
+ 1 && last_line
!= 0)
617 /* Several preceding source lines. Print the trailing ones
618 not associated with code that we'll print later. */
619 for (l
= sal
.line
- 1; l
> last_line
; --l
)
621 if (line_has_code_p (dis_line_table
.get (),
625 if (l
< sal
.line
- 1)
627 start_preceding_line_to_display
= l
+ 1;
628 end_preceding_line_to_display
= sal
.line
;
631 if (sal
.line
!= last_line
)
635 /* Same source line as last time. This can happen, depending
636 on the debug info. */
643 /* Skip the newline if this is the first instruction. */
646 if (ui_out_tuple_chain
!= NULL
)
648 gdb_assert (ui_out_list_chain
!= NULL
);
649 do_cleanups (ui_out_list_chain
);
650 do_cleanups (ui_out_tuple_chain
);
652 if (sal
.symtab
!= last_symtab
653 && !(flags
& DISASSEMBLY_FILENAME
))
655 /* Remember MI ignores ui_out_text.
656 We don't have to do anything here for MI because MI
657 output includes the source specs for each line. */
658 if (sal
.symtab
!= NULL
)
660 uiout
->text (symtab_to_filename_for_display (sal
.symtab
));
663 uiout
->text ("unknown");
666 if (start_preceding_line_to_display
> 0)
668 /* Several source lines w/o asm instructions associated.
669 We need to preserve the structure of the output, so output
670 a bunch of line tuples with no asm entries. */
672 struct cleanup
*ui_out_list_chain_line
;
673 struct cleanup
*ui_out_tuple_chain_line
;
675 gdb_assert (sal
.symtab
!= NULL
);
676 for (l
= start_preceding_line_to_display
;
677 l
< end_preceding_line_to_display
;
680 ui_out_tuple_chain_line
681 = make_cleanup_ui_out_tuple_begin_end (uiout
,
683 print_source_lines (sal
.symtab
, l
, l
+ 1, psl_flags
);
684 ui_out_list_chain_line
685 = make_cleanup_ui_out_list_begin_end (uiout
,
687 do_cleanups (ui_out_list_chain_line
);
688 do_cleanups (ui_out_tuple_chain_line
);
692 = make_cleanup_ui_out_tuple_begin_end (uiout
, "src_and_asm_line");
693 if (sal
.symtab
!= NULL
)
694 print_source_lines (sal
.symtab
, sal
.line
, sal
.line
+ 1, psl_flags
);
696 uiout
->text (_("--- no source info for this pc ---\n"));
698 = make_cleanup_ui_out_list_begin_end (uiout
, "line_asm_insn");
702 /* Here we're appending instructions to an existing line.
703 By construction the very first insn will have a symtab
704 and follow the new_source_line path above. */
705 gdb_assert (ui_out_tuple_chain
!= NULL
);
706 gdb_assert (ui_out_list_chain
!= NULL
);
710 end_pc
= std::min (sal
.end
, high
);
713 num_displayed
+= dump_insns (gdbarch
, uiout
, pc
, end_pc
,
714 how_many
, flags
, &end_pc
);
717 if (how_many
>= 0 && num_displayed
>= how_many
)
720 last_symtab
= sal
.symtab
;
721 last_line
= sal
.line
;
724 do_cleanups (ui_out_chain
);
728 do_assembly_only (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
729 CORE_ADDR low
, CORE_ADDR high
,
730 int how_many
, int flags
)
732 struct cleanup
*ui_out_chain
;
734 ui_out_chain
= make_cleanup_ui_out_list_begin_end (uiout
, "asm_insns");
736 dump_insns (gdbarch
, uiout
, low
, high
, how_many
, flags
, NULL
);
738 do_cleanups (ui_out_chain
);
741 /* Initialize the disassemble info struct ready for the specified
744 static int ATTRIBUTE_PRINTF (2, 3)
745 fprintf_disasm (void *stream
, const char *format
, ...)
749 va_start (args
, format
);
750 vfprintf_filtered ((struct ui_file
*) stream
, format
, args
);
752 /* Something non -ve. */
756 gdb_disassembler::gdb_disassembler (struct gdbarch
*gdbarch
,
757 struct ui_file
*file
,
758 di_read_memory_ftype read_memory_func
)
759 : m_gdbarch (gdbarch
),
762 init_disassemble_info (&m_di
, file
, fprintf_disasm
);
763 m_di
.flavour
= bfd_target_unknown_flavour
;
764 m_di
.memory_error_func
= dis_asm_memory_error
;
765 m_di
.print_address_func
= dis_asm_print_address
;
766 /* NOTE: cagney/2003-04-28: The original code, from the old Insight
767 disassembler had a local optomization here. By default it would
768 access the executable file, instead of the target memory (there
769 was a growing list of exceptions though). Unfortunately, the
770 heuristic was flawed. Commands like "disassemble &variable"
771 didn't work as they relied on the access going to the target.
772 Further, it has been supperseeded by trust-read-only-sections
773 (although that should be superseeded by target_trust..._p()). */
774 m_di
.read_memory_func
= read_memory_func
;
775 m_di
.arch
= gdbarch_bfd_arch_info (gdbarch
)->arch
;
776 m_di
.mach
= gdbarch_bfd_arch_info (gdbarch
)->mach
;
777 m_di
.endian
= gdbarch_byte_order (gdbarch
);
778 m_di
.endian_code
= gdbarch_byte_order_for_code (gdbarch
);
779 m_di
.application_data
= this;
780 disassemble_init_for_target (&m_di
);
784 gdb_disassembler::print_insn (CORE_ADDR memaddr
,
785 int *branch_delay_insns
)
789 int length
= gdbarch_print_insn (arch (), memaddr
, &m_di
);
792 memory_error (TARGET_XFER_E_IO
, m_err_memaddr
);
794 if (branch_delay_insns
!= NULL
)
796 if (m_di
.insn_info_valid
)
797 *branch_delay_insns
= m_di
.branch_delay_insns
;
799 *branch_delay_insns
= 0;
805 gdb_disassembly (struct gdbarch
*gdbarch
, struct ui_out
*uiout
,
806 int flags
, int how_many
,
807 CORE_ADDR low
, CORE_ADDR high
)
809 struct symtab
*symtab
;
812 /* Assume symtab is valid for whole PC range. */
813 symtab
= find_pc_line_symtab (low
);
815 if (symtab
!= NULL
&& SYMTAB_LINETABLE (symtab
) != NULL
)
816 nlines
= SYMTAB_LINETABLE (symtab
)->nitems
;
818 if (!(flags
& (DISASSEMBLY_SOURCE_DEPRECATED
| DISASSEMBLY_SOURCE
))
820 do_assembly_only (gdbarch
, uiout
, low
, high
, how_many
, flags
);
822 else if (flags
& DISASSEMBLY_SOURCE
)
823 do_mixed_source_and_assembly (gdbarch
, uiout
, symtab
, low
, high
,
826 else if (flags
& DISASSEMBLY_SOURCE_DEPRECATED
)
827 do_mixed_source_and_assembly_deprecated (gdbarch
, uiout
, symtab
,
828 low
, high
, how_many
, flags
);
830 gdb_flush (gdb_stdout
);
833 /* Print the instruction at address MEMADDR in debugged memory,
834 on STREAM. Returns the length of the instruction, in bytes,
835 and, if requested, the number of branch delay slot instructions. */
838 gdb_print_insn (struct gdbarch
*gdbarch
, CORE_ADDR memaddr
,
839 struct ui_file
*stream
, int *branch_delay_insns
)
842 gdb_disassembler
di (gdbarch
, stream
);
844 return di
.print_insn (memaddr
, branch_delay_insns
);
847 /* Return the length in bytes of the instruction at address MEMADDR in
851 gdb_insn_length (struct gdbarch
*gdbarch
, CORE_ADDR addr
)
853 return gdb_print_insn (gdbarch
, addr
, &null_stream
, NULL
);
856 /* fprintf-function for gdb_buffered_insn_length. This function is a
857 nop, we don't want to print anything, we just want to compute the
858 length of the insn. */
860 static int ATTRIBUTE_PRINTF (2, 3)
861 gdb_buffered_insn_length_fprintf (void *stream
, const char *format
, ...)
866 /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
869 gdb_buffered_insn_length_init_dis (struct gdbarch
*gdbarch
,
870 struct disassemble_info
*di
,
871 const gdb_byte
*insn
, int max_len
,
874 init_disassemble_info (di
, NULL
, gdb_buffered_insn_length_fprintf
);
876 /* init_disassemble_info installs buffer_read_memory, etc.
877 so we don't need to do that here.
878 The cast is necessary until disassemble_info is const-ified. */
879 di
->buffer
= (gdb_byte
*) insn
;
880 di
->buffer_length
= max_len
;
881 di
->buffer_vma
= addr
;
883 di
->arch
= gdbarch_bfd_arch_info (gdbarch
)->arch
;
884 di
->mach
= gdbarch_bfd_arch_info (gdbarch
)->mach
;
885 di
->endian
= gdbarch_byte_order (gdbarch
);
886 di
->endian_code
= gdbarch_byte_order_for_code (gdbarch
);
888 disassemble_init_for_target (di
);
891 /* Return the length in bytes of INSN. MAX_LEN is the size of the
892 buffer containing INSN. */
895 gdb_buffered_insn_length (struct gdbarch
*gdbarch
,
896 const gdb_byte
*insn
, int max_len
, CORE_ADDR addr
)
898 struct disassemble_info di
;
900 gdb_buffered_insn_length_init_dis (gdbarch
, &di
, insn
, max_len
, addr
);
902 return gdbarch_print_insn (gdbarch
, addr
, &di
);