Home | History | Annotate | Line # | Download | only in gdb
      1   1.1  christos /* Disassemble support for GDB.
      2   1.1  christos 
      3  1.11  christos    Copyright (C) 2000-2024 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.7  christos #include "arch-utils.h"
     21  1.11  christos #include "event-top.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.11  christos #include "cli/cli-cmds.h"
     28   1.1  christos #include "dis-asm.h"
     29   1.6  christos #include "source.h"
     30  1.11  christos #include "gdbsupport/gdb-safe-ctype.h"
     31   1.7  christos #include <algorithm>
     32  1.11  christos #include <optional>
     33   1.8  christos #include "valprint.h"
     34   1.9  christos #include "cli/cli-style.h"
     35  1.11  christos #include "objfiles.h"
     36  1.11  christos #include "inferior.h"
     37   1.1  christos 
     38   1.1  christos /* Disassemble functions.
     39   1.1  christos    FIXME: We should get rid of all the duplicate code in gdb that does
     40   1.1  christos    the same thing: disassemble_command() and the gdbtk variation.  */
     41   1.1  christos 
     42   1.7  christos /* This variable is used to hold the prospective disassembler_options value
     43   1.7  christos    which is set by the "set disassembler_options" command.  */
     44  1.10  christos static std::string prospective_options;
     45  1.10  christos 
     46  1.10  christos /* When this is true we will try to use libopcodes to provide styling to
     47  1.10  christos    the disassembler output.  */
     48  1.10  christos 
     49  1.10  christos static bool use_libopcodes_styling = true;
     50  1.10  christos 
     51  1.10  christos /* To support the set_use_libopcodes_styling function we have a second
     52  1.10  christos    variable which is connected to the actual set/show option.  */
     53  1.10  christos 
     54  1.10  christos static bool use_libopcodes_styling_option = use_libopcodes_styling;
     55  1.10  christos 
     56  1.10  christos /* The "maint show libopcodes-styling enabled" command.  */
     57  1.10  christos 
     58  1.10  christos static void
     59  1.10  christos show_use_libopcodes_styling  (struct ui_file *file, int from_tty,
     60  1.10  christos 			      struct cmd_list_element *c,
     61  1.10  christos 			      const char *value)
     62  1.10  christos {
     63  1.11  christos   gdbarch *arch = current_inferior ()->arch ();
     64  1.11  christos   gdb_non_printing_memory_disassembler dis (arch);
     65  1.10  christos   bool supported = dis.disasm_info ()->created_styled_output;
     66  1.10  christos 
     67  1.10  christos   if (supported || !use_libopcodes_styling)
     68  1.10  christos     gdb_printf (file, _("Use of libopcodes styling support is \"%s\".\n"),
     69  1.10  christos 		value);
     70  1.10  christos   else
     71  1.10  christos     {
     72  1.10  christos       /* Use of libopcodes styling is not supported, and the user has this
     73  1.10  christos 	 turned on!  */
     74  1.10  christos       gdb_printf (file, _("Use of libopcodes styling support is \"off\""
     75  1.10  christos 			  " (not supported on architecture \"%s\")\n"),
     76  1.11  christos 		  gdbarch_bfd_arch_info (arch)->printable_name);
     77  1.10  christos     }
     78  1.10  christos }
     79  1.10  christos 
     80  1.10  christos /* The "maint set libopcodes-styling enabled" command.  */
     81  1.10  christos 
     82  1.10  christos static void
     83  1.10  christos set_use_libopcodes_styling (const char *args, int from_tty,
     84  1.10  christos 			    struct cmd_list_element *c)
     85  1.10  christos {
     86  1.11  christos   gdbarch *arch = current_inferior ()->arch ();
     87  1.11  christos   gdb_non_printing_memory_disassembler dis (arch);
     88  1.10  christos   bool supported = dis.disasm_info ()->created_styled_output;
     89  1.10  christos 
     90  1.10  christos   /* If the current architecture doesn't support libopcodes styling then we
     91  1.10  christos      give an error here, but leave the underlying setting enabled.  This
     92  1.10  christos      means that if the user switches to an architecture that does support
     93  1.10  christos      libopcodes styling the setting will be enabled.  */
     94  1.10  christos 
     95  1.10  christos   if (use_libopcodes_styling_option && !supported)
     96  1.10  christos     {
     97  1.10  christos       use_libopcodes_styling_option = use_libopcodes_styling;
     98  1.10  christos       error (_("Use of libopcodes styling not supported on architecture \"%s\"."),
     99  1.11  christos 	     gdbarch_bfd_arch_info (arch)->printable_name);
    100  1.10  christos     }
    101  1.10  christos   else
    102  1.10  christos     use_libopcodes_styling = use_libopcodes_styling_option;
    103  1.10  christos }
    104   1.7  christos 
    105   1.6  christos /* This structure is used to store line number information for the
    106   1.6  christos    deprecated /m option.
    107   1.6  christos    We need a different sort of line table from the normal one cuz we can't
    108   1.6  christos    depend upon implicit line-end pc's for lines to do the
    109   1.6  christos    reordering in this function.  */
    110   1.6  christos 
    111   1.6  christos struct deprecated_dis_line_entry
    112   1.6  christos {
    113   1.6  christos   int line;
    114   1.6  christos   CORE_ADDR start_pc;
    115   1.6  christos   CORE_ADDR end_pc;
    116   1.6  christos };
    117   1.6  christos 
    118   1.1  christos /* This Structure is used to store line number information.
    119   1.1  christos    We need a different sort of line table from the normal one cuz we can't
    120   1.1  christos    depend upon implicit line-end pc's for lines to do the
    121   1.1  christos    reordering in this function.  */
    122   1.1  christos 
    123   1.1  christos struct dis_line_entry
    124   1.1  christos {
    125   1.6  christos   struct symtab *symtab;
    126   1.1  christos   int line;
    127   1.1  christos };
    128   1.1  christos 
    129   1.6  christos /* Hash function for dis_line_entry.  */
    130   1.6  christos 
    131   1.6  christos static hashval_t
    132   1.6  christos hash_dis_line_entry (const void *item)
    133   1.6  christos {
    134   1.6  christos   const struct dis_line_entry *dle = (const struct dis_line_entry *) item;
    135   1.6  christos 
    136   1.6  christos   return htab_hash_pointer (dle->symtab) + dle->line;
    137   1.6  christos }
    138   1.6  christos 
    139   1.6  christos /* Equal function for dis_line_entry.  */
    140   1.6  christos 
    141   1.6  christos static int
    142   1.6  christos eq_dis_line_entry (const void *item_lhs, const void *item_rhs)
    143   1.6  christos {
    144   1.6  christos   const struct dis_line_entry *lhs = (const struct dis_line_entry *) item_lhs;
    145   1.6  christos   const struct dis_line_entry *rhs = (const struct dis_line_entry *) item_rhs;
    146   1.6  christos 
    147   1.6  christos   return (lhs->symtab == rhs->symtab
    148   1.6  christos 	  && lhs->line == rhs->line);
    149   1.6  christos }
    150   1.6  christos 
    151   1.6  christos /* Create the table to manage lines for mixed source/disassembly.  */
    152   1.6  christos 
    153   1.6  christos static htab_t
    154   1.6  christos allocate_dis_line_table (void)
    155   1.6  christos {
    156   1.6  christos   return htab_create_alloc (41,
    157   1.6  christos 			    hash_dis_line_entry, eq_dis_line_entry,
    158   1.6  christos 			    xfree, xcalloc, xfree);
    159   1.6  christos }
    160   1.6  christos 
    161   1.6  christos /* Add a new dis_line_entry containing SYMTAB and LINE to TABLE.  */
    162   1.6  christos 
    163   1.6  christos static void
    164   1.6  christos add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
    165   1.6  christos {
    166   1.6  christos   void **slot;
    167   1.6  christos   struct dis_line_entry dle, *dlep;
    168   1.6  christos 
    169   1.6  christos   dle.symtab = symtab;
    170   1.6  christos   dle.line = line;
    171   1.6  christos   slot = htab_find_slot (table, &dle, INSERT);
    172   1.6  christos   if (*slot == NULL)
    173   1.6  christos     {
    174   1.6  christos       dlep = XNEW (struct dis_line_entry);
    175   1.6  christos       dlep->symtab = symtab;
    176   1.6  christos       dlep->line = line;
    177   1.6  christos       *slot = dlep;
    178   1.6  christos     }
    179   1.6  christos }
    180   1.6  christos 
    181   1.6  christos /* Return non-zero if SYMTAB, LINE are in TABLE.  */
    182   1.6  christos 
    183   1.6  christos static int
    184   1.6  christos line_has_code_p (htab_t table, struct symtab *symtab, int line)
    185   1.6  christos {
    186   1.6  christos   struct dis_line_entry dle;
    187   1.6  christos 
    188   1.6  christos   dle.symtab = symtab;
    189   1.6  christos   dle.line = line;
    190   1.6  christos   return htab_find (table, &dle) != NULL;
    191   1.6  christos }
    192   1.6  christos 
    193   1.7  christos /* Wrapper of target_read_code.  */
    194   1.7  christos 
    195   1.7  christos int
    196  1.10  christos gdb_disassembler_memory_reader::dis_asm_read_memory
    197  1.10  christos   (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
    198  1.10  christos    struct disassemble_info *info) noexcept
    199   1.1  christos {
    200   1.1  christos   return target_read_code (memaddr, myaddr, len);
    201   1.1  christos }
    202   1.1  christos 
    203   1.7  christos /* Wrapper of memory_error.  */
    204   1.7  christos 
    205   1.7  christos void
    206  1.10  christos gdb_disassembler::dis_asm_memory_error
    207  1.10  christos   (int err, bfd_vma memaddr, struct disassemble_info *info) noexcept
    208   1.1  christos {
    209   1.7  christos   gdb_disassembler *self
    210   1.7  christos     = static_cast<gdb_disassembler *>(info->application_data);
    211   1.7  christos 
    212  1.10  christos   self->m_err_memaddr.emplace (memaddr);
    213   1.1  christos }
    214   1.1  christos 
    215   1.7  christos /* Wrapper of print_address.  */
    216   1.7  christos 
    217   1.7  christos void
    218  1.10  christos gdb_disassembler::dis_asm_print_address
    219  1.10  christos   (bfd_vma addr, struct disassemble_info *info) noexcept
    220   1.1  christos {
    221   1.7  christos   gdb_disassembler *self
    222   1.7  christos     = static_cast<gdb_disassembler *>(info->application_data);
    223   1.1  christos 
    224  1.10  christos   if (self->in_comment_p ())
    225  1.10  christos     {
    226  1.10  christos       /* Calling 'print_address' might add styling to the output (based on
    227  1.10  christos 	 the properties of the stream we're writing too).  This is usually
    228  1.10  christos 	 fine, but if we are in an assembler comment then we'd prefer to
    229  1.10  christos 	 have the comment style, rather than the default address style.
    230  1.10  christos 
    231  1.10  christos 	 Print the address into a temporary buffer which doesn't support
    232  1.10  christos 	 styling, then reprint this unstyled address with the default text
    233  1.10  christos 	 style.
    234  1.10  christos 
    235  1.10  christos 	 As we are inside a comment right now, the standard print routine
    236  1.10  christos 	 will ensure that the comment is printed to the user with a
    237  1.10  christos 	 suitable comment style.  */
    238  1.10  christos       string_file tmp;
    239  1.10  christos       print_address (self->arch (), addr, &tmp);
    240  1.10  christos       self->fprintf_styled_func (self, dis_style_text, "%s", tmp.c_str ());
    241  1.10  christos     }
    242  1.10  christos   else
    243  1.10  christos     print_address (self->arch (), addr, self->stream ());
    244  1.10  christos }
    245  1.10  christos 
    246  1.10  christos /* See disasm.h.  */
    247  1.10  christos 
    248  1.10  christos ui_file *
    249  1.10  christos gdb_printing_disassembler::stream_from_gdb_disassemble_info (void *dis_info)
    250  1.10  christos {
    251  1.10  christos   gdb_disassemble_info *di = (gdb_disassemble_info *) dis_info;
    252  1.10  christos   gdb_printing_disassembler *dis
    253  1.10  christos     = gdb::checked_static_cast<gdb_printing_disassembler *> (di);
    254  1.10  christos   ui_file *stream = dis->stream ();
    255  1.10  christos   gdb_assert (stream != nullptr);
    256  1.10  christos   return stream;
    257  1.10  christos }
    258  1.10  christos 
    259  1.10  christos /* Format disassembler output to STREAM.  */
    260  1.10  christos 
    261  1.10  christos int
    262  1.10  christos gdb_printing_disassembler::fprintf_func (void *dis_info,
    263  1.10  christos 					 const char *format, ...) noexcept
    264  1.10  christos {
    265  1.10  christos   ui_file *stream = stream_from_gdb_disassemble_info (dis_info);
    266  1.10  christos 
    267  1.10  christos   va_list args;
    268  1.10  christos   va_start (args, format);
    269  1.10  christos   gdb_vprintf (stream, format, args);
    270  1.10  christos   va_end (args);
    271  1.10  christos 
    272  1.10  christos   /* Something non -ve.  */
    273  1.10  christos   return 0;
    274  1.10  christos }
    275  1.10  christos 
    276  1.10  christos /* See disasm.h.  */
    277  1.10  christos 
    278  1.10  christos int
    279  1.10  christos gdb_printing_disassembler::fprintf_styled_func
    280  1.10  christos   (void *dis_info, enum disassembler_style style,
    281  1.10  christos    const char *format, ...) noexcept
    282  1.10  christos {
    283  1.10  christos   ui_file *stream = stream_from_gdb_disassemble_info (dis_info);
    284  1.10  christos   gdb_printing_disassembler *dis = (gdb_printing_disassembler *) dis_info;
    285  1.10  christos 
    286  1.10  christos   va_list args;
    287  1.10  christos   va_start (args, format);
    288  1.10  christos   std::string content = string_vprintf (format, args);
    289  1.10  christos   va_end (args);
    290  1.10  christos 
    291  1.10  christos   /* Once in a comment then everything should be styled as a comment.  */
    292  1.10  christos   if (style == dis_style_comment_start)
    293  1.10  christos     dis->set_in_comment (true);
    294  1.10  christos   if (dis->in_comment_p ())
    295  1.10  christos     style = dis_style_comment_start;
    296  1.10  christos 
    297  1.10  christos   /* Now print the content with the correct style.  */
    298  1.10  christos   const char *txt = content.c_str ();
    299  1.10  christos   switch (style)
    300  1.10  christos     {
    301  1.10  christos     case dis_style_mnemonic:
    302  1.10  christos     case dis_style_sub_mnemonic:
    303  1.10  christos     case dis_style_assembler_directive:
    304  1.10  christos       fputs_styled (txt, disasm_mnemonic_style.style (), stream);
    305  1.10  christos       break;
    306  1.10  christos 
    307  1.10  christos     case dis_style_register:
    308  1.10  christos       fputs_styled (txt, disasm_register_style.style (), stream);
    309  1.10  christos       break;
    310  1.10  christos 
    311  1.10  christos     case dis_style_immediate:
    312  1.10  christos     case dis_style_address_offset:
    313  1.10  christos       fputs_styled (txt, disasm_immediate_style.style (), stream);
    314  1.10  christos       break;
    315  1.10  christos 
    316  1.10  christos     case dis_style_address:
    317  1.10  christos       fputs_styled (txt, address_style.style (), stream);
    318  1.10  christos       break;
    319  1.10  christos 
    320  1.10  christos     case dis_style_symbol:
    321  1.10  christos       fputs_styled (txt, function_name_style.style (), stream);
    322  1.10  christos       break;
    323  1.10  christos 
    324  1.10  christos     case dis_style_comment_start:
    325  1.10  christos       fputs_styled (txt, disasm_comment_style.style (), stream);
    326  1.10  christos       break;
    327  1.10  christos 
    328  1.10  christos     case dis_style_text:
    329  1.10  christos       gdb_puts (txt, stream);
    330  1.10  christos       break;
    331  1.10  christos     }
    332  1.10  christos 
    333  1.10  christos   /* Something non -ve.  */
    334  1.10  christos   return 0;
    335   1.1  christos }
    336   1.1  christos 
    337   1.9  christos static bool
    338   1.9  christos line_is_less_than (const deprecated_dis_line_entry &mle1,
    339   1.9  christos 		   const deprecated_dis_line_entry &mle2)
    340   1.1  christos {
    341   1.9  christos   bool val;
    342   1.1  christos 
    343   1.1  christos   /* End of sequence markers have a line number of 0 but don't want to
    344   1.1  christos      be sorted to the head of the list, instead sort by PC.  */
    345   1.9  christos   if (mle1.line == 0 || mle2.line == 0)
    346   1.1  christos     {
    347   1.9  christos       if (mle1.start_pc != mle2.start_pc)
    348   1.9  christos 	val = mle1.start_pc < mle2.start_pc;
    349  1.10  christos       else
    350  1.10  christos 	val = mle1.line < mle2.line;
    351   1.1  christos     }
    352   1.1  christos   else
    353   1.1  christos     {
    354   1.9  christos       if (mle1.line != mle2.line)
    355   1.9  christos 	val = mle1.line < mle2.line;
    356   1.9  christos       else
    357  1.10  christos 	val = mle1.start_pc < mle2.start_pc;
    358   1.1  christos     }
    359   1.1  christos   return val;
    360   1.1  christos }
    361   1.1  christos 
    362   1.6  christos /* See disasm.h.  */
    363   1.6  christos 
    364   1.6  christos int
    365   1.9  christos gdb_pretty_print_disassembler::pretty_print_insn (const struct disasm_insn *insn,
    366   1.8  christos 						  gdb_disassembly_flags flags)
    367   1.1  christos {
    368   1.1  christos   /* parts of the symbolic representation of the address */
    369   1.1  christos   int unmapped;
    370   1.1  christos   int offset;
    371   1.1  christos   int line;
    372   1.6  christos   int size;
    373   1.6  christos   CORE_ADDR pc;
    374   1.7  christos   struct gdbarch *gdbarch = arch ();
    375   1.6  christos 
    376   1.8  christos   {
    377   1.9  christos     ui_out_emit_tuple tuple_emitter (m_uiout, NULL);
    378   1.8  christos     pc = insn->addr;
    379   1.8  christos 
    380   1.8  christos     if (insn->number != 0)
    381   1.8  christos       {
    382   1.9  christos 	m_uiout->field_unsigned ("insn-number", insn->number);
    383   1.9  christos 	m_uiout->text ("\t");
    384   1.8  christos       }
    385   1.8  christos 
    386   1.8  christos     if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
    387   1.8  christos       {
    388   1.8  christos 	if (insn->is_speculative)
    389   1.8  christos 	  {
    390   1.9  christos 	    m_uiout->field_string ("is-speculative", "?");
    391   1.8  christos 
    392   1.8  christos 	    /* The speculative execution indication overwrites the first
    393   1.8  christos 	       character of the PC prefix.
    394   1.8  christos 	       We assume a PC prefix length of 3 characters.  */
    395   1.8  christos 	    if ((flags & DISASSEMBLY_OMIT_PC) == 0)
    396   1.9  christos 	      m_uiout->text (pc_prefix (pc) + 1);
    397   1.8  christos 	    else
    398   1.9  christos 	      m_uiout->text ("  ");
    399   1.8  christos 	  }
    400   1.8  christos 	else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
    401   1.9  christos 	  m_uiout->text (pc_prefix (pc));
    402   1.8  christos 	else
    403   1.9  christos 	  m_uiout->text ("   ");
    404   1.8  christos       }
    405   1.8  christos     else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
    406   1.9  christos       m_uiout->text (pc_prefix (pc));
    407   1.9  christos     m_uiout->field_core_addr ("address", gdbarch, pc);
    408   1.8  christos 
    409   1.8  christos     std::string name, filename;
    410   1.9  christos     bool omit_fname = ((flags & DISASSEMBLY_OMIT_FNAME) != 0);
    411   1.9  christos     if (!build_address_symbolic (gdbarch, pc, false, omit_fname, &name,
    412  1.10  christos 				 &offset, &filename, &line, &unmapped))
    413   1.8  christos       {
    414   1.8  christos 	/* We don't care now about line, filename and unmapped.  But we might in
    415   1.8  christos 	   the future.  */
    416   1.9  christos 	m_uiout->text (" <");
    417   1.9  christos 	if (!omit_fname)
    418  1.10  christos 	  m_uiout->field_string ("func-name", name,
    419   1.9  christos 				 function_name_style.style ());
    420   1.9  christos 	/* For negative offsets, avoid displaying them as +-N; the sign of
    421   1.9  christos 	   the offset takes the place of the "+" here.  */
    422   1.9  christos 	if (offset >= 0)
    423   1.9  christos 	  m_uiout->text ("+");
    424   1.9  christos 	m_uiout->field_signed ("offset", offset);
    425   1.9  christos 	m_uiout->text (">:\t");
    426   1.8  christos       }
    427   1.8  christos     else
    428   1.9  christos       m_uiout->text (":\t");
    429   1.8  christos 
    430  1.10  christos     /* Clear the buffer into which we will disassemble the instruction.  */
    431   1.8  christos     m_insn_stb.clear ();
    432   1.8  christos 
    433  1.10  christos     /* A helper function to write the M_INSN_STB buffer, followed by a
    434  1.10  christos        newline.  This can be called in a couple of situations.  */
    435  1.10  christos     auto write_out_insn_buffer = [&] ()
    436  1.10  christos     {
    437  1.10  christos       m_uiout->field_stream ("inst", m_insn_stb);
    438  1.10  christos       m_uiout->text ("\n");
    439  1.10  christos     };
    440  1.10  christos 
    441  1.10  christos     try
    442  1.10  christos       {
    443  1.10  christos 	/* Now we can disassemble the instruction.  If the disassembler
    444  1.10  christos 	   returns a negative value this indicates an error and is handled
    445  1.10  christos 	   within the print_insn call, resulting in an exception being
    446  1.10  christos 	   thrown.  Returning zero makes no sense, as this indicates we
    447  1.10  christos 	   disassembled something successfully, but it was something of no
    448  1.10  christos 	   size?  */
    449  1.10  christos 	size = m_di.print_insn (pc);
    450  1.10  christos 	gdb_assert (size > 0);
    451  1.10  christos       }
    452  1.10  christos     catch (const gdb_exception &)
    453   1.8  christos       {
    454  1.10  christos 	/* An exception was thrown while disassembling the instruction.
    455  1.10  christos 	   However, the disassembler might still have written something
    456  1.10  christos 	   out, so ensure that we flush the instruction buffer before
    457  1.10  christos 	   rethrowing the exception.  We can't perform this write from an
    458  1.10  christos 	   object destructor as the write itself might throw an exception
    459  1.10  christos 	   if the pager kicks in, and the user selects quit.  */
    460  1.10  christos 	write_out_insn_buffer ();
    461  1.10  christos 	throw;
    462  1.10  christos       }
    463   1.8  christos 
    464  1.10  christos     if ((flags & (DISASSEMBLY_RAW_INSN | DISASSEMBLY_RAW_BYTES)) != 0)
    465  1.10  christos       {
    466   1.8  christos 	/* Build the opcodes using a temporary stream so we can
    467   1.8  christos 	   write them out in a single go for the MI.  */
    468   1.8  christos 	m_opcode_stb.clear ();
    469   1.8  christos 
    470  1.10  christos 	/* Read the instruction opcode data.  */
    471  1.10  christos 	m_opcode_data.resize (size);
    472  1.10  christos 	read_code (pc, m_opcode_data.data (), size);
    473  1.10  christos 
    474  1.10  christos 	/* The disassembler provides information about the best way to
    475  1.10  christos 	   display the instruction bytes to the user.  We provide some sane
    476  1.10  christos 	   defaults in case the disassembler gets it wrong.  */
    477  1.10  christos 	const struct disassemble_info *di = m_di.disasm_info ();
    478  1.10  christos 	int bytes_per_line = std::max (di->bytes_per_line, size);
    479  1.10  christos 	int bytes_per_chunk = std::max (di->bytes_per_chunk, 1);
    480  1.10  christos 
    481  1.10  christos 	/* If the user has requested the instruction bytes be displayed
    482  1.10  christos 	   byte at a time, then handle that here.  Also, if the instruction
    483  1.10  christos 	   is not a multiple of the chunk size (which probably indicates a
    484  1.10  christos 	   disassembler problem) then avoid that causing display problems
    485  1.10  christos 	   by switching to byte at a time mode.  */
    486  1.10  christos 	if ((flags & DISASSEMBLY_RAW_BYTES) != 0
    487  1.10  christos 	    || (size % bytes_per_chunk) != 0)
    488  1.10  christos 	  bytes_per_chunk = 1;
    489  1.10  christos 
    490  1.10  christos 	/* Print the instruction opcodes bytes, grouped into chunks.  */
    491  1.10  christos 	for (int i = 0; i < size; i += bytes_per_chunk)
    492  1.10  christos 	  {
    493  1.10  christos 	    if (i > 0)
    494  1.10  christos 	      m_opcode_stb.puts (" ");
    495  1.10  christos 
    496  1.10  christos 	    if (di->display_endian == BFD_ENDIAN_LITTLE)
    497  1.10  christos 	      {
    498  1.10  christos 		for (int k = bytes_per_chunk; k-- != 0; )
    499  1.10  christos 		  m_opcode_stb.printf ("%02x", (unsigned) m_opcode_data[i + k]);
    500  1.10  christos 	      }
    501  1.10  christos 	    else
    502  1.10  christos 	      {
    503  1.10  christos 		for (int k = 0; k < bytes_per_chunk; k++)
    504  1.10  christos 		  m_opcode_stb.printf ("%02x", (unsigned) m_opcode_data[i + k]);
    505  1.10  christos 	      }
    506  1.10  christos 	  }
    507   1.8  christos 
    508  1.10  christos 	/* Calculate required padding.  */
    509  1.10  christos 	int nspaces = 0;
    510  1.10  christos 	for (int i = size; i < bytes_per_line; i += bytes_per_chunk)
    511   1.8  christos 	  {
    512  1.10  christos 	    if (i > size)
    513  1.10  christos 	      nspaces++;
    514  1.10  christos 	    nspaces += bytes_per_chunk * 2;
    515   1.8  christos 	  }
    516   1.8  christos 
    517   1.9  christos 	m_uiout->field_stream ("opcodes", m_opcode_stb);
    518  1.10  christos 	m_uiout->spaces (nspaces);
    519   1.9  christos 	m_uiout->text ("\t");
    520   1.8  christos       }
    521   1.6  christos 
    522  1.10  christos     /* Disassembly was a success, write out the instruction buffer.  */
    523  1.10  christos     write_out_insn_buffer ();
    524   1.8  christos   }
    525   1.6  christos 
    526   1.6  christos   return size;
    527   1.6  christos }
    528   1.6  christos 
    529   1.6  christos static int
    530   1.7  christos dump_insns (struct gdbarch *gdbarch,
    531   1.7  christos 	    struct ui_out *uiout, CORE_ADDR low, CORE_ADDR high,
    532   1.8  christos 	    int how_many, gdb_disassembly_flags flags, CORE_ADDR *end_pc)
    533   1.6  christos {
    534   1.6  christos   struct disasm_insn insn;
    535   1.6  christos   int num_displayed = 0;
    536   1.6  christos 
    537   1.6  christos   memset (&insn, 0, sizeof (insn));
    538   1.6  christos   insn.addr = low;
    539   1.6  christos 
    540   1.9  christos   gdb_pretty_print_disassembler disasm (gdbarch, uiout);
    541   1.7  christos 
    542   1.6  christos   while (insn.addr < high && (how_many < 0 || num_displayed < how_many))
    543   1.6  christos     {
    544   1.6  christos       int size;
    545   1.6  christos 
    546   1.9  christos       size = disasm.pretty_print_insn (&insn, flags);
    547   1.6  christos       if (size <= 0)
    548   1.6  christos 	break;
    549   1.6  christos 
    550   1.6  christos       ++num_displayed;
    551   1.6  christos       insn.addr += size;
    552   1.1  christos 
    553   1.6  christos       /* Allow user to bail out with ^C.  */
    554   1.6  christos       QUIT;
    555   1.1  christos     }
    556   1.6  christos 
    557   1.6  christos   if (end_pc != NULL)
    558   1.6  christos     *end_pc = insn.addr;
    559   1.6  christos 
    560   1.1  christos   return num_displayed;
    561   1.1  christos }
    562   1.1  christos 
    563   1.1  christos /* The idea here is to present a source-O-centric view of a
    564   1.1  christos    function to the user.  This means that things are presented
    565   1.1  christos    in source order, with (possibly) out of order assembly
    566   1.6  christos    immediately following.
    567   1.6  christos 
    568   1.6  christos    N.B. This view is deprecated.  */
    569   1.1  christos 
    570   1.1  christos static void
    571   1.6  christos do_mixed_source_and_assembly_deprecated
    572   1.6  christos   (struct gdbarch *gdbarch, struct ui_out *uiout,
    573   1.7  christos    struct symtab *symtab,
    574   1.6  christos    CORE_ADDR low, CORE_ADDR high,
    575   1.8  christos    int how_many, gdb_disassembly_flags flags)
    576   1.1  christos {
    577   1.1  christos   int newlines = 0;
    578   1.6  christos   int nlines;
    579  1.11  christos   const struct linetable_entry *le;
    580   1.6  christos   struct deprecated_dis_line_entry *mle;
    581   1.1  christos   struct symtab_and_line sal;
    582   1.1  christos   int i;
    583   1.1  christos   int out_of_order = 0;
    584   1.1  christos   int next_line = 0;
    585   1.1  christos   int num_displayed = 0;
    586   1.6  christos   print_source_lines_flags psl_flags = 0;
    587   1.1  christos 
    588  1.10  christos   gdb_assert (symtab != nullptr && symtab->linetable () != nullptr);
    589   1.6  christos 
    590  1.10  christos   nlines = symtab->linetable ()->nitems;
    591  1.10  christos   le = symtab->linetable ()->item;
    592   1.6  christos 
    593   1.1  christos   if (flags & DISASSEMBLY_FILENAME)
    594   1.1  christos     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
    595   1.1  christos 
    596   1.6  christos   mle = (struct deprecated_dis_line_entry *)
    597   1.6  christos     alloca (nlines * sizeof (struct deprecated_dis_line_entry));
    598   1.1  christos 
    599  1.11  christos   struct objfile *objfile = symtab->compunit ()->objfile ();
    600  1.11  christos 
    601  1.11  christos   unrelocated_addr unrel_low
    602  1.11  christos     = unrelocated_addr (low - objfile->text_section_offset ());
    603  1.11  christos   unrelocated_addr unrel_high
    604  1.11  christos     = unrelocated_addr (high - objfile->text_section_offset ());
    605  1.11  christos 
    606   1.1  christos   /* Copy linetable entries for this function into our data
    607   1.1  christos      structure, creating end_pc's and setting out_of_order as
    608   1.1  christos      appropriate.  */
    609   1.1  christos 
    610   1.1  christos   /* First, skip all the preceding functions.  */
    611   1.1  christos 
    612  1.11  christos   for (i = 0; i < nlines - 1 && le[i].unrelocated_pc () < unrel_low; i++);
    613   1.1  christos 
    614   1.1  christos   /* Now, copy all entries before the end of this function.  */
    615   1.1  christos 
    616  1.11  christos   for (; i < nlines - 1 && le[i].unrelocated_pc () < unrel_high; i++)
    617   1.1  christos     {
    618  1.11  christos       if (le[i] == le[i + 1])
    619   1.1  christos 	continue;		/* Ignore duplicates.  */
    620   1.1  christos 
    621   1.1  christos       /* Skip any end-of-function markers.  */
    622   1.1  christos       if (le[i].line == 0)
    623   1.1  christos 	continue;
    624   1.1  christos 
    625   1.1  christos       mle[newlines].line = le[i].line;
    626   1.1  christos       if (le[i].line > le[i + 1].line)
    627   1.1  christos 	out_of_order = 1;
    628  1.11  christos       mle[newlines].start_pc = le[i].pc (objfile);
    629  1.11  christos       mle[newlines].end_pc = le[i + 1].pc (objfile);
    630   1.1  christos       newlines++;
    631   1.1  christos     }
    632   1.1  christos 
    633   1.1  christos   /* If we're on the last line, and it's part of the function,
    634   1.1  christos      then we need to get the end pc in a special way.  */
    635   1.1  christos 
    636  1.11  christos   if (i == nlines - 1 && le[i].unrelocated_pc () < unrel_high)
    637   1.1  christos     {
    638   1.1  christos       mle[newlines].line = le[i].line;
    639  1.11  christos       mle[newlines].start_pc = le[i].pc (objfile);
    640  1.11  christos       sal = find_pc_line (le[i].pc (objfile), 0);
    641   1.1  christos       mle[newlines].end_pc = sal.end;
    642   1.1  christos       newlines++;
    643   1.1  christos     }
    644   1.1  christos 
    645   1.6  christos   /* Now, sort mle by line #s (and, then by addresses within lines).  */
    646   1.1  christos 
    647   1.1  christos   if (out_of_order)
    648   1.9  christos     std::sort (mle, mle + newlines, line_is_less_than);
    649   1.1  christos 
    650   1.1  christos   /* Now, for each line entry, emit the specified lines (unless
    651   1.1  christos      they have been emitted before), followed by the assembly code
    652   1.1  christos      for that line.  */
    653   1.1  christos 
    654   1.8  christos   ui_out_emit_list asm_insns_list (uiout, "asm_insns");
    655   1.8  christos 
    656  1.11  christos   std::optional<ui_out_emit_tuple> outer_tuple_emitter;
    657  1.11  christos   std::optional<ui_out_emit_list> inner_list_emitter;
    658   1.1  christos 
    659   1.1  christos   for (i = 0; i < newlines; i++)
    660   1.1  christos     {
    661   1.1  christos       /* Print out everything from next_line to the current line.  */
    662   1.1  christos       if (mle[i].line >= next_line)
    663   1.1  christos 	{
    664   1.1  christos 	  if (next_line != 0)
    665   1.1  christos 	    {
    666   1.1  christos 	      /* Just one line to print.  */
    667   1.1  christos 	      if (next_line == mle[i].line)
    668   1.1  christos 		{
    669   1.8  christos 		  outer_tuple_emitter.emplace (uiout, "src_and_asm_line");
    670   1.1  christos 		  print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
    671   1.1  christos 		}
    672   1.1  christos 	      else
    673   1.1  christos 		{
    674   1.1  christos 		  /* Several source lines w/o asm instructions associated.  */
    675   1.1  christos 		  for (; next_line < mle[i].line; next_line++)
    676   1.1  christos 		    {
    677   1.8  christos 		      ui_out_emit_tuple tuple_emitter (uiout,
    678   1.8  christos 						       "src_and_asm_line");
    679   1.1  christos 		      print_source_lines (symtab, next_line, next_line + 1,
    680   1.1  christos 					  psl_flags);
    681   1.8  christos 		      ui_out_emit_list temp_list_emitter (uiout,
    682   1.8  christos 							  "line_asm_insn");
    683   1.1  christos 		    }
    684   1.1  christos 		  /* Print the last line and leave list open for
    685   1.1  christos 		     asm instructions to be added.  */
    686   1.8  christos 		  outer_tuple_emitter.emplace (uiout, "src_and_asm_line");
    687   1.1  christos 		  print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
    688   1.1  christos 		}
    689   1.1  christos 	    }
    690   1.1  christos 	  else
    691   1.1  christos 	    {
    692   1.8  christos 	      outer_tuple_emitter.emplace (uiout, "src_and_asm_line");
    693   1.1  christos 	      print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
    694   1.1  christos 	    }
    695   1.1  christos 
    696   1.1  christos 	  next_line = mle[i].line + 1;
    697   1.8  christos 	  inner_list_emitter.emplace (uiout, "line_asm_insn");
    698   1.1  christos 	}
    699   1.1  christos 
    700   1.7  christos       num_displayed += dump_insns (gdbarch, uiout,
    701   1.1  christos 				   mle[i].start_pc, mle[i].end_pc,
    702   1.7  christos 				   how_many, flags, NULL);
    703   1.1  christos 
    704   1.1  christos       /* When we've reached the end of the mle array, or we've seen the last
    705  1.10  christos 	 assembly range for this source line, close out the list/tuple.  */
    706   1.1  christos       if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
    707   1.1  christos 	{
    708   1.8  christos 	  inner_list_emitter.reset ();
    709   1.8  christos 	  outer_tuple_emitter.reset ();
    710   1.7  christos 	  uiout->text ("\n");
    711   1.1  christos 	}
    712   1.1  christos       if (how_many >= 0 && num_displayed >= how_many)
    713   1.1  christos 	break;
    714   1.1  christos     }
    715   1.1  christos }
    716   1.1  christos 
    717   1.6  christos /* The idea here is to present a source-O-centric view of a
    718   1.6  christos    function to the user.  This means that things are presented
    719   1.6  christos    in source order, with (possibly) out of order assembly
    720   1.6  christos    immediately following.  */
    721   1.6  christos 
    722   1.6  christos static void
    723   1.7  christos do_mixed_source_and_assembly (struct gdbarch *gdbarch,
    724   1.7  christos 			      struct ui_out *uiout,
    725   1.6  christos 			      struct symtab *main_symtab,
    726   1.6  christos 			      CORE_ADDR low, CORE_ADDR high,
    727   1.8  christos 			      int how_many, gdb_disassembly_flags flags)
    728   1.6  christos {
    729   1.6  christos   const struct linetable_entry *le, *first_le;
    730   1.6  christos   int i, nlines;
    731   1.6  christos   int num_displayed = 0;
    732   1.6  christos   print_source_lines_flags psl_flags = 0;
    733   1.6  christos   CORE_ADDR pc;
    734   1.6  christos   struct symtab *last_symtab;
    735   1.6  christos   int last_line;
    736   1.6  christos 
    737  1.10  christos   gdb_assert (main_symtab != NULL && main_symtab->linetable () != NULL);
    738   1.6  christos 
    739   1.6  christos   /* First pass: collect the list of all source files and lines.
    740   1.6  christos      We do this so that we can only print lines containing code once.
    741   1.6  christos      We try to print the source text leading up to the next instruction,
    742   1.6  christos      but if that text is for code that will be disassembled later, then
    743   1.6  christos      we'll want to defer printing it until later with its associated code.  */
    744   1.6  christos 
    745   1.7  christos   htab_up dis_line_table (allocate_dis_line_table ());
    746   1.6  christos 
    747  1.11  christos   struct objfile *objfile = main_symtab->compunit ()->objfile ();
    748  1.11  christos 
    749  1.11  christos   unrelocated_addr unrel_low
    750  1.11  christos     = unrelocated_addr (low - objfile->text_section_offset ());
    751  1.11  christos   unrelocated_addr unrel_high
    752  1.11  christos     = unrelocated_addr (high - objfile->text_section_offset ());
    753  1.11  christos 
    754   1.6  christos   pc = low;
    755   1.6  christos 
    756   1.6  christos   /* The prologue may be empty, but there may still be a line number entry
    757   1.6  christos      for the opening brace which is distinct from the first line of code.
    758   1.6  christos      If the prologue has been eliminated find_pc_line may return the source
    759   1.6  christos      line after the opening brace.  We still want to print this opening brace.
    760   1.6  christos      first_le is used to implement this.  */
    761   1.6  christos 
    762  1.10  christos   nlines = main_symtab->linetable ()->nitems;
    763  1.10  christos   le = main_symtab->linetable ()->item;
    764   1.6  christos   first_le = NULL;
    765   1.6  christos 
    766   1.6  christos   /* Skip all the preceding functions.  */
    767  1.11  christos   for (i = 0; i < nlines && le[i].unrelocated_pc () < unrel_low; i++)
    768   1.6  christos     continue;
    769   1.6  christos 
    770  1.11  christos   if (i < nlines && le[i].unrelocated_pc () < unrel_high)
    771   1.6  christos     first_le = &le[i];
    772   1.6  christos 
    773   1.6  christos   /* Add lines for every pc value.  */
    774   1.6  christos   while (pc < high)
    775   1.6  christos     {
    776   1.6  christos       struct symtab_and_line sal;
    777   1.6  christos       int length;
    778   1.6  christos 
    779   1.6  christos       sal = find_pc_line (pc, 0);
    780   1.6  christos       length = gdb_insn_length (gdbarch, pc);
    781   1.6  christos       pc += length;
    782   1.6  christos 
    783   1.6  christos       if (sal.symtab != NULL)
    784   1.7  christos 	add_dis_line_entry (dis_line_table.get (), sal.symtab, sal.line);
    785   1.6  christos     }
    786   1.6  christos 
    787   1.6  christos   /* Second pass: print the disassembly.
    788   1.6  christos 
    789   1.6  christos      Output format, from an MI perspective:
    790   1.6  christos        The result is a ui_out list, field name "asm_insns", where elements have
    791   1.6  christos        name "src_and_asm_line".
    792   1.6  christos        Each element is a tuple of source line specs (field names line, file,
    793   1.6  christos        fullname), and field "line_asm_insn" which contains the disassembly.
    794   1.6  christos        Field "line_asm_insn" is a list of tuples: address, func-name, offset,
    795   1.6  christos        opcodes, inst.
    796   1.6  christos 
    797   1.6  christos      CLI output works on top of this because MI ignores ui_out_text output,
    798   1.6  christos      which is where we put file name and source line contents output.
    799   1.6  christos 
    800   1.8  christos      Emitter usage:
    801   1.8  christos      asm_insns_emitter
    802   1.6  christos        Handles the outer "asm_insns" list.
    803   1.8  christos      tuple_emitter
    804   1.6  christos        The tuples for each group of consecutive disassemblies.
    805   1.8  christos      list_emitter
    806   1.6  christos        List of consecutive source lines or disassembled insns.  */
    807   1.6  christos 
    808   1.6  christos   if (flags & DISASSEMBLY_FILENAME)
    809   1.6  christos     psl_flags |= PRINT_SOURCE_LINES_FILENAME;
    810   1.6  christos 
    811   1.8  christos   ui_out_emit_list asm_insns_emitter (uiout, "asm_insns");
    812   1.6  christos 
    813  1.11  christos   std::optional<ui_out_emit_tuple> tuple_emitter;
    814  1.11  christos   std::optional<ui_out_emit_list> list_emitter;
    815   1.6  christos 
    816   1.6  christos   last_symtab = NULL;
    817   1.6  christos   last_line = 0;
    818   1.6  christos   pc = low;
    819   1.6  christos 
    820   1.6  christos   while (pc < high)
    821   1.6  christos     {
    822   1.6  christos       struct symtab_and_line sal;
    823   1.6  christos       CORE_ADDR end_pc;
    824   1.6  christos       int start_preceding_line_to_display = 0;
    825   1.6  christos       int end_preceding_line_to_display = 0;
    826   1.6  christos       int new_source_line = 0;
    827   1.6  christos 
    828   1.6  christos       sal = find_pc_line (pc, 0);
    829   1.6  christos 
    830   1.6  christos       if (sal.symtab != last_symtab)
    831   1.6  christos 	{
    832   1.6  christos 	  /* New source file.  */
    833   1.6  christos 	  new_source_line = 1;
    834   1.6  christos 
    835   1.6  christos 	  /* If this is the first line of output, check for any preceding
    836   1.6  christos 	     lines.  */
    837   1.6  christos 	  if (last_line == 0
    838   1.6  christos 	      && first_le != NULL
    839   1.6  christos 	      && first_le->line < sal.line)
    840   1.6  christos 	    {
    841   1.6  christos 	      start_preceding_line_to_display = first_le->line;
    842   1.6  christos 	      end_preceding_line_to_display = sal.line;
    843   1.6  christos 	    }
    844   1.6  christos 	}
    845   1.6  christos       else
    846   1.6  christos 	{
    847   1.6  christos 	  /* Same source file as last time.  */
    848   1.6  christos 	  if (sal.symtab != NULL)
    849   1.6  christos 	    {
    850   1.6  christos 	      if (sal.line > last_line + 1 && last_line != 0)
    851   1.6  christos 		{
    852   1.6  christos 		  int l;
    853   1.6  christos 
    854   1.6  christos 		  /* Several preceding source lines.  Print the trailing ones
    855   1.6  christos 		     not associated with code that we'll print later.  */
    856   1.6  christos 		  for (l = sal.line - 1; l > last_line; --l)
    857   1.6  christos 		    {
    858   1.7  christos 		      if (line_has_code_p (dis_line_table.get (),
    859   1.7  christos 					   sal.symtab, l))
    860   1.6  christos 			break;
    861   1.6  christos 		    }
    862   1.6  christos 		  if (l < sal.line - 1)
    863   1.6  christos 		    {
    864   1.6  christos 		      start_preceding_line_to_display = l + 1;
    865   1.6  christos 		      end_preceding_line_to_display = sal.line;
    866   1.6  christos 		    }
    867   1.6  christos 		}
    868   1.6  christos 	      if (sal.line != last_line)
    869   1.6  christos 		new_source_line = 1;
    870   1.6  christos 	      else
    871   1.6  christos 		{
    872   1.6  christos 		  /* Same source line as last time.  This can happen, depending
    873   1.6  christos 		     on the debug info.  */
    874   1.6  christos 		}
    875   1.6  christos 	    }
    876   1.6  christos 	}
    877   1.6  christos 
    878   1.6  christos       if (new_source_line)
    879   1.6  christos 	{
    880   1.6  christos 	  /* Skip the newline if this is the first instruction.  */
    881   1.6  christos 	  if (pc > low)
    882   1.7  christos 	    uiout->text ("\n");
    883   1.8  christos 	  if (tuple_emitter.has_value ())
    884   1.6  christos 	    {
    885   1.8  christos 	      gdb_assert (list_emitter.has_value ());
    886   1.8  christos 	      list_emitter.reset ();
    887   1.8  christos 	      tuple_emitter.reset ();
    888   1.6  christos 	    }
    889   1.6  christos 	  if (sal.symtab != last_symtab
    890   1.6  christos 	      && !(flags & DISASSEMBLY_FILENAME))
    891   1.6  christos 	    {
    892   1.6  christos 	      /* Remember MI ignores ui_out_text.
    893   1.6  christos 		 We don't have to do anything here for MI because MI
    894   1.6  christos 		 output includes the source specs for each line.  */
    895   1.6  christos 	      if (sal.symtab != NULL)
    896   1.6  christos 		{
    897   1.7  christos 		  uiout->text (symtab_to_filename_for_display (sal.symtab));
    898   1.6  christos 		}
    899   1.6  christos 	      else
    900   1.7  christos 		uiout->text ("unknown");
    901   1.7  christos 	      uiout->text (":\n");
    902   1.6  christos 	    }
    903   1.6  christos 	  if (start_preceding_line_to_display > 0)
    904   1.6  christos 	    {
    905   1.6  christos 	      /* Several source lines w/o asm instructions associated.
    906   1.6  christos 		 We need to preserve the structure of the output, so output
    907   1.6  christos 		 a bunch of line tuples with no asm entries.  */
    908   1.6  christos 	      int l;
    909   1.6  christos 
    910   1.6  christos 	      gdb_assert (sal.symtab != NULL);
    911   1.6  christos 	      for (l = start_preceding_line_to_display;
    912   1.6  christos 		   l < end_preceding_line_to_display;
    913   1.6  christos 		   ++l)
    914   1.6  christos 		{
    915   1.8  christos 		  ui_out_emit_tuple line_tuple_emitter (uiout,
    916   1.8  christos 							"src_and_asm_line");
    917   1.6  christos 		  print_source_lines (sal.symtab, l, l + 1, psl_flags);
    918   1.8  christos 		  ui_out_emit_list chain_line_emitter (uiout, "line_asm_insn");
    919   1.6  christos 		}
    920   1.6  christos 	    }
    921   1.8  christos 	  tuple_emitter.emplace (uiout, "src_and_asm_line");
    922   1.6  christos 	  if (sal.symtab != NULL)
    923   1.6  christos 	    print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
    924   1.6  christos 	  else
    925   1.7  christos 	    uiout->text (_("--- no source info for this pc ---\n"));
    926   1.8  christos 	  list_emitter.emplace (uiout, "line_asm_insn");
    927   1.6  christos 	}
    928   1.6  christos       else
    929   1.6  christos 	{
    930   1.6  christos 	  /* Here we're appending instructions to an existing line.
    931   1.6  christos 	     By construction the very first insn will have a symtab
    932   1.6  christos 	     and follow the new_source_line path above.  */
    933   1.8  christos 	  gdb_assert (tuple_emitter.has_value ());
    934   1.8  christos 	  gdb_assert (list_emitter.has_value ());
    935   1.6  christos 	}
    936   1.6  christos 
    937   1.6  christos       if (sal.end != 0)
    938   1.7  christos 	end_pc = std::min (sal.end, high);
    939   1.6  christos       else
    940   1.6  christos 	end_pc = pc + 1;
    941   1.7  christos       num_displayed += dump_insns (gdbarch, uiout, pc, end_pc,
    942   1.7  christos 				   how_many, flags, &end_pc);
    943   1.6  christos       pc = end_pc;
    944   1.6  christos 
    945   1.6  christos       if (how_many >= 0 && num_displayed >= how_many)
    946   1.6  christos 	break;
    947   1.6  christos 
    948   1.6  christos       last_symtab = sal.symtab;
    949   1.6  christos       last_line = sal.line;
    950   1.6  christos     }
    951   1.6  christos }
    952   1.1  christos 
    953   1.1  christos static void
    954   1.1  christos do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
    955   1.1  christos 		  CORE_ADDR low, CORE_ADDR high,
    956   1.8  christos 		  int how_many, gdb_disassembly_flags flags)
    957   1.1  christos {
    958   1.8  christos   ui_out_emit_list list_emitter (uiout, "asm_insns");
    959   1.1  christos 
    960   1.7  christos   dump_insns (gdbarch, uiout, low, high, how_many, flags, NULL);
    961   1.1  christos }
    962   1.1  christos 
    963   1.8  christos /* Combine implicit and user disassembler options and return them
    964   1.8  christos    in a newly-created string.  */
    965   1.8  christos 
    966   1.8  christos static std::string
    967   1.8  christos get_all_disassembler_options (struct gdbarch *gdbarch)
    968   1.8  christos {
    969   1.8  christos   const char *implicit = gdbarch_disassembler_options_implicit (gdbarch);
    970   1.8  christos   const char *options = get_disassembler_options (gdbarch);
    971   1.8  christos   const char *comma = ",";
    972   1.8  christos 
    973   1.8  christos   if (implicit == nullptr)
    974   1.8  christos     {
    975   1.8  christos       implicit = "";
    976   1.8  christos       comma = "";
    977   1.8  christos     }
    978   1.8  christos 
    979   1.8  christos   if (options == nullptr)
    980   1.8  christos     {
    981   1.8  christos       options = "";
    982   1.8  christos       comma = "";
    983   1.8  christos     }
    984   1.8  christos 
    985   1.8  christos   return string_printf ("%s%s%s", implicit, comma, options);
    986   1.8  christos }
    987   1.8  christos 
    988   1.7  christos gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch,
    989   1.7  christos 				    struct ui_file *file,
    990  1.10  christos 				    read_memory_ftype func)
    991  1.10  christos   : gdb_printing_disassembler (gdbarch, &m_buffer, func,
    992  1.10  christos 			       dis_asm_memory_error, dis_asm_print_address),
    993  1.10  christos     m_dest (file),
    994  1.10  christos     m_buffer (!use_ext_lang_for_styling () && use_libopcodes_for_styling ())
    995  1.10  christos { /* Nothing.  */ }
    996  1.10  christos 
    997  1.10  christos /* See disasm.h.  */
    998  1.10  christos 
    999  1.10  christos bool
   1000  1.10  christos gdb_disassembler::use_ext_lang_for_styling () const
   1001   1.7  christos {
   1002  1.10  christos   /* The use of m_di.created_styled_output here is a bit of a cheat, but
   1003  1.10  christos      it works fine for now.
   1004  1.10  christos 
   1005  1.10  christos      This function is called in situations after m_di has been initialized,
   1006  1.10  christos      but before the instruction has been disassembled.
   1007  1.10  christos 
   1008  1.10  christos      Currently, every target that supports libopcodes styling sets the
   1009  1.10  christos      created_styled_output field in disassemble_init_for_target, which was
   1010  1.10  christos      called as part of the initialization of gdb_printing_disassembler.
   1011  1.10  christos 
   1012  1.10  christos      This means that we are OK to check the created_styled_output field
   1013  1.10  christos      here.
   1014  1.10  christos 
   1015  1.10  christos      If, in the future, there's ever a target that only sets the
   1016  1.10  christos      created_styled_output field during the actual instruction disassembly
   1017  1.10  christos      phase, then we will need to update this code.  */
   1018  1.10  christos   return (disassembler_styling
   1019  1.10  christos 	  && (!m_di.created_styled_output || !use_libopcodes_styling)
   1020  1.10  christos 	  && use_ext_lang_colorization_p
   1021  1.10  christos 	  && m_dest->can_emit_style_escape ());
   1022  1.10  christos }
   1023  1.10  christos 
   1024  1.10  christos /* See disasm.h.  */
   1025  1.10  christos 
   1026  1.10  christos bool
   1027  1.10  christos gdb_disassembler::use_libopcodes_for_styling () const
   1028  1.10  christos {
   1029  1.10  christos   /* See the comment on the use of m_di.created_styled_output in the
   1030  1.10  christos      gdb_disassembler::use_ext_lang_for_styling function.  */
   1031  1.10  christos   return (disassembler_styling
   1032  1.10  christos 	  && m_di.created_styled_output
   1033  1.10  christos 	  && use_libopcodes_styling
   1034  1.10  christos 	  && m_dest->can_emit_style_escape ());
   1035  1.10  christos }
   1036  1.10  christos 
   1037  1.10  christos /* See disasm.h.  */
   1038  1.10  christos 
   1039  1.10  christos gdb_disassemble_info::gdb_disassemble_info
   1040  1.10  christos   (struct gdbarch *gdbarch,
   1041  1.10  christos    read_memory_ftype read_memory_func, memory_error_ftype memory_error_func,
   1042  1.10  christos    print_address_ftype print_address_func, fprintf_ftype fprintf_func,
   1043  1.10  christos    fprintf_styled_ftype fprintf_styled_func)
   1044  1.10  christos     : m_gdbarch (gdbarch)
   1045  1.10  christos {
   1046  1.10  christos   gdb_assert (fprintf_func != nullptr);
   1047  1.10  christos   gdb_assert (fprintf_styled_func != nullptr);
   1048  1.10  christos   init_disassemble_info (&m_di, (void *) this, fprintf_func,
   1049  1.10  christos 			 fprintf_styled_func);
   1050   1.7  christos   m_di.flavour = bfd_target_unknown_flavour;
   1051  1.10  christos 
   1052  1.10  christos   /* The memory_error_func, print_address_func, and read_memory_func are
   1053  1.10  christos      all initialized to a default (non-nullptr) value by the call to
   1054  1.10  christos      init_disassemble_info above.  If the user is overriding these fields
   1055  1.10  christos      (by passing non-nullptr values) then do that now, otherwise, leave
   1056  1.10  christos      these fields as the defaults.  */
   1057  1.10  christos   if (memory_error_func != nullptr)
   1058  1.10  christos     m_di.memory_error_func = memory_error_func;
   1059  1.10  christos   if (print_address_func != nullptr)
   1060  1.10  christos     m_di.print_address_func = print_address_func;
   1061  1.10  christos   if (read_memory_func != nullptr)
   1062  1.10  christos     m_di.read_memory_func = read_memory_func;
   1063  1.10  christos 
   1064   1.7  christos   m_di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
   1065   1.7  christos   m_di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
   1066   1.7  christos   m_di.endian = gdbarch_byte_order (gdbarch);
   1067   1.7  christos   m_di.endian_code = gdbarch_byte_order_for_code (gdbarch);
   1068   1.7  christos   m_di.application_data = this;
   1069   1.8  christos   m_disassembler_options_holder = get_all_disassembler_options (gdbarch);
   1070   1.8  christos   if (!m_disassembler_options_holder.empty ())
   1071   1.8  christos     m_di.disassembler_options = m_disassembler_options_holder.c_str ();
   1072   1.7  christos   disassemble_init_for_target (&m_di);
   1073   1.7  christos }
   1074   1.7  christos 
   1075  1.10  christos /* See disasm.h.  */
   1076  1.10  christos 
   1077  1.10  christos gdb_disassemble_info::~gdb_disassemble_info ()
   1078   1.9  christos {
   1079   1.9  christos   disassemble_free_target (&m_di);
   1080   1.9  christos }
   1081   1.9  christos 
   1082  1.10  christos /* Wrapper around calling gdbarch_print_insn.  This function takes care of
   1083  1.10  christos    first calling the extension language hooks for print_insn, and, if none
   1084  1.10  christos    of the extension languages can print this instruction, calls
   1085  1.10  christos    gdbarch_print_insn to do the work.
   1086  1.10  christos 
   1087  1.10  christos    GDBARCH is the architecture to disassemble in, VMA is the address of the
   1088  1.10  christos    instruction being disassembled, and INFO is the libopcodes disassembler
   1089  1.10  christos    related information.  */
   1090  1.10  christos 
   1091  1.10  christos static int
   1092  1.10  christos gdb_print_insn_1 (struct gdbarch *gdbarch, CORE_ADDR vma,
   1093  1.10  christos 		  struct disassemble_info *info)
   1094  1.10  christos {
   1095  1.10  christos   /* Call into the extension languages to do the disassembly.  */
   1096  1.11  christos   std::optional<int> length = ext_lang_print_insn (gdbarch, vma, info);
   1097  1.10  christos   if (length.has_value ())
   1098  1.10  christos     return *length;
   1099  1.10  christos 
   1100  1.10  christos   /* No extension language wanted to do the disassembly, so do it
   1101  1.10  christos      manually.  */
   1102  1.10  christos   return gdbarch_print_insn (gdbarch, vma, info);
   1103  1.10  christos }
   1104  1.10  christos 
   1105  1.10  christos /* See disasm.h.  */
   1106  1.10  christos 
   1107  1.10  christos bool gdb_disassembler::use_ext_lang_colorization_p = true;
   1108  1.10  christos 
   1109  1.10  christos /* See disasm.h.  */
   1110  1.10  christos 
   1111   1.7  christos int
   1112   1.7  christos gdb_disassembler::print_insn (CORE_ADDR memaddr,
   1113   1.7  christos 			      int *branch_delay_insns)
   1114   1.7  christos {
   1115  1.10  christos   m_err_memaddr.reset ();
   1116  1.10  christos   m_buffer.clear ();
   1117  1.10  christos   this->set_in_comment (false);
   1118  1.10  christos 
   1119  1.10  christos   int length = gdb_print_insn_1 (arch (), memaddr, &m_di);
   1120  1.10  christos 
   1121  1.10  christos   /* If we have successfully disassembled an instruction, disassembler
   1122  1.10  christos      styling using the extension language is on, and libopcodes hasn't
   1123  1.10  christos      already styled the output for us, and, if the destination can support
   1124  1.10  christos      styling, then lets call into the extension languages in order to style
   1125  1.10  christos      this output.  */
   1126  1.10  christos   if (length > 0 && use_ext_lang_for_styling ())
   1127  1.10  christos     {
   1128  1.11  christos       std::optional<std::string> ext_contents;
   1129  1.10  christos       ext_contents = ext_lang_colorize_disasm (m_buffer.string (), arch ());
   1130  1.10  christos       if (ext_contents.has_value ())
   1131  1.10  christos 	m_buffer = std::move (*ext_contents);
   1132  1.10  christos       else
   1133  1.10  christos 	{
   1134  1.10  christos 	  /* The extension language failed to add styling to the
   1135  1.10  christos 	     disassembly output.  Set the static flag so that next time we
   1136  1.10  christos 	     disassemble we don't even bother attempting to use the
   1137  1.10  christos 	     extension language for styling.  */
   1138  1.10  christos 	  use_ext_lang_colorization_p = false;
   1139  1.10  christos 
   1140  1.10  christos 	  /* We're about to disassemble this instruction again, reset the
   1141  1.10  christos 	     in-comment state.  */
   1142  1.10  christos 	  this->set_in_comment (false);
   1143  1.10  christos 
   1144  1.10  christos 	  /* The instruction we just disassembled, and the extension
   1145  1.10  christos 	     languages failed to style, might have otherwise had some
   1146  1.10  christos 	     minimal styling applied by GDB.  To regain that styling we
   1147  1.10  christos 	     need to recreate m_buffer, but this time with styling support.
   1148  1.10  christos 
   1149  1.10  christos 	     To do this we perform an in-place new, but this time turn on
   1150  1.10  christos 	     the styling support, then we can re-disassembly the
   1151  1.10  christos 	     instruction, and gain any minimal styling GDB might add.  */
   1152  1.11  christos 	  static_assert ((std::is_same<decltype (m_buffer),
   1153  1.10  christos 			      string_file>::value));
   1154  1.10  christos 	  gdb_assert (!m_buffer.term_out ());
   1155  1.10  christos 	  m_buffer.~string_file ();
   1156  1.10  christos 	  new (&m_buffer) string_file (use_libopcodes_for_styling ());
   1157  1.10  christos 	  length = gdb_print_insn_1 (arch (), memaddr, &m_di);
   1158  1.10  christos 	  gdb_assert (length > 0);
   1159  1.10  christos 	}
   1160  1.10  christos     }
   1161   1.7  christos 
   1162  1.10  christos   /* Push any disassemble output to the real destination stream.  We do
   1163  1.10  christos      this even if the disassembler reported failure (-1) as the
   1164  1.10  christos      disassembler may have printed something to its output stream.  */
   1165  1.10  christos   gdb_printf (m_dest, "%s", m_buffer.c_str ());
   1166   1.7  christos 
   1167  1.10  christos   /* If the disassembler failed then report an appropriate error.  */
   1168   1.7  christos   if (length < 0)
   1169  1.10  christos     {
   1170  1.10  christos       if (m_err_memaddr.has_value ())
   1171  1.10  christos 	memory_error (TARGET_XFER_E_IO, *m_err_memaddr);
   1172  1.10  christos       else
   1173  1.10  christos 	error (_("unknown disassembler error (error = %d)"), length);
   1174  1.10  christos     }
   1175   1.7  christos 
   1176   1.7  christos   if (branch_delay_insns != NULL)
   1177   1.7  christos     {
   1178   1.7  christos       if (m_di.insn_info_valid)
   1179   1.7  christos 	*branch_delay_insns = m_di.branch_delay_insns;
   1180   1.7  christos       else
   1181   1.7  christos 	*branch_delay_insns = 0;
   1182   1.7  christos     }
   1183   1.7  christos   return length;
   1184   1.1  christos }
   1185   1.1  christos 
   1186   1.1  christos void
   1187   1.1  christos gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
   1188   1.8  christos 		 gdb_disassembly_flags flags, int how_many,
   1189   1.1  christos 		 CORE_ADDR low, CORE_ADDR high)
   1190   1.1  christos {
   1191   1.3  christos   struct symtab *symtab;
   1192   1.1  christos   int nlines = -1;
   1193   1.1  christos 
   1194   1.1  christos   /* Assume symtab is valid for whole PC range.  */
   1195   1.3  christos   symtab = find_pc_line_symtab (low);
   1196   1.1  christos 
   1197  1.10  christos   if (symtab != NULL && symtab->linetable () != NULL)
   1198  1.10  christos     nlines = symtab->linetable ()->nitems;
   1199   1.1  christos 
   1200   1.6  christos   if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
   1201   1.6  christos       || nlines <= 0)
   1202   1.7  christos     do_assembly_only (gdbarch, uiout, low, high, how_many, flags);
   1203   1.1  christos 
   1204   1.1  christos   else if (flags & DISASSEMBLY_SOURCE)
   1205   1.7  christos     do_mixed_source_and_assembly (gdbarch, uiout, symtab, low, high,
   1206   1.7  christos 				  how_many, flags);
   1207   1.6  christos 
   1208   1.6  christos   else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
   1209   1.7  christos     do_mixed_source_and_assembly_deprecated (gdbarch, uiout, symtab,
   1210   1.7  christos 					     low, high, how_many, flags);
   1211   1.1  christos 
   1212   1.1  christos   gdb_flush (gdb_stdout);
   1213   1.1  christos }
   1214   1.1  christos 
   1215   1.1  christos /* Print the instruction at address MEMADDR in debugged memory,
   1216   1.1  christos    on STREAM.  Returns the length of the instruction, in bytes,
   1217   1.1  christos    and, if requested, the number of branch delay slot instructions.  */
   1218   1.1  christos 
   1219   1.1  christos int
   1220   1.1  christos gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
   1221   1.1  christos 		struct ui_file *stream, int *branch_delay_insns)
   1222   1.1  christos {
   1223   1.1  christos 
   1224   1.7  christos   gdb_disassembler di (gdbarch, stream);
   1225   1.1  christos 
   1226   1.7  christos   return di.print_insn (memaddr, branch_delay_insns);
   1227   1.1  christos }
   1228   1.1  christos 
   1229   1.1  christos /* Return the length in bytes of the instruction at address MEMADDR in
   1230   1.1  christos    debugged memory.  */
   1231   1.1  christos 
   1232   1.1  christos int
   1233   1.1  christos gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
   1234   1.1  christos {
   1235   1.7  christos   return gdb_print_insn (gdbarch, addr, &null_stream, NULL);
   1236   1.1  christos }
   1237   1.1  christos 
   1238  1.10  christos /* See disasm.h.  */
   1239   1.1  christos 
   1240  1.10  christos int
   1241  1.10  christos gdb_non_printing_disassembler::null_fprintf_func
   1242  1.10  christos   (void *stream, const char *format, ...) noexcept
   1243   1.1  christos {
   1244   1.1  christos   return 0;
   1245   1.1  christos }
   1246   1.1  christos 
   1247  1.10  christos /* See disasm.h.  */
   1248   1.1  christos 
   1249  1.10  christos int
   1250  1.10  christos gdb_non_printing_disassembler::null_fprintf_styled_func
   1251  1.10  christos   (void *stream, enum disassembler_style style,
   1252  1.10  christos    const char *format, ...) noexcept
   1253  1.10  christos {
   1254  1.10  christos   return 0;
   1255   1.1  christos }
   1256   1.1  christos 
   1257  1.10  christos /* A non-printing disassemble_info management class.  The disassemble_info
   1258  1.10  christos    setup by this class will not print anything to the output stream (there
   1259  1.10  christos    is no output stream), and the instruction to be disassembled will be
   1260  1.10  christos    read from a buffer passed to the constructor.  */
   1261  1.10  christos 
   1262  1.10  christos struct gdb_non_printing_buffer_disassembler
   1263  1.10  christos   : public gdb_non_printing_disassembler
   1264  1.10  christos {
   1265  1.10  christos   /* Constructor.  GDBARCH is the architecture to disassemble for, BUFFER
   1266  1.10  christos      contains the instruction to disassemble, and INSN_ADDRESS is the
   1267  1.10  christos      address (in target memory) of the instruction to disassemble.  */
   1268  1.10  christos   gdb_non_printing_buffer_disassembler (struct gdbarch *gdbarch,
   1269  1.10  christos 					gdb::array_view<const gdb_byte> buffer,
   1270  1.10  christos 					CORE_ADDR insn_address)
   1271  1.10  christos     : gdb_non_printing_disassembler (gdbarch, nullptr)
   1272  1.10  christos   {
   1273  1.10  christos     /* The cast is necessary until disassemble_info is const-ified.  */
   1274  1.10  christos     m_di.buffer = (gdb_byte *) buffer.data ();
   1275  1.10  christos     m_di.buffer_length = buffer.size ();
   1276  1.10  christos     m_di.buffer_vma = insn_address;
   1277  1.10  christos   }
   1278  1.10  christos };
   1279  1.10  christos 
   1280   1.1  christos /* Return the length in bytes of INSN.  MAX_LEN is the size of the
   1281   1.1  christos    buffer containing INSN.  */
   1282   1.1  christos 
   1283   1.1  christos int
   1284   1.1  christos gdb_buffered_insn_length (struct gdbarch *gdbarch,
   1285   1.1  christos 			  const gdb_byte *insn, int max_len, CORE_ADDR addr)
   1286   1.1  christos {
   1287  1.10  christos   gdb::array_view<const gdb_byte> buffer
   1288  1.10  christos     = gdb::make_array_view (insn, max_len);
   1289  1.10  christos   gdb_non_printing_buffer_disassembler dis (gdbarch, buffer, addr);
   1290  1.10  christos   int result = gdb_print_insn_1 (gdbarch, addr, dis.disasm_info ());
   1291   1.9  christos   return result;
   1292   1.1  christos }
   1293   1.7  christos 
   1294  1.11  christos const char *
   1295   1.7  christos get_disassembler_options (struct gdbarch *gdbarch)
   1296   1.7  christos {
   1297  1.11  christos   std::string *disassembler_options = gdbarch_disassembler_options (gdbarch);
   1298  1.11  christos   if (disassembler_options == nullptr || disassembler_options->empty ())
   1299  1.11  christos     return nullptr;
   1300  1.11  christos   return disassembler_options->c_str ();
   1301   1.7  christos }
   1302   1.7  christos 
   1303   1.7  christos void
   1304  1.10  christos set_disassembler_options (const char *prospective_options)
   1305   1.7  christos {
   1306   1.7  christos   struct gdbarch *gdbarch = get_current_arch ();
   1307  1.11  christos   std::string *disassembler_options = gdbarch_disassembler_options (gdbarch);
   1308   1.8  christos   const disasm_options_and_args_t *valid_options_and_args;
   1309   1.7  christos   const disasm_options_t *valid_options;
   1310  1.10  christos   gdb::unique_xmalloc_ptr<char> prospective_options_local
   1311  1.10  christos     = make_unique_xstrdup (prospective_options);
   1312  1.10  christos   char *options = remove_whitespace_and_extra_commas
   1313  1.10  christos     (prospective_options_local.get ());
   1314   1.7  christos   const char *opt;
   1315   1.7  christos 
   1316   1.7  christos   /* Allow all architectures, even ones that do not support 'set disassembler',
   1317   1.7  christos      to reset their disassembler options to NULL.  */
   1318   1.7  christos   if (options == NULL)
   1319   1.7  christos     {
   1320  1.11  christos       if (disassembler_options != nullptr)
   1321  1.11  christos 	disassembler_options->clear ();
   1322   1.7  christos       return;
   1323   1.7  christos     }
   1324   1.7  christos 
   1325   1.8  christos   valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch);
   1326   1.8  christos   if (valid_options_and_args == NULL)
   1327   1.7  christos     {
   1328  1.10  christos       gdb_printf (gdb_stderr, _("\
   1329   1.7  christos 'set disassembler-options ...' is not supported on this architecture.\n"));
   1330   1.7  christos       return;
   1331   1.7  christos     }
   1332   1.7  christos 
   1333   1.8  christos   valid_options = &valid_options_and_args->options;
   1334   1.8  christos 
   1335   1.7  christos   /* Verify we have valid disassembler options.  */
   1336   1.7  christos   FOR_EACH_DISASSEMBLER_OPTION (opt, options)
   1337   1.7  christos     {
   1338   1.7  christos       size_t i;
   1339   1.7  christos       for (i = 0; valid_options->name[i] != NULL; i++)
   1340   1.8  christos 	if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
   1341   1.8  christos 	  {
   1342   1.8  christos 	    size_t len = strlen (valid_options->name[i]);
   1343   1.8  christos 	    bool found = false;
   1344   1.8  christos 	    const char *arg;
   1345   1.8  christos 	    size_t j;
   1346   1.8  christos 
   1347   1.8  christos 	    if (memcmp (opt, valid_options->name[i], len) != 0)
   1348   1.8  christos 	      continue;
   1349   1.8  christos 	    arg = opt + len;
   1350  1.10  christos 	    if (valid_options->arg[i]->values == NULL)
   1351  1.10  christos 	      break;
   1352   1.8  christos 	    for (j = 0; valid_options->arg[i]->values[j] != NULL; j++)
   1353   1.8  christos 	      if (disassembler_options_cmp
   1354   1.8  christos 		    (arg, valid_options->arg[i]->values[j]) == 0)
   1355   1.8  christos 		{
   1356   1.8  christos 		  found = true;
   1357   1.8  christos 		  break;
   1358   1.8  christos 		}
   1359   1.8  christos 	    if (found)
   1360   1.8  christos 	      break;
   1361   1.8  christos 	  }
   1362   1.8  christos 	else if (disassembler_options_cmp (opt, valid_options->name[i]) == 0)
   1363   1.7  christos 	  break;
   1364   1.7  christos       if (valid_options->name[i] == NULL)
   1365   1.7  christos 	{
   1366  1.10  christos 	  gdb_printf (gdb_stderr,
   1367  1.10  christos 		      _("Invalid disassembler option value: '%s'.\n"),
   1368  1.10  christos 		      opt);
   1369   1.7  christos 	  return;
   1370   1.7  christos 	}
   1371   1.7  christos     }
   1372   1.7  christos 
   1373  1.11  christos   *disassembler_options = options;
   1374   1.7  christos }
   1375   1.7  christos 
   1376   1.7  christos static void
   1377   1.8  christos set_disassembler_options_sfunc (const char *args, int from_tty,
   1378   1.7  christos 				struct cmd_list_element *c)
   1379   1.7  christos {
   1380  1.10  christos   set_disassembler_options (prospective_options.c_str ());
   1381   1.7  christos }
   1382   1.7  christos 
   1383   1.7  christos static void
   1384   1.7  christos show_disassembler_options_sfunc (struct ui_file *file, int from_tty,
   1385   1.7  christos 				 struct cmd_list_element *c, const char *value)
   1386   1.7  christos {
   1387   1.7  christos   struct gdbarch *gdbarch = get_current_arch ();
   1388   1.8  christos   const disasm_options_and_args_t *valid_options_and_args;
   1389   1.8  christos   const disasm_option_arg_t *valid_args;
   1390   1.7  christos   const disasm_options_t *valid_options;
   1391   1.7  christos 
   1392   1.7  christos   const char *options = get_disassembler_options (gdbarch);
   1393   1.7  christos   if (options == NULL)
   1394   1.7  christos     options = "";
   1395   1.7  christos 
   1396  1.10  christos   gdb_printf (file, _("The current disassembler options are '%s'\n\n"),
   1397  1.10  christos 	      options);
   1398   1.7  christos 
   1399   1.8  christos   valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch);
   1400   1.8  christos 
   1401   1.8  christos   if (valid_options_and_args == NULL)
   1402   1.8  christos     {
   1403  1.10  christos       gdb_puts (_("There are no disassembler options available "
   1404  1.10  christos 		  "for this architecture.\n"),
   1405  1.10  christos 		file);
   1406   1.8  christos       return;
   1407   1.8  christos     }
   1408   1.7  christos 
   1409   1.8  christos   valid_options = &valid_options_and_args->options;
   1410   1.7  christos 
   1411  1.10  christos   gdb_printf (file, _("\
   1412   1.7  christos The following disassembler options are supported for use with the\n\
   1413   1.8  christos 'set disassembler-options OPTION [,OPTION]...' command:\n"));
   1414   1.7  christos 
   1415   1.7  christos   if (valid_options->description != NULL)
   1416   1.7  christos     {
   1417   1.7  christos       size_t i, max_len = 0;
   1418   1.7  christos 
   1419  1.10  christos       gdb_printf (file, "\n");
   1420   1.8  christos 
   1421   1.7  christos       /* Compute the length of the longest option name.  */
   1422   1.7  christos       for (i = 0; valid_options->name[i] != NULL; i++)
   1423   1.7  christos 	{
   1424   1.7  christos 	  size_t len = strlen (valid_options->name[i]);
   1425   1.8  christos 
   1426   1.8  christos 	  if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
   1427   1.8  christos 	    len += strlen (valid_options->arg[i]->name);
   1428   1.7  christos 	  if (max_len < len)
   1429   1.7  christos 	    max_len = len;
   1430   1.7  christos 	}
   1431   1.7  christos 
   1432   1.7  christos       for (i = 0, max_len++; valid_options->name[i] != NULL; i++)
   1433   1.7  christos 	{
   1434  1.10  christos 	  gdb_printf (file, "  %s", valid_options->name[i]);
   1435   1.8  christos 	  if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
   1436  1.10  christos 	    gdb_printf (file, "%s", valid_options->arg[i]->name);
   1437   1.7  christos 	  if (valid_options->description[i] != NULL)
   1438   1.8  christos 	    {
   1439   1.8  christos 	      size_t len = strlen (valid_options->name[i]);
   1440   1.8  christos 
   1441   1.8  christos 	      if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
   1442   1.8  christos 		len += strlen (valid_options->arg[i]->name);
   1443  1.10  christos 	      gdb_printf (file, "%*c %s", (int) (max_len - len), ' ',
   1444  1.10  christos 			  valid_options->description[i]);
   1445   1.8  christos 	    }
   1446  1.10  christos 	  gdb_printf (file, "\n");
   1447   1.7  christos 	}
   1448   1.7  christos     }
   1449   1.7  christos   else
   1450   1.7  christos     {
   1451   1.7  christos       size_t i;
   1452  1.10  christos       gdb_printf (file, "  ");
   1453   1.7  christos       for (i = 0; valid_options->name[i] != NULL; i++)
   1454   1.7  christos 	{
   1455  1.10  christos 	  gdb_printf (file, "%s", valid_options->name[i]);
   1456   1.8  christos 	  if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
   1457  1.10  christos 	    gdb_printf (file, "%s", valid_options->arg[i]->name);
   1458   1.7  christos 	  if (valid_options->name[i + 1] != NULL)
   1459  1.10  christos 	    gdb_printf (file, ", ");
   1460  1.10  christos 	  file->wrap_here (2);
   1461   1.7  christos 	}
   1462  1.10  christos       gdb_printf (file, "\n");
   1463   1.7  christos     }
   1464   1.8  christos 
   1465   1.8  christos   valid_args = valid_options_and_args->args;
   1466   1.8  christos   if (valid_args != NULL)
   1467   1.8  christos     {
   1468   1.8  christos       size_t i, j;
   1469   1.8  christos 
   1470   1.8  christos       for (i = 0; valid_args[i].name != NULL; i++)
   1471   1.8  christos 	{
   1472  1.10  christos 	  if (valid_args[i].values == NULL)
   1473  1.10  christos 	    continue;
   1474  1.10  christos 	  gdb_printf (file, _("\n\
   1475   1.8  christos   For the options above, the following values are supported for \"%s\":\n   "),
   1476  1.10  christos 		      valid_args[i].name);
   1477   1.8  christos 	  for (j = 0; valid_args[i].values[j] != NULL; j++)
   1478   1.8  christos 	    {
   1479  1.10  christos 	      gdb_printf (file, " %s", valid_args[i].values[j]);
   1480  1.10  christos 	      file->wrap_here (3);
   1481   1.8  christos 	    }
   1482  1.10  christos 	  gdb_printf (file, "\n");
   1483   1.8  christos 	}
   1484   1.8  christos     }
   1485   1.7  christos }
   1486   1.7  christos 
   1487   1.7  christos /* A completion function for "set disassembler".  */
   1488   1.7  christos 
   1489   1.8  christos static void
   1490   1.7  christos disassembler_options_completer (struct cmd_list_element *ignore,
   1491   1.8  christos 				completion_tracker &tracker,
   1492   1.7  christos 				const char *text, const char *word)
   1493   1.7  christos {
   1494   1.7  christos   struct gdbarch *gdbarch = get_current_arch ();
   1495   1.8  christos   const disasm_options_and_args_t *opts_and_args
   1496   1.8  christos     = gdbarch_valid_disassembler_options (gdbarch);
   1497   1.7  christos 
   1498   1.8  christos   if (opts_and_args != NULL)
   1499   1.7  christos     {
   1500   1.8  christos       const disasm_options_t *opts = &opts_and_args->options;
   1501   1.8  christos 
   1502   1.7  christos       /* Only attempt to complete on the last option text.  */
   1503   1.7  christos       const char *separator = strrchr (text, ',');
   1504   1.7  christos       if (separator != NULL)
   1505   1.7  christos 	text = separator + 1;
   1506   1.8  christos       text = skip_spaces (text);
   1507   1.8  christos       complete_on_enum (tracker, opts->name, text, word);
   1508   1.7  christos     }
   1509   1.7  christos }
   1510   1.7  christos 
   1511   1.7  christos 
   1512   1.7  christos /* Initialization code.  */
   1513   1.7  christos 
   1514   1.9  christos void _initialize_disasm ();
   1515   1.7  christos void
   1516   1.9  christos _initialize_disasm ()
   1517   1.7  christos {
   1518   1.7  christos   /* Add the command that controls the disassembler options.  */
   1519  1.10  christos   set_show_commands set_show_disas_opts
   1520  1.10  christos     = add_setshow_string_noescape_cmd ("disassembler-options", no_class,
   1521  1.10  christos 				       &prospective_options, _("\
   1522   1.7  christos Set the disassembler options.\n\
   1523   1.8  christos Usage: set disassembler-options OPTION [,OPTION]...\n\n\
   1524   1.9  christos See: 'show disassembler-options' for valid option values."), _("\
   1525   1.7  christos Show the disassembler options."), NULL,
   1526   1.7  christos 					 set_disassembler_options_sfunc,
   1527   1.7  christos 					 show_disassembler_options_sfunc,
   1528   1.7  christos 					 &setlist, &showlist);
   1529  1.10  christos   set_cmd_completer (set_show_disas_opts.set, disassembler_options_completer);
   1530  1.10  christos 
   1531  1.10  christos 
   1532  1.10  christos   /* All the 'maint set|show libopcodes-styling' sub-commands.  */
   1533  1.10  christos   static struct cmd_list_element *maint_set_libopcodes_styling_cmdlist;
   1534  1.10  christos   static struct cmd_list_element *maint_show_libopcodes_styling_cmdlist;
   1535  1.10  christos 
   1536  1.10  christos   /* Adds 'maint set|show libopcodes-styling'.  */
   1537  1.10  christos   add_setshow_prefix_cmd ("libopcodes-styling", class_maintenance,
   1538  1.10  christos 			  _("Set libopcodes-styling specific variables."),
   1539  1.10  christos 			  _("Show libopcodes-styling specific variables."),
   1540  1.10  christos 			  &maint_set_libopcodes_styling_cmdlist,
   1541  1.10  christos 			  &maint_show_libopcodes_styling_cmdlist,
   1542  1.10  christos 			  &maintenance_set_cmdlist,
   1543  1.10  christos 			  &maintenance_show_cmdlist);
   1544  1.10  christos 
   1545  1.10  christos   /* Adds 'maint set|show gnu-source-highlight enabled'.  */
   1546  1.10  christos   add_setshow_boolean_cmd ("enabled", class_maintenance,
   1547  1.10  christos 			   &use_libopcodes_styling_option, _("\
   1548  1.10  christos Set whether the libopcodes styling support should be used."), _("\
   1549  1.10  christos Show whether the libopcodes styling support should be used."),_("\
   1550  1.10  christos When enabled, GDB will try to make use of the builtin libopcodes styling\n\
   1551  1.10  christos support, to style the disassembler output.  Not every architecture has\n\
   1552  1.10  christos styling support within libopcodes, so enabling this is not a guarantee\n\
   1553  1.10  christos that libopcodes styling will be available.\n\
   1554  1.10  christos \n\
   1555  1.10  christos When this option is disabled, GDB will make use of the Python Pygments\n\
   1556  1.10  christos package (if available) to style the disassembler output.\n\
   1557  1.10  christos \n\
   1558  1.10  christos All disassembler styling can be disabled with:\n\
   1559  1.10  christos \n\
   1560  1.10  christos   set style disassembler enabled off"),
   1561  1.10  christos 			   set_use_libopcodes_styling,
   1562  1.10  christos 			   show_use_libopcodes_styling,
   1563  1.10  christos 			   &maint_set_libopcodes_styling_cmdlist,
   1564  1.10  christos 			   &maint_show_libopcodes_styling_cmdlist);
   1565   1.7  christos }
   1566