Home | History | Annotate | Line # | Download | only in gdb
disasm.c revision 1.7
      1  1.1  christos /* Disassemble support for GDB.
      2  1.1  christos 
      3  1.7  christos    Copyright (C) 2000-2017 Free Software Foundation, Inc.
      4  1.1  christos 
      5  1.1  christos    This file is part of GDB.
      6  1.1  christos 
      7  1.1  christos    This program is free software; you can redistribute it and/or modify
      8  1.1  christos    it under the terms of the GNU General Public License as published by
      9  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     10  1.1  christos    (at your option) any later version.
     11  1.1  christos 
     12  1.1  christos    This program is distributed in the hope that it will be useful,
     13  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  christos    GNU General Public License for more details.
     16  1.1  christos 
     17  1.1  christos    You should have received a copy of the GNU General Public License
     18  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19  1.1  christos 
     20  1.1  christos #include "defs.h"
     21  1.7  christos #include "arch-utils.h"
     22  1.1  christos #include "target.h"
     23  1.1  christos #include "value.h"
     24  1.1  christos #include "ui-out.h"
     25  1.1  christos #include "disasm.h"
     26  1.1  christos #include "gdbcore.h"
     27  1.7  christos #include "gdbcmd.h"
     28  1.1  christos #include "dis-asm.h"
     29  1.6  christos #include "source.h"
     30  1.7  christos #include "safe-ctype.h"
     31  1.7  christos #include <algorithm>
     32  1.1  christos 
     33  1.1  christos /* Disassemble functions.
     34  1.1  christos    FIXME: We should get rid of all the duplicate code in gdb that does
     35  1.1  christos    the same thing: disassemble_command() and the gdbtk variation.  */
     36  1.1  christos 
     37  1.7  christos /* This variable is used to hold the prospective disassembler_options value
     38  1.7  christos    which is set by the "set disassembler_options" command.  */
     39  1.7  christos static char *prospective_options = NULL;
     40  1.7  christos 
     41  1.6  christos /* This structure is used to store line number information for the
     42  1.6  christos    deprecated /m option.
     43  1.6  christos    We need a different sort of line table from the normal one cuz we can't
     44  1.6  christos    depend upon implicit line-end pc's for lines to do the
     45  1.6  christos    reordering in this function.  */
     46  1.6  christos 
     47  1.6  christos struct deprecated_dis_line_entry
     48  1.6  christos {
     49  1.6  christos   int line;
     50  1.6  christos   CORE_ADDR start_pc;
     51  1.6  christos   CORE_ADDR end_pc;
     52  1.6  christos };
     53  1.6  christos 
     54  1.1  christos /* This Structure is used to store line number information.
     55  1.1  christos    We need a different sort of line table from the normal one cuz we can't
     56  1.1  christos    depend upon implicit line-end pc's for lines to do the
     57  1.1  christos    reordering in this function.  */
     58  1.1  christos 
     59  1.1  christos struct dis_line_entry
     60  1.1  christos {
     61  1.6  christos   struct symtab *symtab;
     62  1.1  christos   int line;
     63  1.1  christos };
     64  1.1  christos 
     65  1.6  christos /* Hash function for dis_line_entry.  */
     66  1.6  christos 
     67  1.6  christos static hashval_t
     68  1.6  christos hash_dis_line_entry (const void *item)
     69  1.6  christos {
     70  1.6  christos   const struct dis_line_entry *dle = (const struct dis_line_entry *) item;
     71  1.6  christos 
     72  1.6  christos   return htab_hash_pointer (dle->symtab) + dle->line;
     73  1.6  christos }
     74  1.6  christos 
     75  1.6  christos /* Equal function for dis_line_entry.  */
     76  1.6  christos 
     77  1.6  christos static int
     78  1.6  christos eq_dis_line_entry (const void *item_lhs, const void *item_rhs)
     79  1.6  christos {
     80  1.6  christos   const struct dis_line_entry *lhs = (const struct dis_line_entry *) item_lhs;
     81  1.6  christos   const struct dis_line_entry *rhs = (const struct dis_line_entry *) item_rhs;
     82  1.6  christos 
     83  1.6  christos   return (lhs->symtab == rhs->symtab
     84  1.6  christos 	  && lhs->line == rhs->line);
     85  1.6  christos }
     86  1.6  christos 
     87  1.6  christos /* Create the table to manage lines for mixed source/disassembly.  */
     88  1.6  christos 
     89  1.6  christos static htab_t
     90  1.6  christos allocate_dis_line_table (void)
     91  1.6  christos {
     92  1.6  christos   return htab_create_alloc (41,
     93  1.6  christos 			    hash_dis_line_entry, eq_dis_line_entry,
     94  1.6  christos 			    xfree, xcalloc, xfree);
     95  1.6  christos }
     96  1.6  christos 
     97  1.6  christos /* Add a new dis_line_entry containing SYMTAB and LINE to TABLE.  */
     98  1.6  christos 
     99  1.6  christos static void
    100  1.6  christos add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
    101  1.6  christos {
    102  1.6  christos   void **slot;
    103  1.6  christos   struct dis_line_entry dle, *dlep;
    104  1.6  christos 
    105  1.6  christos   dle.symtab = symtab;
    106  1.6  christos   dle.line = line;
    107  1.6  christos   slot = htab_find_slot (table, &dle, INSERT);
    108  1.6  christos   if (*slot == NULL)
    109  1.6  christos     {
    110  1.6  christos       dlep = XNEW (struct dis_line_entry);
    111  1.6  christos       dlep->symtab = symtab;
    112  1.6  christos       dlep->line = line;
    113  1.6  christos       *slot = dlep;
    114  1.6  christos     }
    115  1.6  christos }
    116  1.6  christos 
    117  1.6  christos /* Return non-zero if SYMTAB, LINE are in TABLE.  */
    118  1.6  christos 
    119  1.6  christos static int
    120  1.6  christos line_has_code_p (htab_t table, struct symtab *symtab, int line)
    121  1.6  christos {
    122  1.6  christos   struct dis_line_entry dle;
    123  1.6  christos 
    124  1.6  christos   dle.symtab = symtab;
    125  1.6  christos   dle.line = line;
    126  1.6  christos   return htab_find (table, &dle) != NULL;
    127  1.6  christos }
    128  1.6  christos 
    129  1.7  christos /* Wrapper of target_read_code.  */
    130  1.7  christos 
    131  1.7  christos int
    132  1.7  christos gdb_disassembler::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr,
    133  1.7  christos 				       unsigned int len,
    134  1.7  christos 				       struct disassemble_info *info)
    135  1.1  christos {
    136  1.1  christos   return target_read_code (memaddr, myaddr, len);
    137  1.1  christos }
    138  1.1  christos 
    139  1.7  christos /* Wrapper of memory_error.  */
    140  1.7  christos 
    141  1.7  christos void
    142  1.7  christos gdb_disassembler::dis_asm_memory_error (int err, bfd_vma memaddr,
    143  1.7  christos 					struct disassemble_info *info)
    144  1.1  christos {
    145  1.7  christos   gdb_disassembler *self
    146  1.7  christos     = static_cast<gdb_disassembler *>(info->application_data);
    147  1.7  christos 
    148  1.7  christos   self->m_err_memaddr = memaddr;
    149  1.1  christos }
    150  1.1  christos 
    151  1.7  christos /* Wrapper of print_address.  */
    152  1.7  christos 
    153  1.7  christos void
    154  1.7  christos gdb_disassembler::dis_asm_print_address (bfd_vma addr,
    155  1.7  christos 					 struct disassemble_info *info)
    156  1.1  christos {
    157  1.7  christos   gdb_disassembler *self
    158  1.7  christos     = static_cast<gdb_disassembler *>(info->application_data);
    159  1.1  christos 
    160  1.7  christos   print_address (self->arch (), addr, self->stream ());
    161  1.1  christos }
    162  1.1  christos 
    163  1.1  christos static int
    164  1.1  christos compare_lines (const void *mle1p, const void *mle2p)
    165  1.1  christos {
    166  1.6  christos   struct deprecated_dis_line_entry *mle1, *mle2;
    167  1.1  christos   int val;
    168  1.1  christos 
    169  1.6  christos   mle1 = (struct deprecated_dis_line_entry *) mle1p;
    170  1.6  christos   mle2 = (struct deprecated_dis_line_entry *) mle2p;
    171  1.1  christos 
    172  1.1  christos   /* End of sequence markers have a line number of 0 but don't want to
    173  1.1  christos      be sorted to the head of the list, instead sort by PC.  */
    174  1.1  christos   if (mle1->line == 0 || mle2->line == 0)
    175  1.1  christos     {
    176  1.1  christos       val = mle1->start_pc - mle2->start_pc;
    177  1.1  christos       if (val == 0)
    178  1.1  christos         val = mle1->line - mle2->line;
    179  1.1  christos     }
    180  1.1  christos   else
    181  1.1  christos     {
    182  1.1  christos       val = mle1->line - mle2->line;
    183  1.1  christos       if (val == 0)
    184  1.1  christos         val = mle1->start_pc - mle2->start_pc;
    185  1.1  christos     }
    186  1.1  christos   return val;
    187  1.1  christos }
    188  1.1  christos 
    189  1.6  christos /* See disasm.h.  */
    190  1.6  christos 
    191  1.6  christos int
    192  1.7  christos gdb_pretty_print_disassembler::pretty_print_insn (struct ui_out *uiout,
    193  1.7  christos 						  const struct disasm_insn *insn,
    194  1.7  christos 						  int flags)
    195  1.1  christos {
    196  1.1  christos   /* parts of the symbolic representation of the address */
    197  1.1  christos   int unmapped;
    198  1.1  christos   int offset;
    199  1.1  christos   int line;
    200  1.6  christos   int size;
    201  1.1  christos   struct cleanup *ui_out_chain;
    202  1.6  christos   char *filename = NULL;
    203  1.6  christos   char *name = NULL;
    204  1.6  christos   CORE_ADDR pc;
    205  1.7  christos   struct gdbarch *gdbarch = arch ();
    206  1.6  christos 
    207  1.6  christos   ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
    208  1.6  christos   pc = insn->addr;
    209  1.1  christos 
    210  1.6  christos   if (insn->number != 0)
    211  1.1  christos     {
    212  1.7  christos       uiout->field_fmt ("insn-number", "%u", insn->number);
    213  1.7  christos       uiout->text ("\t");
    214  1.6  christos     }
    215  1.1  christos 
    216  1.6  christos   if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
    217  1.6  christos     {
    218  1.6  christos       if (insn->is_speculative)
    219  1.1  christos 	{
    220  1.7  christos 	  uiout->field_string ("is-speculative", "?");
    221  1.6  christos 
    222  1.6  christos 	  /* The speculative execution indication overwrites the first
    223  1.6  christos 	     character of the PC prefix.
    224  1.6  christos 	     We assume a PC prefix length of 3 characters.  */
    225  1.6  christos 	  if ((flags & DISASSEMBLY_OMIT_PC) == 0)
    226  1.7  christos 	    uiout->text (pc_prefix (pc) + 1);
    227  1.1  christos 	  else
    228  1.7  christos 	    uiout->text ("  ");
    229  1.1  christos 	}
    230  1.6  christos       else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
    231  1.7  christos 	uiout->text (pc_prefix (pc));
    232  1.6  christos       else
    233  1.7  christos 	uiout->text ("   ");
    234  1.6  christos     }
    235  1.6  christos   else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
    236  1.7  christos     uiout->text (pc_prefix (pc));
    237  1.7  christos   uiout->field_core_addr ("address", gdbarch, pc);
    238  1.1  christos 
    239  1.6  christos   if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
    240  1.6  christos 			       &line, &unmapped))
    241  1.6  christos     {
    242  1.6  christos       /* We don't care now about line, filename and unmapped.  But we might in
    243  1.6  christos 	 the future.  */
    244  1.7  christos       uiout->text (" <");
    245  1.6  christos       if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
    246  1.7  christos 	uiout->field_string ("func-name", name);
    247  1.7  christos       uiout->text ("+");
    248  1.7  christos       uiout->field_int ("offset", offset);
    249  1.7  christos       uiout->text (">:\t");
    250  1.6  christos     }
    251  1.6  christos   else
    252  1.7  christos     uiout->text (":\t");
    253  1.6  christos 
    254  1.6  christos   if (filename != NULL)
    255  1.6  christos     xfree (filename);
    256  1.6  christos   if (name != NULL)
    257  1.6  christos     xfree (name);
    258  1.6  christos 
    259  1.7  christos   m_insn_stb.clear ();
    260  1.7  christos 
    261  1.6  christos   if (flags & DISASSEMBLY_RAW_INSN)
    262  1.6  christos     {
    263  1.6  christos       CORE_ADDR end_pc;
    264  1.6  christos       bfd_byte data;
    265  1.6  christos       int err;
    266  1.6  christos       const char *spacer = "";
    267  1.6  christos 
    268  1.6  christos       /* Build the opcodes using a temporary stream so we can
    269  1.6  christos 	 write them out in a single go for the MI.  */
    270  1.7  christos       m_opcode_stb.clear ();
    271  1.6  christos 
    272  1.7  christos       size = m_di.print_insn (pc);
    273  1.6  christos       end_pc = pc + size;
    274  1.1  christos 
    275  1.6  christos       for (;pc < end_pc; ++pc)
    276  1.1  christos 	{
    277  1.7  christos 	  read_code (pc, &data, 1);
    278  1.7  christos 	  m_opcode_stb.printf ("%s%02x", spacer, (unsigned) data);
    279  1.6  christos 	  spacer = " ";
    280  1.1  christos 	}
    281  1.1  christos 
    282  1.7  christos       uiout->field_stream ("opcodes", m_opcode_stb);
    283  1.7  christos       uiout->text ("\t");
    284  1.6  christos     }
    285  1.6  christos   else
    286  1.7  christos     size = m_di.print_insn (pc);
    287  1.6  christos 
    288  1.7  christos   uiout->field_stream ("inst", m_insn_stb);
    289  1.6  christos   do_cleanups (ui_out_chain);
    290  1.7  christos   uiout->text ("\n");
    291  1.6  christos 
    292  1.6  christos   return size;
    293  1.6  christos }
    294  1.6  christos 
    295  1.6  christos static int
    296  1.7  christos dump_insns (struct gdbarch *gdbarch,
    297  1.7  christos 	    struct ui_out *uiout, CORE_ADDR low, CORE_ADDR high,
    298  1.7  christos 	    int how_many, int flags, CORE_ADDR *end_pc)
    299  1.6  christos {
    300  1.6  christos   struct disasm_insn insn;
    301  1.6  christos   int num_displayed = 0;
    302  1.6  christos 
    303  1.6  christos   memset (&insn, 0, sizeof (insn));
    304  1.6  christos   insn.addr = low;
    305  1.6  christos 
    306  1.7  christos   gdb_pretty_print_disassembler disasm (gdbarch);
    307  1.7  christos 
    308  1.6  christos   while (insn.addr < high && (how_many < 0 || num_displayed < how_many))
    309  1.6  christos     {
    310  1.6  christos       int size;
    311  1.6  christos 
    312  1.7  christos       size = disasm.pretty_print_insn (uiout, &insn, flags);
    313  1.6  christos       if (size <= 0)
    314  1.6  christos 	break;
    315  1.6  christos 
    316  1.6  christos       ++num_displayed;
    317  1.6  christos       insn.addr += size;
    318  1.1  christos 
    319  1.6  christos       /* Allow user to bail out with ^C.  */
    320  1.6  christos       QUIT;
    321  1.1  christos     }
    322  1.6  christos 
    323  1.6  christos   if (end_pc != NULL)
    324  1.6  christos     *end_pc = insn.addr;
    325  1.6  christos 
    326  1.1  christos   return num_displayed;
    327  1.1  christos }
    328  1.1  christos 
    329  1.1  christos /* The idea here is to present a source-O-centric view of a
    330  1.1  christos    function to the user.  This means that things are presented
    331  1.1  christos    in source order, with (possibly) out of order assembly
    332  1.6  christos    immediately following.
    333  1.6  christos 
    334  1.6  christos    N.B. This view is deprecated.  */
    335  1.1  christos 
    336  1.1  christos static void
    337  1.6  christos do_mixed_source_and_assembly_deprecated
    338  1.6  christos   (struct gdbarch *gdbarch, struct ui_out *uiout,
    339  1.7  christos    struct symtab *symtab,
    340  1.6  christos    CORE_ADDR low, CORE_ADDR high,
    341  1.7  christos    int how_many, int flags)
    342  1.1  christos {
    343  1.1  christos   int newlines = 0;
    344  1.6  christos   int nlines;
    345  1.6  christos   struct linetable_entry *le;
    346  1.6  christos   struct deprecated_dis_line_entry *mle;
    347  1.1  christos   struct symtab_and_line sal;
    348  1.1  christos   int i;
    349  1.1  christos   int out_of_order = 0;
    350  1.1  christos   int next_line = 0;
    351  1.1  christos   int num_displayed = 0;
    352  1.6  christos   print_source_lines_flags psl_flags = 0;
    353  1.1  christos   struct cleanup *ui_out_chain;
    354  1.1  christos   struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
    355  1.1  christos   struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
    356  1.1  christos 
    357  1.6  christos   gdb_assert (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL);
    358  1.6  christos 
    359  1.6  christos   nlines = SYMTAB_LINETABLE (symtab)->nitems;
    360  1.6  christos   le = SYMTAB_LINETABLE (symtab)->item;
    361  1.6  christos 
    362  1.1  christos   if (flags & DISASSEMBLY_FILENAME)
    363  1.1  christos     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
    364  1.1  christos 
    365  1.6  christos   mle = (struct deprecated_dis_line_entry *)
    366  1.6  christos     alloca (nlines * sizeof (struct deprecated_dis_line_entry));
    367  1.1  christos 
    368  1.1  christos   /* Copy linetable entries for this function into our data
    369  1.1  christos      structure, creating end_pc's and setting out_of_order as
    370  1.1  christos      appropriate.  */
    371  1.1  christos 
    372  1.1  christos   /* First, skip all the preceding functions.  */
    373  1.1  christos 
    374  1.1  christos   for (i = 0; i < nlines - 1 && le[i].pc < low; i++);
    375  1.1  christos 
    376  1.1  christos   /* Now, copy all entries before the end of this function.  */
    377  1.1  christos 
    378  1.1  christos   for (; i < nlines - 1 && le[i].pc < high; i++)
    379  1.1  christos     {
    380  1.1  christos       if (le[i].line == le[i + 1].line && le[i].pc == le[i + 1].pc)
    381  1.1  christos 	continue;		/* Ignore duplicates.  */
    382  1.1  christos 
    383  1.1  christos       /* Skip any end-of-function markers.  */
    384  1.1  christos       if (le[i].line == 0)
    385  1.1  christos 	continue;
    386  1.1  christos 
    387  1.1  christos       mle[newlines].line = le[i].line;
    388  1.1  christos       if (le[i].line > le[i + 1].line)
    389  1.1  christos 	out_of_order = 1;
    390  1.1  christos       mle[newlines].start_pc = le[i].pc;
    391  1.1  christos       mle[newlines].end_pc = le[i + 1].pc;
    392  1.1  christos       newlines++;
    393  1.1  christos     }
    394  1.1  christos 
    395  1.1  christos   /* If we're on the last line, and it's part of the function,
    396  1.1  christos      then we need to get the end pc in a special way.  */
    397  1.1  christos 
    398  1.1  christos   if (i == nlines - 1 && le[i].pc < high)
    399  1.1  christos     {
    400  1.1  christos       mle[newlines].line = le[i].line;
    401  1.1  christos       mle[newlines].start_pc = le[i].pc;
    402  1.1  christos       sal = find_pc_line (le[i].pc, 0);
    403  1.1  christos       mle[newlines].end_pc = sal.end;
    404  1.1  christos       newlines++;
    405  1.1  christos     }
    406  1.1  christos 
    407  1.6  christos   /* Now, sort mle by line #s (and, then by addresses within lines).  */
    408  1.1  christos 
    409  1.1  christos   if (out_of_order)
    410  1.6  christos     qsort (mle, newlines, sizeof (struct deprecated_dis_line_entry),
    411  1.6  christos 	   compare_lines);
    412  1.1  christos 
    413  1.1  christos   /* Now, for each line entry, emit the specified lines (unless
    414  1.1  christos      they have been emitted before), followed by the assembly code
    415  1.1  christos      for that line.  */
    416  1.1  christos 
    417  1.1  christos   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
    418  1.1  christos 
    419  1.1  christos   for (i = 0; i < newlines; i++)
    420  1.1  christos     {
    421  1.1  christos       /* Print out everything from next_line to the current line.  */
    422  1.1  christos       if (mle[i].line >= next_line)
    423  1.1  christos 	{
    424  1.1  christos 	  if (next_line != 0)
    425  1.1  christos 	    {
    426  1.1  christos 	      /* Just one line to print.  */
    427  1.1  christos 	      if (next_line == mle[i].line)
    428  1.1  christos 		{
    429  1.1  christos 		  ui_out_tuple_chain
    430  1.1  christos 		    = make_cleanup_ui_out_tuple_begin_end (uiout,
    431  1.1  christos 							   "src_and_asm_line");
    432  1.1  christos 		  print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
    433  1.1  christos 		}
    434  1.1  christos 	      else
    435  1.1  christos 		{
    436  1.1  christos 		  /* Several source lines w/o asm instructions associated.  */
    437  1.1  christos 		  for (; next_line < mle[i].line; next_line++)
    438  1.1  christos 		    {
    439  1.1  christos 		      struct cleanup *ui_out_list_chain_line;
    440  1.1  christos 		      struct cleanup *ui_out_tuple_chain_line;
    441  1.1  christos 
    442  1.1  christos 		      ui_out_tuple_chain_line
    443  1.1  christos 			= make_cleanup_ui_out_tuple_begin_end (uiout,
    444  1.1  christos 							       "src_and_asm_line");
    445  1.1  christos 		      print_source_lines (symtab, next_line, next_line + 1,
    446  1.1  christos 					  psl_flags);
    447  1.1  christos 		      ui_out_list_chain_line
    448  1.1  christos 			= make_cleanup_ui_out_list_begin_end (uiout,
    449  1.1  christos 							      "line_asm_insn");
    450  1.1  christos 		      do_cleanups (ui_out_list_chain_line);
    451  1.1  christos 		      do_cleanups (ui_out_tuple_chain_line);
    452  1.1  christos 		    }
    453  1.1  christos 		  /* Print the last line and leave list open for
    454  1.1  christos 		     asm instructions to be added.  */
    455  1.1  christos 		  ui_out_tuple_chain
    456  1.1  christos 		    = make_cleanup_ui_out_tuple_begin_end (uiout,
    457  1.1  christos 							   "src_and_asm_line");
    458  1.1  christos 		  print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
    459  1.1  christos 		}
    460  1.1  christos 	    }
    461  1.1  christos 	  else
    462  1.1  christos 	    {
    463  1.1  christos 	      ui_out_tuple_chain
    464  1.1  christos 		= make_cleanup_ui_out_tuple_begin_end (uiout,
    465  1.1  christos 						       "src_and_asm_line");
    466  1.1  christos 	      print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
    467  1.1  christos 	    }
    468  1.1  christos 
    469  1.1  christos 	  next_line = mle[i].line + 1;
    470  1.1  christos 	  ui_out_list_chain
    471  1.1  christos 	    = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
    472  1.1  christos 	}
    473  1.1  christos 
    474  1.7  christos       num_displayed += dump_insns (gdbarch, uiout,
    475  1.1  christos 				   mle[i].start_pc, mle[i].end_pc,
    476  1.7  christos 				   how_many, flags, NULL);
    477  1.1  christos 
    478  1.1  christos       /* When we've reached the end of the mle array, or we've seen the last
    479  1.1  christos          assembly range for this source line, close out the list/tuple.  */
    480  1.1  christos       if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
    481  1.1  christos 	{
    482  1.1  christos 	  do_cleanups (ui_out_list_chain);
    483  1.1  christos 	  do_cleanups (ui_out_tuple_chain);
    484  1.1  christos 	  ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
    485  1.1  christos 	  ui_out_list_chain = make_cleanup (null_cleanup, 0);
    486  1.7  christos 	  uiout->text ("\n");
    487  1.1  christos 	}
    488  1.1  christos       if (how_many >= 0 && num_displayed >= how_many)
    489  1.1  christos 	break;
    490  1.1  christos     }
    491  1.1  christos   do_cleanups (ui_out_chain);
    492  1.1  christos }
    493  1.1  christos 
    494  1.6  christos /* The idea here is to present a source-O-centric view of a
    495  1.6  christos    function to the user.  This means that things are presented
    496  1.6  christos    in source order, with (possibly) out of order assembly
    497  1.6  christos    immediately following.  */
    498  1.6  christos 
    499  1.6  christos static void
    500  1.7  christos do_mixed_source_and_assembly (struct gdbarch *gdbarch,
    501  1.7  christos 			      struct ui_out *uiout,
    502  1.6  christos 			      struct symtab *main_symtab,
    503  1.6  christos 			      CORE_ADDR low, CORE_ADDR high,
    504  1.7  christos 			      int how_many, int flags)
    505  1.6  christos {
    506  1.6  christos   const struct linetable_entry *le, *first_le;
    507  1.6  christos   int i, nlines;
    508  1.6  christos   int num_displayed = 0;
    509  1.6  christos   print_source_lines_flags psl_flags = 0;
    510  1.6  christos   struct cleanup *ui_out_chain;
    511  1.6  christos   struct cleanup *ui_out_tuple_chain;
    512  1.6  christos   struct cleanup *ui_out_list_chain;
    513  1.6  christos   CORE_ADDR pc;
    514  1.6  christos   struct symtab *last_symtab;
    515  1.6  christos   int last_line;
    516  1.6  christos 
    517  1.6  christos   gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
    518  1.6  christos 
    519  1.6  christos   /* First pass: collect the list of all source files and lines.
    520  1.6  christos      We do this so that we can only print lines containing code once.
    521  1.6  christos      We try to print the source text leading up to the next instruction,
    522  1.6  christos      but if that text is for code that will be disassembled later, then
    523  1.6  christos      we'll want to defer printing it until later with its associated code.  */
    524  1.6  christos 
    525  1.7  christos   htab_up dis_line_table (allocate_dis_line_table ());
    526  1.6  christos 
    527  1.6  christos   pc = low;
    528  1.6  christos 
    529  1.6  christos   /* The prologue may be empty, but there may still be a line number entry
    530  1.6  christos      for the opening brace which is distinct from the first line of code.
    531  1.6  christos      If the prologue has been eliminated find_pc_line may return the source
    532  1.6  christos      line after the opening brace.  We still want to print this opening brace.
    533  1.6  christos      first_le is used to implement this.  */
    534  1.6  christos 
    535  1.6  christos   nlines = SYMTAB_LINETABLE (main_symtab)->nitems;
    536  1.6  christos   le = SYMTAB_LINETABLE (main_symtab)->item;
    537  1.6  christos   first_le = NULL;
    538  1.6  christos 
    539  1.6  christos   /* Skip all the preceding functions.  */
    540  1.6  christos   for (i = 0; i < nlines && le[i].pc < low; i++)
    541  1.6  christos     continue;
    542  1.6  christos 
    543  1.6  christos   if (i < nlines && le[i].pc < high)
    544  1.6  christos     first_le = &le[i];
    545  1.6  christos 
    546  1.6  christos   /* Add lines for every pc value.  */
    547  1.6  christos   while (pc < high)
    548  1.6  christos     {
    549  1.6  christos       struct symtab_and_line sal;
    550  1.6  christos       int length;
    551  1.6  christos 
    552  1.6  christos       sal = find_pc_line (pc, 0);
    553  1.6  christos       length = gdb_insn_length (gdbarch, pc);
    554  1.6  christos       pc += length;
    555  1.6  christos 
    556  1.6  christos       if (sal.symtab != NULL)
    557  1.7  christos 	add_dis_line_entry (dis_line_table.get (), sal.symtab, sal.line);
    558  1.6  christos     }
    559  1.6  christos 
    560  1.6  christos   /* Second pass: print the disassembly.
    561  1.6  christos 
    562  1.6  christos      Output format, from an MI perspective:
    563  1.6  christos        The result is a ui_out list, field name "asm_insns", where elements have
    564  1.6  christos        name "src_and_asm_line".
    565  1.6  christos        Each element is a tuple of source line specs (field names line, file,
    566  1.6  christos        fullname), and field "line_asm_insn" which contains the disassembly.
    567  1.6  christos        Field "line_asm_insn" is a list of tuples: address, func-name, offset,
    568  1.6  christos        opcodes, inst.
    569  1.6  christos 
    570  1.6  christos      CLI output works on top of this because MI ignores ui_out_text output,
    571  1.6  christos      which is where we put file name and source line contents output.
    572  1.6  christos 
    573  1.6  christos      Cleanup usage:
    574  1.6  christos      ui_out_chain
    575  1.6  christos        Handles the outer "asm_insns" list.
    576  1.6  christos      ui_out_tuple_chain
    577  1.6  christos        The tuples for each group of consecutive disassemblies.
    578  1.6  christos      ui_out_list_chain
    579  1.6  christos        List of consecutive source lines or disassembled insns.  */
    580  1.6  christos 
    581  1.6  christos   if (flags & DISASSEMBLY_FILENAME)
    582  1.6  christos     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
    583  1.6  christos 
    584  1.6  christos   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
    585  1.6  christos 
    586  1.6  christos   ui_out_tuple_chain = NULL;
    587  1.6  christos   ui_out_list_chain = NULL;
    588  1.6  christos 
    589  1.6  christos   last_symtab = NULL;
    590  1.6  christos   last_line = 0;
    591  1.6  christos   pc = low;
    592  1.6  christos 
    593  1.6  christos   while (pc < high)
    594  1.6  christos     {
    595  1.6  christos       struct symtab_and_line sal;
    596  1.6  christos       CORE_ADDR end_pc;
    597  1.6  christos       int start_preceding_line_to_display = 0;
    598  1.6  christos       int end_preceding_line_to_display = 0;
    599  1.6  christos       int new_source_line = 0;
    600  1.6  christos 
    601  1.6  christos       sal = find_pc_line (pc, 0);
    602  1.6  christos 
    603  1.6  christos       if (sal.symtab != last_symtab)
    604  1.6  christos 	{
    605  1.6  christos 	  /* New source file.  */
    606  1.6  christos 	  new_source_line = 1;
    607  1.6  christos 
    608  1.6  christos 	  /* If this is the first line of output, check for any preceding
    609  1.6  christos 	     lines.  */
    610  1.6  christos 	  if (last_line == 0
    611  1.6  christos 	      && first_le != NULL
    612  1.6  christos 	      && first_le->line < sal.line)
    613  1.6  christos 	    {
    614  1.6  christos 	      start_preceding_line_to_display = first_le->line;
    615  1.6  christos 	      end_preceding_line_to_display = sal.line;
    616  1.6  christos 	    }
    617  1.6  christos 	}
    618  1.6  christos       else
    619  1.6  christos 	{
    620  1.6  christos 	  /* Same source file as last time.  */
    621  1.6  christos 	  if (sal.symtab != NULL)
    622  1.6  christos 	    {
    623  1.6  christos 	      if (sal.line > last_line + 1 && last_line != 0)
    624  1.6  christos 		{
    625  1.6  christos 		  int l;
    626  1.6  christos 
    627  1.6  christos 		  /* Several preceding source lines.  Print the trailing ones
    628  1.6  christos 		     not associated with code that we'll print later.  */
    629  1.6  christos 		  for (l = sal.line - 1; l > last_line; --l)
    630  1.6  christos 		    {
    631  1.7  christos 		      if (line_has_code_p (dis_line_table.get (),
    632  1.7  christos 					   sal.symtab, l))
    633  1.6  christos 			break;
    634  1.6  christos 		    }
    635  1.6  christos 		  if (l < sal.line - 1)
    636  1.6  christos 		    {
    637  1.6  christos 		      start_preceding_line_to_display = l + 1;
    638  1.6  christos 		      end_preceding_line_to_display = sal.line;
    639  1.6  christos 		    }
    640  1.6  christos 		}
    641  1.6  christos 	      if (sal.line != last_line)
    642  1.6  christos 		new_source_line = 1;
    643  1.6  christos 	      else
    644  1.6  christos 		{
    645  1.6  christos 		  /* Same source line as last time.  This can happen, depending
    646  1.6  christos 		     on the debug info.  */
    647  1.6  christos 		}
    648  1.6  christos 	    }
    649  1.6  christos 	}
    650  1.6  christos 
    651  1.6  christos       if (new_source_line)
    652  1.6  christos 	{
    653  1.6  christos 	  /* Skip the newline if this is the first instruction.  */
    654  1.6  christos 	  if (pc > low)
    655  1.7  christos 	    uiout->text ("\n");
    656  1.6  christos 	  if (ui_out_tuple_chain != NULL)
    657  1.6  christos 	    {
    658  1.6  christos 	      gdb_assert (ui_out_list_chain != NULL);
    659  1.6  christos 	      do_cleanups (ui_out_list_chain);
    660  1.6  christos 	      do_cleanups (ui_out_tuple_chain);
    661  1.6  christos 	    }
    662  1.6  christos 	  if (sal.symtab != last_symtab
    663  1.6  christos 	      && !(flags & DISASSEMBLY_FILENAME))
    664  1.6  christos 	    {
    665  1.6  christos 	      /* Remember MI ignores ui_out_text.
    666  1.6  christos 		 We don't have to do anything here for MI because MI
    667  1.6  christos 		 output includes the source specs for each line.  */
    668  1.6  christos 	      if (sal.symtab != NULL)
    669  1.6  christos 		{
    670  1.7  christos 		  uiout->text (symtab_to_filename_for_display (sal.symtab));
    671  1.6  christos 		}
    672  1.6  christos 	      else
    673  1.7  christos 		uiout->text ("unknown");
    674  1.7  christos 	      uiout->text (":\n");
    675  1.6  christos 	    }
    676  1.6  christos 	  if (start_preceding_line_to_display > 0)
    677  1.6  christos 	    {
    678  1.6  christos 	      /* Several source lines w/o asm instructions associated.
    679  1.6  christos 		 We need to preserve the structure of the output, so output
    680  1.6  christos 		 a bunch of line tuples with no asm entries.  */
    681  1.6  christos 	      int l;
    682  1.6  christos 	      struct cleanup *ui_out_list_chain_line;
    683  1.6  christos 	      struct cleanup *ui_out_tuple_chain_line;
    684  1.6  christos 
    685  1.6  christos 	      gdb_assert (sal.symtab != NULL);
    686  1.6  christos 	      for (l = start_preceding_line_to_display;
    687  1.6  christos 		   l < end_preceding_line_to_display;
    688  1.6  christos 		   ++l)
    689  1.6  christos 		{
    690  1.6  christos 		  ui_out_tuple_chain_line
    691  1.6  christos 		    = make_cleanup_ui_out_tuple_begin_end (uiout,
    692  1.6  christos 							   "src_and_asm_line");
    693  1.6  christos 		  print_source_lines (sal.symtab, l, l + 1, psl_flags);
    694  1.6  christos 		  ui_out_list_chain_line
    695  1.6  christos 		    = make_cleanup_ui_out_list_begin_end (uiout,
    696  1.6  christos 							  "line_asm_insn");
    697  1.6  christos 		  do_cleanups (ui_out_list_chain_line);
    698  1.6  christos 		  do_cleanups (ui_out_tuple_chain_line);
    699  1.6  christos 		}
    700  1.6  christos 	    }
    701  1.6  christos 	  ui_out_tuple_chain
    702  1.6  christos 	    = make_cleanup_ui_out_tuple_begin_end (uiout, "src_and_asm_line");
    703  1.6  christos 	  if (sal.symtab != NULL)
    704  1.6  christos 	    print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
    705  1.6  christos 	  else
    706  1.7  christos 	    uiout->text (_("--- no source info for this pc ---\n"));
    707  1.6  christos 	  ui_out_list_chain
    708  1.6  christos 	    = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
    709  1.6  christos 	}
    710  1.6  christos       else
    711  1.6  christos 	{
    712  1.6  christos 	  /* Here we're appending instructions to an existing line.
    713  1.6  christos 	     By construction the very first insn will have a symtab
    714  1.6  christos 	     and follow the new_source_line path above.  */
    715  1.6  christos 	  gdb_assert (ui_out_tuple_chain != NULL);
    716  1.6  christos 	  gdb_assert (ui_out_list_chain != NULL);
    717  1.6  christos 	}
    718  1.6  christos 
    719  1.6  christos       if (sal.end != 0)
    720  1.7  christos 	end_pc = std::min (sal.end, high);
    721  1.6  christos       else
    722  1.6  christos 	end_pc = pc + 1;
    723  1.7  christos       num_displayed += dump_insns (gdbarch, uiout, pc, end_pc,
    724  1.7  christos 				   how_many, flags, &end_pc);
    725  1.6  christos       pc = end_pc;
    726  1.6  christos 
    727  1.6  christos       if (how_many >= 0 && num_displayed >= how_many)
    728  1.6  christos 	break;
    729  1.6  christos 
    730  1.6  christos       last_symtab = sal.symtab;
    731  1.6  christos       last_line = sal.line;
    732  1.6  christos     }
    733  1.6  christos 
    734  1.6  christos   do_cleanups (ui_out_chain);
    735  1.6  christos }
    736  1.1  christos 
    737  1.1  christos static void
    738  1.1  christos do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
    739  1.1  christos 		  CORE_ADDR low, CORE_ADDR high,
    740  1.7  christos 		  int how_many, int flags)
    741  1.1  christos {
    742  1.1  christos   struct cleanup *ui_out_chain;
    743  1.1  christos 
    744  1.1  christos   ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
    745  1.1  christos 
    746  1.7  christos   dump_insns (gdbarch, uiout, low, high, how_many, flags, NULL);
    747  1.1  christos 
    748  1.1  christos   do_cleanups (ui_out_chain);
    749  1.1  christos }
    750  1.1  christos 
    751  1.1  christos /* Initialize the disassemble info struct ready for the specified
    752  1.1  christos    stream.  */
    753  1.1  christos 
    754  1.1  christos static int ATTRIBUTE_PRINTF (2, 3)
    755  1.1  christos fprintf_disasm (void *stream, const char *format, ...)
    756  1.1  christos {
    757  1.1  christos   va_list args;
    758  1.1  christos 
    759  1.1  christos   va_start (args, format);
    760  1.6  christos   vfprintf_filtered ((struct ui_file *) stream, format, args);
    761  1.1  christos   va_end (args);
    762  1.1  christos   /* Something non -ve.  */
    763  1.1  christos   return 0;
    764  1.1  christos }
    765  1.1  christos 
    766  1.7  christos gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch,
    767  1.7  christos 				    struct ui_file *file,
    768  1.7  christos 				    di_read_memory_ftype read_memory_func)
    769  1.7  christos   : m_gdbarch (gdbarch),
    770  1.7  christos     m_err_memaddr (0)
    771  1.7  christos {
    772  1.7  christos   init_disassemble_info (&m_di, file, fprintf_disasm);
    773  1.7  christos   m_di.flavour = bfd_target_unknown_flavour;
    774  1.7  christos   m_di.memory_error_func = dis_asm_memory_error;
    775  1.7  christos   m_di.print_address_func = dis_asm_print_address;
    776  1.1  christos   /* NOTE: cagney/2003-04-28: The original code, from the old Insight
    777  1.1  christos      disassembler had a local optomization here.  By default it would
    778  1.1  christos      access the executable file, instead of the target memory (there
    779  1.1  christos      was a growing list of exceptions though).  Unfortunately, the
    780  1.1  christos      heuristic was flawed.  Commands like "disassemble &variable"
    781  1.1  christos      didn't work as they relied on the access going to the target.
    782  1.1  christos      Further, it has been supperseeded by trust-read-only-sections
    783  1.1  christos      (although that should be superseeded by target_trust..._p()).  */
    784  1.7  christos   m_di.read_memory_func = read_memory_func;
    785  1.7  christos   m_di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
    786  1.7  christos   m_di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
    787  1.7  christos   m_di.endian = gdbarch_byte_order (gdbarch);
    788  1.7  christos   m_di.endian_code = gdbarch_byte_order_for_code (gdbarch);
    789  1.7  christos   m_di.application_data = this;
    790  1.7  christos   m_di.disassembler_options = get_disassembler_options (gdbarch);
    791  1.7  christos   disassemble_init_for_target (&m_di);
    792  1.7  christos }
    793  1.7  christos 
    794  1.7  christos int
    795  1.7  christos gdb_disassembler::print_insn (CORE_ADDR memaddr,
    796  1.7  christos 			      int *branch_delay_insns)
    797  1.7  christos {
    798  1.7  christos   m_err_memaddr = 0;
    799  1.7  christos 
    800  1.7  christos   int length = gdbarch_print_insn (arch (), memaddr, &m_di);
    801  1.7  christos 
    802  1.7  christos   if (length < 0)
    803  1.7  christos     memory_error (TARGET_XFER_E_IO, m_err_memaddr);
    804  1.7  christos 
    805  1.7  christos   if (branch_delay_insns != NULL)
    806  1.7  christos     {
    807  1.7  christos       if (m_di.insn_info_valid)
    808  1.7  christos 	*branch_delay_insns = m_di.branch_delay_insns;
    809  1.7  christos       else
    810  1.7  christos 	*branch_delay_insns = 0;
    811  1.7  christos     }
    812  1.7  christos   return length;
    813  1.1  christos }
    814  1.1  christos 
    815  1.1  christos void
    816  1.1  christos gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
    817  1.7  christos 		 int flags, int how_many,
    818  1.1  christos 		 CORE_ADDR low, CORE_ADDR high)
    819  1.1  christos {
    820  1.3  christos   struct symtab *symtab;
    821  1.1  christos   int nlines = -1;
    822  1.1  christos 
    823  1.1  christos   /* Assume symtab is valid for whole PC range.  */
    824  1.3  christos   symtab = find_pc_line_symtab (low);
    825  1.1  christos 
    826  1.3  christos   if (symtab != NULL && SYMTAB_LINETABLE (symtab) != NULL)
    827  1.6  christos     nlines = SYMTAB_LINETABLE (symtab)->nitems;
    828  1.1  christos 
    829  1.6  christos   if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
    830  1.6  christos       || nlines <= 0)
    831  1.7  christos     do_assembly_only (gdbarch, uiout, low, high, how_many, flags);
    832  1.1  christos 
    833  1.1  christos   else if (flags & DISASSEMBLY_SOURCE)
    834  1.7  christos     do_mixed_source_and_assembly (gdbarch, uiout, symtab, low, high,
    835  1.7  christos 				  how_many, flags);
    836  1.6  christos 
    837  1.6  christos   else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
    838  1.7  christos     do_mixed_source_and_assembly_deprecated (gdbarch, uiout, symtab,
    839  1.7  christos 					     low, high, how_many, flags);
    840  1.1  christos 
    841  1.1  christos   gdb_flush (gdb_stdout);
    842  1.1  christos }
    843  1.1  christos 
    844  1.1  christos /* Print the instruction at address MEMADDR in debugged memory,
    845  1.1  christos    on STREAM.  Returns the length of the instruction, in bytes,
    846  1.1  christos    and, if requested, the number of branch delay slot instructions.  */
    847  1.1  christos 
    848  1.1  christos int
    849  1.1  christos gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
    850  1.1  christos 		struct ui_file *stream, int *branch_delay_insns)
    851  1.1  christos {
    852  1.1  christos 
    853  1.7  christos   gdb_disassembler di (gdbarch, stream);
    854  1.1  christos 
    855  1.7  christos   return di.print_insn (memaddr, branch_delay_insns);
    856  1.1  christos }
    857  1.1  christos 
    858  1.1  christos /* Return the length in bytes of the instruction at address MEMADDR in
    859  1.1  christos    debugged memory.  */
    860  1.1  christos 
    861  1.1  christos int
    862  1.1  christos gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
    863  1.1  christos {
    864  1.7  christos   return gdb_print_insn (gdbarch, addr, &null_stream, NULL);
    865  1.1  christos }
    866  1.1  christos 
    867  1.1  christos /* fprintf-function for gdb_buffered_insn_length.  This function is a
    868  1.1  christos    nop, we don't want to print anything, we just want to compute the
    869  1.1  christos    length of the insn.  */
    870  1.1  christos 
    871  1.1  christos static int ATTRIBUTE_PRINTF (2, 3)
    872  1.1  christos gdb_buffered_insn_length_fprintf (void *stream, const char *format, ...)
    873  1.1  christos {
    874  1.1  christos   return 0;
    875  1.1  christos }
    876  1.1  christos 
    877  1.1  christos /* Initialize a struct disassemble_info for gdb_buffered_insn_length.  */
    878  1.1  christos 
    879  1.1  christos static void
    880  1.1  christos gdb_buffered_insn_length_init_dis (struct gdbarch *gdbarch,
    881  1.1  christos 				   struct disassemble_info *di,
    882  1.1  christos 				   const gdb_byte *insn, int max_len,
    883  1.1  christos 				   CORE_ADDR addr)
    884  1.1  christos {
    885  1.1  christos   init_disassemble_info (di, NULL, gdb_buffered_insn_length_fprintf);
    886  1.1  christos 
    887  1.1  christos   /* init_disassemble_info installs buffer_read_memory, etc.
    888  1.1  christos      so we don't need to do that here.
    889  1.1  christos      The cast is necessary until disassemble_info is const-ified.  */
    890  1.1  christos   di->buffer = (gdb_byte *) insn;
    891  1.1  christos   di->buffer_length = max_len;
    892  1.1  christos   di->buffer_vma = addr;
    893  1.1  christos 
    894  1.1  christos   di->arch = gdbarch_bfd_arch_info (gdbarch)->arch;
    895  1.1  christos   di->mach = gdbarch_bfd_arch_info (gdbarch)->mach;
    896  1.1  christos   di->endian = gdbarch_byte_order (gdbarch);
    897  1.1  christos   di->endian_code = gdbarch_byte_order_for_code (gdbarch);
    898  1.1  christos 
    899  1.7  christos   di->disassembler_options = get_disassembler_options (gdbarch);
    900  1.1  christos   disassemble_init_for_target (di);
    901  1.1  christos }
    902  1.1  christos 
    903  1.1  christos /* Return the length in bytes of INSN.  MAX_LEN is the size of the
    904  1.1  christos    buffer containing INSN.  */
    905  1.1  christos 
    906  1.1  christos int
    907  1.1  christos gdb_buffered_insn_length (struct gdbarch *gdbarch,
    908  1.1  christos 			  const gdb_byte *insn, int max_len, CORE_ADDR addr)
    909  1.1  christos {
    910  1.1  christos   struct disassemble_info di;
    911  1.1  christos 
    912  1.1  christos   gdb_buffered_insn_length_init_dis (gdbarch, &di, insn, max_len, addr);
    913  1.1  christos 
    914  1.1  christos   return gdbarch_print_insn (gdbarch, addr, &di);
    915  1.1  christos }
    916  1.7  christos 
    917  1.7  christos char *
    918  1.7  christos get_disassembler_options (struct gdbarch *gdbarch)
    919  1.7  christos {
    920  1.7  christos   char **disassembler_options = gdbarch_disassembler_options (gdbarch);
    921  1.7  christos   if (disassembler_options == NULL)
    922  1.7  christos     return NULL;
    923  1.7  christos   return *disassembler_options;
    924  1.7  christos }
    925  1.7  christos 
    926  1.7  christos void
    927  1.7  christos set_disassembler_options (char *prospective_options)
    928  1.7  christos {
    929  1.7  christos   struct gdbarch *gdbarch = get_current_arch ();
    930  1.7  christos   char **disassembler_options = gdbarch_disassembler_options (gdbarch);
    931  1.7  christos   const disasm_options_t *valid_options;
    932  1.7  christos   char *options = remove_whitespace_and_extra_commas (prospective_options);
    933  1.7  christos   const char *opt;
    934  1.7  christos 
    935  1.7  christos   /* Allow all architectures, even ones that do not support 'set disassembler',
    936  1.7  christos      to reset their disassembler options to NULL.  */
    937  1.7  christos   if (options == NULL)
    938  1.7  christos     {
    939  1.7  christos       if (disassembler_options != NULL)
    940  1.7  christos 	{
    941  1.7  christos 	  free (*disassembler_options);
    942  1.7  christos 	  *disassembler_options = NULL;
    943  1.7  christos 	}
    944  1.7  christos       return;
    945  1.7  christos     }
    946  1.7  christos 
    947  1.7  christos   valid_options = gdbarch_valid_disassembler_options (gdbarch);
    948  1.7  christos   if (valid_options  == NULL)
    949  1.7  christos     {
    950  1.7  christos       fprintf_filtered (gdb_stdlog, _("\
    951  1.7  christos 'set disassembler-options ...' is not supported on this architecture.\n"));
    952  1.7  christos       return;
    953  1.7  christos     }
    954  1.7  christos 
    955  1.7  christos   /* Verify we have valid disassembler options.  */
    956  1.7  christos   FOR_EACH_DISASSEMBLER_OPTION (opt, options)
    957  1.7  christos     {
    958  1.7  christos       size_t i;
    959  1.7  christos       for (i = 0; valid_options->name[i] != NULL; i++)
    960  1.7  christos 	if (disassembler_options_cmp (opt, valid_options->name[i]) == 0)
    961  1.7  christos 	  break;
    962  1.7  christos       if (valid_options->name[i] == NULL)
    963  1.7  christos 	{
    964  1.7  christos 	  fprintf_filtered (gdb_stdlog,
    965  1.7  christos 			    _("Invalid disassembler option value: '%s'.\n"),
    966  1.7  christos 			    opt);
    967  1.7  christos 	  return;
    968  1.7  christos 	}
    969  1.7  christos     }
    970  1.7  christos 
    971  1.7  christos   free (*disassembler_options);
    972  1.7  christos   *disassembler_options = xstrdup (options);
    973  1.7  christos }
    974  1.7  christos 
    975  1.7  christos static void
    976  1.7  christos set_disassembler_options_sfunc (char *args, int from_tty,
    977  1.7  christos 				struct cmd_list_element *c)
    978  1.7  christos {
    979  1.7  christos   set_disassembler_options (prospective_options);
    980  1.7  christos }
    981  1.7  christos 
    982  1.7  christos static void
    983  1.7  christos show_disassembler_options_sfunc (struct ui_file *file, int from_tty,
    984  1.7  christos 				 struct cmd_list_element *c, const char *value)
    985  1.7  christos {
    986  1.7  christos   struct gdbarch *gdbarch = get_current_arch ();
    987  1.7  christos   const disasm_options_t *valid_options;
    988  1.7  christos 
    989  1.7  christos   const char *options = get_disassembler_options (gdbarch);
    990  1.7  christos   if (options == NULL)
    991  1.7  christos     options = "";
    992  1.7  christos 
    993  1.7  christos   fprintf_filtered (file, _("The current disassembler options are '%s'\n"),
    994  1.7  christos 		    options);
    995  1.7  christos 
    996  1.7  christos   valid_options = gdbarch_valid_disassembler_options (gdbarch);
    997  1.7  christos 
    998  1.7  christos   if (valid_options == NULL)
    999  1.7  christos     return;
   1000  1.7  christos 
   1001  1.7  christos   fprintf_filtered (file, _("\n\
   1002  1.7  christos The following disassembler options are supported for use with the\n\
   1003  1.7  christos 'set disassembler-options <option>[,<option>...]' command:\n"));
   1004  1.7  christos 
   1005  1.7  christos   if (valid_options->description != NULL)
   1006  1.7  christos     {
   1007  1.7  christos       size_t i, max_len = 0;
   1008  1.7  christos 
   1009  1.7  christos       /* Compute the length of the longest option name.  */
   1010  1.7  christos       for (i = 0; valid_options->name[i] != NULL; i++)
   1011  1.7  christos 	{
   1012  1.7  christos 	  size_t len = strlen (valid_options->name[i]);
   1013  1.7  christos 	  if (max_len < len)
   1014  1.7  christos 	    max_len = len;
   1015  1.7  christos 	}
   1016  1.7  christos 
   1017  1.7  christos       for (i = 0, max_len++; valid_options->name[i] != NULL; i++)
   1018  1.7  christos 	{
   1019  1.7  christos 	  fprintf_filtered (file, "  %s", valid_options->name[i]);
   1020  1.7  christos 	  if (valid_options->description[i] != NULL)
   1021  1.7  christos 	    fprintf_filtered (file, "%*c %s",
   1022  1.7  christos 			      (int)(max_len - strlen (valid_options->name[i])), ' ',
   1023  1.7  christos 			      valid_options->description[i]);
   1024  1.7  christos 	  fprintf_filtered (file, "\n");
   1025  1.7  christos 	}
   1026  1.7  christos     }
   1027  1.7  christos   else
   1028  1.7  christos     {
   1029  1.7  christos       size_t i;
   1030  1.7  christos       fprintf_filtered (file, "  ");
   1031  1.7  christos       for (i = 0; valid_options->name[i] != NULL; i++)
   1032  1.7  christos 	{
   1033  1.7  christos 	  fprintf_filtered (file, "%s", valid_options->name[i]);
   1034  1.7  christos 	  if (valid_options->name[i + 1] != NULL)
   1035  1.7  christos 	    fprintf_filtered (file, ", ");
   1036  1.7  christos 	  wrap_here ("  ");
   1037  1.7  christos 	}
   1038  1.7  christos       fprintf_filtered (file, "\n");
   1039  1.7  christos     }
   1040  1.7  christos }
   1041  1.7  christos 
   1042  1.7  christos /* A completion function for "set disassembler".  */
   1043  1.7  christos 
   1044  1.7  christos static VEC (char_ptr) *
   1045  1.7  christos disassembler_options_completer (struct cmd_list_element *ignore,
   1046  1.7  christos 				const char *text, const char *word)
   1047  1.7  christos {
   1048  1.7  christos   struct gdbarch *gdbarch = get_current_arch ();
   1049  1.7  christos   const disasm_options_t *opts = gdbarch_valid_disassembler_options (gdbarch);
   1050  1.7  christos 
   1051  1.7  christos   if (opts != NULL)
   1052  1.7  christos     {
   1053  1.7  christos       /* Only attempt to complete on the last option text.  */
   1054  1.7  christos       const char *separator = strrchr (text, ',');
   1055  1.7  christos       if (separator != NULL)
   1056  1.7  christos 	text = separator + 1;
   1057  1.7  christos       text = skip_spaces_const (text);
   1058  1.7  christos       return complete_on_enum (opts->name, text, word);
   1059  1.7  christos     }
   1060  1.7  christos   return NULL;
   1061  1.7  christos }
   1062  1.7  christos 
   1063  1.7  christos 
   1064  1.7  christos /* Initialization code.  */
   1065  1.7  christos 
   1066  1.7  christos /* -Wmissing-prototypes */
   1067  1.7  christos extern initialize_file_ftype _initialize_disasm;
   1068  1.7  christos 
   1069  1.7  christos void
   1070  1.7  christos _initialize_disasm (void)
   1071  1.7  christos {
   1072  1.7  christos   struct cmd_list_element *cmd;
   1073  1.7  christos 
   1074  1.7  christos   /* Add the command that controls the disassembler options.  */
   1075  1.7  christos   cmd = add_setshow_string_noescape_cmd ("disassembler-options", no_class,
   1076  1.7  christos 					 &prospective_options, _("\
   1077  1.7  christos Set the disassembler options.\n\
   1078  1.7  christos Usage: set disassembler-options <option>[,<option>...]\n\n\
   1079  1.7  christos See: 'show disassembler-options' for valid option values.\n"), _("\
   1080  1.7  christos Show the disassembler options."), NULL,
   1081  1.7  christos 					 set_disassembler_options_sfunc,
   1082  1.7  christos 					 show_disassembler_options_sfunc,
   1083  1.7  christos 					 &setlist, &showlist);
   1084  1.7  christos   set_cmd_completer (cmd, disassembler_options_completer);
   1085  1.7  christos }
   1086