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