1 /* Disassemble support for GDB.
3 Copyright (C) 2000-2016 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);
89 /* Add a new dis_line_entry containing SYMTAB and LINE to TABLE. */
92 add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
95 struct dis_line_entry dle, *dlep;
99 slot = htab_find_slot (table, &dle, INSERT);
102 dlep = XNEW (struct dis_line_entry);
103 dlep->symtab = symtab;
109 /* Return non-zero if SYMTAB, LINE are in TABLE. */
112 line_has_code_p (htab_t table, struct symtab *symtab, int line)
114 struct dis_line_entry dle;
118 return htab_find (table, &dle) != NULL;
121 /* Like target_read_memory, but slightly different parameters. */
123 dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
124 struct disassemble_info *info)
126 return target_read_code (memaddr, myaddr, len);
129 /* Like memory_error with slightly different parameters. */
131 dis_asm_memory_error (int err, bfd_vma memaddr,
132 struct disassemble_info *info)
134 memory_error (TARGET_XFER_E_IO, memaddr);
137 /* Like print_address with slightly different parameters. */
139 dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
141 struct gdbarch *gdbarch = (struct gdbarch *) info->application_data;
143 print_address (gdbarch, addr, (struct ui_file *) info->stream);
147 compare_lines (const void *mle1p, const void *mle2p)
149 struct deprecated_dis_line_entry *mle1, *mle2;
152 mle1 = (struct deprecated_dis_line_entry *) mle1p;
153 mle2 = (struct deprecated_dis_line_entry *) mle2p;
155 /* End of sequence markers have a line number of 0 but don't want to
156 be sorted to the head of the list, instead sort by PC. */
157 if (mle1->line == 0 || mle2->line == 0)
159 val = mle1->start_pc - mle2->start_pc;
161 val = mle1->line - mle2->line;
165 val = mle1->line - mle2->line;
167 val = mle1->start_pc - mle2->start_pc;
175 gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
176 struct disassemble_info * di,
177 const struct disasm_insn *insn, int flags,
180 /* parts of the symbolic representation of the address */
185 struct cleanup *ui_out_chain;
186 char *filename = NULL;
190 ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
193 if (insn->number != 0)
195 ui_out_field_fmt (uiout, "insn-number", "%u", insn->number);
196 ui_out_text (uiout, "\t");
199 if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
201 if (insn->is_speculative)
203 ui_out_field_string (uiout, "is-speculative", "?");
205 /* The speculative execution indication overwrites the first
206 character of the PC prefix.
207 We assume a PC prefix length of 3 characters. */
208 if ((flags & DISASSEMBLY_OMIT_PC) == 0)
209 ui_out_text (uiout, pc_prefix (pc) + 1);
211 ui_out_text (uiout, " ");
213 else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
214 ui_out_text (uiout, pc_prefix (pc));
216 ui_out_text (uiout, " ");
218 else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
219 ui_out_text (uiout, pc_prefix (pc));
220 ui_out_field_core_addr (uiout, "address", gdbarch, pc);
222 if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
225 /* We don't care now about line, filename and unmapped. But we might in
227 ui_out_text (uiout, " <");
228 if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
229 ui_out_field_string (uiout, "func-name", name);
230 ui_out_text (uiout, "+");
231 ui_out_field_int (uiout, "offset", offset);
232 ui_out_text (uiout, ">:\t");
235 ui_out_text (uiout, ":\t");
237 if (filename != NULL)
242 ui_file_rewind (stb);
243 if (flags & DISASSEMBLY_RAW_INSN)
248 const char *spacer = "";
250 /* Build the opcodes using a temporary stream so we can
251 write them out in a single go for the MI. */
252 struct ui_file *opcode_stream = mem_fileopen ();
253 struct cleanup *cleanups =
254 make_cleanup_ui_file_delete (opcode_stream);
256 size = gdbarch_print_insn (gdbarch, pc, di);
259 for (;pc < end_pc; ++pc)
261 err = (*di->read_memory_func) (pc, &data, 1, di);
263 (*di->memory_error_func) (err, pc, di);
264 fprintf_filtered (opcode_stream, "%s%02x",
265 spacer, (unsigned) data);
269 ui_out_field_stream (uiout, "opcodes", opcode_stream);
270 ui_out_text (uiout, "\t");
272 do_cleanups (cleanups);
275 size = gdbarch_print_insn (gdbarch, pc, di);
277 ui_out_field_stream (uiout, "inst", stb);
278 ui_file_rewind (stb);
279 do_cleanups (ui_out_chain);
280 ui_out_text (uiout, "\n");
286 dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
287 struct disassemble_info * di,
288 CORE_ADDR low, CORE_ADDR high,
289 int how_many, int flags, struct ui_file *stb,
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, di, &insn, flags, stb);
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 disassemble_info *di, struct symtab *symtab,
330 CORE_ADDR low, CORE_ADDR high,
331 int how_many, int flags, struct ui_file *stb)
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, di,
465 mle[i].start_pc, mle[i].end_pc,
466 how_many, flags, stb, 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);
476 ui_out_text (uiout, "\n");
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, struct ui_out *uiout,
491 struct disassemble_info *di,
492 struct symtab *main_symtab,
493 CORE_ADDR low, CORE_ADDR high,
494 int how_many, int flags, struct ui_file *stb)
496 const struct linetable_entry *le, *first_le;
498 int num_displayed = 0;
499 print_source_lines_flags psl_flags = 0;
500 struct cleanup *cleanups;
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;
507 htab_t dis_line_table;
509 gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
511 /* First pass: collect the list of all source files and lines.
512 We do this so that we can only print lines containing code once.
513 We try to print the source text leading up to the next instruction,
514 but if that text is for code that will be disassembled later, then
515 we'll want to defer printing it until later with its associated code. */
517 dis_line_table = allocate_dis_line_table ();
518 cleanups = make_cleanup_htab_delete (dis_line_table);
522 /* The prologue may be empty, but there may still be a line number entry
523 for the opening brace which is distinct from the first line of code.
524 If the prologue has been eliminated find_pc_line may return the source
525 line after the opening brace. We still want to print this opening brace.
526 first_le is used to implement this. */
528 nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
529 le = SYMTAB_LINETABLE (main_symtab)->item;
532 /* Skip all the preceding functions. */
533 for (i = 0; i < nlines && le[i].pc < low; i++)
536 if (i < nlines && le[i].pc < high)
539 /* Add lines for every pc value. */
542 struct symtab_and_line sal;
545 sal = find_pc_line (pc, 0);
546 length = gdb_insn_length (gdbarch, pc);
549 if (sal.symtab != NULL)
550 add_dis_line_entry (dis_line_table, sal.symtab, sal.line);
553 /* Second pass: print the disassembly.
555 Output format, from an MI perspective:
556 The result is a ui_out list, field name "asm_insns", where elements have
557 name "src_and_asm_line".
558 Each element is a tuple of source line specs (field names line, file,
559 fullname), and field "line_asm_insn" which contains the disassembly.
560 Field "line_asm_insn" is a list of tuples: address, func-name, offset,
563 CLI output works on top of this because MI ignores ui_out_text output,
564 which is where we put file name and source line contents output.
568 For things created at the beginning of this function and need to be
569 kept until the end of this function.
571 Handles the outer "asm_insns" list.
573 The tuples for each group of consecutive disassemblies.
575 List of consecutive source lines or disassembled insns. */
577 if (flags & DISASSEMBLY_FILENAME)
578 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
580 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
582 ui_out_tuple_chain = NULL;
583 ui_out_list_chain = NULL;
591 struct symtab_and_line sal;
593 int start_preceding_line_to_display = 0;
594 int end_preceding_line_to_display = 0;
595 int new_source_line = 0;
597 sal = find_pc_line (pc, 0);
599 if (sal.symtab != last_symtab)
601 /* New source file. */
604 /* If this is the first line of output, check for any preceding
608 && first_le->line < sal.line)
610 start_preceding_line_to_display = first_le->line;
611 end_preceding_line_to_display = sal.line;
616 /* Same source file as last time. */
617 if (sal.symtab != NULL)
619 if (sal.line > last_line + 1 && last_line != 0)
623 /* Several preceding source lines. Print the trailing ones
624 not associated with code that we'll print later. */
625 for (l = sal.line - 1; l > last_line; --l)
627 if (line_has_code_p (dis_line_table, sal.symtab, l))
630 if (l < sal.line - 1)
632 start_preceding_line_to_display = l + 1;
633 end_preceding_line_to_display = sal.line;
636 if (sal.line != last_line)
640 /* Same source line as last time. This can happen, depending
641 on the debug info. */
648 /* Skip the newline if this is the first instruction. */
650 ui_out_text (uiout, "\n");
651 if (ui_out_tuple_chain != NULL)
653 gdb_assert (ui_out_list_chain != NULL);
654 do_cleanups (ui_out_list_chain);
655 do_cleanups (ui_out_tuple_chain);
657 if (sal.symtab != last_symtab
658 && !(flags & DISASSEMBLY_FILENAME))
660 /* Remember MI ignores ui_out_text.
661 We don't have to do anything here for MI because MI
662 output includes the source specs for each line. */
663 if (sal.symtab != NULL)
666 symtab_to_filename_for_display (sal.symtab));
669 ui_out_text (uiout, "unknown");
670 ui_out_text (uiout, ":\n");
672 if (start_preceding_line_to_display > 0)
674 /* Several source lines w/o asm instructions associated.
675 We need to preserve the structure of the output, so output
676 a bunch of line tuples with no asm entries. */
678 struct cleanup *ui_out_list_chain_line;
679 struct cleanup *ui_out_tuple_chain_line;
681 gdb_assert (sal.symtab != NULL);
682 for (l = start_preceding_line_to_display;
683 l < end_preceding_line_to_display;
686 ui_out_tuple_chain_line
687 = make_cleanup_ui_out_tuple_begin_end (uiout,
689 print_source_lines (sal.symtab, l, l + 1, psl_flags);
690 ui_out_list_chain_line
691 = make_cleanup_ui_out_list_begin_end (uiout,
693 do_cleanups (ui_out_list_chain_line);
694 do_cleanups (ui_out_tuple_chain_line);
698 = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
699 if (sal.symtab != NULL)
700 print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
702 ui_out_text (uiout, _("--- no source info for this pc ---\n"));
704 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
708 /* Here we're appending instructions to an existing line.
709 By construction the very first insn will have a symtab
710 and follow the new_source_line path above. */
711 gdb_assert (ui_out_tuple_chain != NULL);
712 gdb_assert (ui_out_list_chain != NULL);
716 end_pc = min (sal.end, high);
719 num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc,
720 how_many, flags, stb, &end_pc);
723 if (how_many >= 0 && num_displayed >= how_many)
726 last_symtab = sal.symtab;
727 last_line = sal.line;
730 do_cleanups (ui_out_chain);
731 do_cleanups (cleanups);
735 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
736 struct disassemble_info * di,
737 CORE_ADDR low, CORE_ADDR high,
738 int how_many, int flags, struct ui_file *stb)
740 int num_displayed = 0;
741 struct cleanup *ui_out_chain;
743 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
745 num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
748 do_cleanups (ui_out_chain);
751 /* Initialize the disassemble info struct ready for the specified
754 static int ATTRIBUTE_PRINTF (2, 3)
755 fprintf_disasm (void *stream, const char *format, ...)
759 va_start (args, format);
760 vfprintf_filtered ((struct ui_file *) stream, format, args);
762 /* Something non -ve. */
766 struct disassemble_info
767 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
769 struct disassemble_info di;
771 init_disassemble_info (&di, file, fprintf_disasm);
772 di.flavour = bfd_target_unknown_flavour;
773 di.memory_error_func = dis_asm_memory_error;
774 di.print_address_func = dis_asm_print_address;
775 /* NOTE: cagney/2003-04-28: The original code, from the old Insight
776 disassembler had a local optomization here. By default it would
777 access the executable file, instead of the target memory (there
778 was a growing list of exceptions though). Unfortunately, the
779 heuristic was flawed. Commands like "disassemble &variable"
780 didn't work as they relied on the access going to the target.
781 Further, it has been supperseeded by trust-read-only-sections
782 (although that should be superseeded by target_trust..._p()). */
783 di.read_memory_func = dis_asm_read_memory;
784 di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
785 di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
786 di.endian = gdbarch_byte_order (gdbarch);
787 di.endian_code = gdbarch_byte_order_for_code (gdbarch);
788 di.application_data = gdbarch;
789 disassemble_init_for_target (&di);
794 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
795 char *file_string, int flags, int how_many,
796 CORE_ADDR low, CORE_ADDR high)
798 struct ui_file *stb = mem_fileopen ();
799 struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
800 struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
801 struct symtab *symtab;
804 /* Assume symtab is valid for whole PC range. */
805 symtab = find_pc_line_symtab (low);
807 if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
808 nlines = SYMTAB_LINETABLE (symtab)->nitems;
810 if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
812 do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
814 else if (flags & DISASSEMBLY_SOURCE)
815 do_mixed_source_and_assembly (gdbarch, uiout, &di, symtab, low, high,
816 how_many, flags, stb);
818 else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
819 do_mixed_source_and_assembly_deprecated (gdbarch, uiout, &di, symtab,
820 low, high, how_many, flags, stb);
822 do_cleanups (cleanups);
823 gdb_flush (gdb_stdout);
826 /* Print the instruction at address MEMADDR in debugged memory,
827 on STREAM. Returns the length of the instruction, in bytes,
828 and, if requested, the number of branch delay slot instructions. */
831 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
832 struct ui_file *stream, int *branch_delay_insns)
834 struct disassemble_info di;
837 di = gdb_disassemble_info (gdbarch, stream);
838 length = gdbarch_print_insn (gdbarch, memaddr, &di);
839 if (branch_delay_insns)
841 if (di.insn_info_valid)
842 *branch_delay_insns = di.branch_delay_insns;
844 *branch_delay_insns = 0;
850 do_ui_file_delete (void *arg)
852 ui_file_delete ((struct ui_file *) arg);
855 /* Return the length in bytes of the instruction at address MEMADDR in
859 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
861 static struct ui_file *null_stream = NULL;
863 /* Dummy file descriptor for the disassembler. */
866 null_stream = ui_file_new ();
867 make_final_cleanup (do_ui_file_delete, null_stream);
870 return gdb_print_insn (gdbarch, addr, null_stream, NULL);
873 /* fprintf-function for gdb_buffered_insn_length. This function is a
874 nop, we don't want to print anything, we just want to compute the
875 length of the insn. */
877 static int ATTRIBUTE_PRINTF (2, 3)
878 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
883 /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
886 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
887 struct disassemble_info *di,
888 const gdb_byte *insn, int max_len,
891 init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
893 /* init_disassemble_info installs buffer_read_memory, etc.
894 so we don't need to do that here.
895 The cast is necessary until disassemble_info is const-ified. */
896 di->buffer = (gdb_byte *) insn;
897 di->buffer_length = max_len;
898 di->buffer_vma = addr;
900 di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
901 di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
902 di->endian = gdbarch_byte_order (gdbarch);
903 di->endian_code = gdbarch_byte_order_for_code (gdbarch);
905 disassemble_init_for_target (di);
908 /* Return the length in bytes of INSN. MAX_LEN is the size of the
909 buffer containing INSN. */
912 gdb_buffered_insn_length (struct gdbarch *gdbarch,
913 const gdb_byte *insn, int max_len, CORE_ADDR addr)
915 struct disassemble_info di;
917 gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
919 return gdbarch_print_insn (gdbarch, addr, &di);