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;
174 dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
175 struct disassemble_info * di,
176 CORE_ADDR low, CORE_ADDR high,
177 int how_many, int flags, struct ui_file *stb,
180 int num_displayed = 0;
183 /* parts of the symbolic representation of the address */
187 struct cleanup *ui_out_chain;
189 for (pc = low; pc < high;)
191 char *filename = NULL;
197 if (num_displayed >= how_many)
202 ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
204 if ((flags & DISASSEMBLY_OMIT_PC) == 0)
205 ui_out_text (uiout, pc_prefix (pc));
206 ui_out_field_core_addr (uiout, "address", gdbarch, pc);
208 if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
211 /* We don't care now about line, filename and
212 unmapped. But we might in the future. */
213 ui_out_text (uiout, " <");
214 if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
215 ui_out_field_string (uiout, "func-name", name);
216 ui_out_text (uiout, "+");
217 ui_out_field_int (uiout, "offset", offset);
218 ui_out_text (uiout, ">:\t");
221 ui_out_text (uiout, ":\t");
223 if (filename != NULL)
228 ui_file_rewind (stb);
229 if (flags & DISASSEMBLY_RAW_INSN)
231 CORE_ADDR old_pc = pc;
234 const char *spacer = "";
236 /* Build the opcodes using a temporary stream so we can
237 write them out in a single go for the MI. */
238 struct ui_file *opcode_stream = mem_fileopen ();
239 struct cleanup *cleanups =
240 make_cleanup_ui_file_delete (opcode_stream);
242 pc += gdbarch_print_insn (gdbarch, pc, di);
243 for (;old_pc < pc; old_pc++)
245 err = (*di->read_memory_func) (old_pc, &data, 1, di);
247 (*di->memory_error_func) (err, old_pc, di);
248 fprintf_filtered (opcode_stream, "%s%02x",
249 spacer, (unsigned) data);
252 ui_out_field_stream (uiout, "opcodes", opcode_stream);
253 ui_out_text (uiout, "\t");
255 do_cleanups (cleanups);
258 pc += gdbarch_print_insn (gdbarch, pc, di);
259 ui_out_field_stream (uiout, "inst", stb);
260 ui_file_rewind (stb);
261 do_cleanups (ui_out_chain);
262 ui_out_text (uiout, "\n");
267 return num_displayed;
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
273 immediately following.
275 N.B. This view is deprecated. */
278 do_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)
286 struct linetable_entry *le;
287 struct deprecated_dis_line_entry *mle;
288 struct symtab_and_line sal;
290 int out_of_order = 0;
292 int num_displayed = 0;
293 enum print_source_lines_flags psl_flags = 0;
294 struct cleanup *ui_out_chain;
295 struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
296 struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
298 gdb_assert (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL);
300 nlines = SYMTAB_LINETABLE (symtab)->nitems;
301 le = SYMTAB_LINETABLE (symtab)->item;
303 if (flags & DISASSEMBLY_FILENAME)
304 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
306 mle = (struct deprecated_dis_line_entry *)
307 alloca (nlines * sizeof (struct deprecated_dis_line_entry));
309 /* Copy linetable entries for this function into our data
310 structure, creating end_pc's and setting out_of_order as
313 /* First, skip all the preceding functions. */
315 for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
317 /* Now, copy all entries before the end of this function. */
319 for (; i < nlines - 1 && le[i].pc < high; i++)
321 if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
322 continue; /* Ignore duplicates. */
324 /* Skip any end-of-function markers. */
328 mle[newlines].line = le[i].line;
329 if (le[i].line > le[i + 1].line)
331 mle[newlines].start_pc = le[i].pc;
332 mle[newlines].end_pc = le[i + 1].pc;
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. */
339 if (i == nlines - 1 && le[i].pc < high)
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;
348 /* Now, sort mle by line #s (and, then by addresses within lines). */
351 qsort (mle, newlines, sizeof (struct deprecated_dis_line_entry),
354 /* Now, for each line entry, emit the specified lines (unless
355 they have been emitted before), followed by the assembly code
358 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
360 for (i = 0; i < newlines; i++)
362 /* Print out everything from next_line to the current line. */
363 if (mle[i].line >= next_line)
367 /* Just one line to print. */
368 if (next_line == mle[i].line)
371 = make_cleanup_ui_out_tuple_begin_end (uiout,
373 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
377 /* Several source lines w/o asm instructions associated. */
378 for (; next_line < mle[i].line; next_line++)
380 struct cleanup *ui_out_list_chain_line;
381 struct cleanup *ui_out_tuple_chain_line;
383 ui_out_tuple_chain_line
384 = make_cleanup_ui_out_tuple_begin_end (uiout,
386 print_source_lines (symtab, next_line, next_line + 1,
388 ui_out_list_chain_line
389 = make_cleanup_ui_out_list_begin_end (uiout,
391 do_cleanups (ui_out_list_chain_line);
392 do_cleanups (ui_out_tuple_chain_line);
394 /* Print the last line and leave list open for
395 asm instructions to be added. */
397 = make_cleanup_ui_out_tuple_begin_end (uiout,
399 print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
405 = make_cleanup_ui_out_tuple_begin_end (uiout,
407 print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
410 next_line = mle[i].line + 1;
412 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
415 num_displayed += dump_insns (gdbarch, uiout, di,
416 mle[i].start_pc, mle[i].end_pc,
417 how_many, flags, stb, NULL);
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)
423 do_cleanups (ui_out_list_chain);
424 do_cleanups (ui_out_tuple_chain);
425 ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
426 ui_out_list_chain = make_cleanup (null_cleanup, 0);
427 ui_out_text (uiout, "\n");
429 if (how_many >= 0 && num_displayed >= how_many)
432 do_cleanups (ui_out_chain);
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. */
441 do_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)
448 const struct linetable_entry *le, *first_le;
449 struct symtab_and_line sal;
451 int out_of_order = 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;
460 struct symtab *last_symtab;
462 htab_t dis_line_table;
464 gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
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. */
472 dis_line_table = allocate_dis_line_table ();
473 cleanups = make_cleanup_htab_delete (dis_line_table);
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. */
483 nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
484 le = SYMTAB_LINETABLE (main_symtab)->item;
487 /* Skip all the preceding functions. */
488 for (i = 0; i < nlines && le[i].pc < low; i++)
491 if (i < nlines && le[i].pc < high)
494 /* Add lines for every pc value. */
497 struct symtab_and_line sal;
500 sal = find_pc_line (pc, 0);
501 length = gdb_insn_length (gdbarch, pc);
504 if (sal.symtab != NULL)
505 maybe_add_dis_line_entry (dis_line_table, sal.symtab, sal.line);
508 /* Second pass: print the disassembly.
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,
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.
523 For things created at the beginning of this function and need to be
524 kept until the end of this function.
526 Handles the outer "asm_insns" list.
528 The tuples for each group of consecutive disassemblies.
530 List of consecutive source lines or disassembled insns. */
532 if (flags & DISASSEMBLY_FILENAME)
533 psl_flags |= PRINT_SOURCE_LINES_FILENAME;
535 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
537 ui_out_tuple_chain = NULL;
538 ui_out_list_chain = NULL;
546 struct linetable_entry *le = NULL;
547 struct symtab_and_line sal;
549 int start_preceding_line_to_display = 0;
550 int end_preceding_line_to_display = 0;
551 int new_source_line = 0;
553 sal = find_pc_line (pc, 0);
555 if (sal.symtab != last_symtab)
557 /* New source file. */
560 /* If this is the first line of output, check for any preceding
564 && first_le->line < sal.line)
566 start_preceding_line_to_display = first_le->line;
567 end_preceding_line_to_display = sal.line;
572 /* Same source file as last time. */
573 if (sal.symtab != NULL)
575 if (sal.line > last_line + 1 && last_line != 0)
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)
583 if (line_has_code_p (dis_line_table, sal.symtab, l))
586 if (l < sal.line - 1)
588 start_preceding_line_to_display = l + 1;
589 end_preceding_line_to_display = sal.line;
592 if (sal.line != last_line)
596 /* Same source line as last time. This can happen, depending
597 on the debug info. */
604 /* Skip the newline if this is the first instruction. */
606 ui_out_text (uiout, "\n");
607 if (ui_out_tuple_chain != NULL)
609 gdb_assert (ui_out_list_chain != NULL);
610 do_cleanups (ui_out_list_chain);
611 do_cleanups (ui_out_tuple_chain);
613 if (sal.symtab != last_symtab
614 && !(flags & DISASSEMBLY_FILENAME))
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)
622 symtab_to_filename_for_display (sal.symtab));
625 ui_out_text (uiout, "unknown");
626 ui_out_text (uiout, ":\n");
628 if (start_preceding_line_to_display > 0)
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. */
634 struct cleanup *ui_out_list_chain_line;
635 struct cleanup *ui_out_tuple_chain_line;
637 gdb_assert (sal.symtab != NULL);
638 for (l = start_preceding_line_to_display;
639 l < end_preceding_line_to_display;
642 ui_out_tuple_chain_line
643 = make_cleanup_ui_out_tuple_begin_end (uiout,
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,
649 do_cleanups (ui_out_list_chain_line);
650 do_cleanups (ui_out_tuple_chain_line);
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);
658 ui_out_text (uiout, _("--- no source info for this pc ---\n"));
660 = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
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);
672 end_pc = min (sal.end, high);
675 num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc,
676 how_many, flags, stb, &end_pc);
679 if (how_many >= 0 && num_displayed >= how_many)
682 last_symtab = sal.symtab;
683 last_line = sal.line;
686 do_cleanups (ui_out_chain);
687 do_cleanups (cleanups);
691 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
692 struct disassemble_info * di,
693 CORE_ADDR low, CORE_ADDR high,
694 int how_many, int flags, struct ui_file *stb)
696 int num_displayed = 0;
697 struct cleanup *ui_out_chain;
699 ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
701 num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
704 do_cleanups (ui_out_chain);
707 /* Initialize the disassemble info struct ready for the specified
710 static int ATTRIBUTE_PRINTF (2, 3)
711 fprintf_disasm (void *stream, const char *format, ...)
715 va_start (args, format);
716 vfprintf_filtered ((struct ui_file *) stream, format, args);
718 /* Something non -ve. */
722 struct disassemble_info
723 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
725 struct disassemble_info di;
727 init_disassemble_info (&di, file, fprintf_disasm);
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
734 was a growing list of exceptions though). Unfortunately, the
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;
740 di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
741 di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
742 di.endian = gdbarch_byte_order (gdbarch);
743 di.endian_code = gdbarch_byte_order_for_code (gdbarch);
744 di.application_data = gdbarch;
745 disassemble_init_for_target (&di);
750 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
751 char *file_string, int flags, int how_many,
752 CORE_ADDR low, CORE_ADDR high)
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);
757 struct symtab *symtab;
758 struct linetable_entry *le = NULL;
761 /* Assume symtab is valid for whole PC range. */
762 symtab = find_pc_line_symtab (low);
764 if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
765 nlines = SYMTAB_LINETABLE (symtab)->nitems;
767 if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
769 do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
771 else if (flags & DISASSEMBLY_SOURCE)
772 do_mixed_source_and_assembly (gdbarch, uiout, &di, symtab, low, high,
773 how_many, flags, stb);
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);
779 do_cleanups (cleanups);
780 gdb_flush (gdb_stdout);
783 /* Print the instruction at address MEMADDR in debugged memory,
784 on STREAM. Returns the length of the instruction, in bytes,
785 and, if requested, the number of branch delay slot instructions. */
788 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
789 struct ui_file *stream, int *branch_delay_insns)
791 struct disassemble_info di;
794 di = gdb_disassemble_info (gdbarch, stream);
795 length = gdbarch_print_insn (gdbarch, memaddr, &di);
796 if (branch_delay_insns)
798 if (di.insn_info_valid)
799 *branch_delay_insns = di.branch_delay_insns;
801 *branch_delay_insns = 0;
807 do_ui_file_delete (void *arg)
809 ui_file_delete ((struct ui_file *) arg);
812 /* Return the length in bytes of the instruction at address MEMADDR in
816 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
818 static struct ui_file *null_stream = NULL;
820 /* Dummy file descriptor for the disassembler. */
823 null_stream = ui_file_new ();
824 make_final_cleanup (do_ui_file_delete, null_stream);
827 return gdb_print_insn (gdbarch, addr, null_stream, NULL);
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. */
834 static int ATTRIBUTE_PRINTF (2, 3)
835 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
840 /* Initialize a struct disassemble_info for gdb_buffered_insn_length. */
843 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
844 struct disassemble_info *di,
845 const gdb_byte *insn, int max_len,
848 init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
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;
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);
862 disassemble_init_for_target (di);
865 /* Return the length in bytes of INSN. MAX_LEN is the size of the
866 buffer containing INSN. */
869 gdb_buffered_insn_length (struct gdbarch *gdbarch,
870 const gdb_byte *insn, int max_len, CORE_ADDR addr)
872 struct disassemble_info di;
874 gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
876 return gdbarch_print_insn (gdbarch, addr, &di);