disasm: split dump_insns
[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 = (const struct dis_line_entry *) 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 = (const struct dis_line_entry *) item_lhs;
73   const struct dis_line_entry *rhs = (const struct dis_line_entry *) 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 err, bfd_vma memaddr,
133                       struct disassemble_info *info)
134 {
135   memory_error (TARGET_XFER_E_IO, 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 = (struct gdbarch *) info->application_data;
143
144   print_address (gdbarch, addr, (struct ui_file *) 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 /* Prints the instruction at PC into UIOUT and returns the length of the
174    printed instruction in bytes.  */
175
176 static int
177 gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
178                        struct disassemble_info * di, CORE_ADDR pc, int flags,
179                        struct ui_file *stb)
180 {
181   /* parts of the symbolic representation of the address */
182   int unmapped;
183   int offset;
184   int line;
185   int size;
186   struct cleanup *ui_out_chain;
187   char *filename = NULL;
188   char *name = NULL;
189
190   ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
191
192   if ((flags & DISASSEMBLY_OMIT_PC) == 0)
193     ui_out_text (uiout, pc_prefix (pc));
194   ui_out_field_core_addr (uiout, "address", gdbarch, pc);
195
196   if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
197                                &line, &unmapped))
198     {
199       /* We don't care now about line, filename and unmapped.  But we might in
200          the future.  */
201       ui_out_text (uiout, " <");
202       if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
203         ui_out_field_string (uiout, "func-name", name);
204       ui_out_text (uiout, "+");
205       ui_out_field_int (uiout, "offset", offset);
206       ui_out_text (uiout, ">:\t");
207     }
208   else
209     ui_out_text (uiout, ":\t");
210
211   if (filename != NULL)
212     xfree (filename);
213   if (name != NULL)
214     xfree (name);
215
216   ui_file_rewind (stb);
217   if (flags & DISASSEMBLY_RAW_INSN)
218     {
219       CORE_ADDR end_pc;
220       bfd_byte data;
221       int err;
222       const char *spacer = "";
223
224       /* Build the opcodes using a temporary stream so we can
225          write them out in a single go for the MI.  */
226       struct ui_file *opcode_stream = mem_fileopen ();
227       struct cleanup *cleanups =
228         make_cleanup_ui_file_delete (opcode_stream);
229
230       size = gdbarch_print_insn (gdbarch, pc, di);
231       end_pc = pc + size;
232
233       for (;pc < end_pc; ++pc)
234         {
235           err = (*di->read_memory_func) (pc, &data, 1, di);
236           if (err != 0)
237             (*di->memory_error_func) (err, pc, di);
238           fprintf_filtered (opcode_stream, "%s%02x",
239                             spacer, (unsigned) data);
240           spacer = " ";
241         }
242
243       ui_out_field_stream (uiout, "opcodes", opcode_stream);
244       ui_out_text (uiout, "\t");
245
246       do_cleanups (cleanups);
247     }
248   else
249     size = gdbarch_print_insn (gdbarch, pc, di);
250
251   ui_out_field_stream (uiout, "inst", stb);
252   ui_file_rewind (stb);
253   do_cleanups (ui_out_chain);
254   ui_out_text (uiout, "\n");
255
256   return size;
257 }
258
259 static int
260 dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
261             struct disassemble_info * di,
262             CORE_ADDR low, CORE_ADDR high,
263             int how_many, int flags, struct ui_file *stb,
264             CORE_ADDR *end_pc)
265 {
266   int num_displayed = 0;
267
268   while (low < high && (how_many < 0 || num_displayed < how_many))
269     {
270       int size;
271
272       size = gdb_pretty_print_insn (gdbarch, uiout, di, low, flags, stb);
273       if (size <= 0)
274         break;
275
276       ++num_displayed;
277       low += size;
278
279       /* Allow user to bail out with ^C.  */
280       QUIT;
281     }
282
283   if (end_pc != NULL)
284     *end_pc = low;
285
286   return num_displayed;
287 }
288
289 /* The idea here is to present a source-O-centric view of a
290    function to the user.  This means that things are presented
291    in source order, with (possibly) out of order assembly
292    immediately following.
293
294    N.B. This view is deprecated.  */
295
296 static void
297 do_mixed_source_and_assembly_deprecated
298   (struct gdbarch *gdbarch, struct ui_out *uiout,
299    struct disassemble_info *di, struct symtab *symtab,
300    CORE_ADDR low, CORE_ADDR high,
301    int how_many, int flags, struct ui_file *stb)
302 {
303   int newlines = 0;
304   int nlines;
305   struct linetable_entry *le;
306   struct deprecated_dis_line_entry *mle;
307   struct symtab_and_line sal;
308   int i;
309   int out_of_order = 0;
310   int next_line = 0;
311   int num_displayed = 0;
312   enum print_source_lines_flags psl_flags = 0;
313   struct cleanup *ui_out_chain;
314   struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
315   struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
316
317   gdb_assert (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL);
318
319   nlines = SYMTAB_LINETABLE (symtab)->nitems;
320   le = SYMTAB_LINETABLE (symtab)->item;
321
322   if (flags & DISASSEMBLY_FILENAME)
323     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
324
325   mle = (struct deprecated_dis_line_entry *)
326     alloca (nlines * sizeof (struct deprecated_dis_line_entry));
327
328   /* Copy linetable entries for this function into our data
329      structure, creating end_pc's and setting out_of_order as
330      appropriate.  */
331
332   /* First, skip all the preceding functions.  */
333
334   for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
335
336   /* Now, copy all entries before the end of this function.  */
337
338   for (; i < nlines - 1 && le[i].pc < high; i++)
339     {
340       if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
341         continue;               /* Ignore duplicates.  */
342
343       /* Skip any end-of-function markers.  */
344       if (le[i].line == 0)
345         continue;
346
347       mle[newlines].line = le[i].line;
348       if (le[i].line > le[i + 1].line)
349         out_of_order = 1;
350       mle[newlines].start_pc = le[i].pc;
351       mle[newlines].end_pc = le[i + 1].pc;
352       newlines++;
353     }
354
355   /* If we're on the last line, and it's part of the function,
356      then we need to get the end pc in a special way.  */
357
358   if (i == nlines - 1 && le[i].pc < high)
359     {
360       mle[newlines].line = le[i].line;
361       mle[newlines].start_pc = le[i].pc;
362       sal = find_pc_line (le[i].pc, 0);
363       mle[newlines].end_pc = sal.end;
364       newlines++;
365     }
366
367   /* Now, sort mle by line #s (and, then by addresses within lines).  */
368
369   if (out_of_order)
370     qsort (mle, newlines, sizeof (struct deprecated_dis_line_entry),
371            compare_lines);
372
373   /* Now, for each line entry, emit the specified lines (unless
374      they have been emitted before), followed by the assembly code
375      for that line.  */
376
377   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
378
379   for (i = 0; i < newlines; i++)
380     {
381       /* Print out everything from next_line to the current line.  */
382       if (mle[i].line >= next_line)
383         {
384           if (next_line != 0)
385             {
386               /* Just one line to print.  */
387               if (next_line == mle[i].line)
388                 {
389                   ui_out_tuple_chain
390                     = make_cleanup_ui_out_tuple_begin_end (uiout,
391                                                            "src_and_asm_line");
392                   print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
393                 }
394               else
395                 {
396                   /* Several source lines w/o asm instructions associated.  */
397                   for (; next_line < mle[i].line; next_line++)
398                     {
399                       struct cleanup *ui_out_list_chain_line;
400                       struct cleanup *ui_out_tuple_chain_line;
401                       
402                       ui_out_tuple_chain_line
403                         = make_cleanup_ui_out_tuple_begin_end (uiout,
404                                                                "src_and_asm_line");
405                       print_source_lines (symtab, next_line, next_line + 1,
406                                           psl_flags);
407                       ui_out_list_chain_line
408                         = make_cleanup_ui_out_list_begin_end (uiout,
409                                                               "line_asm_insn");
410                       do_cleanups (ui_out_list_chain_line);
411                       do_cleanups (ui_out_tuple_chain_line);
412                     }
413                   /* Print the last line and leave list open for
414                      asm instructions to be added.  */
415                   ui_out_tuple_chain
416                     = make_cleanup_ui_out_tuple_begin_end (uiout,
417                                                            "src_and_asm_line");
418                   print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
419                 }
420             }
421           else
422             {
423               ui_out_tuple_chain
424                 = make_cleanup_ui_out_tuple_begin_end (uiout,
425                                                        "src_and_asm_line");
426               print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
427             }
428
429           next_line = mle[i].line + 1;
430           ui_out_list_chain
431             = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
432         }
433
434       num_displayed += dump_insns (gdbarch, uiout, di,
435                                    mle[i].start_pc, mle[i].end_pc,
436                                    how_many, flags, stb, NULL);
437
438       /* When we've reached the end of the mle array, or we've seen the last
439          assembly range for this source line, close out the list/tuple.  */
440       if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
441         {
442           do_cleanups (ui_out_list_chain);
443           do_cleanups (ui_out_tuple_chain);
444           ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
445           ui_out_list_chain = make_cleanup (null_cleanup, 0);
446           ui_out_text (uiout, "\n");
447         }
448       if (how_many >= 0 && num_displayed >= how_many)
449         break;
450     }
451   do_cleanups (ui_out_chain);
452 }
453
454 /* The idea here is to present a source-O-centric view of a
455    function to the user.  This means that things are presented
456    in source order, with (possibly) out of order assembly
457    immediately following.  */
458
459 static void
460 do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
461                               struct disassemble_info *di,
462                               struct symtab *main_symtab,
463                               CORE_ADDR low, CORE_ADDR high,
464                               int how_many, int flags, struct ui_file *stb)
465 {
466   int newlines = 0;
467   const struct linetable_entry *le, *first_le;
468   struct symtab_and_line sal;
469   int i, nlines;
470   int out_of_order = 0;
471   int next_line = 0;
472   int num_displayed = 0;
473   enum print_source_lines_flags psl_flags = 0;
474   struct cleanup *cleanups;
475   struct cleanup *ui_out_chain;
476   struct cleanup *ui_out_tuple_chain;
477   struct cleanup *ui_out_list_chain;
478   CORE_ADDR pc;
479   struct symtab *last_symtab;
480   int last_line;
481   htab_t dis_line_table;
482
483   gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
484
485   /* First pass: collect the list of all source files and lines.
486      We do this so that we can only print lines containing code once.
487      We try to print the source text leading up to the next instruction,
488      but if that text is for code that will be disassembled later, then
489      we'll want to defer printing it until later with its associated code.  */
490
491   dis_line_table = allocate_dis_line_table ();
492   cleanups = make_cleanup_htab_delete (dis_line_table);
493
494   pc = low;
495
496   /* The prologue may be empty, but there may still be a line number entry
497      for the opening brace which is distinct from the first line of code.
498      If the prologue has been eliminated find_pc_line may return the source
499      line after the opening brace.  We still want to print this opening brace.
500      first_le is used to implement this.  */
501
502   nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
503   le = SYMTAB_LINETABLE (main_symtab)->item;
504   first_le = NULL;
505
506   /* Skip all the preceding functions.  */
507   for (i = 0; i < nlines && le[i].pc < low; i++)
508     continue;
509
510   if (i < nlines && le[i].pc < high)
511     first_le = &le[i];
512
513   /* Add lines for every pc value.  */
514   while (pc < high)
515     {
516       struct symtab_and_line sal;
517       int length;
518
519       sal = find_pc_line (pc, 0);
520       length = gdb_insn_length (gdbarch, pc);
521       pc += length;
522
523       if (sal.symtab != NULL)
524         maybe_add_dis_line_entry (dis_line_table, sal.symtab, sal.line);
525     }
526
527   /* Second pass: print the disassembly.
528
529      Output format, from an MI perspective:
530        The result is a ui_out list, field name "asm_insns", where elements have
531        name "src_and_asm_line".
532        Each element is a tuple of source line specs (field names line, file,
533        fullname), and field "line_asm_insn" which contains the disassembly.
534        Field "line_asm_insn" is a list of tuples: address, func-name, offset,
535        opcodes, inst.
536
537      CLI output works on top of this because MI ignores ui_out_text output,
538      which is where we put file name and source line contents output.
539
540      Cleanup usage:
541      cleanups:
542        For things created at the beginning of this function and need to be
543        kept until the end of this function.
544      ui_out_chain
545        Handles the outer "asm_insns" list.
546      ui_out_tuple_chain
547        The tuples for each group of consecutive disassemblies.
548      ui_out_list_chain
549        List of consecutive source lines or disassembled insns.  */
550
551   if (flags & DISASSEMBLY_FILENAME)
552     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
553
554   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
555
556   ui_out_tuple_chain = NULL;
557   ui_out_list_chain = NULL;
558
559   last_symtab = NULL;
560   last_line = 0;
561   pc = low;
562
563   while (pc < high)
564     {
565       struct linetable_entry *le = NULL;
566       struct symtab_and_line sal;
567       CORE_ADDR end_pc;
568       int start_preceding_line_to_display = 0;
569       int end_preceding_line_to_display = 0;
570       int new_source_line = 0;
571
572       sal = find_pc_line (pc, 0);
573
574       if (sal.symtab != last_symtab)
575         {
576           /* New source file.  */
577           new_source_line = 1;
578
579           /* If this is the first line of output, check for any preceding
580              lines.  */
581           if (last_line == 0
582               && first_le != NULL
583               && first_le->line < sal.line)
584             {
585               start_preceding_line_to_display = first_le->line;
586               end_preceding_line_to_display = sal.line;
587             }
588         }
589       else
590         {
591           /* Same source file as last time.  */
592           if (sal.symtab != NULL)
593             {
594               if (sal.line > last_line + 1 && last_line != 0)
595                 {
596                   int l;
597
598                   /* Several preceding source lines.  Print the trailing ones
599                      not associated with code that we'll print later.  */
600                   for (l = sal.line - 1; l > last_line; --l)
601                     {
602                       if (line_has_code_p (dis_line_table, sal.symtab, l))
603                         break;
604                     }
605                   if (l < sal.line - 1)
606                     {
607                       start_preceding_line_to_display = l + 1;
608                       end_preceding_line_to_display = sal.line;
609                     }
610                 }
611               if (sal.line != last_line)
612                 new_source_line = 1;
613               else
614                 {
615                   /* Same source line as last time.  This can happen, depending
616                      on the debug info.  */
617                 }
618             }
619         }
620
621       if (new_source_line)
622         {
623           /* Skip the newline if this is the first instruction.  */
624           if (pc > low)
625             ui_out_text (uiout, "\n");
626           if (ui_out_tuple_chain != NULL)
627             {
628               gdb_assert (ui_out_list_chain != NULL);
629               do_cleanups (ui_out_list_chain);
630               do_cleanups (ui_out_tuple_chain);
631             }
632           if (sal.symtab != last_symtab
633               && !(flags & DISASSEMBLY_FILENAME))
634             {
635               /* Remember MI ignores ui_out_text.
636                  We don't have to do anything here for MI because MI
637                  output includes the source specs for each line.  */
638               if (sal.symtab != NULL)
639                 {
640                   ui_out_text (uiout,
641                                symtab_to_filename_for_display (sal.symtab));
642                 }
643               else
644                 ui_out_text (uiout, "unknown");
645               ui_out_text (uiout, ":\n");
646             }
647           if (start_preceding_line_to_display > 0)
648             {
649               /* Several source lines w/o asm instructions associated.
650                  We need to preserve the structure of the output, so output
651                  a bunch of line tuples with no asm entries.  */
652               int l;
653               struct cleanup *ui_out_list_chain_line;
654               struct cleanup *ui_out_tuple_chain_line;
655
656               gdb_assert (sal.symtab != NULL);
657               for (l = start_preceding_line_to_display;
658                    l < end_preceding_line_to_display;
659                    ++l)
660                 {
661                   ui_out_tuple_chain_line
662                     = make_cleanup_ui_out_tuple_begin_end (uiout,
663                                                            "src_and_asm_line");
664                   print_source_lines (sal.symtab, l, l + 1, psl_flags);
665                   ui_out_list_chain_line
666                     = make_cleanup_ui_out_list_begin_end (uiout,
667                                                           "line_asm_insn");
668                   do_cleanups (ui_out_list_chain_line);
669                   do_cleanups (ui_out_tuple_chain_line);
670                 }
671             }
672           ui_out_tuple_chain
673             = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
674           if (sal.symtab != NULL)
675             print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
676           else
677             ui_out_text (uiout, _("--- no source info for this pc ---\n"));
678           ui_out_list_chain
679             = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
680         }
681       else
682         {
683           /* Here we're appending instructions to an existing line.
684              By construction the very first insn will have a symtab
685              and follow the new_source_line path above.  */
686           gdb_assert (ui_out_tuple_chain != NULL);
687           gdb_assert (ui_out_list_chain != NULL);
688         }
689
690       if (sal.end != 0)
691         end_pc = min (sal.end, high);
692       else
693         end_pc = pc + 1;
694       num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc,
695                                    how_many, flags, stb, &end_pc);
696       pc = end_pc;
697
698       if (how_many >= 0 && num_displayed >= how_many)
699         break;
700
701       last_symtab = sal.symtab;
702       last_line = sal.line;
703     }
704
705   do_cleanups (ui_out_chain);
706   do_cleanups (cleanups);
707 }
708
709 static void
710 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
711                   struct disassemble_info * di,
712                   CORE_ADDR low, CORE_ADDR high,
713                   int how_many, int flags, struct ui_file *stb)
714 {
715   int num_displayed = 0;
716   struct cleanup *ui_out_chain;
717
718   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
719
720   num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
721                               flags, stb, NULL);
722
723   do_cleanups (ui_out_chain);
724 }
725
726 /* Initialize the disassemble info struct ready for the specified
727    stream.  */
728
729 static int ATTRIBUTE_PRINTF (2, 3)
730 fprintf_disasm (void *stream, const char *format, ...)
731 {
732   va_list args;
733
734   va_start (args, format);
735   vfprintf_filtered ((struct ui_file *) stream, format, args);
736   va_end (args);
737   /* Something non -ve.  */
738   return 0;
739 }
740
741 struct disassemble_info
742 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
743 {
744   struct disassemble_info di;
745
746   init_disassemble_info (&di, file, fprintf_disasm);
747   di.flavour = bfd_target_unknown_flavour;
748   di.memory_error_func = dis_asm_memory_error;
749   di.print_address_func = dis_asm_print_address;
750   /* NOTE: cagney/2003-04-28: The original code, from the old Insight
751      disassembler had a local optomization here.  By default it would
752      access the executable file, instead of the target memory (there
753      was a growing list of exceptions though).  Unfortunately, the
754      heuristic was flawed.  Commands like "disassemble &variable"
755      didn't work as they relied on the access going to the target.
756      Further, it has been supperseeded by trust-read-only-sections
757      (although that should be superseeded by target_trust..._p()).  */
758   di.read_memory_func = dis_asm_read_memory;
759   di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
760   di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
761   di.endian = gdbarch_byte_order (gdbarch);
762   di.endian_code = gdbarch_byte_order_for_code (gdbarch);
763   di.application_data = gdbarch;
764   disassemble_init_for_target (&di);
765   return di;
766 }
767
768 void
769 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
770                  char *file_string, int flags, int how_many,
771                  CORE_ADDR low, CORE_ADDR high)
772 {
773   struct ui_file *stb = mem_fileopen ();
774   struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
775   struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
776   struct symtab *symtab;
777   struct linetable_entry *le = NULL;
778   int nlines = -1;
779
780   /* Assume symtab is valid for whole PC range.  */
781   symtab = find_pc_line_symtab (low);
782
783   if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
784     nlines = SYMTAB_LINETABLE (symtab)->nitems;
785
786   if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
787       || nlines <= 0)
788     do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
789
790   else if (flags & DISASSEMBLY_SOURCE)
791     do_mixed_source_and_assembly (gdbarch, uiout, &di, symtab, low, high,
792                                   how_many, flags, stb);
793
794   else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
795     do_mixed_source_and_assembly_deprecated (gdbarch, uiout, &di, symtab,
796                                              low, high, how_many, flags, stb);
797
798   do_cleanups (cleanups);
799   gdb_flush (gdb_stdout);
800 }
801
802 /* Print the instruction at address MEMADDR in debugged memory,
803    on STREAM.  Returns the length of the instruction, in bytes,
804    and, if requested, the number of branch delay slot instructions.  */
805
806 int
807 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
808                 struct ui_file *stream, int *branch_delay_insns)
809 {
810   struct disassemble_info di;
811   int length;
812
813   di = gdb_disassemble_info (gdbarch, stream);
814   length = gdbarch_print_insn (gdbarch, memaddr, &di);
815   if (branch_delay_insns)
816     {
817       if (di.insn_info_valid)
818         *branch_delay_insns = di.branch_delay_insns;
819       else
820         *branch_delay_insns = 0;
821     }
822   return length;
823 }
824
825 static void
826 do_ui_file_delete (void *arg)
827 {
828   ui_file_delete ((struct ui_file *) arg);
829 }
830
831 /* Return the length in bytes of the instruction at address MEMADDR in
832    debugged memory.  */
833
834 int
835 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
836 {
837   static struct ui_file *null_stream = NULL;
838
839   /* Dummy file descriptor for the disassembler.  */
840   if (!null_stream)
841     {
842       null_stream = ui_file_new ();
843       make_final_cleanup (do_ui_file_delete, null_stream);
844     }
845
846   return gdb_print_insn (gdbarch, addr, null_stream, NULL);
847 }
848
849 /* fprintf-function for gdb_buffered_insn_length.  This function is a
850    nop, we don't want to print anything, we just want to compute the
851    length of the insn.  */
852
853 static int ATTRIBUTE_PRINTF (2, 3)
854 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
855 {
856   return 0;
857 }
858
859 /* Initialize a struct disassemble_info for gdb_buffered_insn_length.  */
860
861 static void
862 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
863                                    struct disassemble_info *di,
864                                    const gdb_byte *insn, int max_len,
865                                    CORE_ADDR addr)
866 {
867   init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
868
869   /* init_disassemble_info installs buffer_read_memory, etc.
870      so we don't need to do that here.
871      The cast is necessary until disassemble_info is const-ified.  */
872   di->buffer = (gdb_byte *) insn;
873   di->buffer_length = max_len;
874   di->buffer_vma = addr;
875
876   di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
877   di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
878   di->endian = gdbarch_byte_order (gdbarch);
879   di->endian_code = gdbarch_byte_order_for_code (gdbarch);
880
881   disassemble_init_for_target (di);
882 }
883
884 /* Return the length in bytes of INSN.  MAX_LEN is the size of the
885    buffer containing INSN.  */
886
887 int
888 gdb_buffered_insn_length (struct gdbarch *gdbarch,
889                           const gdb_byte *insn, int max_len, CORE_ADDR addr)
890 {
891   struct disassemble_info di;
892
893   gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
894
895   return gdbarch_print_insn (gdbarch, addr, &di);
896 }