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