Add initial Intel K1OM support.
[deliverable/binutils-gdb.git] / binutils / dwarf.c
index 102d1642dcea769fef3550ebe53427cff81caa6f..08febadf5504ed61b79c79220e8fa0e94a279e7e 100644 (file)
@@ -63,6 +63,9 @@ int do_trace_abbrevs;
 int do_trace_aranges;
 int do_wide;
 
+int dwarf_cutoff_level = -1;
+unsigned long dwarf_start_die;
+
 /* Values for do_debug_lines.  */
 #define FLAG_DEBUG_LINES_RAW    1
 #define FLAG_DEBUG_LINES_DECODED 2
@@ -324,16 +327,71 @@ process_extended_line_op (unsigned char *data, int is_stmt)
     case DW_LNE_HP_define_proc:
       printf ("DW_LNE_HP_define_proc\n");
       break;
+    case DW_LNE_HP_source_file_correlation:
+      {
+        unsigned char *edata = data + len - bytes_read - 1;
+
+        printf ("DW_LNE_HP_source_file_correlation\n");
+
+        while (data < edata)
+          {
+            unsigned int opc;
+
+            opc = read_leb128 (data, & bytes_read, 0);
+            data += bytes_read;
+
+            switch (opc)
+              {
+              case DW_LNE_HP_SFC_formfeed:
+                printf ("    DW_LNE_HP_SFC_formfeed\n");
+                break;
+              case DW_LNE_HP_SFC_set_listing_line:
+                printf ("    DW_LNE_HP_SFC_set_listing_line (%s)\n",
+                        dwarf_vmatoa ("u",
+                                      read_leb128 (data, & bytes_read, 0)));
+                data += bytes_read;
+                break;
+              case DW_LNE_HP_SFC_associate:
+                printf ("    DW_LNE_HP_SFC_associate ");
+                printf (_("(%s"),
+                        dwarf_vmatoa ("u",
+                                      read_leb128 (data, & bytes_read, 0)));
+                data += bytes_read;
+                printf (_(",%s"),
+                        dwarf_vmatoa ("u",
+                                      read_leb128 (data, & bytes_read, 0)));
+                data += bytes_read;
+                printf (_(",%s)\n"),
+                        dwarf_vmatoa ("u",
+                                      read_leb128 (data, & bytes_read, 0)));
+                data += bytes_read;
+                break;
+              default:
+                printf ("    UNKNOW DW_LNE_HP_SFC opcode (%u)\n", opc);
+                data = edata;
+                break;
+              }
+          }
+      }
+      break;
 
     default:
-      if (op_code >= DW_LNE_lo_user
-         /* The test against DW_LNW_hi_user is redundant due to
-            the limited range of the unsigned char data type used
-            for op_code.  */
-         /*&& op_code <= DW_LNE_hi_user*/)
-       printf (_("user defined: length %d\n"), len - bytes_read);
-      else
-       printf (_("UNKNOWN: length %d\n"), len - bytes_read);
+      {
+        unsigned int rlen = len - bytes_read - 1;
+
+        if (op_code >= DW_LNE_lo_user
+            /* The test against DW_LNW_hi_user is redundant due to
+               the limited range of the unsigned char data type used
+               for op_code.  */
+            /*&& op_code <= DW_LNE_hi_user*/)
+          printf (_("user defined: "));
+        else
+          printf (_("UNKNOWN: "));
+        printf (_("length %d ["), rlen);
+        for (; rlen; rlen--)
+          printf (" %02x", *data++);
+        printf ("]\n");
+      }
       break;
     }
 
@@ -674,8 +732,8 @@ decode_location_expression (unsigned char * data,
       switch (op)
        {
        case DW_OP_addr:
-         printf ("DW_OP_addr: %lx",
-                 (unsigned long) byte_get (data, pointer_size));
+         printf ("DW_OP_addr: %s",
+                 dwarf_vmatoa ("x", byte_get (data, pointer_size)));
          data += pointer_size;
          break;
        case DW_OP_deref:
@@ -1034,17 +1092,6 @@ decode_location_expression (unsigned char * data,
          display_block (data, uvalue);
          data += uvalue;
          break;
-       case DW_OP_GNU_entry_value:
-         uvalue = read_leb128 (data, &bytes_read, 0);
-         data += bytes_read;
-         printf ("DW_OP_GNU_entry_value: (");
-         if (decode_location_expression (data, pointer_size, offset_size,
-                                         dwarf_version, uvalue,
-                                         cu_offset, section))
-           need_frame_base = 1;
-         putchar (')');
-         data += uvalue;
-         break;
 
          /* GNU extensions.  */
        case DW_OP_GNU_push_tls_address:
@@ -1093,6 +1140,58 @@ decode_location_expression (unsigned char * data,
              data += offset_size + bytes_read;
            }
          break;
+       case DW_OP_GNU_entry_value:
+         uvalue = read_leb128 (data, &bytes_read, 0);
+         data += bytes_read;
+         printf ("DW_OP_GNU_entry_value: (");
+         if (decode_location_expression (data, pointer_size, offset_size,
+                                         dwarf_version, uvalue,
+                                         cu_offset, section))
+           need_frame_base = 1;
+         putchar (')');
+         data += uvalue;
+         break;
+       case DW_OP_GNU_const_type:
+         uvalue = read_leb128 (data, &bytes_read, 0);
+         data += bytes_read;
+         printf ("DW_OP_GNU_const_type: <0x%s> ",
+                 dwarf_vmatoa ("x", cu_offset + uvalue));
+         uvalue = byte_get (data++, 1);
+         display_block (data, uvalue);
+         data += uvalue;
+         break;
+       case DW_OP_GNU_regval_type:
+         uvalue = read_leb128 (data, &bytes_read, 0);
+         data += bytes_read;
+         printf ("DW_OP_GNU_regval_type: %s (%s)",
+                 dwarf_vmatoa ("u", uvalue), regname (uvalue, 1));
+         uvalue = read_leb128 (data, &bytes_read, 0);
+         data += bytes_read;
+         printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue));
+         break;
+       case DW_OP_GNU_deref_type:
+         printf ("DW_OP_GNU_deref_type: %ld", (long) byte_get (data++, 1));
+         uvalue = read_leb128 (data, &bytes_read, 0);
+         data += bytes_read;
+         printf (" <0x%s>", dwarf_vmatoa ("x", cu_offset + uvalue));
+         break;
+       case DW_OP_GNU_convert:
+         uvalue = read_leb128 (data, &bytes_read, 0);
+         data += bytes_read;
+         printf ("DW_OP_GNU_convert <0x%s>",
+                 dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0));
+         break;
+       case DW_OP_GNU_reinterpret:
+         uvalue = read_leb128 (data, &bytes_read, 0);
+         data += bytes_read;
+         printf ("DW_OP_GNU_reinterpret <0x%s>",
+                 dwarf_vmatoa ("x", uvalue ? cu_offset + uvalue : 0));
+         break;
+       case DW_OP_GNU_parameter_ref:
+         printf ("DW_OP_GNU_parameter_ref: <0x%s>",
+                 dwarf_vmatoa ("x", cu_offset + byte_get (data, 4)));
+         data += 4;
+         break;
 
          /* HP extensions.  */
        case DW_OP_HP_is_value:
@@ -1367,7 +1466,8 @@ read_and_display_attr_value (unsigned long attribute,
     }
 
   if ((do_loc || do_debug_loc || do_debug_ranges)
-      && num_debug_info_entries == 0)
+      && num_debug_info_entries == 0
+      && debug_info_p != NULL)
     {
       switch (attribute)
        {
@@ -1926,7 +2026,7 @@ process_debug_info (struct dwarf_section *section,
       && num_debug_info_entries == 0
       && ! do_types)
     {
-      unsigned long length;
+      dwarf_vma length;
 
       /* First scan the section to get the number of comp units.  */
       for (section_begin = start, num_units = 0; section_begin < end;
@@ -1944,7 +2044,8 @@ process_debug_info (struct dwarf_section *section,
            }
          else if (length >= 0xfffffff0 && length < 0xffffffff)
            {
-             warn (_("Reserved length value (%lx) found in section %s\n"), length, section->name);
+             warn (_("Reserved length value (0x%s) found in section %s\n"),
+                   dwarf_vmatoa ("x", length), section->name);
              return 0;
            }
          else
@@ -1955,7 +2056,8 @@ process_debug_info (struct dwarf_section *section,
             relocations to an object file.  */
          if ((signed long) length <= 0)
            {
-             warn (_("Corrupt unit length (%lx) found in section %s\n"), length, section->name);
+             warn (_("Corrupt unit length (0x%s) found in section %s\n"),
+                   dwarf_vmatoa ("x", length), section->name);
              return 0;
            }
        }
@@ -1979,7 +2081,8 @@ process_debug_info (struct dwarf_section *section,
 
   if (!do_loc)
     {
-      printf (_("Contents of the %s section:\n\n"), section->name);
+      if (dwarf_start_die == 0)
+       printf (_("Contents of the %s section:\n\n"), section->name);
 
       load_debug_section (str, file);
     }
@@ -1997,12 +2100,12 @@ process_debug_info (struct dwarf_section *section,
       DWARF2_Internal_CompUnit compunit;
       unsigned char *hdrptr;
       unsigned char *tags;
-      int level;
+      int level, last_level, saved_level;
       dwarf_vma cu_offset;
       int offset_size;
       int initial_length_size;
       unsigned char signature[8] = { 0 };
-      unsigned long type_offset = 0;
+      dwarf_vma type_offset = 0;
 
       hdrptr = start;
 
@@ -2066,7 +2169,7 @@ process_debug_info (struct dwarf_section *section,
          debug_information [unit].num_range_lists = 0;
        }
 
-      if (!do_loc)
+      if (!do_loc && dwarf_start_die == 0)
        {
          printf (_("  Compilation Unit @ offset 0x%s:\n"),
                  dwarf_vmatoa ("x", cu_offset));
@@ -2084,7 +2187,8 @@ process_debug_info (struct dwarf_section *section,
              for (i = 0; i < 8; i++)
                printf ("%02x", signature[i]);
              printf ("\n");
-             printf (_("   Type Offset:   0x%lx\n"), type_offset);
+             printf (_("   Type Offset:   0x%s\n"),
+                     dwarf_vmatoa ("x", type_offset));
            }
        }
 
@@ -2126,6 +2230,8 @@ process_debug_info (struct dwarf_section *section,
           + debug_displays [abbrev_sec].section.size);
 
       level = 0;
+      last_level = level;
+      saved_level = -1;
       while (tags < start)
        {
          unsigned int bytes_read;
@@ -2133,6 +2239,7 @@ process_debug_info (struct dwarf_section *section,
          unsigned long die_offset;
          abbrev_entry *entry;
          abbrev_attr *attr;
+         int do_printing = 1;
 
          die_offset = tags - section_begin;
 
@@ -2169,12 +2276,30 @@ process_debug_info (struct dwarf_section *section,
                        warn (_("Further warnings about bogus end-of-sibling markers suppressed\n"));
                    }
                }
+             if (dwarf_start_die != 0 && level < saved_level)
+               return 1;
              continue;
            }
 
          if (!do_loc)
-           printf (_(" <%d><%lx>: Abbrev Number: %lu"),
-                   level, die_offset, abbrev_number);
+           {
+             if (dwarf_start_die != 0 && die_offset < dwarf_start_die)
+               do_printing = 0;
+             else
+               {
+                 if (dwarf_start_die != 0 && die_offset == dwarf_start_die)
+                   saved_level = level;
+                 do_printing = (dwarf_cutoff_level == -1
+                                || level < dwarf_cutoff_level);
+                 if (do_printing)
+                   printf (_(" <%d><%lx>: Abbrev Number: %lu"),
+                           level, die_offset, abbrev_number);
+                 else if (dwarf_cutoff_level == -1
+                          || last_level < dwarf_cutoff_level)
+                   printf (_(" <%d><%lx>: ...\n"), level, die_offset);
+                 last_level = level;
+               }
+           }
 
          /* Scan through the abbreviation list until we reach the
             correct entry.  */
@@ -2185,7 +2310,7 @@ process_debug_info (struct dwarf_section *section,
 
          if (entry == NULL)
            {
-             if (!do_loc)
+             if (!do_loc && do_printing)
                {
                  printf ("\n");
                  fflush (stdout);
@@ -2195,7 +2320,7 @@ process_debug_info (struct dwarf_section *section,
              return 0;
            }
 
-         if (!do_loc)
+         if (!do_loc && do_printing)
            printf (" (%s)\n", get_TAG_name (entry->tag));
 
          switch (entry->tag)
@@ -2216,9 +2341,15 @@ process_debug_info (struct dwarf_section *section,
 
          for (attr = entry->first_attr; attr; attr = attr->next)
            {
-             if (! do_loc)
+             debug_info *arg;
+
+             if (! do_loc && do_printing)
                /* Show the offset from where the tag was extracted.  */
-               printf ("    <%2lx>", (unsigned long)(tags - section_begin));
+               printf ("    <%lx>", (unsigned long)(tags - section_begin));
+
+             arg = debug_information;
+             if (debug_information)
+               arg += unit;
 
              tags = read_and_display_attr (attr->attribute,
                                            attr->form,
@@ -2226,8 +2357,8 @@ process_debug_info (struct dwarf_section *section,
                                            compunit.cu_pointer_size,
                                            offset_size,
                                            compunit.cu_version,
-                                           debug_information + unit,
-                                           do_loc, section);
+                                           arg,
+                                           do_loc || ! do_printing, section);
            }
 
          if (entry->children)
@@ -3362,6 +3493,19 @@ display_debug_abbrev (struct dwarf_section *section,
   return 1;
 }
 
+/* Sort array of indexes in ascending order of loc_offsets[idx].  */
+
+static dwarf_vma *loc_offsets;
+
+static int
+loc_offsets_compar (const void *ap, const void *bp)
+{
+  dwarf_vma a = loc_offsets[*(const unsigned int *) ap];
+  dwarf_vma b = loc_offsets[*(const unsigned int *) bp];
+
+  return (a > b) - (b > a);
+}
+
 static int
 display_debug_loc (struct dwarf_section *section, void *file)
 {
@@ -3374,9 +3518,11 @@ display_debug_loc (struct dwarf_section *section, void *file)
   unsigned int first = 0;
   unsigned int i;
   unsigned int j;
+  unsigned int k;
   int seen_first_offset = 0;
-  int use_debug_info = 1;
+  int locs_sorted = 1;
   unsigned char *next;
+  unsigned int *array = NULL;
 
   bytes = section->size;
   section_end = start + bytes;
@@ -3402,10 +3548,11 @@ display_debug_loc (struct dwarf_section *section, void *file)
       unsigned int num;
 
       num = debug_information [i].num_loc_offsets;
-      num_loc_list += num;
+      if (num > num_loc_list)
+       num_loc_list = num;
 
       /* Check if we can use `debug_information' directly.  */
-      if (use_debug_info && num != 0)
+      if (locs_sorted && num != 0)
        {
          if (!seen_first_offset)
            {
@@ -3423,7 +3570,7 @@ display_debug_loc (struct dwarf_section *section, void *file)
              if (last_offset >
                  debug_information [i].loc_offsets [j])
                {
-                 use_debug_info = 0;
+                 locs_sorted = 0;
                  break;
                }
              last_offset = debug_information [i].loc_offsets [j];
@@ -3431,10 +3578,6 @@ display_debug_loc (struct dwarf_section *section, void *file)
        }
     }
 
-  if (!use_debug_info)
-    /* FIXME: Should we handle this case?  */
-    error (_("Location lists in .debug_info section aren't in ascending order!\n"));
-
   if (!seen_first_offset)
     error (_("No location lists in .debug_info section!\n"));
 
@@ -3445,6 +3588,8 @@ display_debug_loc (struct dwarf_section *section, void *file)
          section->name,
          dwarf_vmatoa ("x", debug_information [first].loc_offsets [0]));
 
+  if (!locs_sorted)
+    array = (unsigned int *) xcmalloc (num_loc_list, sizeof (unsigned int));
   printf (_("Contents of the %s section:\n\n"), section->name);
   printf (_("    Offset   Begin    End      Expression\n"));
 
@@ -3467,9 +3612,23 @@ display_debug_loc (struct dwarf_section *section, void *file)
       cu_offset = debug_information [i].cu_offset;
       offset_size = debug_information [i].offset_size;
       dwarf_version = debug_information [i].dwarf_version;
+      if (!locs_sorted)
+       {
+         for (k = 0; k < debug_information [i].num_loc_offsets; k++)
+           array[k] = k;
+         loc_offsets = debug_information [i].loc_offsets;
+         qsort (array, debug_information [i].num_loc_offsets,
+                sizeof (*array), loc_offsets_compar);
+       }
 
-      for (j = 0; j < debug_information [i].num_loc_offsets; j++)
+      for (k = 0; k < debug_information [i].num_loc_offsets; k++)
        {
+         j = locs_sorted ? k : array[k];
+         if (k
+             && debug_information [i].loc_offsets [locs_sorted
+                                                   ? k - 1 : array [k - 1]]
+                == debug_information [i].loc_offsets [j])
+           continue;
          has_frame_base = debug_information [i].have_frame_base [j];
          /* DWARF sections under Mach-O have non-zero addresses.  */
          offset = debug_information [i].loc_offsets [j] - section->address;
@@ -3583,6 +3742,7 @@ display_debug_loc (struct dwarf_section *section, void *file)
     warn (_("There are %ld unused bytes at the end of section %s\n"),
          (long) (section_end - start), section->name);
   putchar ('\n');
+  free (array);
   return 1;
 }
 
@@ -4073,6 +4233,7 @@ init_dwarf_regnames (unsigned int e_machine)
 
     case EM_X86_64:
     case EM_L1OM:
+    case EM_K1OM:
       init_dwarf_regnames_x86_64 ();
       break;
 
@@ -5020,6 +5181,9 @@ display_gdb_index (struct dwarf_section *section,
       warn (_("The address table data in version 3 may be wrong.\n"));
       break;
     case 4:
+      warn (_("Version 4 does not support case insensitive lookups.\n"));
+      break;
+    case 5:
       break;
     default:
       warn (_("Unsupported version %lu.\n"), (unsigned long) version);
@@ -5108,8 +5272,8 @@ display_gdb_index (struct dwarf_section *section,
            {
              cu = byte_get_little_endian (constant_pool + cu_vector_offset + 4 + j * 4, 4);
              /* Convert to TU number if it's for a type unit.  */
-             if (cu >= cu_list_elements)
-               printf (" T%lu", (unsigned long) (cu - cu_list_elements));
+             if (cu >= cu_list_elements / 2)
+               printf (" T%lu", (unsigned long) (cu - cu_list_elements / 2));
              else
                printf (" %lu", (unsigned long) cu);
            }
This page took 0.032643 seconds and 4 git commands to generate.