Upgrade GDB from 7.3 to 7.4.1 on the vendor branch
[dragonfly.git] / contrib / gdb-7 / gdb / disasm.c
1 /* Disassemble support for GDB.
2
3    Copyright (C) 2000-2005, 2007-2012 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 "gdb_string.h"
25 #include "disasm.h"
26 #include "gdbcore.h"
27 #include "dis-asm.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.
34    We need a different sort of line table from the normal one cuz we can't
35    depend upon implicit line-end pc's for lines to do the
36    reordering in this function.  */
37
38 struct dis_line_entry
39 {
40   int line;
41   CORE_ADDR start_pc;
42   CORE_ADDR end_pc;
43 };
44
45 /* Like target_read_memory, but slightly different parameters.  */
46 static int
47 dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
48                      struct disassemble_info *info)
49 {
50   return target_read_memory (memaddr, myaddr, len);
51 }
52
53 /* Like memory_error with slightly different parameters.  */
54 static void
55 dis_asm_memory_error (int status, bfd_vma memaddr,
56                       struct disassemble_info *info)
57 {
58   memory_error (status, memaddr);
59 }
60
61 /* Like print_address with slightly different parameters.  */
62 static void
63 dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
64 {
65   struct gdbarch *gdbarch = info->application_data;
66
67   print_address (gdbarch, addr, info->stream);
68 }
69
70 static int
71 compare_lines (const void *mle1p, const void *mle2p)
72 {
73   struct dis_line_entry *mle1, *mle2;
74   int val;
75
76   mle1 = (struct dis_line_entry *) mle1p;
77   mle2 = (struct dis_line_entry *) mle2p;
78
79   /* End of sequence markers have a line number of 0 but don't want to
80      be sorted to the head of the list, instead sort by PC.  */
81   if (mle1->line == 0 || mle2->line == 0)
82     {
83       val = mle1->start_pc - mle2->start_pc;
84       if (val == 0)
85         val = mle1->line - mle2->line;
86     }
87   else
88     {
89       val = mle1->line - mle2->line;
90       if (val == 0)
91         val = mle1->start_pc - mle2->start_pc;
92     }
93   return val;
94 }
95
96 static int
97 dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
98             struct disassemble_info * di,
99             CORE_ADDR low, CORE_ADDR high,
100             int how_many, int flags, struct ui_stream *stb)
101 {
102   int num_displayed = 0;
103   CORE_ADDR pc;
104
105   /* parts of the symbolic representation of the address */
106   int unmapped;
107   int offset;
108   int line;
109   struct cleanup *ui_out_chain;
110
111   for (pc = low; pc < high;)
112     {
113       char *filename = NULL;
114       char *name = NULL;
115
116       QUIT;
117       if (how_many >= 0)
118         {
119           if (num_displayed >= how_many)
120             break;
121           else
122             num_displayed++;
123         }
124       ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
125       ui_out_text (uiout, pc_prefix (pc));
126       ui_out_field_core_addr (uiout, "address", gdbarch, pc);
127
128       if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
129                                    &line, &unmapped))
130         {
131           /* We don't care now about line, filename and
132              unmapped. But we might in the future.  */
133           ui_out_text (uiout, " <");
134           if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
135             ui_out_field_string (uiout, "func-name", name);
136           ui_out_text (uiout, "+");
137           ui_out_field_int (uiout, "offset", offset);
138           ui_out_text (uiout, ">:\t");
139         }
140       else
141         ui_out_text (uiout, ":\t");
142
143       if (filename != NULL)
144         xfree (filename);
145       if (name != NULL)
146         xfree (name);
147
148       ui_file_rewind (stb->stream);
149       if (flags & DISASSEMBLY_RAW_INSN)
150         {
151           CORE_ADDR old_pc = pc;
152           bfd_byte data;
153           int status;
154           const char *spacer = "";
155
156           /* Build the opcodes using a temporary stream so we can
157              write them out in a single go for the MI.  */
158           struct ui_stream *opcode_stream = ui_out_stream_new (uiout);
159           struct cleanup *cleanups =
160             make_cleanup_ui_out_stream_delete (opcode_stream);
161
162           pc += gdbarch_print_insn (gdbarch, pc, di);
163           for (;old_pc < pc; old_pc++)
164             {
165               status = (*di->read_memory_func) (old_pc, &data, 1, di);
166               if (status != 0)
167                 (*di->memory_error_func) (status, old_pc, di);
168               fprintf_filtered (opcode_stream->stream, "%s%02x",
169                                 spacer, (unsigned) data);
170               spacer = " ";
171             }
172           ui_out_field_stream (uiout, "opcodes", opcode_stream);
173           ui_out_text (uiout, "\t");
174
175           do_cleanups (cleanups);
176         }
177       else
178         pc += gdbarch_print_insn (gdbarch, pc, di);
179       ui_out_field_stream (uiout, "inst", stb);
180       ui_file_rewind (stb->stream);
181       do_cleanups (ui_out_chain);
182       ui_out_text (uiout, "\n");
183     }
184   return num_displayed;
185 }
186
187 /* The idea here is to present a source-O-centric view of a
188    function to the user.  This means that things are presented
189    in source order, with (possibly) out of order assembly
190    immediately following.  */
191
192 static void
193 do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
194                               struct disassemble_info *di, int nlines,
195                               struct linetable_entry *le,
196                               CORE_ADDR low, CORE_ADDR high,
197                               struct symtab *symtab,
198                               int how_many, int flags, struct ui_stream *stb)
199 {
200   int newlines = 0;
201   struct dis_line_entry *mle;
202   struct symtab_and_line sal;
203   int i;
204   int out_of_order = 0;
205   int next_line = 0;
206   int num_displayed = 0;
207   struct cleanup *ui_out_chain;
208   struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
209   struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
210
211   mle = (struct dis_line_entry *) alloca (nlines
212                                           * sizeof (struct dis_line_entry));
213
214   /* Copy linetable entries for this function into our data
215      structure, creating end_pc's and setting out_of_order as
216      appropriate.  */
217
218   /* First, skip all the preceding functions.  */
219
220   for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
221
222   /* Now, copy all entries before the end of this function.  */
223
224   for (; i < nlines - 1 && le[i].pc < high; i++)
225     {
226       if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
227         continue;               /* Ignore duplicates.  */
228
229       /* Skip any end-of-function markers.  */
230       if (le[i].line == 0)
231         continue;
232
233       mle[newlines].line = le[i].line;
234       if (le[i].line > le[i + 1].line)
235         out_of_order = 1;
236       mle[newlines].start_pc = le[i].pc;
237       mle[newlines].end_pc = le[i + 1].pc;
238       newlines++;
239     }
240
241   /* If we're on the last line, and it's part of the function,
242      then we need to get the end pc in a special way.  */
243
244   if (i == nlines - 1 && le[i].pc < high)
245     {
246       mle[newlines].line = le[i].line;
247       mle[newlines].start_pc = le[i].pc;
248       sal = find_pc_line (le[i].pc, 0);
249       mle[newlines].end_pc = sal.end;
250       newlines++;
251     }
252
253   /* Now, sort mle by line #s (and, then by addresses within
254      lines).  */
255
256   if (out_of_order)
257     qsort (mle, newlines, sizeof (struct dis_line_entry), compare_lines);
258
259   /* Now, for each line entry, emit the specified lines (unless
260      they have been emitted before), followed by the assembly code
261      for that line.  */
262
263   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
264
265   for (i = 0; i < newlines; i++)
266     {
267       /* Print out everything from next_line to the current line.  */
268       if (mle[i].line >= next_line)
269         {
270           if (next_line != 0)
271             {
272               /* Just one line to print.  */
273               if (next_line == mle[i].line)
274                 {
275                   ui_out_tuple_chain
276                     = make_cleanup_ui_out_tuple_begin_end (uiout,
277                                                            "src_and_asm_line");
278                   print_source_lines (symtab, next_line, mle[i].line + 1, 0);
279                 }
280               else
281                 {
282                   /* Several source lines w/o asm instructions associated.  */
283                   for (; next_line < mle[i].line; next_line++)
284                     {
285                       struct cleanup *ui_out_list_chain_line;
286                       struct cleanup *ui_out_tuple_chain_line;
287                       
288                       ui_out_tuple_chain_line
289                         = make_cleanup_ui_out_tuple_begin_end (uiout,
290                                                                "src_and_asm_line");
291                       print_source_lines (symtab, next_line, next_line + 1,
292                                           0);
293                       ui_out_list_chain_line
294                         = make_cleanup_ui_out_list_begin_end (uiout,
295                                                               "line_asm_insn");
296                       do_cleanups (ui_out_list_chain_line);
297                       do_cleanups (ui_out_tuple_chain_line);
298                     }
299                   /* Print the last line and leave list open for
300                      asm instructions to be added.  */
301                   ui_out_tuple_chain
302                     = make_cleanup_ui_out_tuple_begin_end (uiout,
303                                                            "src_and_asm_line");
304                   print_source_lines (symtab, next_line, mle[i].line + 1, 0);
305                 }
306             }
307           else
308             {
309               ui_out_tuple_chain
310                 = make_cleanup_ui_out_tuple_begin_end (uiout,
311                                                        "src_and_asm_line");
312               print_source_lines (symtab, mle[i].line, mle[i].line + 1, 0);
313             }
314
315           next_line = mle[i].line + 1;
316           ui_out_list_chain
317             = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
318         }
319
320       num_displayed += dump_insns (gdbarch, uiout, di,
321                                    mle[i].start_pc, mle[i].end_pc,
322                                    how_many, flags, stb);
323
324       /* When we've reached the end of the mle array, or we've seen the last
325          assembly range for this source line, close out the list/tuple.  */
326       if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
327         {
328           do_cleanups (ui_out_list_chain);
329           do_cleanups (ui_out_tuple_chain);
330           ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
331           ui_out_list_chain = make_cleanup (null_cleanup, 0);
332           ui_out_text (uiout, "\n");
333         }
334       if (how_many >= 0 && num_displayed >= how_many)
335         break;
336     }
337   do_cleanups (ui_out_chain);
338 }
339
340
341 static void
342 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
343                   struct disassemble_info * di,
344                   CORE_ADDR low, CORE_ADDR high,
345                   int how_many, int flags, struct ui_stream *stb)
346 {
347   int num_displayed = 0;
348   struct cleanup *ui_out_chain;
349
350   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
351
352   num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
353                               flags, stb);
354
355   do_cleanups (ui_out_chain);
356 }
357
358 /* Initialize the disassemble info struct ready for the specified
359    stream.  */
360
361 static int ATTRIBUTE_PRINTF (2, 3)
362 fprintf_disasm (void *stream, const char *format, ...)
363 {
364   va_list args;
365
366   va_start (args, format);
367   vfprintf_filtered (stream, format, args);
368   va_end (args);
369   /* Something non -ve.  */
370   return 0;
371 }
372
373 static struct disassemble_info
374 gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
375 {
376   struct disassemble_info di;
377
378   init_disassemble_info (&di, file, fprintf_disasm);
379   di.flavour = bfd_target_unknown_flavour;
380   di.memory_error_func = dis_asm_memory_error;
381   di.print_address_func = dis_asm_print_address;
382   /* NOTE: cagney/2003-04-28: The original code, from the old Insight
383      disassembler had a local optomization here.  By default it would
384      access the executable file, instead of the target memory (there
385      was a growing list of exceptions though).  Unfortunately, the
386      heuristic was flawed.  Commands like "disassemble &variable"
387      didn't work as they relied on the access going to the target.
388      Further, it has been supperseeded by trust-read-only-sections
389      (although that should be superseeded by target_trust..._p()).  */
390   di.read_memory_func = dis_asm_read_memory;
391   di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
392   di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
393   di.endian = gdbarch_byte_order (gdbarch);
394   di.endian_code = gdbarch_byte_order_for_code (gdbarch);
395   di.application_data = gdbarch;
396   disassemble_init_for_target (&di);
397   return di;
398 }
399
400 void
401 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
402                  char *file_string, int flags, int how_many,
403                  CORE_ADDR low, CORE_ADDR high)
404 {
405   struct ui_stream *stb = ui_out_stream_new (uiout);
406   struct cleanup *cleanups = make_cleanup_ui_out_stream_delete (stb);
407   struct disassemble_info di = gdb_disassemble_info (gdbarch, stb->stream);
408   /* To collect the instruction outputted from opcodes.  */
409   struct symtab *symtab = NULL;
410   struct linetable_entry *le = NULL;
411   int nlines = -1;
412
413   /* Assume symtab is valid for whole PC range.  */
414   symtab = find_pc_symtab (low);
415
416   if (symtab != NULL && symtab->linetable != NULL)
417     {
418       /* Convert the linetable to a bunch of my_line_entry's.  */
419       le = symtab->linetable->item;
420       nlines = symtab->linetable->nitems;
421     }
422
423   if (!(flags & DISASSEMBLY_SOURCE) || nlines <= 0
424       || symtab == NULL || symtab->linetable == NULL)
425     do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
426
427   else if (flags & DISASSEMBLY_SOURCE)
428     do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low,
429                                   high, symtab, how_many, flags, stb);
430
431   do_cleanups (cleanups);
432   gdb_flush (gdb_stdout);
433 }
434
435 /* Print the instruction at address MEMADDR in debugged memory,
436    on STREAM.  Returns the length of the instruction, in bytes,
437    and, if requested, the number of branch delay slot instructions.  */
438
439 int
440 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
441                 struct ui_file *stream, int *branch_delay_insns)
442 {
443   struct disassemble_info di;
444   int length;
445
446   di = gdb_disassemble_info (gdbarch, stream);
447   length = gdbarch_print_insn (gdbarch, memaddr, &di);
448   if (branch_delay_insns)
449     {
450       if (di.insn_info_valid)
451         *branch_delay_insns = di.branch_delay_insns;
452       else
453         *branch_delay_insns = 0;
454     }
455   return length;
456 }
457
458 static void
459 do_ui_file_delete (void *arg)
460 {
461   ui_file_delete (arg);
462 }
463
464 /* Return the length in bytes of the instruction at address MEMADDR in
465    debugged memory.  */
466
467 int
468 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
469 {
470   static struct ui_file *null_stream = NULL;
471
472   /* Dummy file descriptor for the disassembler.  */
473   if (!null_stream)
474     {
475       null_stream = ui_file_new ();
476       make_final_cleanup (do_ui_file_delete, null_stream);
477     }
478
479   return gdb_print_insn (gdbarch, addr, null_stream, NULL);
480 }
481
482 /* fprintf-function for gdb_buffered_insn_length.  This function is a
483    nop, we don't want to print anything, we just want to compute the
484    length of the insn.  */
485
486 static int ATTRIBUTE_PRINTF (2, 3)
487 gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
488 {
489   return 0;
490 }
491
492 /* Initialize a struct disassemble_info for gdb_buffered_insn_length.  */
493
494 static void
495 gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
496                                    struct disassemble_info *di,
497                                    const gdb_byte *insn, int max_len,
498                                    CORE_ADDR addr)
499 {
500   init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
501
502   /* init_disassemble_info installs buffer_read_memory, etc.
503      so we don't need to do that here.
504      The cast is necessary until disassemble_info is const-ified.  */
505   di->buffer = (gdb_byte *) insn;
506   di->buffer_length = max_len;
507   di->buffer_vma = addr;
508
509   di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
510   di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
511   di->endian = gdbarch_byte_order (gdbarch);
512   di->endian_code = gdbarch_byte_order_for_code (gdbarch);
513
514   disassemble_init_for_target (di);
515 }
516
517 /* Return the length in bytes of INSN.  MAX_LEN is the size of the
518    buffer containing INSN.  */
519
520 int
521 gdb_buffered_insn_length (struct gdbarch *gdbarch,
522                           const gdb_byte *insn, int max_len, CORE_ADDR addr)
523 {
524   struct disassemble_info di;
525
526   gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
527
528   return gdbarch_print_insn (gdbarch, addr, &di);
529 }