New /s modifier for the disassemble command.
[external/binutils.git] / gdb / disasm.c
1 /* Disassemble support for GDB.
2
3    Copyright (C) 2000-2015 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
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.
11
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.
16
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/>.  */
19
20 #include "defs.h"
21 #include "target.h"
22 #include "value.h"
23 #include "ui-out.h"
24 #include "disasm.h"
25 #include "gdbcore.h"
26 #include "dis-asm.h"
27 #include "source.h"
28
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.  */
32
33 /* This structure is used to store line number information for the
34    deprecated /m option.
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.  */
38
39 struct deprecated_dis_line_entry
40 {
41   int line;
42   CORE_ADDR start_pc;
43   CORE_ADDR end_pc;
44 };
45
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.  */
50
51 struct dis_line_entry
52 {
53   struct symtab *symtab;
54   int line;
55 };
56
57 /* Hash function for dis_line_entry.  */
58
59 static hashval_t
60 hash_dis_line_entry (const void *item)
61 {
62   const struct dis_line_entry *dle = item;
63
64   return htab_hash_pointer (dle->symtab) + dle->line;
65 }
66
67 /* Equal function for dis_line_entry.  */
68
69 static int
70 eq_dis_line_entry (const void *item_lhs, const void *item_rhs)
71 {
72   const struct dis_line_entry *lhs = item_lhs;
73   const struct dis_line_entry *rhs = item_rhs;
74
75   return (lhs->symtab == rhs->symtab
76           && lhs->line == rhs->line);
77 }
78
79 /* Create the table to manage lines for mixed source/disassembly.  */
80
81 static htab_t
82 allocate_dis_line_table (void)
83 {
84   return htab_create_alloc (41,
85                             hash_dis_line_entry, eq_dis_line_entry,
86                             xfree, xcalloc, xfree);
87 }
88
89 /* Add DLE to TABLE.
90    Returns 1 if added, 0 if already present.  */
91
92 static void
93 maybe_add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
94 {
95   void **slot;
96   struct dis_line_entry dle, *dlep;
97
98   dle.symtab = symtab;
99   dle.line = line;
100   slot = htab_find_slot (table, &dle, INSERT);
101   if (*slot == NULL)
102     {
103       dlep = XNEW (struct dis_line_entry);
104       dlep->symtab = symtab;
105       dlep->line = line;
106       *slot = dlep;
107     }
108 }
109
110 /* Return non-zero if SYMTAB, LINE are in TABLE.  */
111
112 static int
113 line_has_code_p (htab_t table, struct symtab *symtab, int line)
114 {
115   struct dis_line_entry dle;
116
117   dle.symtab = symtab;
118   dle.line = line;
119   return htab_find (table, &dle) != NULL;
120 }
121
122 /* Like target_read_memory, but slightly different parameters.  */
123 static int
124 dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
125                      struct disassemble_info *info)
126 {
127   return target_read_code (memaddr, myaddr, len);
128 }
129
130 /* Like memory_error with slightly different parameters.  */
131 static void
132 dis_asm_memory_error (int status, bfd_vma memaddr,
133                       struct disassemble_info *info)
134 {
135   memory_error (status, memaddr);
136 }
137
138 /* Like print_address with slightly different parameters.  */
139 static void
140 dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
141 {
142   struct gdbarch *gdbarch = info->application_data;
143
144   print_address (gdbarch, addr, info->stream);
145 }
146
147 static int
148 compare_lines (const void *mle1p, const void *mle2p)
149 {
150   struct deprecated_dis_line_entry *mle1, *mle2;
151   int val;
152
153   mle1 = (struct deprecated_dis_line_entry *) mle1p;
154   mle2 = (struct deprecated_dis_line_entry *) mle2p;
155
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)
159     {
160       val = mle1->start_pc - mle2->start_pc;
161       if (val == 0)
162         val = mle1->line - mle2->line;
163     }
164   else
165     {
166       val = mle1->line - mle2->line;
167       if (val == 0)
168         val = mle1->start_pc - mle2->start_pc;
169     }
170   return val;
171 }
172
173 static int
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,
178             CORE_ADDR *end_pc)
179 {
180   int num_displayed = 0;
181   CORE_ADDR pc;
182
183   /* parts of the symbolic representation of the address */
184   int unmapped;
185   int offset;
186   int line;
187   struct cleanup *ui_out_chain;
188
189   for (pc = low; pc < high;)
190     {
191       char *filename = NULL;
192       char *name = NULL;
193
194       QUIT;
195       if (how_many >= 0)
196         {
197           if (num_displayed >= how_many)
198             break;
199           else
200             num_displayed++;
201         }
202       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
203
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);
207
208       if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
209                                    &line, &unmapped))
210         {
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");
219         }
220       else
221         ui_out_text (uiout, ":\t");
222
223       if (filename != NULL)
224         xfree (filename);
225       if (name != NULL)
226         xfree (name);
227
228       ui_file_rewind (stb);
229       if (flags & DISASSEMBLY_RAW_INSN)
230         {
231           CORE_ADDR old_pc = pc;
232           bfd_byte data;
233           int status;
234           const char *spacer = "";
235
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);
241
242           pc += gdbarch_print_insn (gdbarch, pc, di);
243           for (;old_pc < pc; old_pc++)
244             {
245               status = (*di->read_memory_func) (old_pc, &data, 1, di);
246               if (status != 0)
247                 (*di->memory_error_func) (status, old_pc, di);
248               fprintf_filtered (opcode_stream, "%s%02x",
249                                 spacer, (unsigned) data);
250               spacer = " ";
251             }
252           ui_out_field_stream (uiout, "opcodes", opcode_stream);
253           ui_out_text (uiout, "\t");
254
255           do_cleanups (cleanups);
256         }
257       else
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");
263     }
264
265   if (end_pc != NULL)
266     *end_pc = pc;
267   return num_displayed;
268 }
269
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.
274
275    N.B. This view is deprecated.  */
276
277 static void
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)
283 {
284   int newlines = 0;
285   int nlines;
286   struct linetable_entry *le;
287   struct deprecated_dis_line_entry *mle;
288   struct symtab_and_line sal;
289   int i;
290   int out_of_order = 0;
291   int next_line = 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);
297
298   gdb_assert (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL);
299
300   nlines = SYMTAB_LINETABLE (symtab)->nitems;
301   le = SYMTAB_LINETABLE (symtab)->item;
302
303   if (flags & DISASSEMBLY_FILENAME)
304     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
305
306   mle = (struct deprecated_dis_line_entry *)
307     alloca (nlines * sizeof (struct deprecated_dis_line_entry));
308
309   /* Copy linetable entries for this function into our data
310      structure, creating end_pc's and setting out_of_order as
311      appropriate.  */
312
313   /* First, skip all the preceding functions.  */
314
315   for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
316
317   /* Now, copy all entries before the end of this function.  */
318
319   for (; i < nlines - 1 && le[i].pc < high; i++)
320     {
321       if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
322         continue;               /* Ignore duplicates.  */
323
324       /* Skip any end-of-function markers.  */
325       if (le[i].line == 0)
326         continue;
327
328       mle[newlines].line = le[i].line;
329       if (le[i].line > le[i + 1].line)
330         out_of_order = 1;
331       mle[newlines].start_pc = le[i].pc;
332       mle[newlines].end_pc = le[i + 1].pc;
333       newlines++;
334     }
335
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.  */
338
339   if (i == nlines - 1 && le[i].pc < high)
340     {
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;
345       newlines++;
346     }
347
348   /* Now, sort mle by line #s (and, then by addresses within lines).  */
349
350   if (out_of_order)
351     qsort (mle, newlines, sizeof (struct deprecated_dis_line_entry),
352            compare_lines);
353
354   /* Now, for each line entry, emit the specified lines (unless
355      they have been emitted before), followed by the assembly code
356      for that line.  */
357
358   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
359
360   for (i = 0; i < newlines; i++)
361     {
362       /* Print out everything from next_line to the current line.  */
363       if (mle[i].line >= next_line)
364         {
365           if (next_line != 0)
366             {
367               /* Just one line to print.  */
368               if (next_line == mle[i].line)
369                 {
370                   ui_out_tuple_chain
371                     = make_cleanup_ui_out_tuple_begin_end (uiout,
372                                                            "src_and_asm_line");
373                   print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
374                 }
375               else
376                 {
377                   /* Several source lines w/o asm instructions associated.  */
378                   for (; next_line < mle[i].line; next_line++)
379                     {
380                       struct cleanup *ui_out_list_chain_line;
381                       struct cleanup *ui_out_tuple_chain_line;
382                       
383                       ui_out_tuple_chain_line
384                         = make_cleanup_ui_out_tuple_begin_end (uiout,
385                                                                "src_and_asm_line");
386                       print_source_lines (symtab, next_line, next_line + 1,
387                                           psl_flags);
388                       ui_out_list_chain_line
389                         = make_cleanup_ui_out_list_begin_end (uiout,
390                                                               "line_asm_insn");
391                       do_cleanups (ui_out_list_chain_line);
392                       do_cleanups (ui_out_tuple_chain_line);
393                     }
394                   /* Print the last line and leave list open for
395                      asm instructions to be added.  */
396                   ui_out_tuple_chain
397                     = make_cleanup_ui_out_tuple_begin_end (uiout,
398                                                            "src_and_asm_line");
399                   print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
400                 }
401             }
402           else
403             {
404               ui_out_tuple_chain
405                 = make_cleanup_ui_out_tuple_begin_end (uiout,
406                                                        "src_and_asm_line");
407               print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
408             }
409
410           next_line = mle[i].line + 1;
411           ui_out_list_chain
412             = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
413         }
414
415       num_displayed += dump_insns (gdbarch, uiout, di,
416                                    mle[i].start_pc, mle[i].end_pc,
417                                    how_many, flags, stb, NULL);
418
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)
422         {
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");
428         }
429       if (how_many >= 0 && num_displayed >= how_many)
430         break;
431     }
432   do_cleanups (ui_out_chain);
433 }
434
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.  */
439
440 static void
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)
446 {
447   int newlines = 0;
448   const struct linetable_entry *le, *first_le;
449   struct symtab_and_line sal;
450   int i, nlines;
451   int out_of_order = 0;
452   int next_line = 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;
459   CORE_ADDR pc;
460   struct symtab *last_symtab;
461   int last_line;
462   htab_t dis_line_table;
463
464   gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
465
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.  */
471
472   dis_line_table = allocate_dis_line_table ();
473   cleanups = make_cleanup_htab_delete (dis_line_table);
474
475   pc = low;
476
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.  */
482
483   nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
484   le = SYMTAB_LINETABLE (main_symtab)->item;
485   first_le = NULL;
486
487   /* Skip all the preceding functions.  */
488   for (i = 0; i < nlines && le[i].pc < low; i++)
489     continue;
490
491   if (i < nlines && le[i].pc < high)
492     first_le = &le[i];
493
494   /* Add lines for every pc value.  */
495   while (pc < high)
496     {
497       struct symtab_and_line sal;
498       int length;
499
500       sal = find_pc_line (pc, 0);
501       length = gdb_insn_length (gdbarch, pc);
502       pc += length;
503
504       if (sal.symtab != NULL)
505         maybe_add_dis_line_entry (dis_line_table, sal.symtab, sal.line);
506     }
507
508   /* Second pass: print the disassembly.
509
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,
516        opcodes, inst.
517
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.
520
521      Cleanup usage:
522      cleanups:
523        For things created at the beginning of this function and need to be
524        kept until the end of this function.
525      ui_out_chain
526        Handles the outer "asm_insns" list.
527      ui_out_tuple_chain
528        The tuples for each group of consecutive disassemblies.
529      ui_out_list_chain
530        List of consecutive source lines or disassembled insns.  */
531
532   if (flags & DISASSEMBLY_FILENAME)
533     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
534
535   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
536
537   ui_out_tuple_chain = NULL;
538   ui_out_list_chain = NULL;
539
540   last_symtab = NULL;
541   last_line = 0;
542   pc = low;
543
544   while (pc < high)
545     {
546       struct linetable_entry *le = NULL;
547       struct symtab_and_line sal;
548       CORE_ADDR end_pc;
549       int start_preceding_line_to_display = 0;
550       int end_preceding_line_to_display = 0;
551       int new_source_line = 0;
552
553       sal = find_pc_line (pc, 0);
554
555       if (sal.symtab != last_symtab)
556         {
557           /* New source file.  */
558           new_source_line = 1;
559
560           /* If this is the first line of output, check for any preceding
561              lines.  */
562           if (last_line == 0
563               && first_le != NULL
564               && first_le->line < sal.line)
565             {
566               start_preceding_line_to_display = first_le->line;
567               end_preceding_line_to_display = sal.line;
568             }
569         }
570       else
571         {
572           /* Same source file as last time.  */
573           if (sal.symtab != NULL)
574             {
575               if (sal.line > last_line + 1 && last_line != 0)
576                 {
577                   int l;
578
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)
582                     {
583                       if (line_has_code_p (dis_line_table, sal.symtab, l))
584                         break;
585                     }
586                   if (l < sal.line - 1)
587                     {
588                       start_preceding_line_to_display = l + 1;
589                       end_preceding_line_to_display = sal.line;
590                     }
591                 }
592               if (sal.line != last_line)
593                 new_source_line = 1;
594               else
595                 {
596                   /* Same source line as last time.  This can happen, depending
597                      on the debug info.  */
598                 }
599             }
600         }
601
602       if (new_source_line)
603         {
604           /* Skip the newline if this is the first instruction.  */
605           if (pc > low)
606             ui_out_text (uiout, "\n");
607           if (ui_out_tuple_chain != NULL)
608             {
609               gdb_assert (ui_out_list_chain != NULL);
610               do_cleanups (ui_out_list_chain);
611               do_cleanups (ui_out_tuple_chain);
612             }
613           if (sal.symtab != last_symtab
614               && !(flags & DISASSEMBLY_FILENAME))
615             {
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)
620                 {
621                   ui_out_text (uiout,
622                                symtab_to_filename_for_display (sal.symtab));
623                 }
624               else
625                 ui_out_text (uiout, "unknown");
626               ui_out_text (uiout, ":\n");
627             }
628           if (start_preceding_line_to_display > 0)
629             {
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.  */
633               int l;
634               struct cleanup *ui_out_list_chain_line;
635               struct cleanup *ui_out_tuple_chain_line;
636
637               gdb_assert (sal.symtab != NULL);
638               for (l = start_preceding_line_to_display;
639                    l < end_preceding_line_to_display;
640                    ++l)
641                 {
642                   ui_out_tuple_chain_line
643                     = make_cleanup_ui_out_tuple_begin_end (uiout,
644                                                            "src_and_asm_line");
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,
648                                                           "line_asm_insn");
649                   do_cleanups (ui_out_list_chain_line);
650                   do_cleanups (ui_out_tuple_chain_line);
651                 }
652             }
653           ui_out_tuple_chain
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);
657           else
658             ui_out_text (uiout, _("--- no source info for this pc ---\n"));
659           ui_out_list_chain
660             = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
661         }
662       else
663         {
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);
669         }
670
671       if (sal.end != 0)
672         end_pc = min (sal.end, high);
673       else
674         end_pc = pc + 1;
675       num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc,
676                                    how_many, flags, stb, &end_pc);
677       pc = end_pc;
678
679       if (how_many >= 0 && num_displayed >= how_many)
680         break;
681
682       last_symtab = sal.symtab;
683       last_line = sal.line;
684     }
685
686   do_cleanups (ui_out_chain);
687   do_cleanups (cleanups);
688 }
689
690 static void
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)
695 {
696   int num_displayed = 0;
697   struct cleanup *ui_out_chain;
698
699   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
700
701   num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
702                               flags, stb, NULL);
703
704   do_cleanups (ui_out_chain);
705 }
706
707 /* Initialize the disassemble info struct ready for the specified
708    stream.  */
709
710 static int ATTRIBUTE_PRINTF (2, 3)
711 fprintf_disasm (void *stream, const char *format, ...)
712 {
713   va_list args;
714
715   va_start (args, format);
716   vfprintf_filtered (stream, format, args);
717   va_end (args);
718   /* Something non -ve.  */
719   return 0;
720 }
721
722 struct disassemble_info
723 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
724 {
725   struct disassemble_info di;
726
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);
746   return di;
747 }
748
749 void
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)
753 {
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;
759   int nlines = -1;
760
761   /* Assume symtab is valid for whole PC range.  */
762   symtab = find_pc_line_symtab (low);
763
764   if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
765     nlines = SYMTAB_LINETABLE (symtab)->nitems;
766
767   if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
768       || nlines <= 0)
769     do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
770
771   else if (flags & DISASSEMBLY_SOURCE)
772     do_mixed_source_and_assembly (gdbarch, uiout, &di, symtab, low, high,
773                                   how_many, flags, stb);
774
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);
778
779   do_cleanups (cleanups);
780   gdb_flush (gdb_stdout);
781 }
782
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.  */
786
787 int
788 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
789                 struct ui_file *stream, int *branch_delay_insns)
790 {
791   struct disassemble_info di;
792   int length;
793
794   di = gdb_disassemble_info (gdbarch, stream);
795   length = gdbarch_print_insn (gdbarch, memaddr, &di);
796   if (branch_delay_insns)
797     {
798       if (di.insn_info_valid)
799         *branch_delay_insns = di.branch_delay_insns;
800       else
801         *branch_delay_insns = 0;
802     }
803   return length;
804 }
805
806 static void
807 do_ui_file_delete (void *arg)
808 {
809   ui_file_delete (arg);
810 }
811
812 /* Return the length in bytes of the instruction at address MEMADDR in
813    debugged memory.  */
814
815 int
816 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
817 {
818   static struct ui_file *null_stream = NULL;
819
820   /* Dummy file descriptor for the disassembler.  */
821   if (!null_stream)
822     {
823       null_stream = ui_file_new ();
824       make_final_cleanup (do_ui_file_delete, null_stream);
825     }
826
827   return gdb_print_insn (gdbarch, addr, null_stream, NULL);
828 }
829
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.  */
833
834 static int ATTRIBUTE_PRINTF (2, 3)
835 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
836 {
837   return 0;
838 }
839
840 /* Initialize a struct disassemble_info for gdb_buffered_insn_length.  */
841
842 static void
843 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
844                                    struct disassemble_info *di,
845                                    const gdb_byte *insn, int max_len,
846                                    CORE_ADDR addr)
847 {
848   init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
849
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;
856
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);
861
862   disassemble_init_for_target (di);
863 }
864
865 /* Return the length in bytes of INSN.  MAX_LEN is the size of the
866    buffer containing INSN.  */
867
868 int
869 gdb_buffered_insn_length (struct gdbarch *gdbarch,
870                           const gdb_byte *insn, int max_len, CORE_ADDR addr)
871 {
872   struct disassemble_info di;
873
874   gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
875
876   return gdbarch_print_insn (gdbarch, addr, &di);
877 }