* dwarf.c (dwarf_vmatoa64): New function.
[external/binutils.git] / binutils / dwarf.c
index 9d874ca..5ad9b93 100644 (file)
@@ -169,6 +169,27 @@ dwarf_vmatoa (const char *fmtch, dwarf_vma value)
   return ret;
 }
 
+/* Format a 64-bit value, given as two 32-bit values, in hex.
+   For reentrancy, this uses a buffer provided by the caller.  */
+
+static const char *
+dwarf_vmatoa64 (dwarf_vma hvalue, dwarf_vma lvalue, char *buf,
+               unsigned int buf_len)
+{
+  int len = 0;
+
+  if (hvalue == 0)
+    snprintf (buf, buf_len, "%" DWARF_VMA_FMT "x", lvalue);
+  else
+    {
+      len = snprintf (buf, buf_len, "%" DWARF_VMA_FMT "x", hvalue);
+      snprintf (buf + len, buf_len - len,
+               "%08" DWARF_VMA_FMT "x", lvalue);
+    }
+
+  return buf;
+}
+
 dwarf_vma
 read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
 {
@@ -247,6 +268,7 @@ process_extended_line_op (unsigned char *data, int is_stmt)
   unsigned int len;
   unsigned char *name;
   dwarf_vma adr;
+  unsigned char *orig_data = data;
 
   len = read_leb128 (data, & bytes_read, 0);
   data += bytes_read;
@@ -277,7 +299,7 @@ process_extended_line_op (unsigned char *data, int is_stmt)
       break;
 
     case DW_LNE_define_file:
-      printf (_("  define new File Table entry\n"));
+      printf (_("define new File Table entry\n"));
       printf (_("  Entry\tDir\tTime\tSize\tName\n"));
 
       printf ("   %d\t", ++state_machine_regs.last_file_entry);
@@ -288,7 +310,11 @@ process_extended_line_op (unsigned char *data, int is_stmt)
       printf ("%s\t", dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0)));
       data += bytes_read;
       printf ("%s\t", dwarf_vmatoa ("u", read_leb128 (data, & bytes_read, 0)));
-      printf ("%s\n\n", name);
+      data += bytes_read;
+      printf ("%s", name);
+      if ((unsigned int) (data - orig_data) != len)
+        printf (_(" [Bad opcode length]"));
+      printf ("\n\n");
       break;
 
     case DW_LNE_set_discriminator:
@@ -1376,9 +1402,12 @@ read_and_display_attr_value (unsigned long attribute,
     case DW_FORM_data8:
       if (!do_loc)
        {
-         uvalue = byte_get (data, 4);
-         printf (" 0x%s", dwarf_vmatoa ("x", uvalue));
-         printf (" 0x%lx", (unsigned long) byte_get (data + 4, 4));
+         dwarf_vma high_bits;
+         char buf[64];
+
+         byte_get_64 (data, &high_bits, &uvalue);
+         printf (" 0x%s",
+                 dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
        }
       if ((do_loc || do_debug_loc || do_debug_ranges)
          && num_debug_info_entries == 0)
@@ -1448,16 +1477,14 @@ read_and_display_attr_value (unsigned long attribute,
     case DW_FORM_ref_sig8:
       if (!do_loc)
        {
-         int i;
-         printf (" signature: ");
-         for (i = 0; i < 8; i++)
-           {
-             printf ("%02x", (unsigned) byte_get (data, 1));
-             data += 1;
-           }
+         dwarf_vma high_bits;
+         char buf[64];
+
+         byte_get_64 (data, &high_bits, &uvalue);
+         printf (" signature: 0x%s",
+                 dwarf_vmatoa64 (high_bits, uvalue, buf, sizeof (buf)));
        }
-      else
-        data += 8;
+      data += 8;
       break;
 
     default:
@@ -1599,6 +1626,8 @@ read_and_display_attr_value (unsigned long attribute,
        case DW_LANG_D:                 printf ("(D)"); break;
          /* DWARF 4 values.  */
        case DW_LANG_Python:            printf ("(Python)"); break;
+         /* DWARF 5 values.  */
+       case DW_LANG_Go:                printf ("(Go)"); break;
          /* MIPS extension.  */
        case DW_LANG_Mips_Assembler:    printf ("(MIPS assembler)"); break;
          /* UPC extension.  */
@@ -1769,7 +1798,8 @@ read_and_display_attr_value (unsigned long attribute,
 
        if (form == DW_FORM_ref1
            || form == DW_FORM_ref2
-           || form == DW_FORM_ref4)
+           || form == DW_FORM_ref4
+           || form == DW_FORM_ref_udata)
          uvalue += cu_offset;
 
        if (uvalue >= section->size)
@@ -2105,7 +2135,8 @@ process_debug_info (struct dwarf_section *section,
       dwarf_vma cu_offset;
       int offset_size;
       int initial_length_size;
-      unsigned char signature[8] = { 0 };
+      dwarf_vma signature_high = 0;
+      dwarf_vma signature_low = 0;
       dwarf_vma type_offset = 0;
 
       hdrptr = start;
@@ -2139,14 +2170,8 @@ process_debug_info (struct dwarf_section *section,
 
       if (do_types)
         {
-          int i;
-
-          for (i = 0; i < 8; i++)
-            {
-              signature[i] = byte_get (hdrptr, 1);
-              hdrptr += 1;
-            }
-
+          byte_get_64 (hdrptr, &signature_high, &signature_low);
+          hdrptr += 8;
           type_offset = byte_get (hdrptr, offset_size);
           hdrptr += offset_size;
         }
@@ -2183,13 +2208,13 @@ process_debug_info (struct dwarf_section *section,
          printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
          if (do_types)
            {
-             int i;
-             printf (_("   Signature:     "));
-             for (i = 0; i < 8; i++)
-               printf ("%02x", signature[i]);
-             printf ("\n");
-             printf (_("   Type Offset:   0x%s\n"),
-                     dwarf_vmatoa ("x", type_offset));
+             char buf[64];
+
+             printf (_("   Signature:     0x%s\n"),
+                     dwarf_vmatoa64 (signature_high, signature_low,
+                                     buf, sizeof (buf)));
+             printf (_("   Type Offset:   0x%s\n"),
+                     dwarf_vmatoa ("x", type_offset));
            }
        }
 
@@ -2797,7 +2822,9 @@ display_debug_lines_decoded (struct dwarf_section *section,
       int offset_size;
       int i;
       File_Entry *file_table = NULL;
+      unsigned int n_files = 0;
       unsigned char **directory_table = NULL;
+      unsigned int n_directories = 0;
 
       hdrptr = data;
 
@@ -2882,7 +2909,6 @@ display_debug_lines_decoded (struct dwarf_section *section,
       data = standard_opcodes + linfo.li_opcode_base - 1;
       if (*data != 0)
         {
-          unsigned int n_directories = 0;
           unsigned char *ptr_directory_table = data;
 
          while (*data != 0)
@@ -2909,7 +2935,6 @@ display_debug_lines_decoded (struct dwarf_section *section,
       /* Traverse the File Name table just to count the entries.  */
       if (*data != 0)
         {
-          unsigned int n_files = 0;
           unsigned char *ptr_file_name_table = data;
 
           while (*data != 0)
@@ -3041,21 +3066,36 @@ display_debug_lines_decoded (struct dwarf_section *section,
                     break;
                   case DW_LNE_define_file:
                     {
-                      unsigned int dir_index = 0;
+                      file_table = (File_Entry *) xrealloc
+                        (file_table, (n_files + 1) * sizeof (File_Entry));
 
                       ++state_machine_regs.last_file_entry;
+                      /* Source file name.  */
+                      file_table[n_files].name = op_code_data;
                       op_code_data += strlen ((char *) op_code_data) + 1;
-                      dir_index = read_leb128 (op_code_data, & bytes_read, 0);
+                      /* Directory index.  */
+                      file_table[n_files].directory_index =
+                        read_leb128 (op_code_data, & bytes_read, 0);
                       op_code_data += bytes_read;
-                      read_leb128 (op_code_data, & bytes_read, 0);
+                      /* Last modification time.  */
+                      file_table[n_files].modification_date =
+                        read_leb128 (op_code_data, & bytes_read, 0);
                       op_code_data += bytes_read;
-                      read_leb128 (op_code_data, & bytes_read, 0);
+                      /* File length.  */
+                      file_table[n_files].length =
+                        read_leb128 (op_code_data, & bytes_read, 0);
 
-                      printf ("%s:\n", directory_table[dir_index]);
+                      n_files++;
                       break;
                     }
+                  case DW_LNE_set_discriminator:
+                  case DW_LNE_HP_set_sequence:
+                    /* Simply ignored.  */
+                    break;
+
                   default:
-                    printf (_("UNKNOWN: length %d\n"), ext_op_code_len - bytes_read);
+                    printf (_("UNKNOWN (%u): length %d\n"),
+                            ext_op_code, ext_op_code_len - bytes_read);
                     break;
                   }
                 data += ext_op_code_len;
@@ -5109,6 +5149,9 @@ display_debug_frames (struct dwarf_section *section,
                {
                  fc->col_type[opa] = cie->col_type[opa];
                  fc->col_offset[opa] = cie->col_offset[opa];
+                 if (do_debug_frames_interp
+                     && fc->col_type[opa] == DW_CFA_unreferenced)
+                   fc->col_type[opa] = DW_CFA_undefined;
                }
              break;