gold: Add a linker configure option --enable-relro
[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   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 *cleanups;
501   struct cleanup *ui_out_chain;
502   struct cleanup *ui_out_tuple_chain;
503   struct cleanup *ui_out_list_chain;
504   CORE_ADDR pc;
505   struct symtab *last_symtab;
506   int last_line;
507   htab_t dis_line_table;
508
509   gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
510
511   /* First pass: collect the list of all source files and lines.
512      We do this so that we can only print lines containing code once.
513      We try to print the source text leading up to the next instruction,
514      but if that text is for code that will be disassembled later, then
515      we'll want to defer printing it until later with its associated code.  */
516
517   dis_line_table = allocate_dis_line_table ();
518   cleanups = make_cleanup_htab_delete (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, 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      cleanups:
568        For things created at the beginning of this function and need to be
569        kept until the end of this function.
570      ui_out_chain
571        Handles the outer "asm_insns" list.
572      ui_out_tuple_chain
573        The tuples for each group of consecutive disassemblies.
574      ui_out_list_chain
575        List of consecutive source lines or disassembled insns.  */
576
577   if (flags & DISASSEMBLY_FILENAME)
578     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
579
580   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
581
582   ui_out_tuple_chain = NULL;
583   ui_out_list_chain = NULL;
584
585   last_symtab = NULL;
586   last_line = 0;
587   pc = low;
588
589   while (pc < high)
590     {
591       struct symtab_and_line sal;
592       CORE_ADDR end_pc;
593       int start_preceding_line_to_display = 0;
594       int end_preceding_line_to_display = 0;
595       int new_source_line = 0;
596
597       sal = find_pc_line (pc, 0);
598
599       if (sal.symtab != last_symtab)
600         {
601           /* New source file.  */
602           new_source_line = 1;
603
604           /* If this is the first line of output, check for any preceding
605              lines.  */
606           if (last_line == 0
607               && first_le != NULL
608               && first_le->line < sal.line)
609             {
610               start_preceding_line_to_display = first_le->line;
611               end_preceding_line_to_display = sal.line;
612             }
613         }
614       else
615         {
616           /* Same source file as last time.  */
617           if (sal.symtab != NULL)
618             {
619               if (sal.line > last_line + 1 && last_line != 0)
620                 {
621                   int l;
622
623                   /* Several preceding source lines.  Print the trailing ones
624                      not associated with code that we'll print later.  */
625                   for (l = sal.line - 1; l > last_line; --l)
626                     {
627                       if (line_has_code_p (dis_line_table, sal.symtab, l))
628                         break;
629                     }
630                   if (l < sal.line - 1)
631                     {
632                       start_preceding_line_to_display = l + 1;
633                       end_preceding_line_to_display = sal.line;
634                     }
635                 }
636               if (sal.line != last_line)
637                 new_source_line = 1;
638               else
639                 {
640                   /* Same source line as last time.  This can happen, depending
641                      on the debug info.  */
642                 }
643             }
644         }
645
646       if (new_source_line)
647         {
648           /* Skip the newline if this is the first instruction.  */
649           if (pc > low)
650             ui_out_text (uiout, "\n");
651           if (ui_out_tuple_chain != NULL)
652             {
653               gdb_assert (ui_out_list_chain != NULL);
654               do_cleanups (ui_out_list_chain);
655               do_cleanups (ui_out_tuple_chain);
656             }
657           if (sal.symtab != last_symtab
658               && !(flags & DISASSEMBLY_FILENAME))
659             {
660               /* Remember MI ignores ui_out_text.
661                  We don't have to do anything here for MI because MI
662                  output includes the source specs for each line.  */
663               if (sal.symtab != NULL)
664                 {
665                   ui_out_text (uiout,
666                                symtab_to_filename_for_display (sal.symtab));
667                 }
668               else
669                 ui_out_text (uiout, "unknown");
670               ui_out_text (uiout, ":\n");
671             }
672           if (start_preceding_line_to_display > 0)
673             {
674               /* Several source lines w/o asm instructions associated.
675                  We need to preserve the structure of the output, so output
676                  a bunch of line tuples with no asm entries.  */
677               int l;
678               struct cleanup *ui_out_list_chain_line;
679               struct cleanup *ui_out_tuple_chain_line;
680
681               gdb_assert (sal.symtab != NULL);
682               for (l = start_preceding_line_to_display;
683                    l < end_preceding_line_to_display;
684                    ++l)
685                 {
686                   ui_out_tuple_chain_line
687                     = make_cleanup_ui_out_tuple_begin_end (uiout,
688                                                            "src_and_asm_line");
689                   print_source_lines (sal.symtab, l, l + 1, psl_flags);
690                   ui_out_list_chain_line
691                     = make_cleanup_ui_out_list_begin_end (uiout,
692                                                           "line_asm_insn");
693                   do_cleanups (ui_out_list_chain_line);
694                   do_cleanups (ui_out_tuple_chain_line);
695                 }
696             }
697           ui_out_tuple_chain
698             = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
699           if (sal.symtab != NULL)
700             print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
701           else
702             ui_out_text (uiout, _("--- no source info for this pc ---\n"));
703           ui_out_list_chain
704             = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
705         }
706       else
707         {
708           /* Here we're appending instructions to an existing line.
709              By construction the very first insn will have a symtab
710              and follow the new_source_line path above.  */
711           gdb_assert (ui_out_tuple_chain != NULL);
712           gdb_assert (ui_out_list_chain != NULL);
713         }
714
715       if (sal.end != 0)
716         end_pc = min (sal.end, high);
717       else
718         end_pc = pc + 1;
719       num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc,
720                                    how_many, flags, stb, &end_pc);
721       pc = end_pc;
722
723       if (how_many >= 0 && num_displayed >= how_many)
724         break;
725
726       last_symtab = sal.symtab;
727       last_line = sal.line;
728     }
729
730   do_cleanups (ui_out_chain);
731   do_cleanups (cleanups);
732 }
733
734 static void
735 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
736                   struct disassemble_info * di,
737                   CORE_ADDR low, CORE_ADDR high,
738                   int how_many, int flags, struct ui_file *stb)
739 {
740   int num_displayed = 0;
741   struct cleanup *ui_out_chain;
742
743   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
744
745   num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
746                               flags, stb, NULL);
747
748   do_cleanups (ui_out_chain);
749 }
750
751 /* Initialize the disassemble info struct ready for the specified
752    stream.  */
753
754 static int ATTRIBUTE_PRINTF (2, 3)
755 fprintf_disasm (void *stream, const char *format, ...)
756 {
757   va_list args;
758
759   va_start (args, format);
760   vfprintf_filtered ((struct ui_file *) stream, format, args);
761   va_end (args);
762   /* Something non -ve.  */
763   return 0;
764 }
765
766 struct disassemble_info
767 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
768 {
769   struct disassemble_info di;
770
771   init_disassemble_info (&di, file, fprintf_disasm);
772   di.flavour = bfd_target_unknown_flavour;
773   di.memory_error_func = dis_asm_memory_error;
774   di.print_address_func = dis_asm_print_address;
775   /* NOTE: cagney/2003-04-28: The original code, from the old Insight
776      disassembler had a local optomization here.  By default it would
777      access the executable file, instead of the target memory (there
778      was a growing list of exceptions though).  Unfortunately, the
779      heuristic was flawed.  Commands like "disassemble &variable"
780      didn't work as they relied on the access going to the target.
781      Further, it has been supperseeded by trust-read-only-sections
782      (although that should be superseeded by target_trust..._p()).  */
783   di.read_memory_func = dis_asm_read_memory;
784   di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
785   di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
786   di.endian = gdbarch_byte_order (gdbarch);
787   di.endian_code = gdbarch_byte_order_for_code (gdbarch);
788   di.application_data = gdbarch;
789   disassemble_init_for_target (&di);
790   return di;
791 }
792
793 void
794 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
795                  char *file_string, int flags, int how_many,
796                  CORE_ADDR low, CORE_ADDR high)
797 {
798   struct ui_file *stb = mem_fileopen ();
799   struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
800   struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
801   struct symtab *symtab;
802   int nlines = -1;
803
804   /* Assume symtab is valid for whole PC range.  */
805   symtab = find_pc_line_symtab (low);
806
807   if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
808     nlines = SYMTAB_LINETABLE (symtab)->nitems;
809
810   if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
811       || nlines <= 0)
812     do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
813
814   else if (flags & DISASSEMBLY_SOURCE)
815     do_mixed_source_and_assembly (gdbarch, uiout, &di, symtab, low, high,
816                                   how_many, flags, stb);
817
818   else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
819     do_mixed_source_and_assembly_deprecated (gdbarch, uiout, &di, symtab,
820                                              low, high, how_many, flags, stb);
821
822   do_cleanups (cleanups);
823   gdb_flush (gdb_stdout);
824 }
825
826 /* Print the instruction at address MEMADDR in debugged memory,
827    on STREAM.  Returns the length of the instruction, in bytes,
828    and, if requested, the number of branch delay slot instructions.  */
829
830 int
831 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
832                 struct ui_file *stream, int *branch_delay_insns)
833 {
834   struct disassemble_info di;
835   int length;
836
837   di = gdb_disassemble_info (gdbarch, stream);
838   length = gdbarch_print_insn (gdbarch, memaddr, &di);
839   if (branch_delay_insns)
840     {
841       if (di.insn_info_valid)
842         *branch_delay_insns = di.branch_delay_insns;
843       else
844         *branch_delay_insns = 0;
845     }
846   return length;
847 }
848
849 static void
850 do_ui_file_delete (void *arg)
851 {
852   ui_file_delete ((struct ui_file *) arg);
853 }
854
855 /* Return the length in bytes of the instruction at address MEMADDR in
856    debugged memory.  */
857
858 int
859 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
860 {
861   static struct ui_file *null_stream = NULL;
862
863   /* Dummy file descriptor for the disassembler.  */
864   if (!null_stream)
865     {
866       null_stream = ui_file_new ();
867       make_final_cleanup (do_ui_file_delete, null_stream);
868     }
869
870   return gdb_print_insn (gdbarch, addr, null_stream, NULL);
871 }
872
873 /* fprintf-function for gdb_buffered_insn_length.  This function is a
874    nop, we don't want to print anything, we just want to compute the
875    length of the insn.  */
876
877 static int ATTRIBUTE_PRINTF (2, 3)
878 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
879 {
880   return 0;
881 }
882
883 /* Initialize a struct disassemble_info for gdb_buffered_insn_length.  */
884
885 static void
886 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
887                                    struct disassemble_info *di,
888                                    const gdb_byte *insn, int max_len,
889                                    CORE_ADDR addr)
890 {
891   init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
892
893   /* init_disassemble_info installs buffer_read_memory, etc.
894      so we don't need to do that here.
895      The cast is necessary until disassemble_info is const-ified.  */
896   di->buffer = (gdb_byte *) insn;
897   di->buffer_length = max_len;
898   di->buffer_vma = addr;
899
900   di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
901   di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
902   di->endian = gdbarch_byte_order (gdbarch);
903   di->endian_code = gdbarch_byte_order_for_code (gdbarch);
904
905   disassemble_init_for_target (di);
906 }
907
908 /* Return the length in bytes of INSN.  MAX_LEN is the size of the
909    buffer containing INSN.  */
910
911 int
912 gdb_buffered_insn_length (struct gdbarch *gdbarch,
913                           const gdb_byte *insn, int max_len, CORE_ADDR addr)
914 {
915   struct disassemble_info di;
916
917   gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
918
919   return gdbarch_print_insn (gdbarch, addr, &di);
920 }