Avoid crash in varobj deletion
[binutils-gdb.git] / opcodes / xtensa-dis.c
index ecef0c55edf541a3379b964055b826bcb9edb072..c1cf4c82d608328eebf27e958d8767e5d6d94040 100644 (file)
@@ -1,5 +1,5 @@
 /* xtensa-dis.c.  Disassembly functions for Xtensa.
-   Copyright (C) 2003-2019 Free Software Foundation, Inc.
+   Copyright (C) 2003-2021 Free Software Foundation, Inc.
    Contributed by Bob Wilson at Tensilica, Inc. (bwilson@tensilica.com)
 
    This file is part of the GNU opcodes library.
@@ -194,7 +194,8 @@ print_xtensa_operand (bfd_vma memaddr,
                      unsigned operand_val)
 {
   xtensa_isa isa = xtensa_default_isa;
-  int signed_operand_val;
+  int signed_operand_val, status;
+  bfd_byte litbuf[4];
 
   if (show_raw_fields)
     {
@@ -216,6 +217,23 @@ print_xtensa_operand (bfd_vma memaddr,
                                            &operand_val, memaddr);
          info->target = operand_val;
          (*info->print_address_func) (info->target, info);
+         /*  Also display value loaded by L32R (but not if reloc exists,
+             those tend to be wrong):  */
+         if ((info->flags & INSN_HAS_RELOC) == 0
+             && !strcmp ("l32r", xtensa_opcode_name (isa, opc)))
+           status = (*info->read_memory_func) (operand_val, litbuf, 4, info);
+         else
+           status = -1;
+
+         if (status == 0)
+           {
+             unsigned literal = bfd_get_bits (litbuf, 32,
+                                              info->endian == BFD_ENDIAN_BIG);
+
+             (*info->fprintf_func) (info->stream, " (");
+             (*info->print_address_func) (literal, info);
+             (*info->fprintf_func) (info->stream, ")");
+           }
        }
       else
        {
@@ -306,8 +324,7 @@ print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
            {
              /* Reset insn_table_entries.  */
              priv.insn_table_entry_count = 0;
-             if (priv.insn_table_entries)
-               free (priv.insn_table_entries);
+             free (priv.insn_table_entries);
              priv.insn_table_entries = NULL;
            }
          priv.last_section = section;
@@ -316,17 +333,16 @@ print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
          priv.insn_table_entry_count =
            xtensa_read_table_entries (abfd, section,
                                       &priv.insn_table_entries,
-                                      XTENSA_PROP_SEC_NAME, FALSE);
+                                      XTENSA_PROP_SEC_NAME, false);
          if (priv.insn_table_entry_count == 0)
            {
-             if (priv.insn_table_entries)
-               free (priv.insn_table_entries);
+             free (priv.insn_table_entries);
              priv.insn_table_entries = NULL;
              /* Backwards compatibility support.  */
              priv.insn_table_entry_count =
                xtensa_read_table_entries (abfd, section,
                                           &priv.insn_table_entries,
-                                          XTENSA_INSN_SEC_NAME, FALSE);
+                                          XTENSA_INSN_SEC_NAME, false);
            }
          priv.insn_table_cur_idx = 0;
          xtensa_coalesce_insn_tables (&priv);
@@ -383,6 +399,7 @@ print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
       if (insn_block && (insn_block->flags & XTENSA_PROP_LITERAL)
          && (memaddr & 3) == 0 && bytes_fetched >= 4)
        {
+         info->bytes_per_chunk = 4;
          return 4;
        }
       else
@@ -395,6 +412,9 @@ print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
   if (nslots > 1)
     (*info->fprintf_func) (info->stream, "{ ");
 
+  info->insn_type = dis_nonbranch;
+  info->insn_info_valid = 1;
+
   first_slot = 1;
   for (n = 0; n < nslots; n++)
     {
@@ -408,6 +428,13 @@ print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
       (*info->fprintf_func) (info->stream, "%s",
                             xtensa_opcode_name (isa, opc));
 
+      if (xtensa_opcode_is_branch (isa, opc))
+       info->insn_type = dis_condbranch;
+      else if (xtensa_opcode_is_jump (isa, opc))
+       info->insn_type = dis_branch;
+      else if (xtensa_opcode_is_call (isa, opc))
+       info->insn_type = dis_jsr;
+
       /* Print the operands (if any).  */
       noperands = xtensa_opcode_num_operands (isa, opc);
       first = 1;