gdb: Small cleanup to disasm.c:maybe_add_dis_line_entry
[external/binutils.git] / gdb / disasm.c
1 /* Disassemble support for GDB.
2
3    Copyright (C) 2000-2016 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 a new dis_line_entry containing SYMTAB and LINE to TABLE.  */
90
91 static void
92 add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
93 {
94   void **slot;
95   struct dis_line_entry dle, *dlep;
96
97   dle.symtab = symtab;
98   dle.line = line;
99   slot = htab_find_slot (table, &dle, INSERT);
100   if (*slot == NULL)
101     {
102       dlep = XNEW (struct dis_line_entry);
103       dlep->symtab = symtab;
104       dlep->line = line;
105       *slot = dlep;
106     }
107 }
108
109 /* Return non-zero if SYMTAB, LINE are in TABLE.  */
110
111 static int
112 line_has_code_p (htab_t table, struct symtab *symtab, int line)
113 {
114   struct dis_line_entry dle;
115
116   dle.symtab = symtab;
117   dle.line = line;
118   return htab_find (table, &dle) != NULL;
119 }
120
121 /* Like target_read_memory, but slightly different parameters.  */
122 static int
123 dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
124                      struct disassemble_info *info)
125 {
126   return target_read_code (memaddr, myaddr, len);
127 }
128
129 /* Like memory_error with slightly different parameters.  */
130 static void
131 dis_asm_memory_error (int err, bfd_vma memaddr,
132                       struct disassemble_info *info)
133 {
134   memory_error (TARGET_XFER_E_IO, memaddr);
135 }
136
137 /* Like print_address with slightly different parameters.  */
138 static void
139 dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
140 {
141   struct gdbarch *gdbarch = (struct gdbarch *) info->application_data;
142
143   print_address (gdbarch, addr, (struct ui_file *) info->stream);
144 }
145
146 static int
147 compare_lines (const void *mle1p, const void *mle2p)
148 {
149   struct deprecated_dis_line_entry *mle1, *mle2;
150   int val;
151
152   mle1 = (struct deprecated_dis_line_entry *) mle1p;
153   mle2 = (struct deprecated_dis_line_entry *) mle2p;
154
155   /* End of sequence markers have a line number of 0 but don't want to
156      be sorted to the head of the list, instead sort by PC.  */
157   if (mle1->line == 0 || mle2->line == 0)
158     {
159       val = mle1->start_pc - mle2->start_pc;
160       if (val == 0)
161         val = mle1->line - mle2->line;
162     }
163   else
164     {
165       val = mle1->line - mle2->line;
166       if (val == 0)
167         val = mle1->start_pc - mle2->start_pc;
168     }
169   return val;
170 }
171
172 /* See disasm.h.  */
173
174 int
175 gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
176                        struct disassemble_info * di,
177                        const struct disasm_insn *insn, int flags,
178                        struct ui_file *stb)
179 {
180   /* parts of the symbolic representation of the address */
181   int unmapped;
182   int offset;
183   int line;
184   int size;
185   struct cleanup *ui_out_chain;
186   char *filename = NULL;
187   char *name = NULL;
188   CORE_ADDR pc;
189
190   ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
191   pc = insn->addr;
192
193   if (insn->number != 0)
194     {
195       ui_out_field_fmt (uiout, "insn-number", "%u", insn->number);
196       ui_out_text (uiout, "\t");
197     }
198
199   if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
200     {
201       if (insn->is_speculative)
202         {
203           ui_out_field_string (uiout, "is-speculative", "?");
204
205           /* The speculative execution indication overwrites the first
206              character of the PC prefix.
207              We assume a PC prefix length of 3 characters.  */
208           if ((flags & DISASSEMBLY_OMIT_PC) == 0)
209             ui_out_text (uiout, pc_prefix (pc) + 1);
210           else
211             ui_out_text (uiout, "  ");
212         }
213       else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
214         ui_out_text (uiout, pc_prefix (pc));
215       else
216         ui_out_text (uiout, "   ");
217     }
218   else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
219     ui_out_text (uiout, pc_prefix (pc));
220   ui_out_field_core_addr (uiout, "address", gdbarch, pc);
221
222   if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
223                                &line, &unmapped))
224     {
225       /* We don't care now about line, filename and unmapped.  But we might in
226          the future.  */
227       ui_out_text (uiout, " <");
228       if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
229         ui_out_field_string (uiout, "func-name", name);
230       ui_out_text (uiout, "+");
231       ui_out_field_int (uiout, "offset", offset);
232       ui_out_text (uiout, ">:\t");
233     }
234   else
235     ui_out_text (uiout, ":\t");
236
237   if (filename != NULL)
238     xfree (filename);
239   if (name != NULL)
240     xfree (name);
241
242   ui_file_rewind (stb);
243   if (flags & DISASSEMBLY_RAW_INSN)
244     {
245       CORE_ADDR end_pc;
246       bfd_byte data;
247       int err;
248       const char *spacer = "";
249
250       /* Build the opcodes using a temporary stream so we can
251          write them out in a single go for the MI.  */
252       struct ui_file *opcode_stream = mem_fileopen ();
253       struct cleanup *cleanups =
254         make_cleanup_ui_file_delete (opcode_stream);
255
256       size = gdbarch_print_insn (gdbarch, pc, di);
257       end_pc = pc + size;
258
259       for (;pc < end_pc; ++pc)
260         {
261           err = (*di->read_memory_func) (pc, &data, 1, di);
262           if (err != 0)
263             (*di->memory_error_func) (err, pc, di);
264           fprintf_filtered (opcode_stream, "%s%02x",
265                             spacer, (unsigned) data);
266           spacer = " ";
267         }
268
269       ui_out_field_stream (uiout, "opcodes", opcode_stream);
270       ui_out_text (uiout, "\t");
271
272       do_cleanups (cleanups);
273     }
274   else
275     size = gdbarch_print_insn (gdbarch, pc, di);
276
277   ui_out_field_stream (uiout, "inst", stb);
278   ui_file_rewind (stb);
279   do_cleanups (ui_out_chain);
280   ui_out_text (uiout, "\n");
281
282   return size;
283 }
284
285 static int
286 dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
287             struct disassemble_info * di,
288             CORE_ADDR low, CORE_ADDR high,
289             int how_many, int flags, struct ui_file *stb,
290             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, di, &insn, flags, stb);
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 disassemble_info *di, struct symtab *symtab,
330    CORE_ADDR low, CORE_ADDR high,
331    int how_many, int flags, struct ui_file *stb)
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, di,
465                                    mle[i].start_pc, mle[i].end_pc,
466                                    how_many, flags, stb, 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           ui_out_text (uiout, "\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, struct ui_out *uiout,
491                               struct disassemble_info *di,
492                               struct symtab *main_symtab,
493                               CORE_ADDR low, CORE_ADDR high,
494                               int how_many, int flags, struct ui_file *stb)
495 {
496   int newlines = 0;
497   const struct linetable_entry *le, *first_le;
498   struct symtab_and_line sal;
499   int i, nlines;
500   int out_of_order = 0;
501   int next_line = 0;
502   int num_displayed = 0;
503   print_source_lines_flags psl_flags = 0;
504   struct cleanup *cleanups;
505   struct cleanup *ui_out_chain;
506   struct cleanup *ui_out_tuple_chain;
507   struct cleanup *ui_out_list_chain;
508   CORE_ADDR pc;
509   struct symtab *last_symtab;
510   int last_line;
511   htab_t dis_line_table;
512
513   gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
514
515   /* First pass: collect the list of all source files and lines.
516      We do this so that we can only print lines containing code once.
517      We try to print the source text leading up to the next instruction,
518      but if that text is for code that will be disassembled later, then
519      we'll want to defer printing it until later with its associated code.  */
520
521   dis_line_table = allocate_dis_line_table ();
522   cleanups = make_cleanup_htab_delete (dis_line_table);
523
524   pc = low;
525
526   /* The prologue may be empty, but there may still be a line number entry
527      for the opening brace which is distinct from the first line of code.
528      If the prologue has been eliminated find_pc_line may return the source
529      line after the opening brace.  We still want to print this opening brace.
530      first_le is used to implement this.  */
531
532   nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
533   le = SYMTAB_LINETABLE (main_symtab)->item;
534   first_le = NULL;
535
536   /* Skip all the preceding functions.  */
537   for (i = 0; i < nlines && le[i].pc < low; i++)
538     continue;
539
540   if (i < nlines && le[i].pc < high)
541     first_le = &le[i];
542
543   /* Add lines for every pc value.  */
544   while (pc < high)
545     {
546       struct symtab_and_line sal;
547       int length;
548
549       sal = find_pc_line (pc, 0);
550       length = gdb_insn_length (gdbarch, pc);
551       pc += length;
552
553       if (sal.symtab != NULL)
554         add_dis_line_entry (dis_line_table, sal.symtab, sal.line);
555     }
556
557   /* Second pass: print the disassembly.
558
559      Output format, from an MI perspective:
560        The result is a ui_out list, field name "asm_insns", where elements have
561        name "src_and_asm_line".
562        Each element is a tuple of source line specs (field names line, file,
563        fullname), and field "line_asm_insn" which contains the disassembly.
564        Field "line_asm_insn" is a list of tuples: address, func-name, offset,
565        opcodes, inst.
566
567      CLI output works on top of this because MI ignores ui_out_text output,
568      which is where we put file name and source line contents output.
569
570      Cleanup usage:
571      cleanups:
572        For things created at the beginning of this function and need to be
573        kept until the end of this function.
574      ui_out_chain
575        Handles the outer "asm_insns" list.
576      ui_out_tuple_chain
577        The tuples for each group of consecutive disassemblies.
578      ui_out_list_chain
579        List of consecutive source lines or disassembled insns.  */
580
581   if (flags & DISASSEMBLY_FILENAME)
582     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
583
584   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
585
586   ui_out_tuple_chain = NULL;
587   ui_out_list_chain = NULL;
588
589   last_symtab = NULL;
590   last_line = 0;
591   pc = low;
592
593   while (pc < high)
594     {
595       struct linetable_entry *le = NULL;
596       struct symtab_and_line sal;
597       CORE_ADDR end_pc;
598       int start_preceding_line_to_display = 0;
599       int end_preceding_line_to_display = 0;
600       int new_source_line = 0;
601
602       sal = find_pc_line (pc, 0);
603
604       if (sal.symtab != last_symtab)
605         {
606           /* New source file.  */
607           new_source_line = 1;
608
609           /* If this is the first line of output, check for any preceding
610              lines.  */
611           if (last_line == 0
612               && first_le != NULL
613               && first_le->line < sal.line)
614             {
615               start_preceding_line_to_display = first_le->line;
616               end_preceding_line_to_display = sal.line;
617             }
618         }
619       else
620         {
621           /* Same source file as last time.  */
622           if (sal.symtab != NULL)
623             {
624               if (sal.line > last_line + 1 && last_line != 0)
625                 {
626                   int l;
627
628                   /* Several preceding source lines.  Print the trailing ones
629                      not associated with code that we'll print later.  */
630                   for (l = sal.line - 1; l > last_line; --l)
631                     {
632                       if (line_has_code_p (dis_line_table, sal.symtab, l))
633                         break;
634                     }
635                   if (l < sal.line - 1)
636                     {
637                       start_preceding_line_to_display = l + 1;
638                       end_preceding_line_to_display = sal.line;
639                     }
640                 }
641               if (sal.line != last_line)
642                 new_source_line = 1;
643               else
644                 {
645                   /* Same source line as last time.  This can happen, depending
646                      on the debug info.  */
647                 }
648             }
649         }
650
651       if (new_source_line)
652         {
653           /* Skip the newline if this is the first instruction.  */
654           if (pc > low)
655             ui_out_text (uiout, "\n");
656           if (ui_out_tuple_chain != NULL)
657             {
658               gdb_assert (ui_out_list_chain != NULL);
659               do_cleanups (ui_out_list_chain);
660               do_cleanups (ui_out_tuple_chain);
661             }
662           if (sal.symtab != last_symtab
663               && !(flags & DISASSEMBLY_FILENAME))
664             {
665               /* Remember MI ignores ui_out_text.
666                  We don't have to do anything here for MI because MI
667                  output includes the source specs for each line.  */
668               if (sal.symtab != NULL)
669                 {
670                   ui_out_text (uiout,
671                                symtab_to_filename_for_display (sal.symtab));
672                 }
673               else
674                 ui_out_text (uiout, "unknown");
675               ui_out_text (uiout, ":\n");
676             }
677           if (start_preceding_line_to_display > 0)
678             {
679               /* Several source lines w/o asm instructions associated.
680                  We need to preserve the structure of the output, so output
681                  a bunch of line tuples with no asm entries.  */
682               int l;
683               struct cleanup *ui_out_list_chain_line;
684               struct cleanup *ui_out_tuple_chain_line;
685
686               gdb_assert (sal.symtab != NULL);
687               for (l = start_preceding_line_to_display;
688                    l < end_preceding_line_to_display;
689                    ++l)
690                 {
691                   ui_out_tuple_chain_line
692                     = make_cleanup_ui_out_tuple_begin_end (uiout,
693                                                            "src_and_asm_line");
694                   print_source_lines (sal.symtab, l, l + 1, psl_flags);
695                   ui_out_list_chain_line
696                     = make_cleanup_ui_out_list_begin_end (uiout,
697                                                           "line_asm_insn");
698                   do_cleanups (ui_out_list_chain_line);
699                   do_cleanups (ui_out_tuple_chain_line);
700                 }
701             }
702           ui_out_tuple_chain
703             = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
704           if (sal.symtab != NULL)
705             print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
706           else
707             ui_out_text (uiout, _("--- no source info for this pc ---\n"));
708           ui_out_list_chain
709             = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
710         }
711       else
712         {
713           /* Here we're appending instructions to an existing line.
714              By construction the very first insn will have a symtab
715              and follow the new_source_line path above.  */
716           gdb_assert (ui_out_tuple_chain != NULL);
717           gdb_assert (ui_out_list_chain != NULL);
718         }
719
720       if (sal.end != 0)
721         end_pc = min (sal.end, high);
722       else
723         end_pc = pc + 1;
724       num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc,
725                                    how_many, flags, stb, &end_pc);
726       pc = end_pc;
727
728       if (how_many >= 0 && num_displayed >= how_many)
729         break;
730
731       last_symtab = sal.symtab;
732       last_line = sal.line;
733     }
734
735   do_cleanups (ui_out_chain);
736   do_cleanups (cleanups);
737 }
738
739 static void
740 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
741                   struct disassemble_info * di,
742                   CORE_ADDR low, CORE_ADDR high,
743                   int how_many, int flags, struct ui_file *stb)
744 {
745   int num_displayed = 0;
746   struct cleanup *ui_out_chain;
747
748   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
749
750   num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
751                               flags, stb, NULL);
752
753   do_cleanups (ui_out_chain);
754 }
755
756 /* Initialize the disassemble info struct ready for the specified
757    stream.  */
758
759 static int ATTRIBUTE_PRINTF (2, 3)
760 fprintf_disasm (void *stream, const char *format, ...)
761 {
762   va_list args;
763
764   va_start (args, format);
765   vfprintf_filtered ((struct ui_file *) stream, format, args);
766   va_end (args);
767   /* Something non -ve.  */
768   return 0;
769 }
770
771 struct disassemble_info
772 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
773 {
774   struct disassemble_info di;
775
776   init_disassemble_info (&di, file, fprintf_disasm);
777   di.flavour = bfd_target_unknown_flavour;
778   di.memory_error_func = dis_asm_memory_error;
779   di.print_address_func = dis_asm_print_address;
780   /* NOTE: cagney/2003-04-28: The original code, from the old Insight
781      disassembler had a local optomization here.  By default it would
782      access the executable file, instead of the target memory (there
783      was a growing list of exceptions though).  Unfortunately, the
784      heuristic was flawed.  Commands like "disassemble &variable"
785      didn't work as they relied on the access going to the target.
786      Further, it has been supperseeded by trust-read-only-sections
787      (although that should be superseeded by target_trust..._p()).  */
788   di.read_memory_func = dis_asm_read_memory;
789   di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
790   di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
791   di.endian = gdbarch_byte_order (gdbarch);
792   di.endian_code = gdbarch_byte_order_for_code (gdbarch);
793   di.application_data = gdbarch;
794   disassemble_init_for_target (&di);
795   return di;
796 }
797
798 void
799 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
800                  char *file_string, int flags, int how_many,
801                  CORE_ADDR low, CORE_ADDR high)
802 {
803   struct ui_file *stb = mem_fileopen ();
804   struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
805   struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
806   struct symtab *symtab;
807   struct linetable_entry *le = NULL;
808   int nlines = -1;
809
810   /* Assume symtab is valid for whole PC range.  */
811   symtab = find_pc_line_symtab (low);
812
813   if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
814     nlines = SYMTAB_LINETABLE (symtab)->nitems;
815
816   if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
817       || nlines <= 0)
818     do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
819
820   else if (flags & DISASSEMBLY_SOURCE)
821     do_mixed_source_and_assembly (gdbarch, uiout, &di, symtab, low, high,
822                                   how_many, flags, stb);
823
824   else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
825     do_mixed_source_and_assembly_deprecated (gdbarch, uiout, &di, symtab,
826                                              low, high, how_many, flags, stb);
827
828   do_cleanups (cleanups);
829   gdb_flush (gdb_stdout);
830 }
831
832 /* Print the instruction at address MEMADDR in debugged memory,
833    on STREAM.  Returns the length of the instruction, in bytes,
834    and, if requested, the number of branch delay slot instructions.  */
835
836 int
837 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
838                 struct ui_file *stream, int *branch_delay_insns)
839 {
840   struct disassemble_info di;
841   int length;
842
843   di = gdb_disassemble_info (gdbarch, stream);
844   length = gdbarch_print_insn (gdbarch, memaddr, &di);
845   if (branch_delay_insns)
846     {
847       if (di.insn_info_valid)
848         *branch_delay_insns = di.branch_delay_insns;
849       else
850         *branch_delay_insns = 0;
851     }
852   return length;
853 }
854
855 static void
856 do_ui_file_delete (void *arg)
857 {
858   ui_file_delete ((struct ui_file *) arg);
859 }
860
861 /* Return the length in bytes of the instruction at address MEMADDR in
862    debugged memory.  */
863
864 int
865 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
866 {
867   static struct ui_file *null_stream = NULL;
868
869   /* Dummy file descriptor for the disassembler.  */
870   if (!null_stream)
871     {
872       null_stream = ui_file_new ();
873       make_final_cleanup (do_ui_file_delete, null_stream);
874     }
875
876   return gdb_print_insn (gdbarch, addr, null_stream, NULL);
877 }
878
879 /* fprintf-function for gdb_buffered_insn_length.  This function is a
880    nop, we don't want to print anything, we just want to compute the
881    length of the insn.  */
882
883 static int ATTRIBUTE_PRINTF (2, 3)
884 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
885 {
886   return 0;
887 }
888
889 /* Initialize a struct disassemble_info for gdb_buffered_insn_length.  */
890
891 static void
892 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
893                                    struct disassemble_info *di,
894                                    const gdb_byte *insn, int max_len,
895                                    CORE_ADDR addr)
896 {
897   init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
898
899   /* init_disassemble_info installs buffer_read_memory, etc.
900      so we don't need to do that here.
901      The cast is necessary until disassemble_info is const-ified.  */
902   di->buffer = (gdb_byte *) insn;
903   di->buffer_length = max_len;
904   di->buffer_vma = addr;
905
906   di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
907   di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
908   di->endian = gdbarch_byte_order (gdbarch);
909   di->endian_code = gdbarch_byte_order_for_code (gdbarch);
910
911   disassemble_init_for_target (di);
912 }
913
914 /* Return the length in bytes of INSN.  MAX_LEN is the size of the
915    buffer containing INSN.  */
916
917 int
918 gdb_buffered_insn_length (struct gdbarch *gdbarch,
919                           const gdb_byte *insn, int max_len, CORE_ADDR addr)
920 {
921   struct disassemble_info di;
922
923   gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
924
925   return gdbarch_print_insn (gdbarch, addr, &di);
926 }